@tangle-network/agent-integrations 0.53.46 → 0.53.48

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.
Files changed (54) hide show
  1. package/dist/catalog.d.ts +2 -2
  2. package/dist/catalog.js +9 -9
  3. package/dist/{chunk-AAIEUJSS.js → chunk-CBWD2IOL.js} +251 -10
  4. package/dist/chunk-CBWD2IOL.js.map +1 -0
  5. package/dist/{chunk-TP4MD4PD.js → chunk-EZR72HCQ.js} +2 -2
  6. package/dist/{chunk-ATIOKZO5.js → chunk-GY4PFAWA.js} +380 -63
  7. package/dist/chunk-GY4PFAWA.js.map +1 -0
  8. package/dist/{chunk-CMNY7MMC.js → chunk-HNEEIMQC.js} +2732 -500
  9. package/dist/{chunk-CMNY7MMC.js.map → chunk-HNEEIMQC.js.map} +1 -1
  10. package/dist/{chunk-JR2RWYQO.js → chunk-I5EF5KIT.js} +2 -2
  11. package/dist/{chunk-7UEPOLGS.js → chunk-PXOM5AVK.js} +7 -2
  12. package/dist/{chunk-7UEPOLGS.js.map → chunk-PXOM5AVK.js.map} +1 -1
  13. package/dist/{chunk-EKSAOR2I.js → chunk-Q7TDHVRZ.js} +2 -2
  14. package/dist/{chunk-WE7SQ7PB.js → chunk-RRSNINEV.js} +15 -3
  15. package/dist/chunk-RRSNINEV.js.map +1 -0
  16. package/dist/{chunk-AG4ORH2A.js → chunk-TKEVCGAI.js} +6 -6
  17. package/dist/chunk-TKEVCGAI.js.map +1 -0
  18. package/dist/connect/index.d.ts +2 -2
  19. package/dist/connect/index.js +2 -2
  20. package/dist/connectors/adapters/index.d.ts +50 -3
  21. package/dist/connectors/adapters/index.js +18 -2
  22. package/dist/connectors/index.d.ts +37 -12
  23. package/dist/connectors/index.js +19 -3
  24. package/dist/{consumer-UnsjK9iM.d.ts → consumer-BcFIDgMD.d.ts} +1 -1
  25. package/dist/consumer.d.ts +3 -3
  26. package/dist/consumer.js +2 -2
  27. package/dist/{core-types-Cx53j2Xp.d.ts → core-types-CE1oMiuI.d.ts} +7 -1
  28. package/dist/coverage-catalog.d.ts +2 -2
  29. package/dist/coverage-catalog.js +1 -1
  30. package/dist/{importers-YLXwPCz_.d.ts → importers-CHOC-2Y8.d.ts} +1 -1
  31. package/dist/index.d.ts +13 -12
  32. package/dist/index.js +25 -9
  33. package/dist/mcp.d.ts +3 -3
  34. package/dist/mcp.js +9 -9
  35. package/dist/middleware/index.d.ts +2 -2
  36. package/dist/middleware/index.js +2 -2
  37. package/dist/registry.d.ts +2 -2
  38. package/dist/registry.js +9 -9
  39. package/dist/runtime.d.ts +2 -2
  40. package/dist/runtime.js +9 -9
  41. package/dist/specs.d.ts +11 -3
  42. package/dist/specs.js +5 -5
  43. package/dist/{tangle-id--7mgjNkq.d.ts → tangle-id-BL_JQwKA.d.ts} +1 -1
  44. package/dist/{types-qFsboS2G.d.ts → types-EXGqQYoU.d.ts} +25 -10
  45. package/docs/integration-execution-audit.md +17 -11
  46. package/docs/integration-execution-matrix.json +837 -304
  47. package/package.json +1 -1
  48. package/dist/chunk-AAIEUJSS.js.map +0 -1
  49. package/dist/chunk-AG4ORH2A.js.map +0 -1
  50. package/dist/chunk-ATIOKZO5.js.map +0 -1
  51. package/dist/chunk-WE7SQ7PB.js.map +0 -1
  52. /package/dist/{chunk-TP4MD4PD.js.map → chunk-EZR72HCQ.js.map} +0 -0
  53. /package/dist/{chunk-JR2RWYQO.js.map → chunk-I5EF5KIT.js.map} +0 -0
  54. /package/dist/{chunk-EKSAOR2I.js.map → chunk-Q7TDHVRZ.js.map} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  TangleIdentityUnreachableError,
15
15
  createTangleIdentityClient,
16
16
  tangleIdentity
17
- } from "./chunk-WE7SQ7PB.js";
17
+ } from "./chunk-RRSNINEV.js";
18
18
  import {
19
19
  __export
20
20
  } from "./chunk-PZ5AY32C.js";
@@ -50,7 +50,9 @@ __export(adapters_exports, {
50
50
  altTextAiConnector: () => altTextAiConnector,
51
51
  alttextifyConnector: () => alttextifyConnector,
52
52
  amazonBedrockConnector: () => amazonBedrockConnector,
53
+ amazonCloudWatchConnector: () => amazonCloudWatchConnector,
53
54
  amazonEventBridgeConnector: () => amazonEventBridgeConnector,
55
+ amazonLambdaConnector: () => amazonLambdaConnector,
54
56
  amazonS3Connector: () => amazonS3Connector,
55
57
  amazonSecretsManagerConnector: () => amazonSecretsManagerConnector,
56
58
  amazonSesConnector: () => amazonSesConnector,
@@ -60,6 +62,7 @@ __export(adapters_exports, {
60
62
  aminosConnector: () => aminosConnector,
61
63
  ampecoConnector: () => ampecoConnector,
62
64
  amplemarketConnector: () => amplemarketConnector,
65
+ amplitudeConnector: () => amplitudeConnector,
63
66
  anthropicConnector: () => anthropicConnector,
64
67
  anyhookWebsocketConnector: () => anyhookWebsocketConnector,
65
68
  apifyConnector: () => apifyConnector,
@@ -118,6 +121,7 @@ __export(adapters_exports, {
118
121
  browseAiConnector: () => browseAiConnector,
119
122
  builtwithConnector: () => builtwithConnector,
120
123
  buttondownConnector: () => buttondownConnector,
124
+ calCom: () => calCom,
121
125
  calComConnector: () => calComConnector,
122
126
  calendlyConnector: () => calendlyConnector,
123
127
  cambAiConnector: () => cambAiConnector,
@@ -161,6 +165,7 @@ __export(adapters_exports, {
161
165
  clockodoConnector: () => clockodoConnector,
162
166
  closeConnector: () => closeConnector,
163
167
  cloudconvertConnector: () => cloudconvertConnector,
168
+ cloudflareConnector: () => cloudflareConnector,
164
169
  cloudinaryConnector: () => cloudinaryConnector,
165
170
  cloutlyConnector: () => cloutlyConnector,
166
171
  codaConnector: () => codaConnector,
@@ -182,6 +187,7 @@ __export(adapters_exports, {
182
187
  copyAiConnector: () => copyAiConnector,
183
188
  couchbaseConnector: () => couchbaseConnector,
184
189
  createKafkaConnector: () => createKafkaConnector,
190
+ createLinkedinConnector: () => createLinkedinConnector,
185
191
  createMongoDbConnector: () => createMongoDbConnector,
186
192
  createMySqlConnector: () => createMySqlConnector,
187
193
  createPostgresConnector: () => createPostgresConnector,
@@ -603,6 +609,8 @@ __export(adapters_exports, {
603
609
  textcortexAiConnector: () => textcortexAiConnector,
604
610
  theirstackConnector: () => theirstackConnector,
605
611
  ticktickConnector: () => ticktickConnector,
612
+ tiktok: () => tiktok,
613
+ tiktokConnector: () => tiktokConnector,
606
614
  timeOpsConnector: () => timeOpsConnector,
607
615
  timelinesAiConnector: () => timelinesAiConnector,
608
616
  tlDvConnector: () => tlDvConnector,
@@ -746,8 +754,8 @@ function signSigV4(input) {
746
754
  const authorization = `${ALGORITHM} Credential=${accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
747
755
  return { amzDate, signedHeaders, canonicalRequest, stringToSign, signature, authorization };
748
756
  }
749
- function amzDateNow(date = /* @__PURE__ */ new Date()) {
750
- return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
757
+ function amzDateNow(date2 = /* @__PURE__ */ new Date()) {
758
+ return date2.toISOString().replace(/[:-]|\.\d{3}/g, "");
751
759
  }
752
760
  function hashSha256Hex(data4) {
753
761
  return createHash("sha256").update(data4, "utf8").digest("hex");
@@ -956,7 +964,7 @@ async function executeRestRequest(spec, request4, inv, requiredArgs) {
956
964
  const headers = {
957
965
  accept: "application/json",
958
966
  ...renderHeaders(spec.defaultHeaders ?? {}, scope, true),
959
- ...renderHeaders(renderableHeaders, scope)
967
+ ...renderHeaders(renderableHeaders, scope, false, requiredArgs)
960
968
  };
961
969
  const structuredCredentials = placement.kind === "structured-headers" || placement.kind === "structured-json-body" ? readStructuredCredentials(inv.source.credentials, placement.fields) : placement.kind === "basic-structured" ? readStructuredCredentials(inv.source.credentials, {
962
970
  [placement.usernameField]: placement.usernameField,
@@ -1010,7 +1018,8 @@ async function executeRestRequest(spec, request4, inv, requiredArgs) {
1010
1018
  body: bodyString,
1011
1019
  signal: AbortSignal.timeout(2e4)
1012
1020
  });
1013
- if (res.status === 401 || res.status === 403) {
1021
+ const credentialsExpiredStatuses = spec.credentialsExpiredStatuses ?? [401, 403];
1022
+ if (credentialsExpiredStatuses.includes(res.status)) {
1014
1023
  throw new CredentialsExpired(`${spec.displayName} rejected credentials (${res.status})`, inv.source.id);
1015
1024
  }
1016
1025
  if (res.status === 409 || res.status === 412) {
@@ -1187,7 +1196,12 @@ function credentialToken(credentials) {
1187
1196
  }
1188
1197
  function redactCredentialText(text, credentials, additionalSecrets = []) {
1189
1198
  const candidates = credentials.kind === "oauth2" ? [credentials.accessToken, credentials.refreshToken] : credentials.kind === "api-key" ? [credentials.apiKey, ...jsonStringValues(credentials.apiKey)] : credentials.kind === "custom" ? Object.values(credentials.values) : [];
1190
- const secrets = [...candidates, ...additionalSecrets].filter(
1199
+ const authorizationSecrets = additionalSecrets.flatMap((secret) => {
1200
+ if (typeof secret !== "string") return [];
1201
+ const credential2 = secret.match(/^(?:Basic|Bearer)\s+(.+)$/i)?.[1];
1202
+ return credential2 ? [secret, credential2] : [secret];
1203
+ });
1204
+ const secrets = [...candidates, ...authorizationSecrets].filter(
1191
1205
  (secret) => typeof secret === "string" && secret.length > 0
1192
1206
  );
1193
1207
  return secrets.reduce(
@@ -1269,12 +1283,24 @@ function retryAfterMsFromHeader(raw) {
1269
1283
  function renderScope(inv, credentialDefaults) {
1270
1284
  return { ...credentialDefaults, ...inv.args, connection: inv.source.metadata };
1271
1285
  }
1272
- function renderHeaders(headers, args, rawExact = false) {
1273
- return Object.fromEntries(Object.entries(headers).map(([key, value]) => {
1286
+ function renderHeaders(headers, args, rawExact = false, requiredArgs) {
1287
+ const out = {};
1288
+ for (const [key, value] of Object.entries(headers)) {
1274
1289
  const exact = value.match(/^\{([a-zA-Z0-9_.-]+)\}$/);
1275
- if (rawExact && exact) return [key, String(readRequiredPath(args, exact[1]))];
1276
- return [key, interpolate(value, args)];
1277
- }));
1290
+ if (exact) {
1291
+ const resolved = readPath(args, exact[1]);
1292
+ if (resolved === void 0 || resolved === null) {
1293
+ if (rawExact || requiredArgs?.includes(exact[1])) {
1294
+ throw new Error(`missing required argument: ${exact[1]}`);
1295
+ }
1296
+ continue;
1297
+ }
1298
+ out[key] = rawExact ? String(resolved) : encodeURIComponent(String(resolved));
1299
+ continue;
1300
+ }
1301
+ out[key] = interpolate(value, args);
1302
+ }
1303
+ return out;
1278
1304
  }
1279
1305
  function renderObject(input, args, requiredArgs) {
1280
1306
  const out = {};
@@ -20102,6 +20128,332 @@ function arbitraryBodyParameters() {
20102
20128
  };
20103
20129
  }
20104
20130
 
20131
+ // src/connectors/adapters/amplitude.ts
20132
+ var date = {
20133
+ type: "string",
20134
+ pattern: "^[0-9]{8}$",
20135
+ description: "Inclusive date in YYYYMMDD format."
20136
+ };
20137
+ var isoTimestamp = {
20138
+ type: "string",
20139
+ description: "ISO 8601 timestamp with a time-zone offset."
20140
+ };
20141
+ var annotationId = {
20142
+ annotationId: { type: "integer", minimum: 1, description: "Amplitude annotation ID." }
20143
+ };
20144
+ var categoryId = {
20145
+ categoryId: { type: "integer", minimum: 1, description: "Amplitude annotation category ID." }
20146
+ };
20147
+ var annotation = {
20148
+ type: "object",
20149
+ properties: {
20150
+ label: { type: "string", minLength: 1 },
20151
+ start: isoTimestamp,
20152
+ category: { type: "string" },
20153
+ chart_id: { type: ["string", "null"] },
20154
+ details: { type: "string" },
20155
+ end: { ...isoTimestamp, type: ["string", "null"] }
20156
+ },
20157
+ required: ["label", "start"],
20158
+ additionalProperties: false
20159
+ };
20160
+ var amplitudeConnector = declarativeRestConnector({
20161
+ kind: "amplitude",
20162
+ displayName: "Amplitude",
20163
+ description: "Query project analytics and manage chart annotations with Amplitude project API credentials.",
20164
+ auth: {
20165
+ kind: "api-key",
20166
+ hint: 'JSON credential bundle: {"apiKey":"...","secretKey":"..."} from Project Settings \u2192 General. Set metadata.apiBaseUrl to https://analytics.eu.amplitude.com only for an EU-resident project; the default is https://amplitude.com.'
20167
+ },
20168
+ category: "other",
20169
+ defaultConsistencyModel: "authoritative",
20170
+ baseUrl: { metadataKey: "apiBaseUrl", fallback: "https://amplitude.com" },
20171
+ allowedBaseUrls: ["https://amplitude.com", "https://analytics.eu.amplitude.com"],
20172
+ credentialPlacement: {
20173
+ kind: "basic-structured",
20174
+ usernameField: "apiKey",
20175
+ passwordField: "secretKey"
20176
+ },
20177
+ test: { method: "GET", path: "/api/2/events/list" },
20178
+ capabilities: [
20179
+ {
20180
+ name: "events.list",
20181
+ class: "read",
20182
+ description: "List visible project events with current-week totals, uniques, and daily-active-user share.",
20183
+ parameters: { type: "object", properties: {} },
20184
+ request: { method: "GET", path: "/api/2/events/list" }
20185
+ },
20186
+ {
20187
+ name: "events.segment",
20188
+ class: "read",
20189
+ description: "Query event totals, uniques, percentages, averages, or formulas over a date range.",
20190
+ parameters: {
20191
+ type: "object",
20192
+ properties: {
20193
+ event: {
20194
+ type: "string",
20195
+ description: 'JSON event definition, for example {"event_type":"_active"}.'
20196
+ },
20197
+ secondEvent: { type: "string", description: "Optional second JSON event definition." },
20198
+ metric: {
20199
+ type: "string",
20200
+ enum: ["uniques", "totals", "pct_dau", "average", "histogram", "sums", "value_avg", "formula"]
20201
+ },
20202
+ activeUserType: { type: "string", enum: ["any", "active"] },
20203
+ start: date,
20204
+ end: date,
20205
+ interval: { type: "integer", enum: [-3e5, -36e5, 1, 7, 30] },
20206
+ segment: { type: "string", description: "JSON array of Amplitude segment definitions." },
20207
+ groupBy: { type: "string" },
20208
+ secondGroupBy: { type: "string" },
20209
+ limit: { type: "integer", minimum: 1, maximum: 1e3 },
20210
+ formula: { type: "string" },
20211
+ rollingWindow: { type: "integer", minimum: 1 },
20212
+ rollingAverage: { type: "integer", minimum: 1 }
20213
+ },
20214
+ required: ["event", "start", "end"]
20215
+ },
20216
+ request: {
20217
+ method: "GET",
20218
+ path: "/api/2/events/segmentation",
20219
+ query: {
20220
+ e: "{event}",
20221
+ e2: "{secondEvent}",
20222
+ m: "{metric}",
20223
+ n: "{activeUserType}",
20224
+ start: "{start}",
20225
+ end: "{end}",
20226
+ i: "{interval}",
20227
+ s: "{segment}",
20228
+ g: "{groupBy}",
20229
+ g2: "{secondGroupBy}",
20230
+ limit: "{limit}",
20231
+ formula: "{formula}",
20232
+ rollingWindow: "{rollingWindow}",
20233
+ rollingAverage: "{rollingAverage}"
20234
+ }
20235
+ }
20236
+ },
20237
+ {
20238
+ name: "users.counts",
20239
+ class: "read",
20240
+ description: "Get active or new user counts over a date range.",
20241
+ parameters: {
20242
+ type: "object",
20243
+ properties: {
20244
+ start: date,
20245
+ end: date,
20246
+ mode: { type: "string", enum: ["active", "new"] },
20247
+ interval: { type: "integer", enum: [1, 7, 30] },
20248
+ segment: { type: "string", description: "JSON array of Amplitude segment definitions." },
20249
+ groupBy: { type: "string" }
20250
+ },
20251
+ required: ["start", "end"]
20252
+ },
20253
+ request: {
20254
+ method: "GET",
20255
+ path: "/api/2/users",
20256
+ query: {
20257
+ start: "{start}",
20258
+ end: "{end}",
20259
+ m: "{mode}",
20260
+ i: "{interval}",
20261
+ s: "{segment}",
20262
+ g: "{groupBy}"
20263
+ }
20264
+ }
20265
+ },
20266
+ {
20267
+ name: "sessions.average-length",
20268
+ class: "read",
20269
+ description: "Get average session length in seconds for each day in a date range.",
20270
+ parameters: {
20271
+ type: "object",
20272
+ properties: { start: date, end: date },
20273
+ required: ["start", "end"]
20274
+ },
20275
+ request: {
20276
+ method: "GET",
20277
+ path: "/api/2/sessions/average",
20278
+ query: { start: "{start}", end: "{end}" }
20279
+ }
20280
+ },
20281
+ {
20282
+ name: "users.search",
20283
+ class: "read",
20284
+ description: "Search for a user by Amplitude ID, device ID, user ID, or user ID prefix.",
20285
+ parameters: {
20286
+ type: "object",
20287
+ properties: { user: { type: "string", minLength: 1 } },
20288
+ required: ["user"]
20289
+ },
20290
+ request: { method: "GET", path: "/api/2/usersearch", query: { user: "{user}" } }
20291
+ },
20292
+ {
20293
+ name: "users.activity",
20294
+ class: "read",
20295
+ description: "Read one user summary and a bounded window of recent or earliest events.",
20296
+ parameters: {
20297
+ type: "object",
20298
+ properties: {
20299
+ user: { type: "string", minLength: 1, description: "Amplitude user ID." },
20300
+ offset: { type: "integer", minimum: 0 },
20301
+ limit: { type: "integer", minimum: 0, maximum: 1e3 },
20302
+ direction: { type: "string", enum: ["earliest", "latest"] }
20303
+ },
20304
+ required: ["user"]
20305
+ },
20306
+ request: {
20307
+ method: "GET",
20308
+ path: "/api/2/useractivity",
20309
+ query: { user: "{user}", offset: "{offset}", limit: "{limit}", direction: "{direction}" }
20310
+ }
20311
+ },
20312
+ {
20313
+ name: "charts.results",
20314
+ class: "read",
20315
+ description: "Export results from one saved Amplitude chart by chart ID.",
20316
+ parameters: {
20317
+ type: "object",
20318
+ properties: { chartId: { type: "string", minLength: 1 } },
20319
+ required: ["chartId"]
20320
+ },
20321
+ request: { method: "GET", path: "/api/3/chart/{chartId}/csv" }
20322
+ },
20323
+ {
20324
+ name: "annotations.list",
20325
+ class: "read",
20326
+ description: "List project chart annotations with optional category, chart, and date filters.",
20327
+ parameters: {
20328
+ type: "object",
20329
+ properties: {
20330
+ category: { type: "string" },
20331
+ chartId: { type: "string" },
20332
+ start: isoTimestamp,
20333
+ end: isoTimestamp
20334
+ }
20335
+ },
20336
+ request: {
20337
+ method: "GET",
20338
+ path: "/api/3/annotations",
20339
+ query: { category: "{category}", chart_id: "{chartId}", start: "{start}", end: "{end}" }
20340
+ }
20341
+ },
20342
+ {
20343
+ name: "annotations.get",
20344
+ class: "read",
20345
+ description: "Read one chart annotation by ID.",
20346
+ parameters: { type: "object", properties: annotationId, required: ["annotationId"] },
20347
+ request: { method: "GET", path: "/api/3/annotations/{annotationId}" }
20348
+ },
20349
+ {
20350
+ name: "annotations.create",
20351
+ class: "mutation",
20352
+ description: "Create a project-wide or chart-specific annotation.",
20353
+ parameters: {
20354
+ type: "object",
20355
+ properties: { annotation },
20356
+ required: ["annotation"]
20357
+ },
20358
+ request: { method: "POST", path: "/api/3/annotations", body: "{annotation}" },
20359
+ cas: "none",
20360
+ externalEffect: true
20361
+ },
20362
+ {
20363
+ name: "annotations.update",
20364
+ class: "mutation",
20365
+ description: "Partially update one annotation.",
20366
+ parameters: {
20367
+ type: "object",
20368
+ properties: {
20369
+ ...annotationId,
20370
+ changes: {
20371
+ ...annotation,
20372
+ required: []
20373
+ }
20374
+ },
20375
+ required: ["annotationId", "changes"]
20376
+ },
20377
+ request: { method: "PUT", path: "/api/3/annotations/{annotationId}", body: "{changes}" },
20378
+ cas: "optimistic-read-verify",
20379
+ externalEffect: true
20380
+ },
20381
+ {
20382
+ name: "annotations.delete",
20383
+ class: "mutation",
20384
+ description: "Permanently delete one annotation.",
20385
+ parameters: { type: "object", properties: annotationId, required: ["annotationId"] },
20386
+ request: { method: "DELETE", path: "/api/3/annotations/{annotationId}" },
20387
+ cas: "optimistic-read-verify",
20388
+ externalEffect: true
20389
+ },
20390
+ {
20391
+ name: "annotation-categories.list",
20392
+ class: "read",
20393
+ description: "List annotation categories or filter by exact category name.",
20394
+ parameters: {
20395
+ type: "object",
20396
+ properties: { category: { type: "string" } }
20397
+ },
20398
+ request: {
20399
+ method: "GET",
20400
+ path: "/api/3/annotation-categories",
20401
+ query: { category: "{category}" }
20402
+ }
20403
+ },
20404
+ {
20405
+ name: "annotation-categories.get",
20406
+ class: "read",
20407
+ description: "Read one annotation category by ID.",
20408
+ parameters: { type: "object", properties: categoryId, required: ["categoryId"] },
20409
+ request: { method: "GET", path: "/api/3/annotation-categories/{categoryId}" }
20410
+ },
20411
+ {
20412
+ name: "annotation-categories.create",
20413
+ class: "mutation",
20414
+ description: "Create an annotation category.",
20415
+ parameters: {
20416
+ type: "object",
20417
+ properties: { category: { type: "string", minLength: 1 } },
20418
+ required: ["category"]
20419
+ },
20420
+ request: {
20421
+ method: "POST",
20422
+ path: "/api/3/annotation-categories",
20423
+ body: { category: "{category}" }
20424
+ },
20425
+ cas: "none",
20426
+ externalEffect: true
20427
+ },
20428
+ {
20429
+ name: "annotation-categories.update",
20430
+ class: "mutation",
20431
+ description: "Rename one annotation category.",
20432
+ parameters: {
20433
+ type: "object",
20434
+ properties: { ...categoryId, category: { type: "string", minLength: 1 } },
20435
+ required: ["categoryId", "category"]
20436
+ },
20437
+ request: {
20438
+ method: "PUT",
20439
+ path: "/api/3/annotation-categories/{categoryId}",
20440
+ body: { category: "{category}" }
20441
+ },
20442
+ cas: "optimistic-read-verify",
20443
+ externalEffect: true
20444
+ },
20445
+ {
20446
+ name: "annotation-categories.delete",
20447
+ class: "mutation",
20448
+ description: "Permanently delete one annotation category.",
20449
+ parameters: { type: "object", properties: categoryId, required: ["categoryId"] },
20450
+ request: { method: "DELETE", path: "/api/3/annotation-categories/{categoryId}" },
20451
+ cas: "optimistic-read-verify",
20452
+ externalEffect: true
20453
+ }
20454
+ ]
20455
+ });
20456
+
20105
20457
  // src/connectors/adapters/amazon-eventbridge.ts
20106
20458
  var amazonEventBridgeConnector = declarativeRestConnector({
20107
20459
  kind: "amazon-eventbridge",
@@ -20441,6 +20793,717 @@ var amazonEventBridgeConnector = declarativeRestConnector({
20441
20793
  ]
20442
20794
  });
20443
20795
 
20796
+ // src/connectors/adapters/amazon-cloudwatch.ts
20797
+ var target = (operation) => `GraniteServiceVersion20100801.${operation}`;
20798
+ var amazonCloudWatchConnector = declarativeRestConnector({
20799
+ kind: "aws-cloudwatch",
20800
+ displayName: "AWS CloudWatch",
20801
+ description: "Read and publish CloudWatch metrics, manage metric alarms, and manage dashboards.",
20802
+ auth: {
20803
+ kind: "api-key",
20804
+ hint: 'AWS credentials as JSON: {"accessKeyId":"AKIA\u2026","secretAccessKey":"\u2026","region":"us-east-1"}. Optional "sessionToken" and "endpoint" support temporary credentials and local AWS-compatible endpoints.'
20805
+ },
20806
+ category: "other",
20807
+ // Metric publication is eventually consistent and cannot be deduplicated by
20808
+ // a caller-provided key. Alarm and dashboard writes use stronger CAS labels.
20809
+ defaultConsistencyModel: "advisory",
20810
+ credentialPlacement: { kind: "aws-sigv4", service: "monitoring" },
20811
+ baseUrl: {
20812
+ metadataKey: "endpoint",
20813
+ fallback: "https://monitoring.{region}.amazonaws.com"
20814
+ },
20815
+ defaultHeaders: {
20816
+ "Content-Type": "application/x-amz-json-1.0"
20817
+ },
20818
+ test: {
20819
+ method: "POST",
20820
+ path: "/",
20821
+ headers: { "X-Amz-Target": target("ListMetrics") },
20822
+ body: {}
20823
+ },
20824
+ capabilities: [
20825
+ {
20826
+ name: "metrics.list",
20827
+ class: "read",
20828
+ description: "List available CloudWatch metrics and their dimensions.",
20829
+ parameters: {
20830
+ type: "object",
20831
+ properties: {
20832
+ namespace: { type: "string" },
20833
+ metricName: { type: "string" },
20834
+ dimensions: { type: "array", description: "AWS DimensionFilter objects." },
20835
+ nextToken: { type: "string" },
20836
+ recentlyActive: { type: "string", enum: ["PT3H"] },
20837
+ includeLinkedAccounts: { type: "boolean" },
20838
+ owningAccount: { type: "string" }
20839
+ }
20840
+ },
20841
+ request: {
20842
+ method: "POST",
20843
+ path: "/",
20844
+ headers: { "X-Amz-Target": target("ListMetrics") },
20845
+ body: {
20846
+ Namespace: "{namespace}",
20847
+ MetricName: "{metricName}",
20848
+ Dimensions: "{dimensions}",
20849
+ NextToken: "{nextToken}",
20850
+ RecentlyActive: "{recentlyActive}",
20851
+ IncludeLinkedAccounts: "{includeLinkedAccounts}",
20852
+ OwningAccount: "{owningAccount}"
20853
+ }
20854
+ }
20855
+ },
20856
+ {
20857
+ name: "metrics.statistics.get",
20858
+ class: "read",
20859
+ description: "Get statistics for one metric over a time range.",
20860
+ parameters: {
20861
+ type: "object",
20862
+ properties: {
20863
+ namespace: { type: "string" },
20864
+ metricName: { type: "string" },
20865
+ dimensions: { type: "array", description: "AWS Dimension objects." },
20866
+ startTime: { type: "number", description: "Unix epoch seconds." },
20867
+ endTime: { type: "number", description: "Unix epoch seconds." },
20868
+ period: { type: "integer", description: "Aggregation period in seconds." },
20869
+ statistics: { type: "array", items: { type: "string" } },
20870
+ extendedStatistics: { type: "array", items: { type: "string" } },
20871
+ unit: { type: "string" }
20872
+ },
20873
+ required: ["namespace", "metricName", "startTime", "endTime", "period"]
20874
+ },
20875
+ request: {
20876
+ method: "POST",
20877
+ path: "/",
20878
+ headers: { "X-Amz-Target": target("GetMetricStatistics") },
20879
+ body: {
20880
+ Namespace: "{namespace}",
20881
+ MetricName: "{metricName}",
20882
+ Dimensions: "{dimensions}",
20883
+ StartTime: "{startTime}",
20884
+ EndTime: "{endTime}",
20885
+ Period: "{period}",
20886
+ Statistics: "{statistics}",
20887
+ ExtendedStatistics: "{extendedStatistics}",
20888
+ Unit: "{unit}"
20889
+ }
20890
+ }
20891
+ },
20892
+ {
20893
+ name: "metrics.data.get",
20894
+ class: "read",
20895
+ description: "Run up to 500 metric-data or metric-math queries in one request.",
20896
+ parameters: {
20897
+ type: "object",
20898
+ properties: {
20899
+ metricDataQueries: { type: "array", description: "AWS MetricDataQuery objects." },
20900
+ startTime: { type: "number", description: "Unix epoch seconds." },
20901
+ endTime: { type: "number", description: "Unix epoch seconds." },
20902
+ nextToken: { type: "string" },
20903
+ scanBy: { type: "string", enum: ["TimestampDescending", "TimestampAscending"] },
20904
+ maxDatapoints: { type: "integer" },
20905
+ labelOptions: { type: "object" }
20906
+ },
20907
+ required: ["metricDataQueries", "startTime", "endTime"]
20908
+ },
20909
+ request: {
20910
+ method: "POST",
20911
+ path: "/",
20912
+ headers: { "X-Amz-Target": target("GetMetricData") },
20913
+ body: {
20914
+ MetricDataQueries: "{metricDataQueries}",
20915
+ StartTime: "{startTime}",
20916
+ EndTime: "{endTime}",
20917
+ NextToken: "{nextToken}",
20918
+ ScanBy: "{scanBy}",
20919
+ MaxDatapoints: "{maxDatapoints}",
20920
+ LabelOptions: "{labelOptions}"
20921
+ }
20922
+ }
20923
+ },
20924
+ {
20925
+ name: "alarms.list",
20926
+ class: "read",
20927
+ description: "List metric and composite alarms with optional filters.",
20928
+ parameters: {
20929
+ type: "object",
20930
+ properties: {
20931
+ alarmNames: { type: "array", items: { type: "string" } },
20932
+ alarmNamePrefix: { type: "string" },
20933
+ alarmTypes: { type: "array", items: { type: "string" } },
20934
+ childrenOfAlarmName: { type: "string" },
20935
+ parentsOfAlarmName: { type: "string" },
20936
+ stateValue: { type: "string", enum: ["OK", "ALARM", "INSUFFICIENT_DATA"] },
20937
+ actionPrefix: { type: "string" },
20938
+ maxRecords: { type: "integer" },
20939
+ nextToken: { type: "string" }
20940
+ }
20941
+ },
20942
+ request: {
20943
+ method: "POST",
20944
+ path: "/",
20945
+ headers: { "X-Amz-Target": target("DescribeAlarms") },
20946
+ body: {
20947
+ AlarmNames: "{alarmNames}",
20948
+ AlarmNamePrefix: "{alarmNamePrefix}",
20949
+ AlarmTypes: "{alarmTypes}",
20950
+ ChildrenOfAlarmName: "{childrenOfAlarmName}",
20951
+ ParentsOfAlarmName: "{parentsOfAlarmName}",
20952
+ StateValue: "{stateValue}",
20953
+ ActionPrefix: "{actionPrefix}",
20954
+ MaxRecords: "{maxRecords}",
20955
+ NextToken: "{nextToken}"
20956
+ }
20957
+ }
20958
+ },
20959
+ {
20960
+ name: "dashboards.list",
20961
+ class: "read",
20962
+ description: "List CloudWatch dashboards in the account.",
20963
+ parameters: {
20964
+ type: "object",
20965
+ properties: {
20966
+ dashboardNamePrefix: { type: "string" },
20967
+ nextToken: { type: "string" }
20968
+ }
20969
+ },
20970
+ request: {
20971
+ method: "POST",
20972
+ path: "/",
20973
+ headers: { "X-Amz-Target": target("ListDashboards") },
20974
+ body: {
20975
+ DashboardNamePrefix: "{dashboardNamePrefix}",
20976
+ NextToken: "{nextToken}"
20977
+ }
20978
+ }
20979
+ },
20980
+ {
20981
+ name: "dashboards.get",
20982
+ class: "read",
20983
+ description: "Get one CloudWatch dashboard definition.",
20984
+ parameters: {
20985
+ type: "object",
20986
+ properties: { dashboardName: { type: "string" } },
20987
+ required: ["dashboardName"]
20988
+ },
20989
+ request: {
20990
+ method: "POST",
20991
+ path: "/",
20992
+ headers: { "X-Amz-Target": target("GetDashboard") },
20993
+ body: { DashboardName: "{dashboardName}" }
20994
+ }
20995
+ },
20996
+ {
20997
+ name: "metrics.publish",
20998
+ class: "mutation",
20999
+ description: "Publish custom metric data or entity metric data to CloudWatch.",
21000
+ parameters: {
21001
+ type: "object",
21002
+ properties: {
21003
+ namespace: { type: "string" },
21004
+ metricData: { type: "array", description: "AWS MetricDatum objects." },
21005
+ entityMetricData: { type: "array", description: "AWS EntityMetricData objects." },
21006
+ strictEntityValidation: { type: "boolean" }
21007
+ },
21008
+ required: ["namespace"]
21009
+ },
21010
+ request: {
21011
+ method: "POST",
21012
+ path: "/",
21013
+ headers: { "X-Amz-Target": target("PutMetricData") },
21014
+ body: {
21015
+ Namespace: "{namespace}",
21016
+ MetricData: "{metricData}",
21017
+ EntityMetricData: "{entityMetricData}",
21018
+ StrictEntityValidation: "{strictEntityValidation}"
21019
+ }
21020
+ },
21021
+ cas: "none",
21022
+ externalEffect: true
21023
+ },
21024
+ {
21025
+ name: "alarms.put",
21026
+ class: "mutation",
21027
+ description: "Create or fully replace a CloudWatch metric alarm.",
21028
+ parameters: {
21029
+ type: "object",
21030
+ properties: {
21031
+ alarm: {
21032
+ type: "object",
21033
+ description: "AWS PutMetricAlarm input without undeclared transport fields."
21034
+ }
21035
+ },
21036
+ required: ["alarm"]
21037
+ },
21038
+ request: {
21039
+ method: "POST",
21040
+ path: "/",
21041
+ headers: { "X-Amz-Target": target("PutMetricAlarm") },
21042
+ body: "{alarm}"
21043
+ },
21044
+ cas: "optimistic-read-verify",
21045
+ externalEffect: true
21046
+ },
21047
+ {
21048
+ name: "alarms.delete",
21049
+ class: "mutation",
21050
+ description: "Delete up to 100 CloudWatch alarms by name.",
21051
+ parameters: {
21052
+ type: "object",
21053
+ properties: {
21054
+ alarmNames: { type: "array", items: { type: "string" } }
21055
+ },
21056
+ required: ["alarmNames"]
21057
+ },
21058
+ request: {
21059
+ method: "POST",
21060
+ path: "/",
21061
+ headers: { "X-Amz-Target": target("DeleteAlarms") },
21062
+ body: { AlarmNames: "{alarmNames}" }
21063
+ },
21064
+ cas: "native-idempotency",
21065
+ externalEffect: true
21066
+ },
21067
+ {
21068
+ name: "dashboards.put",
21069
+ class: "mutation",
21070
+ description: "Create or fully replace a CloudWatch dashboard.",
21071
+ parameters: {
21072
+ type: "object",
21073
+ properties: {
21074
+ dashboardName: { type: "string" },
21075
+ dashboardBody: { type: "string", description: "CloudWatch dashboard JSON string." }
21076
+ },
21077
+ required: ["dashboardName", "dashboardBody"]
21078
+ },
21079
+ request: {
21080
+ method: "POST",
21081
+ path: "/",
21082
+ headers: { "X-Amz-Target": target("PutDashboard") },
21083
+ body: {
21084
+ DashboardName: "{dashboardName}",
21085
+ DashboardBody: "{dashboardBody}"
21086
+ }
21087
+ },
21088
+ cas: "optimistic-read-verify",
21089
+ externalEffect: true
21090
+ },
21091
+ {
21092
+ name: "dashboards.delete",
21093
+ class: "mutation",
21094
+ description: "Delete up to 100 CloudWatch dashboards by name.",
21095
+ parameters: {
21096
+ type: "object",
21097
+ properties: {
21098
+ dashboardNames: { type: "array", items: { type: "string" } }
21099
+ },
21100
+ required: ["dashboardNames"]
21101
+ },
21102
+ request: {
21103
+ method: "POST",
21104
+ path: "/",
21105
+ headers: { "X-Amz-Target": target("DeleteDashboards") },
21106
+ body: { DashboardNames: "{dashboardNames}" }
21107
+ },
21108
+ cas: "native-idempotency",
21109
+ externalEffect: true
21110
+ }
21111
+ ]
21112
+ });
21113
+
21114
+ // src/connectors/adapters/amazon-lambda.ts
21115
+ var awsCredentialHint = 'AWS credentials as JSON: {"accessKeyId":"AKIA\u2026","secretAccessKey":"\u2026","region":"us-east-1"}. Optional "sessionToken" and "endpoint" support temporary credentials and local AWS-compatible endpoints.';
21116
+ var amazonLambdaConnector = declarativeRestConnector({
21117
+ kind: "aws-lambda",
21118
+ displayName: "AWS Lambda",
21119
+ description: "Inspect, invoke, create, update, version, alias, and delete AWS Lambda functions.",
21120
+ auth: { kind: "api-key", hint: awsCredentialHint },
21121
+ category: "other",
21122
+ // Lambda invocation is at-least-once and can cause arbitrary downstream
21123
+ // effects. The connection cannot promise authoritative mutation replay.
21124
+ defaultConsistencyModel: "advisory",
21125
+ credentialPlacement: { kind: "aws-sigv4", service: "lambda" },
21126
+ baseUrl: {
21127
+ metadataKey: "endpoint",
21128
+ fallback: "https://lambda.{region}.amazonaws.com"
21129
+ },
21130
+ test: {
21131
+ method: "GET",
21132
+ path: "/2015-03-31/functions",
21133
+ query: { MaxItems: "1" }
21134
+ },
21135
+ capabilities: [
21136
+ {
21137
+ name: "functions.list",
21138
+ class: "read",
21139
+ description: "List Lambda functions in the configured AWS region.",
21140
+ parameters: {
21141
+ type: "object",
21142
+ properties: {
21143
+ marker: { type: "string", description: "Pagination marker." },
21144
+ maxItems: { type: "integer", description: "Maximum functions to return (1-50)." },
21145
+ functionVersion: {
21146
+ type: "string",
21147
+ enum: ["ALL"],
21148
+ description: "Include published versions when set to ALL."
21149
+ },
21150
+ masterRegion: { type: "string", description: "Filter Lambda@Edge replicas by region." }
21151
+ }
21152
+ },
21153
+ request: {
21154
+ method: "GET",
21155
+ path: "/2015-03-31/functions",
21156
+ query: {
21157
+ Marker: "{marker}",
21158
+ MaxItems: "{maxItems}",
21159
+ FunctionVersion: "{functionVersion}",
21160
+ MasterRegion: "{masterRegion}"
21161
+ }
21162
+ }
21163
+ },
21164
+ {
21165
+ name: "functions.get",
21166
+ class: "read",
21167
+ description: "Get one function configuration and its temporary deployment-package URL.",
21168
+ parameters: {
21169
+ type: "object",
21170
+ properties: {
21171
+ functionName: { type: "string", description: "Function name or ARN." },
21172
+ qualifier: { type: "string", description: "Version number or alias." }
21173
+ },
21174
+ required: ["functionName"]
21175
+ },
21176
+ request: {
21177
+ method: "GET",
21178
+ path: "/2015-03-31/functions/{functionName}",
21179
+ query: { Qualifier: "{qualifier}" }
21180
+ }
21181
+ },
21182
+ {
21183
+ name: "aliases.list",
21184
+ class: "read",
21185
+ description: "List aliases for a Lambda function.",
21186
+ parameters: {
21187
+ type: "object",
21188
+ properties: {
21189
+ functionName: { type: "string" },
21190
+ functionVersion: { type: "string" },
21191
+ marker: { type: "string" },
21192
+ maxItems: { type: "integer" }
21193
+ },
21194
+ required: ["functionName"]
21195
+ },
21196
+ request: {
21197
+ method: "GET",
21198
+ path: "/2015-03-31/functions/{functionName}/aliases",
21199
+ query: {
21200
+ FunctionVersion: "{functionVersion}",
21201
+ Marker: "{marker}",
21202
+ MaxItems: "{maxItems}"
21203
+ }
21204
+ }
21205
+ },
21206
+ {
21207
+ name: "functions.invoke",
21208
+ class: "mutation",
21209
+ description: "Invoke a Lambda function synchronously, asynchronously, or as a dry-run permission check.",
21210
+ parameters: {
21211
+ type: "object",
21212
+ properties: {
21213
+ functionName: { type: "string", description: "Function name or ARN." },
21214
+ qualifier: { type: "string", description: "Version number or alias." },
21215
+ invocationType: {
21216
+ type: "string",
21217
+ enum: ["RequestResponse", "Event", "DryRun"]
21218
+ },
21219
+ logType: { type: "string", enum: ["None", "Tail"] },
21220
+ clientContext: {
21221
+ type: "string",
21222
+ description: "Base64-encoded client context for synchronous invocation."
21223
+ },
21224
+ payload: {
21225
+ description: "JSON payload passed directly to the function."
21226
+ }
21227
+ },
21228
+ required: ["functionName", "payload"]
21229
+ },
21230
+ request: {
21231
+ method: "POST",
21232
+ path: "/2015-03-31/functions/{functionName}/invocations",
21233
+ query: { Qualifier: "{qualifier}" },
21234
+ headers: {
21235
+ "X-Amz-Invocation-Type": "{invocationType}",
21236
+ "X-Amz-Log-Type": "{logType}",
21237
+ "X-Amz-Client-Context": "{clientContext}"
21238
+ },
21239
+ body: "{payload}"
21240
+ },
21241
+ cas: "none",
21242
+ externalEffect: true
21243
+ },
21244
+ {
21245
+ name: "functions.create",
21246
+ class: "mutation",
21247
+ description: "Create a Lambda function from an S3 object, inline zip, or ECR image.",
21248
+ parameters: {
21249
+ type: "object",
21250
+ properties: {
21251
+ functionName: { type: "string" },
21252
+ role: { type: "string", description: "Execution-role ARN." },
21253
+ code: {
21254
+ type: "object",
21255
+ description: "AWS FunctionCode shape: S3Bucket/S3Key/S3ObjectVersion, ZipFile, or ImageUri."
21256
+ },
21257
+ runtime: { type: "string" },
21258
+ handler: { type: "string" },
21259
+ description: { type: "string" },
21260
+ timeout: { type: "integer" },
21261
+ memorySize: { type: "integer" },
21262
+ publish: { type: "boolean" },
21263
+ packageType: { type: "string", enum: ["Zip", "Image"] },
21264
+ architectures: { type: "array", items: { type: "string" } },
21265
+ environment: { type: "object", description: "AWS Environment shape." },
21266
+ vpcConfig: { type: "object", description: "AWS VpcConfig shape." },
21267
+ layers: { type: "array", items: { type: "string" } },
21268
+ tags: { type: "object" },
21269
+ ephemeralStorage: { type: "object" },
21270
+ loggingConfig: { type: "object" }
21271
+ },
21272
+ required: ["functionName", "role", "code"]
21273
+ },
21274
+ request: {
21275
+ method: "POST",
21276
+ path: "/2015-03-31/functions",
21277
+ body: {
21278
+ FunctionName: "{functionName}",
21279
+ Role: "{role}",
21280
+ Code: "{code}",
21281
+ Runtime: "{runtime}",
21282
+ Handler: "{handler}",
21283
+ Description: "{description}",
21284
+ Timeout: "{timeout}",
21285
+ MemorySize: "{memorySize}",
21286
+ Publish: "{publish}",
21287
+ PackageType: "{packageType}",
21288
+ Architectures: "{architectures}",
21289
+ Environment: "{environment}",
21290
+ VpcConfig: "{vpcConfig}",
21291
+ Layers: "{layers}",
21292
+ Tags: "{tags}",
21293
+ EphemeralStorage: "{ephemeralStorage}",
21294
+ LoggingConfig: "{loggingConfig}"
21295
+ }
21296
+ },
21297
+ cas: "native-idempotency",
21298
+ externalEffect: true
21299
+ },
21300
+ {
21301
+ name: "functions.code.update",
21302
+ class: "mutation",
21303
+ description: "Replace the unpublished code for a Lambda function.",
21304
+ parameters: {
21305
+ type: "object",
21306
+ properties: {
21307
+ functionName: { type: "string" },
21308
+ s3Bucket: { type: "string" },
21309
+ s3Key: { type: "string" },
21310
+ s3ObjectVersion: { type: "string" },
21311
+ imageUri: { type: "string" },
21312
+ zipFile: { type: "string", description: "Base64-encoded zip bytes." },
21313
+ publish: { type: "boolean" },
21314
+ dryRun: { type: "boolean" },
21315
+ revisionId: { type: "string" },
21316
+ architectures: { type: "array", items: { type: "string" } }
21317
+ },
21318
+ required: ["functionName"]
21319
+ },
21320
+ request: {
21321
+ method: "PUT",
21322
+ path: "/2015-03-31/functions/{functionName}/code",
21323
+ body: {
21324
+ S3Bucket: "{s3Bucket}",
21325
+ S3Key: "{s3Key}",
21326
+ S3ObjectVersion: "{s3ObjectVersion}",
21327
+ ImageUri: "{imageUri}",
21328
+ ZipFile: "{zipFile}",
21329
+ Publish: "{publish}",
21330
+ DryRun: "{dryRun}",
21331
+ RevisionId: "{revisionId}",
21332
+ Architectures: "{architectures}"
21333
+ }
21334
+ },
21335
+ cas: "optimistic-read-verify",
21336
+ externalEffect: true
21337
+ },
21338
+ {
21339
+ name: "functions.configuration.update",
21340
+ class: "mutation",
21341
+ description: "Update the unpublished configuration for a Lambda function.",
21342
+ parameters: {
21343
+ type: "object",
21344
+ properties: {
21345
+ functionName: { type: "string" },
21346
+ role: { type: "string" },
21347
+ handler: { type: "string" },
21348
+ description: { type: "string" },
21349
+ timeout: { type: "integer" },
21350
+ memorySize: { type: "integer" },
21351
+ runtime: { type: "string" },
21352
+ environment: { type: "object" },
21353
+ layers: { type: "array", items: { type: "string" } },
21354
+ vpcConfig: { type: "object" },
21355
+ revisionId: { type: "string" },
21356
+ ephemeralStorage: { type: "object" },
21357
+ loggingConfig: { type: "object" }
21358
+ },
21359
+ required: ["functionName"]
21360
+ },
21361
+ request: {
21362
+ method: "PUT",
21363
+ path: "/2015-03-31/functions/{functionName}/configuration",
21364
+ body: {
21365
+ Role: "{role}",
21366
+ Handler: "{handler}",
21367
+ Description: "{description}",
21368
+ Timeout: "{timeout}",
21369
+ MemorySize: "{memorySize}",
21370
+ Runtime: "{runtime}",
21371
+ Environment: "{environment}",
21372
+ Layers: "{layers}",
21373
+ VpcConfig: "{vpcConfig}",
21374
+ RevisionId: "{revisionId}",
21375
+ EphemeralStorage: "{ephemeralStorage}",
21376
+ LoggingConfig: "{loggingConfig}"
21377
+ }
21378
+ },
21379
+ cas: "optimistic-read-verify",
21380
+ externalEffect: true
21381
+ },
21382
+ {
21383
+ name: "versions.publish",
21384
+ class: "mutation",
21385
+ description: "Publish an immutable version from the current function code and configuration.",
21386
+ parameters: {
21387
+ type: "object",
21388
+ properties: {
21389
+ functionName: { type: "string" },
21390
+ codeSha256: { type: "string" },
21391
+ description: { type: "string" },
21392
+ revisionId: { type: "string" }
21393
+ },
21394
+ required: ["functionName"]
21395
+ },
21396
+ request: {
21397
+ method: "POST",
21398
+ path: "/2015-03-31/functions/{functionName}/versions",
21399
+ body: {
21400
+ CodeSha256: "{codeSha256}",
21401
+ Description: "{description}",
21402
+ RevisionId: "{revisionId}"
21403
+ }
21404
+ },
21405
+ cas: "optimistic-read-verify",
21406
+ externalEffect: true
21407
+ },
21408
+ {
21409
+ name: "aliases.create",
21410
+ class: "mutation",
21411
+ description: "Create an alias that points to a published function version.",
21412
+ parameters: {
21413
+ type: "object",
21414
+ properties: {
21415
+ functionName: { type: "string" },
21416
+ name: { type: "string" },
21417
+ functionVersion: { type: "string" },
21418
+ description: { type: "string" },
21419
+ routingConfig: { type: "object" }
21420
+ },
21421
+ required: ["functionName", "name", "functionVersion"]
21422
+ },
21423
+ request: {
21424
+ method: "POST",
21425
+ path: "/2015-03-31/functions/{functionName}/aliases",
21426
+ body: {
21427
+ Name: "{name}",
21428
+ FunctionVersion: "{functionVersion}",
21429
+ Description: "{description}",
21430
+ RoutingConfig: "{routingConfig}"
21431
+ }
21432
+ },
21433
+ cas: "native-idempotency",
21434
+ externalEffect: true
21435
+ },
21436
+ {
21437
+ name: "aliases.update",
21438
+ class: "mutation",
21439
+ description: "Move or reconfigure an existing function alias.",
21440
+ parameters: {
21441
+ type: "object",
21442
+ properties: {
21443
+ functionName: { type: "string" },
21444
+ name: { type: "string" },
21445
+ functionVersion: { type: "string" },
21446
+ description: { type: "string" },
21447
+ routingConfig: { type: "object" },
21448
+ revisionId: { type: "string" }
21449
+ },
21450
+ required: ["functionName", "name"]
21451
+ },
21452
+ request: {
21453
+ method: "PUT",
21454
+ path: "/2015-03-31/functions/{functionName}/aliases/{name}",
21455
+ body: {
21456
+ FunctionVersion: "{functionVersion}",
21457
+ Description: "{description}",
21458
+ RoutingConfig: "{routingConfig}",
21459
+ RevisionId: "{revisionId}"
21460
+ }
21461
+ },
21462
+ cas: "optimistic-read-verify",
21463
+ externalEffect: true
21464
+ },
21465
+ {
21466
+ name: "aliases.delete",
21467
+ class: "mutation",
21468
+ description: "Delete a function alias without deleting the function version.",
21469
+ parameters: {
21470
+ type: "object",
21471
+ properties: {
21472
+ functionName: { type: "string" },
21473
+ name: { type: "string" }
21474
+ },
21475
+ required: ["functionName", "name"]
21476
+ },
21477
+ request: {
21478
+ method: "DELETE",
21479
+ path: "/2015-03-31/functions/{functionName}/aliases/{name}"
21480
+ },
21481
+ cas: "native-idempotency",
21482
+ externalEffect: true
21483
+ },
21484
+ {
21485
+ name: "functions.delete",
21486
+ class: "mutation",
21487
+ description: "Permanently delete a Lambda function or one published version.",
21488
+ parameters: {
21489
+ type: "object",
21490
+ properties: {
21491
+ functionName: { type: "string" },
21492
+ qualifier: { type: "string", description: "Version to delete. Omit to delete all versions." }
21493
+ },
21494
+ required: ["functionName"]
21495
+ },
21496
+ request: {
21497
+ method: "DELETE",
21498
+ path: "/2015-03-31/functions/{functionName}",
21499
+ query: { Qualifier: "{qualifier}" }
21500
+ },
21501
+ cas: "native-idempotency",
21502
+ externalEffect: true
21503
+ }
21504
+ ]
21505
+ });
21506
+
20444
21507
  // src/connectors/adapters/amazon-s3.ts
20445
21508
  var amazonS3Connector = declarativeRestConnector({
20446
21509
  kind: "amazon-s3",
@@ -23994,9 +25057,9 @@ function requiredString4(value, field) {
23994
25057
  }
23995
25058
  function isoDate(value, field) {
23996
25059
  const parsed = requiredString4(value, field);
23997
- const date = new Date(parsed);
23998
- if (!Number.isFinite(date.getTime())) throw new Error(`${field} must be an ISO 8601 timestamp`);
23999
- return date.toISOString();
25060
+ const date2 = new Date(parsed);
25061
+ if (!Number.isFinite(date2.getTime())) throw new Error(`${field} must be an ISO 8601 timestamp`);
25062
+ return date2.toISOString();
24000
25063
  }
24001
25064
  function requiredJsonValue(value, field) {
24002
25065
  if (value === void 0) throw new Error(`${field} is required`);
@@ -24014,8 +25077,8 @@ function retryAfterMs3(value) {
24014
25077
  if (!value) return 6e4;
24015
25078
  const seconds = Number(value);
24016
25079
  if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
24017
- const date = Date.parse(value);
24018
- return Number.isFinite(date) ? Math.max(0, date - Date.now()) : 6e4;
25080
+ const date2 = Date.parse(value);
25081
+ return Number.isFinite(date2) ? Math.max(0, date2 - Date.now()) : 6e4;
24019
25082
  }
24020
25083
  function isRecord(value) {
24021
25084
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -24572,8 +25635,8 @@ function retryAfterMs4(value) {
24572
25635
  if (!value) return 6e4;
24573
25636
  const seconds = Number(value);
24574
25637
  if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
24575
- const date = Date.parse(value);
24576
- return Number.isFinite(date) ? Math.max(0, date - Date.now()) : 6e4;
25638
+ const date2 = Date.parse(value);
25639
+ return Number.isFinite(date2) ? Math.max(0, date2 - Date.now()) : 6e4;
24577
25640
  }
24578
25641
  function redactProviderText(value) {
24579
25642
  return value.replace(/SharedAccessSignature\s+[^\s<]+/gi, "SharedAccessSignature [redacted]").replace(/SharedAccessKey=[^;\s<]+/gi, "SharedAccessKey=[redacted]");
@@ -26299,10 +27362,190 @@ var billplzConnector = declarativeRestConnector({
26299
27362
  ]
26300
27363
  });
26301
27364
 
27365
+ // src/connectors/oauth.ts
27366
+ import { createHash as createHash4, randomBytes } from "crypto";
27367
+ var PENDING_TTL_MS = 10 * 60 * 1e3;
27368
+ var InMemoryOAuthFlowStore = class {
27369
+ pendingFlows = /* @__PURE__ */ new Map();
27370
+ put(state, flow) {
27371
+ this.pendingFlows.set(state, flow);
27372
+ }
27373
+ consume(state) {
27374
+ const flow = this.pendingFlows.get(state);
27375
+ this.pendingFlows.delete(state);
27376
+ if (!flow || flow.expiresAt <= Date.now()) return void 0;
27377
+ return flow;
27378
+ }
27379
+ sweep(now) {
27380
+ for (const [k, v] of this.pendingFlows) {
27381
+ if (v.expiresAt <= now) this.pendingFlows.delete(k);
27382
+ }
27383
+ }
27384
+ clear() {
27385
+ this.pendingFlows.clear();
27386
+ }
27387
+ };
27388
+ var defaultFlowStore = new InMemoryOAuthFlowStore();
27389
+ function startOAuthFlow(input) {
27390
+ const store = input.store ?? defaultFlowStore;
27391
+ const now = input.now ?? Date.now();
27392
+ store.sweep?.(now);
27393
+ const usePkce = (input.pkce ?? "required") !== "unsupported";
27394
+ const codeVerifier = usePkce ? base64Url(randomBytes(48)) : void 0;
27395
+ const codeChallenge = codeVerifier ? base64Url(createHash4("sha256").update(codeVerifier).digest()) : void 0;
27396
+ const state = base64Url(randomBytes(24));
27397
+ store.put(state, {
27398
+ codeVerifier,
27399
+ state,
27400
+ projectId: input.projectId,
27401
+ kind: input.kind,
27402
+ label: input.label,
27403
+ redirectUri: input.redirectUri,
27404
+ expiresAt: now + PENDING_TTL_MS
27405
+ });
27406
+ const url = new URL(input.authorizationUrl);
27407
+ url.searchParams.set("response_type", "code");
27408
+ url.searchParams.set(
27409
+ oauthParameterName(input.authorizationClientIdParam, "client_id"),
27410
+ input.clientId
27411
+ );
27412
+ url.searchParams.set("redirect_uri", input.redirectUri);
27413
+ url.searchParams.set("scope", input.scopes.join(input.scopeSeparator ?? " "));
27414
+ url.searchParams.set("state", state);
27415
+ if (input.extraAuthParams) {
27416
+ for (const [k, v] of Object.entries(input.extraAuthParams)) {
27417
+ url.searchParams.set(k, v);
27418
+ }
27419
+ }
27420
+ if (codeChallenge) {
27421
+ url.searchParams.set("code_challenge", codeChallenge);
27422
+ url.searchParams.set("code_challenge_method", "S256");
27423
+ } else {
27424
+ url.searchParams.delete("code_challenge");
27425
+ url.searchParams.delete("code_challenge_method");
27426
+ }
27427
+ return { authorizationUrl: url.toString(), state };
27428
+ }
27429
+ async function consumePendingFlow(state, store = defaultFlowStore) {
27430
+ await store.sweep?.(Date.now());
27431
+ const flow = await store.consume(state);
27432
+ if (!flow) {
27433
+ throw new Error("Unknown or expired OAuth state: possible CSRF, replay, or stale flow");
27434
+ }
27435
+ return flow;
27436
+ }
27437
+ async function exchangeAuthorizationCode(input) {
27438
+ const usePkce = (input.pkce ?? "required") !== "unsupported";
27439
+ if (usePkce && !input.codeVerifier) {
27440
+ throw new Error("OAuth token exchange requires a PKCE code_verifier");
27441
+ }
27442
+ const body = new URLSearchParams({
27443
+ grant_type: "authorization_code",
27444
+ code: input.code,
27445
+ redirect_uri: input.redirectUri
27446
+ });
27447
+ if (usePkce) body.set("code_verifier", input.codeVerifier);
27448
+ const headers = {
27449
+ "content-type": "application/x-www-form-urlencoded",
27450
+ accept: "application/json"
27451
+ };
27452
+ applyTokenClientAuthentication(input, body, headers);
27453
+ const res = await (input.fetchImpl ?? fetch)(input.tokenUrl, {
27454
+ method: "POST",
27455
+ headers,
27456
+ body,
27457
+ signal: input.signal
27458
+ });
27459
+ if (!res.ok) {
27460
+ const text = await res.text().catch(() => "");
27461
+ throw new Error(`OAuth token exchange failed: ${res.status} ${res.statusText} \u2014 ${text.slice(0, 200)}`);
27462
+ }
27463
+ const json = await res.json();
27464
+ return {
27465
+ accessToken: json.access_token,
27466
+ refreshToken: json.refresh_token,
27467
+ expiresIn: json.expires_in,
27468
+ scope: json.scope,
27469
+ tokenType: json.token_type,
27470
+ idToken: json.id_token
27471
+ };
27472
+ }
27473
+ async function refreshAccessToken(input) {
27474
+ const body = new URLSearchParams({
27475
+ grant_type: "refresh_token",
27476
+ refresh_token: input.refreshToken
27477
+ });
27478
+ const headers = {
27479
+ "content-type": "application/x-www-form-urlencoded",
27480
+ accept: "application/json"
27481
+ };
27482
+ applyTokenClientAuthentication(input, body, headers);
27483
+ const res = await (input.fetchImpl ?? fetch)(input.tokenUrl, {
27484
+ method: "POST",
27485
+ headers,
27486
+ body,
27487
+ signal: input.signal
27488
+ });
27489
+ if (!res.ok) {
27490
+ const text = await res.text().catch(() => "");
27491
+ throw new Error(`OAuth refresh failed: ${res.status} ${res.statusText} \u2014 ${text.slice(0, 200)}`);
27492
+ }
27493
+ const json = await res.json();
27494
+ return {
27495
+ accessToken: json.access_token,
27496
+ // Some providers omit refresh_token on refresh — keep the previous one
27497
+ // in that case (caller passes through if undefined).
27498
+ refreshToken: json.refresh_token,
27499
+ expiresIn: json.expires_in,
27500
+ scope: json.scope,
27501
+ tokenType: json.token_type,
27502
+ idToken: json.id_token
27503
+ };
27504
+ }
27505
+ function applyTokenClientAuthentication(input, body, headers) {
27506
+ const method = input.tokenClientAuthMethod ?? "client_secret_post";
27507
+ if (method === "none") {
27508
+ body.set(oauthParameterName(input.tokenClientIdParam, "client_id"), input.clientId);
27509
+ return;
27510
+ }
27511
+ if (!input.clientSecret) {
27512
+ throw new Error(`OAuth ${method} client authentication requires a client secret`);
27513
+ }
27514
+ if (method === "client_secret_post") {
27515
+ body.set(oauthParameterName(input.tokenClientIdParam, "client_id"), input.clientId);
27516
+ body.set(
27517
+ oauthParameterName(input.tokenClientSecretParam, "client_secret"),
27518
+ input.clientSecret
27519
+ );
27520
+ return;
27521
+ }
27522
+ if (method === "client_secret_basic") {
27523
+ headers.authorization = `Basic ${Buffer.from(
27524
+ `${input.clientId}:${input.clientSecret}`,
27525
+ "utf8"
27526
+ ).toString("base64")}`;
27527
+ return;
27528
+ }
27529
+ throw new Error("Unsupported OAuth token client authentication method");
27530
+ }
27531
+ function base64Url(buf) {
27532
+ return buf.toString("base64").replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_");
27533
+ }
27534
+ function oauthParameterName(value, fallback) {
27535
+ const name = value ?? fallback;
27536
+ if (!/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(name)) {
27537
+ throw new Error("Invalid OAuth parameter name");
27538
+ }
27539
+ return name;
27540
+ }
27541
+ function _resetPendingFlowsForTests() {
27542
+ defaultFlowStore.clear?.();
27543
+ }
27544
+
26302
27545
  // src/connectors/adapters/cal-com.ts
26303
27546
  var authorizeUrl = "https://app.cal.com/auth/oauth2/authorize";
26304
27547
  var tokenUrl = "https://api.cal.com/v2/auth/oauth2/token";
26305
- var calComConnector = declarativeRestConnector({
27548
+ var calComSpec = {
26306
27549
  kind: "cal-com",
26307
27550
  displayName: "Cal.com",
26308
27551
  description: "Schedule, query, and cancel Cal.com bookings and read event types through the Platform v2 API.",
@@ -26319,8 +27562,9 @@ var calComConnector = declarativeRestConnector({
26319
27562
  "SCHEDULE_READ",
26320
27563
  "SCHEDULE_WRITE"
26321
27564
  ],
26322
- clientIdEnv: "CALCOM_OAUTH_CLIENT_ID",
26323
- clientSecretEnv: "CALCOM_OAUTH_CLIENT_SECRET"
27565
+ pkce: "required",
27566
+ tokenClientAuthMethod: "none",
27567
+ clientIdEnv: "CALCOM_OAUTH_CLIENT_ID"
26324
27568
  },
26325
27569
  category: "calendar",
26326
27570
  defaultConsistencyModel: "authoritative",
@@ -26641,7 +27885,100 @@ var calComConnector = declarativeRestConnector({
26641
27885
  requiredScopes: ["EVENT_TYPE_READ"]
26642
27886
  }
26643
27887
  ]
26644
- });
27888
+ };
27889
+ var calComConnector = declarativeRestConnector(calComSpec);
27890
+ function calCom(options) {
27891
+ const adapter = declarativeRestConnector(calComSpec);
27892
+ const now = options.now ?? Date.now;
27893
+ const refreshes = /* @__PURE__ */ new Map();
27894
+ adapter.exchangeOAuth = async (input) => {
27895
+ const tokens = await exchangeAuthorizationCode({
27896
+ tokenUrl,
27897
+ clientId: options.clientId,
27898
+ tokenClientAuthMethod: "none",
27899
+ code: input.code,
27900
+ codeVerifier: input.codeVerifier,
27901
+ redirectUri: input.redirectUri,
27902
+ fetchImpl: options.fetchImpl
27903
+ });
27904
+ return {
27905
+ credentials: {
27906
+ kind: "oauth2",
27907
+ accessToken: tokens.accessToken,
27908
+ refreshToken: tokens.refreshToken,
27909
+ expiresAt: tokens.expiresIn ? now() + tokens.expiresIn * 1e3 : void 0
27910
+ },
27911
+ scopes: tokens.scope?.split(/[\s,]+/).filter(Boolean) ?? calComSpec.auth.scopes,
27912
+ metadata: {}
27913
+ };
27914
+ };
27915
+ adapter.refreshToken = async (credentials) => {
27916
+ if (credentials.kind !== "oauth2" || !credentials.refreshToken) {
27917
+ throw new Error("cal-com.refreshToken: missing refresh token");
27918
+ }
27919
+ const refreshed = await refreshAccessToken({
27920
+ tokenUrl,
27921
+ clientId: options.clientId,
27922
+ tokenClientAuthMethod: "none",
27923
+ refreshToken: credentials.refreshToken,
27924
+ fetchImpl: options.fetchImpl
27925
+ });
27926
+ return {
27927
+ kind: "oauth2",
27928
+ accessToken: refreshed.accessToken,
27929
+ refreshToken: refreshed.refreshToken ?? credentials.refreshToken,
27930
+ expiresAt: refreshed.expiresIn ? now() + refreshed.expiresIn * 1e3 : void 0
27931
+ };
27932
+ };
27933
+ const executeRead2 = adapter.executeRead?.bind(adapter);
27934
+ const executeMutation = adapter.executeMutation?.bind(adapter);
27935
+ if (executeRead2) {
27936
+ adapter.executeRead = async (invocation) => executeRead2(
27937
+ await withFreshCalComCredentials(invocation, adapter, refreshes, now)
27938
+ );
27939
+ }
27940
+ if (executeMutation) {
27941
+ adapter.executeMutation = async (invocation) => executeMutation(
27942
+ await withFreshCalComCredentials(invocation, adapter, refreshes, now)
27943
+ );
27944
+ }
27945
+ return adapter;
27946
+ }
27947
+ async function withFreshCalComCredentials(invocation, adapter, refreshes, now) {
27948
+ const credentials = invocation.source.credentials;
27949
+ if (credentials.kind !== "oauth2") {
27950
+ throw new CredentialsExpired("Cal.com requires OAuth2 credentials.", invocation.source.id);
27951
+ }
27952
+ if (!credentials.expiresAt || credentials.expiresAt > now() + 6e4) {
27953
+ return invocation;
27954
+ }
27955
+ if (!credentials.refreshToken || !adapter.refreshToken) {
27956
+ throw new CredentialsExpired(
27957
+ "Cal.com access token expired and no refresh token is available.",
27958
+ invocation.source.id
27959
+ );
27960
+ }
27961
+ let refresh = refreshes.get(invocation.source.id);
27962
+ if (!refresh) {
27963
+ refresh = adapter.refreshToken(credentials);
27964
+ refreshes.set(invocation.source.id, refresh);
27965
+ const clear = () => {
27966
+ if (refreshes.get(invocation.source.id) === refresh) {
27967
+ refreshes.delete(invocation.source.id);
27968
+ }
27969
+ };
27970
+ void refresh.then(clear, clear);
27971
+ }
27972
+ const rotated = await refresh;
27973
+ await invocation.onCredentialsRotated?.(rotated);
27974
+ return {
27975
+ ...invocation,
27976
+ source: {
27977
+ ...invocation.source,
27978
+ credentials: rotated
27979
+ }
27980
+ };
27981
+ }
26645
27982
 
26646
27983
  // src/connectors/adapters/calendly.ts
26647
27984
  var calendlyConnector = declarativeRestConnector({
@@ -27839,6 +29176,273 @@ var clickupConnector = declarativeRestConnector({
27839
29176
  ]
27840
29177
  });
27841
29178
 
29179
+ // src/connectors/adapters/cloudflare.ts
29180
+ var pagination = {
29181
+ page: { type: "integer", minimum: 1 },
29182
+ perPage: { type: "integer", minimum: 5, maximum: 50 }
29183
+ };
29184
+ var paginationQuery = { page: "{page}", per_page: "{perPage}" };
29185
+ var zoneId = {
29186
+ zoneId: { type: "string", minLength: 1, description: "Cloudflare zone identifier." }
29187
+ };
29188
+ var recordId = {
29189
+ recordId: { type: "string", minLength: 1, description: "Cloudflare DNS record identifier." }
29190
+ };
29191
+ var recordFields = {
29192
+ type: {
29193
+ type: "string",
29194
+ enum: [
29195
+ "A",
29196
+ "AAAA",
29197
+ "CAA",
29198
+ "CERT",
29199
+ "CNAME",
29200
+ "DNSKEY",
29201
+ "DS",
29202
+ "HTTPS",
29203
+ "LOC",
29204
+ "MX",
29205
+ "NAPTR",
29206
+ "NS",
29207
+ "OPENPGPKEY",
29208
+ "PTR",
29209
+ "SMIMEA",
29210
+ "SRV",
29211
+ "SSHFP",
29212
+ "SVCB",
29213
+ "TLSA",
29214
+ "TXT",
29215
+ "URI"
29216
+ ]
29217
+ },
29218
+ name: { type: "string", minLength: 1, description: "Complete DNS record name." },
29219
+ content: { type: "string", description: "Provider-native record content." },
29220
+ ttl: {
29221
+ type: "integer",
29222
+ minimum: 1,
29223
+ maximum: 86400,
29224
+ description: "TTL in seconds. Use 1 for automatic."
29225
+ },
29226
+ proxied: { type: "boolean" },
29227
+ priority: { type: "integer" },
29228
+ comment: { type: ["string", "null"] },
29229
+ tags: { type: "array", items: { type: "string" } },
29230
+ data: { type: "object", description: "Provider-native structured data for records such as SRV or CAA." },
29231
+ settings: { type: "object", description: "Provider-native DNS record settings." }
29232
+ };
29233
+ var cloudflareConnector = declarativeRestConnector({
29234
+ kind: "cloudflare",
29235
+ displayName: "Cloudflare",
29236
+ description: "Inspect Cloudflare accounts and zones, then manage DNS records with a dedicated scoped API token.",
29237
+ auth: {
29238
+ kind: "api-key",
29239
+ hint: "Create a dedicated Cloudflare API token for Tangle Integration Hub. Grant Account Settings Read, Zone Read, Zone Settings Read, and DNS Read or DNS Edit only on selected resources. Never reuse a Tangle deployment, Workers, Terraform, or infrastructure token."
29240
+ },
29241
+ category: "other",
29242
+ defaultConsistencyModel: "authoritative",
29243
+ baseUrl: "https://api.cloudflare.com/client/v4",
29244
+ credentialPlacement: { kind: "bearer" },
29245
+ test: {
29246
+ method: "GET",
29247
+ path: "/user/tokens/verify",
29248
+ expectResponse: [
29249
+ { path: "success", equals: true },
29250
+ { path: "result.status", equals: "active" }
29251
+ ]
29252
+ },
29253
+ capabilities: [
29254
+ {
29255
+ name: "auth.verify",
29256
+ class: "read",
29257
+ description: "Verify that the current API token is valid and active.",
29258
+ parameters: { type: "object", properties: {} },
29259
+ request: { method: "GET", path: "/user/tokens/verify" }
29260
+ },
29261
+ {
29262
+ name: "accounts.get",
29263
+ class: "read",
29264
+ description: "Read one Cloudflare account and its settings.",
29265
+ parameters: {
29266
+ type: "object",
29267
+ properties: { accountId: { type: "string", minLength: 1 } },
29268
+ required: ["accountId"]
29269
+ },
29270
+ request: { method: "GET", path: "/accounts/{accountId}" }
29271
+ },
29272
+ {
29273
+ name: "zones.list",
29274
+ class: "read",
29275
+ description: "List or filter zones by account, domain, status, and type.",
29276
+ parameters: {
29277
+ type: "object",
29278
+ properties: {
29279
+ ...pagination,
29280
+ accountId: { type: "string" },
29281
+ name: { type: "string" },
29282
+ status: { type: "string", enum: ["initializing", "pending", "active", "moved"] },
29283
+ type: { type: "string", description: "Comma-separated zone types." },
29284
+ match: { type: "string", enum: ["any", "all"] },
29285
+ order: { type: "string", enum: ["name", "status", "account.id", "account.name", "plan.id"] },
29286
+ direction: { type: "string", enum: ["asc", "desc"] }
29287
+ }
29288
+ },
29289
+ request: {
29290
+ method: "GET",
29291
+ path: "/zones",
29292
+ query: {
29293
+ ...paginationQuery,
29294
+ "account.id": "{accountId}",
29295
+ name: "{name}",
29296
+ status: "{status}",
29297
+ type: "{type}",
29298
+ match: "{match}",
29299
+ order: "{order}",
29300
+ direction: "{direction}"
29301
+ }
29302
+ }
29303
+ },
29304
+ {
29305
+ name: "zones.get",
29306
+ class: "read",
29307
+ description: "Read one zone with status, nameservers, plan, and ownership metadata.",
29308
+ parameters: { type: "object", properties: zoneId, required: ["zoneId"] },
29309
+ request: { method: "GET", path: "/zones/{zoneId}" }
29310
+ },
29311
+ {
29312
+ name: "zones.settings.list",
29313
+ class: "read",
29314
+ description: "List all settings for one zone.",
29315
+ parameters: { type: "object", properties: zoneId, required: ["zoneId"] },
29316
+ request: { method: "GET", path: "/zones/{zoneId}/settings" }
29317
+ },
29318
+ {
29319
+ name: "zones.settings.get",
29320
+ class: "read",
29321
+ description: "Read one setting for a zone.",
29322
+ parameters: {
29323
+ type: "object",
29324
+ properties: {
29325
+ ...zoneId,
29326
+ settingId: { type: "string", minLength: 1 }
29327
+ },
29328
+ required: ["zoneId", "settingId"]
29329
+ },
29330
+ request: { method: "GET", path: "/zones/{zoneId}/settings/{settingId}" }
29331
+ },
29332
+ {
29333
+ name: "dns.records.list",
29334
+ class: "read",
29335
+ description: "List and filter DNS records in one zone.",
29336
+ parameters: {
29337
+ type: "object",
29338
+ properties: {
29339
+ ...zoneId,
29340
+ ...pagination,
29341
+ type: { type: "string" },
29342
+ name: { type: "string", description: "Exact record name." },
29343
+ content: { type: "string", description: "Exact record content." },
29344
+ proxied: { type: "boolean" },
29345
+ match: { type: "string", enum: ["any", "all"] },
29346
+ order: { type: "string", enum: ["type", "name", "content", "ttl", "proxied"] },
29347
+ direction: { type: "string", enum: ["asc", "desc"] }
29348
+ },
29349
+ required: ["zoneId"]
29350
+ },
29351
+ request: {
29352
+ method: "GET",
29353
+ path: "/zones/{zoneId}/dns_records",
29354
+ query: {
29355
+ ...paginationQuery,
29356
+ type: "{type}",
29357
+ "name.exact": "{name}",
29358
+ "content.exact": "{content}",
29359
+ proxied: "{proxied}",
29360
+ match: "{match}",
29361
+ order: "{order}",
29362
+ direction: "{direction}"
29363
+ }
29364
+ }
29365
+ },
29366
+ {
29367
+ name: "dns.records.get",
29368
+ class: "read",
29369
+ description: "Read one DNS record by zone and record ID.",
29370
+ parameters: {
29371
+ type: "object",
29372
+ properties: { ...zoneId, ...recordId },
29373
+ required: ["zoneId", "recordId"]
29374
+ },
29375
+ request: { method: "GET", path: "/zones/{zoneId}/dns_records/{recordId}" }
29376
+ },
29377
+ {
29378
+ name: "dns.records.export",
29379
+ class: "read",
29380
+ description: "Export the current zone records as a BIND zone file before a change.",
29381
+ parameters: { type: "object", properties: zoneId, required: ["zoneId"] },
29382
+ request: { method: "GET", path: "/zones/{zoneId}/dns_records/export" }
29383
+ },
29384
+ {
29385
+ name: "dns.records.create",
29386
+ class: "mutation",
29387
+ description: "Create one DNS record in a selected zone.",
29388
+ parameters: {
29389
+ type: "object",
29390
+ properties: {
29391
+ ...zoneId,
29392
+ record: {
29393
+ type: "object",
29394
+ properties: recordFields,
29395
+ required: ["type", "name"],
29396
+ additionalProperties: false
29397
+ }
29398
+ },
29399
+ required: ["zoneId", "record"]
29400
+ },
29401
+ request: { method: "POST", path: "/zones/{zoneId}/dns_records", body: "{record}" },
29402
+ cas: "none",
29403
+ externalEffect: true
29404
+ },
29405
+ {
29406
+ name: "dns.records.update",
29407
+ class: "mutation",
29408
+ description: "Partially update one DNS record.",
29409
+ parameters: {
29410
+ type: "object",
29411
+ properties: {
29412
+ ...zoneId,
29413
+ ...recordId,
29414
+ changes: {
29415
+ type: "object",
29416
+ properties: recordFields,
29417
+ additionalProperties: false
29418
+ }
29419
+ },
29420
+ required: ["zoneId", "recordId", "changes"]
29421
+ },
29422
+ request: {
29423
+ method: "PATCH",
29424
+ path: "/zones/{zoneId}/dns_records/{recordId}",
29425
+ body: "{changes}"
29426
+ },
29427
+ cas: "optimistic-read-verify",
29428
+ externalEffect: true
29429
+ },
29430
+ {
29431
+ name: "dns.records.delete",
29432
+ class: "mutation",
29433
+ description: "Permanently delete one DNS record.",
29434
+ parameters: {
29435
+ type: "object",
29436
+ properties: { ...zoneId, ...recordId },
29437
+ required: ["zoneId", "recordId"]
29438
+ },
29439
+ request: { method: "DELETE", path: "/zones/{zoneId}/dns_records/{recordId}" },
29440
+ cas: "optimistic-read-verify",
29441
+ externalEffect: true
29442
+ }
29443
+ ]
29444
+ });
29445
+
27842
29446
  // src/connectors/adapters/cloudinary.ts
27843
29447
  var cloudinaryConnector = declarativeRestConnector({
27844
29448
  kind: "cloudinary",
@@ -36163,134 +37767,6 @@ var frontConnector = declarativeRestConnector({
36163
37767
  ]
36164
37768
  });
36165
37769
 
36166
- // src/connectors/oauth.ts
36167
- import { createHash as createHash4, randomBytes } from "crypto";
36168
- var PENDING_TTL_MS = 10 * 60 * 1e3;
36169
- var InMemoryOAuthFlowStore = class {
36170
- pendingFlows = /* @__PURE__ */ new Map();
36171
- put(state, flow) {
36172
- this.pendingFlows.set(state, flow);
36173
- }
36174
- consume(state) {
36175
- const flow = this.pendingFlows.get(state);
36176
- this.pendingFlows.delete(state);
36177
- if (!flow || flow.expiresAt <= Date.now()) return void 0;
36178
- return flow;
36179
- }
36180
- sweep(now) {
36181
- for (const [k, v] of this.pendingFlows) {
36182
- if (v.expiresAt <= now) this.pendingFlows.delete(k);
36183
- }
36184
- }
36185
- clear() {
36186
- this.pendingFlows.clear();
36187
- }
36188
- };
36189
- var defaultFlowStore = new InMemoryOAuthFlowStore();
36190
- function startOAuthFlow(input) {
36191
- const store = input.store ?? defaultFlowStore;
36192
- const now = input.now ?? Date.now();
36193
- store.sweep?.(now);
36194
- const codeVerifier = base64Url(randomBytes(48));
36195
- const codeChallenge = base64Url(createHash4("sha256").update(codeVerifier).digest());
36196
- const state = base64Url(randomBytes(24));
36197
- store.put(state, {
36198
- codeVerifier,
36199
- state,
36200
- projectId: input.projectId,
36201
- kind: input.kind,
36202
- label: input.label,
36203
- redirectUri: input.redirectUri,
36204
- expiresAt: now + PENDING_TTL_MS
36205
- });
36206
- const url = new URL(input.authorizationUrl);
36207
- url.searchParams.set("response_type", "code");
36208
- url.searchParams.set("client_id", input.clientId);
36209
- url.searchParams.set("redirect_uri", input.redirectUri);
36210
- url.searchParams.set("scope", input.scopes.join(input.scopeSeparator ?? " "));
36211
- url.searchParams.set("state", state);
36212
- url.searchParams.set("code_challenge", codeChallenge);
36213
- url.searchParams.set("code_challenge_method", "S256");
36214
- if (input.extraAuthParams) {
36215
- for (const [k, v] of Object.entries(input.extraAuthParams)) {
36216
- url.searchParams.set(k, v);
36217
- }
36218
- }
36219
- return { authorizationUrl: url.toString(), state };
36220
- }
36221
- async function consumePendingFlow(state, store = defaultFlowStore) {
36222
- await store.sweep?.(Date.now());
36223
- const flow = await store.consume(state);
36224
- if (!flow) {
36225
- throw new Error("Unknown or expired OAuth state: possible CSRF, replay, or stale flow");
36226
- }
36227
- return flow;
36228
- }
36229
- async function exchangeAuthorizationCode(input) {
36230
- const body = new URLSearchParams({
36231
- grant_type: "authorization_code",
36232
- client_id: input.clientId,
36233
- client_secret: input.clientSecret,
36234
- code: input.code,
36235
- redirect_uri: input.redirectUri,
36236
- code_verifier: input.codeVerifier
36237
- });
36238
- const res = await (input.fetchImpl ?? fetch)(input.tokenUrl, {
36239
- method: "POST",
36240
- headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" },
36241
- body,
36242
- signal: input.signal
36243
- });
36244
- if (!res.ok) {
36245
- const text = await res.text().catch(() => "");
36246
- throw new Error(`OAuth token exchange failed: ${res.status} ${res.statusText} \u2014 ${text.slice(0, 200)}`);
36247
- }
36248
- const json = await res.json();
36249
- return {
36250
- accessToken: json.access_token,
36251
- refreshToken: json.refresh_token,
36252
- expiresIn: json.expires_in,
36253
- scope: json.scope,
36254
- tokenType: json.token_type,
36255
- idToken: json.id_token
36256
- };
36257
- }
36258
- async function refreshAccessToken(input) {
36259
- const body = new URLSearchParams({
36260
- grant_type: "refresh_token",
36261
- client_id: input.clientId,
36262
- client_secret: input.clientSecret,
36263
- refresh_token: input.refreshToken
36264
- });
36265
- const res = await (input.fetchImpl ?? fetch)(input.tokenUrl, {
36266
- method: "POST",
36267
- headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" },
36268
- body,
36269
- signal: input.signal
36270
- });
36271
- if (!res.ok) {
36272
- const text = await res.text().catch(() => "");
36273
- throw new Error(`OAuth refresh failed: ${res.status} ${res.statusText} \u2014 ${text.slice(0, 200)}`);
36274
- }
36275
- const json = await res.json();
36276
- return {
36277
- accessToken: json.access_token,
36278
- // Some providers omit refresh_token on refresh — keep the previous one
36279
- // in that case (caller passes through if undefined).
36280
- refreshToken: json.refresh_token,
36281
- expiresIn: json.expires_in,
36282
- scope: json.scope,
36283
- tokenType: json.token_type,
36284
- idToken: json.id_token
36285
- };
36286
- }
36287
- function base64Url(buf) {
36288
- return buf.toString("base64").replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_");
36289
- }
36290
- function _resetPendingFlowsForTests() {
36291
- defaultFlowStore.clear?.();
36292
- }
36293
-
36294
37770
  // src/connectors/adapters/google-errors.ts
36295
37771
  var AUTH_REASONS = /* @__PURE__ */ new Set([
36296
37772
  "autherror",
@@ -38526,13 +40002,13 @@ var googlePubSubConnector = {
38526
40002
  let data4;
38527
40003
  switch (inv.capabilityName) {
38528
40004
  case "topics.list":
38529
- data4 = await pubSubRequest(credentials, inv, "GET", projectPath(credentials, "topics"), pagination(inv.args));
40005
+ data4 = await pubSubRequest(credentials, inv, "GET", projectPath(credentials, "topics"), pagination2(inv.args));
38530
40006
  break;
38531
40007
  case "topics.get":
38532
40008
  data4 = await pubSubRequest(credentials, inv, "GET", topicPath(credentials, inv.args.topic));
38533
40009
  break;
38534
40010
  case "subscriptions.list":
38535
- data4 = await pubSubRequest(credentials, inv, "GET", projectPath(credentials, "subscriptions"), pagination(inv.args));
40011
+ data4 = await pubSubRequest(credentials, inv, "GET", projectPath(credentials, "subscriptions"), pagination2(inv.args));
38536
40012
  break;
38537
40013
  case "subscriptions.get":
38538
40014
  data4 = await pubSubRequest(credentials, inv, "GET", subscriptionPath(credentials, inv.args.subscription));
@@ -38816,7 +40292,7 @@ function resourceId(value, field) {
38816
40292
  }
38817
40293
  return id2;
38818
40294
  }
38819
- function pagination(args) {
40295
+ function pagination2(args) {
38820
40296
  const query2 = new URLSearchParams();
38821
40297
  if (args.pageSize !== void 0) query2.set("pageSize", String(boundedInteger2(args.pageSize, "pageSize", 1, 1e3)));
38822
40298
  if (args.pageToken !== void 0) query2.set("pageToken", requiredString6(args.pageToken, "pageToken"));
@@ -38968,8 +40444,8 @@ function retryAfterMs5(value) {
38968
40444
  if (!value) return 6e4;
38969
40445
  const seconds = Number(value);
38970
40446
  if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
38971
- const date = Date.parse(value);
38972
- return Number.isFinite(date) ? Math.max(0, date - Date.now()) : 6e4;
40447
+ const date2 = Date.parse(value);
40448
+ return Number.isFinite(date2) ? Math.max(0, date2 - Date.now()) : 6e4;
38973
40449
  }
38974
40450
  function isRecord3(value) {
38975
40451
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -41902,25 +43378,25 @@ async function updateRow(inv, accessToken4, timeoutMs) {
41902
43378
  const meta = readSheetMeta(inv.source.metadata);
41903
43379
  const { rowKey, patch, expectedFingerprint } = inv.args;
41904
43380
  const rows = await fetchAllRows(accessToken4, meta);
41905
- const target = rows.find((r) => normalizeKey(r.values[meta.keyColumn]) === normalizeKey(rowKey));
41906
- if (!target) {
43381
+ const target2 = rows.find((r) => normalizeKey(r.values[meta.keyColumn]) === normalizeKey(rowKey));
43382
+ if (!target2) {
41907
43383
  throw new ResourceContention(
41908
43384
  `row with key "${rowKey}" not found`,
41909
43385
  [],
41910
43386
  { availableRows: rows.length }
41911
43387
  );
41912
43388
  }
41913
- if (expectedFingerprint && expectedFingerprint !== target.fingerprint) {
43389
+ if (expectedFingerprint && expectedFingerprint !== target2.fingerprint) {
41914
43390
  throw new ResourceContention(
41915
43391
  `row "${rowKey}" was modified since the agent last read it; re-read and try again`,
41916
43392
  [],
41917
- { current: target.values, currentFingerprint: target.fingerprint }
43393
+ { current: target2.values, currentFingerprint: target2.fingerprint }
41918
43394
  );
41919
43395
  }
41920
43396
  const updatedValues = meta.headers.map(
41921
- (h) => h in patch ? String(patch[h]) : target.values[h] ?? ""
43397
+ (h) => h in patch ? String(patch[h]) : target2.values[h] ?? ""
41922
43398
  );
41923
- const range = `${meta.sheetName}!A${target.rowIndex + 1}:${columnIndexToLetter(meta.headers.length - 1)}${target.rowIndex + 1}`;
43399
+ const range = `${meta.sheetName}!A${target2.rowIndex + 1}:${columnIndexToLetter(meta.headers.length - 1)}${target2.rowIndex + 1}`;
41924
43400
  const url = `https://sheets.googleapis.com/v4/spreadsheets/${encodeURIComponent(meta.spreadsheetId)}/values/${encodeURIComponent(range)}?valueInputOption=USER_ENTERED`;
41925
43401
  const res = await fetch(url, {
41926
43402
  method: "PUT",
@@ -44533,9 +46009,9 @@ function parseRetryAfterMs(header2) {
44533
46009
  if (!header2) return 1e3;
44534
46010
  const seconds = Number(header2);
44535
46011
  if (Number.isFinite(seconds) && seconds >= 0) return Math.floor(seconds * 1e3);
44536
- const date = Date.parse(header2);
44537
- if (!Number.isFinite(date)) return 1e3;
44538
- return Math.max(0, date - Date.now());
46012
+ const date2 = Date.parse(header2);
46013
+ if (!Number.isFinite(date2)) return 1e3;
46014
+ return Math.max(0, date2 - Date.now());
44539
46015
  }
44540
46016
  function stringify2(value) {
44541
46017
  if (typeof value === "string") return value;
@@ -48394,327 +49870,335 @@ var linearConnector = declarativeRestConnector({
48394
49870
  });
48395
49871
 
48396
49872
  // src/connectors/adapters/linkedin.ts
48397
- var linkedinConnector = declarativeRestConnector({
48398
- kind: "linkedin",
48399
- displayName: "LinkedIn",
48400
- description: "Read the connected LinkedIn member profile and administered organizations, and create / read / delete member or organization posts and comments via the LinkedIn REST API.",
48401
- auth: {
48402
- kind: "oauth2",
48403
- authorizationUrl: "https://www.linkedin.com/oauth/v2/authorization",
48404
- tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken",
48405
- scopes: [
48406
- "openid",
48407
- "profile",
48408
- "email",
48409
- "w_member_social",
48410
- "r_organization_social",
48411
- "w_organization_social",
48412
- "rw_organization_admin"
48413
- ],
48414
- clientIdEnv: "LINKEDIN_OAUTH_CLIENT_ID",
48415
- clientSecretEnv: "LINKEDIN_OAUTH_CLIENT_SECRET"
48416
- },
48417
- category: "comms",
48418
- defaultConsistencyModel: "advisory",
48419
- baseUrl: "https://api.linkedin.com",
48420
- defaultHeaders: {
48421
- "LinkedIn-Version": "202405",
48422
- "X-Restli-Protocol-Version": "2.0.0"
48423
- },
48424
- test: { method: "GET", path: "/v2/userinfo" },
48425
- capabilities: [
48426
- {
48427
- name: "userinfo",
48428
- class: "read",
48429
- description: "Return the OpenID-Connect userinfo for the connected LinkedIn member (sub, name, given_name, family_name, picture, email, email_verified, locale).",
48430
- parameters: { type: "object", properties: {} },
48431
- request: { method: "GET", path: "/v2/userinfo" },
48432
- requiredScopes: ["openid", "profile"]
49873
+ var MEMBER_SCOPES = ["openid", "profile", "email", "w_member_social"];
49874
+ var ORGANIZATION_SCOPES = [
49875
+ "r_organization_social",
49876
+ "w_organization_social",
49877
+ "rw_organization_admin"
49878
+ ];
49879
+ var ORGANIZATION_SCOPE_SET = new Set(ORGANIZATION_SCOPES);
49880
+ function createLinkedinConnector(options = {}) {
49881
+ const organizationAccess = options.organizationAccess === true;
49882
+ const postScope = organizationAccess ? "w_organization_social" : "w_member_social";
49883
+ return declarativeRestConnector({
49884
+ kind: "linkedin",
49885
+ displayName: "LinkedIn",
49886
+ description: organizationAccess ? "Read the connected LinkedIn member profile and administered organizations, and create / read / delete organization posts and comments via the LinkedIn REST API." : "Read the connected LinkedIn member profile and create / delete member posts and comments via the LinkedIn REST API.",
49887
+ auth: {
49888
+ kind: "oauth2",
49889
+ authorizationUrl: "https://www.linkedin.com/oauth/v2/authorization",
49890
+ tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken",
49891
+ scopes: organizationAccess ? [...MEMBER_SCOPES, ...ORGANIZATION_SCOPES] : [...MEMBER_SCOPES],
49892
+ clientIdEnv: "LINKEDIN_OAUTH_CLIENT_ID",
49893
+ clientSecretEnv: "LINKEDIN_OAUTH_CLIENT_SECRET"
48433
49894
  },
48434
- {
48435
- name: "organizations.get",
48436
- class: "read",
48437
- description: "Read a single LinkedIn organization (company page) by numeric id. The connected member must be an administrator of the organization.",
48438
- parameters: {
48439
- type: "object",
48440
- properties: { organizationId: { type: "string" } },
48441
- required: ["organizationId"]
48442
- },
48443
- request: { method: "GET", path: "/v2/organizations/{organizationId}" },
48444
- requiredScopes: ["r_organization_social"]
49895
+ category: "comms",
49896
+ defaultConsistencyModel: "advisory",
49897
+ baseUrl: "https://api.linkedin.com",
49898
+ defaultHeaders: {
49899
+ "LinkedIn-Version": "202405",
49900
+ "X-Restli-Protocol-Version": "2.0.0"
48445
49901
  },
48446
- {
48447
- name: "organizations.acls.list",
48448
- class: "read",
48449
- description: "List the organizations (and roles) for which the connected member has an ACL \u2014 i.e. the company pages they can read or post on behalf of.",
48450
- parameters: {
48451
- type: "object",
48452
- properties: {
48453
- role: {
48454
- type: "string",
48455
- enum: ["ADMINISTRATOR", "DIRECT_SPONSORED_CONTENT_POSTER", "RECRUITING_POSTER"],
48456
- default: "ADMINISTRATOR"
48457
- },
48458
- state: {
48459
- type: "string",
48460
- enum: ["APPROVED", "REQUESTED", "REJECTED", "REVOKED"],
48461
- default: "APPROVED"
48462
- },
48463
- count: { type: "integer", minimum: 1, maximum: 100, default: 100 },
48464
- start: { type: "integer", minimum: 0, default: 0 }
48465
- }
48466
- },
48467
- request: {
48468
- method: "GET",
48469
- path: "/v2/organizationAcls",
48470
- query: {
48471
- q: "roleAssignee",
48472
- role: "{role}",
48473
- state: "{state}",
48474
- count: "{count}",
48475
- start: "{start}"
48476
- }
49902
+ test: { method: "GET", path: "/v2/userinfo" },
49903
+ capabilities: [
49904
+ {
49905
+ name: "userinfo",
49906
+ class: "read",
49907
+ description: "Return the OpenID-Connect userinfo for the connected LinkedIn member (sub, name, given_name, family_name, picture, email, email_verified, locale).",
49908
+ parameters: { type: "object", properties: {} },
49909
+ request: { method: "GET", path: "/v2/userinfo" },
49910
+ requiredScopes: ["openid", "profile", "email"]
48477
49911
  },
48478
- requiredScopes: ["r_organization_social", "rw_organization_admin"]
48479
- },
48480
- {
48481
- name: "posts.create",
48482
- class: "mutation",
48483
- description: "Create a LinkedIn post on the REST Posts API. `author` is the member or organization URN (e.g. `urn:li:person:{sub}` or `urn:li:organization:{id}`). `commentary` is the post text; `distribution.feedDistribution` defaults to `MAIN_FEED`; `lifecycleState` defaults to `PUBLISHED`. Append-only \u2014 caller owns dedupe via idempotencyKey.",
48484
- parameters: {
48485
- type: "object",
48486
- properties: {
48487
- author: {
48488
- type: "string",
48489
- description: "URN of the post author (urn:li:person:{sub} or urn:li:organization:{id})."
48490
- },
48491
- commentary: { type: "string", description: "Post text body." },
48492
- visibility: {
48493
- type: "string",
48494
- enum: ["PUBLIC", "CONNECTIONS", "LOGGED_IN", "CONTAINER"],
48495
- default: "PUBLIC"
48496
- },
48497
- distribution: {
48498
- type: "object",
48499
- description: 'Distribution policy. Defaults to { feedDistribution: "MAIN_FEED", targetEntities: [], thirdPartyDistributionChannels: [] }.'
48500
- },
48501
- content: {
48502
- type: "object",
48503
- description: "Optional rich-media content block ({ article: {...} } | { media: {...} } | { multiImage: {...} } | { poll: {...} } | { carousel: {...} })."
48504
- },
48505
- lifecycleState: {
48506
- type: "string",
48507
- enum: ["PUBLISHED", "DRAFT"],
48508
- default: "PUBLISHED"
48509
- },
48510
- isReshareDisabledByAuthor: { type: "boolean", default: false }
49912
+ {
49913
+ name: "organizations.get",
49914
+ class: "read",
49915
+ description: "Read a single LinkedIn organization (company page) by numeric id. The connected member must be an administrator of the organization.",
49916
+ parameters: {
49917
+ type: "object",
49918
+ properties: { organizationId: { type: "string" } },
49919
+ required: ["organizationId"]
48511
49920
  },
48512
- required: ["author", "commentary"]
49921
+ request: { method: "GET", path: "/v2/organizations/{organizationId}" },
49922
+ requiredScopes: ["r_organization_social"]
48513
49923
  },
48514
- request: {
48515
- method: "POST",
48516
- path: "/rest/posts",
48517
- body: {
48518
- author: "{author}",
48519
- commentary: "{commentary}",
48520
- visibility: "{visibility}",
48521
- distribution: "{distribution}",
48522
- content: "{content}",
48523
- lifecycleState: "{lifecycleState}",
48524
- isReshareDisabledByAuthor: "{isReshareDisabledByAuthor}"
48525
- }
48526
- },
48527
- cas: "none",
48528
- externalEffect: true,
48529
- requiredScopes: ["w_member_social"]
48530
- },
48531
- {
48532
- name: "posts.get",
48533
- class: "read",
48534
- description: "Read a single post by its URN (e.g. `urn:li:share:1234567890` or `urn:li:ugcPost:1234567890`). The URN must be URL-encoded by the caller.",
48535
- parameters: {
48536
- type: "object",
48537
- properties: {
48538
- postUrn: {
48539
- type: "string",
48540
- description: "URL-encoded URN of the post (urn:li:share:* or urn:li:ugcPost:*)."
49924
+ {
49925
+ name: "organizations.acls.list",
49926
+ class: "read",
49927
+ description: "List the organizations (and roles) for which the connected member has an ACL \u2014 i.e. the company pages they can read or post on behalf of.",
49928
+ parameters: {
49929
+ type: "object",
49930
+ properties: {
49931
+ role: {
49932
+ type: "string",
49933
+ enum: ["ADMINISTRATOR", "DIRECT_SPONSORED_CONTENT_POSTER", "RECRUITING_POSTER"],
49934
+ default: "ADMINISTRATOR"
49935
+ },
49936
+ state: {
49937
+ type: "string",
49938
+ enum: ["APPROVED", "REQUESTED", "REJECTED", "REVOKED"],
49939
+ default: "APPROVED"
49940
+ },
49941
+ count: { type: "integer", minimum: 1, maximum: 100, default: 100 },
49942
+ start: { type: "integer", minimum: 0, default: 0 }
49943
+ }
49944
+ },
49945
+ request: {
49946
+ method: "GET",
49947
+ path: "/v2/organizationAcls",
49948
+ query: {
49949
+ q: "roleAssignee",
49950
+ role: "{role}",
49951
+ state: "{state}",
49952
+ count: "{count}",
49953
+ start: "{start}"
48541
49954
  }
48542
49955
  },
48543
- required: ["postUrn"]
49956
+ requiredScopes: ["r_organization_social", "rw_organization_admin"]
48544
49957
  },
48545
- request: { method: "GET", path: "/rest/posts/{postUrn}" },
48546
- requiredScopes: ["r_organization_social"]
48547
- },
48548
- {
48549
- name: "posts.list.byAuthor",
48550
- class: "read",
48551
- description: "List posts authored by a given URN (member or organization). Uses the Posts API finder `q=author`.",
48552
- parameters: {
48553
- type: "object",
48554
- properties: {
48555
- author: {
48556
- type: "string",
48557
- description: "URN of the author to list posts for."
49958
+ {
49959
+ name: "posts.create",
49960
+ class: "mutation",
49961
+ description: organizationAccess ? "Create a LinkedIn organization post on the REST Posts API. `author` is an organization URN (e.g. `urn:li:organization:{id}`). `commentary` is the post text; `distribution.feedDistribution` defaults to `MAIN_FEED`; `lifecycleState` defaults to `PUBLISHED`. Append-only \u2014 caller owns dedupe via idempotencyKey." : "Create a LinkedIn member post on the REST Posts API. `author` is the connected member URN (e.g. `urn:li:person:{sub}`). `commentary` is the post text; `distribution.feedDistribution` defaults to `MAIN_FEED`; `lifecycleState` defaults to `PUBLISHED`. Append-only \u2014 caller owns dedupe via idempotencyKey.",
49962
+ parameters: {
49963
+ type: "object",
49964
+ properties: {
49965
+ author: {
49966
+ type: "string",
49967
+ description: organizationAccess ? "URN of the organization post author (urn:li:organization:{id})." : "URN of the connected member post author (urn:li:person:{sub})."
49968
+ },
49969
+ commentary: { type: "string", description: "Post text body." },
49970
+ visibility: {
49971
+ type: "string",
49972
+ enum: ["PUBLIC", "CONNECTIONS", "LOGGED_IN", "CONTAINER"],
49973
+ default: "PUBLIC"
49974
+ },
49975
+ distribution: {
49976
+ type: "object",
49977
+ description: 'Distribution policy. Defaults to { feedDistribution: "MAIN_FEED", targetEntities: [], thirdPartyDistributionChannels: [] }.'
49978
+ },
49979
+ content: {
49980
+ type: "object",
49981
+ description: "Optional rich-media content block ({ article: {...} } | { media: {...} } | { multiImage: {...} } | { poll: {...} } | { carousel: {...} })."
49982
+ },
49983
+ lifecycleState: {
49984
+ type: "string",
49985
+ enum: ["PUBLISHED", "DRAFT"],
49986
+ default: "PUBLISHED"
49987
+ },
49988
+ isReshareDisabledByAuthor: { type: "boolean", default: false }
48558
49989
  },
48559
- count: { type: "integer", minimum: 1, maximum: 100, default: 20 },
48560
- start: { type: "integer", minimum: 0, default: 0 },
48561
- sortBy: {
48562
- type: "string",
48563
- enum: ["CREATED", "LAST_MODIFIED"],
48564
- default: "CREATED"
49990
+ required: ["author", "commentary"]
49991
+ },
49992
+ request: {
49993
+ method: "POST",
49994
+ path: "/rest/posts",
49995
+ body: {
49996
+ author: "{author}",
49997
+ commentary: "{commentary}",
49998
+ visibility: "{visibility}",
49999
+ distribution: "{distribution}",
50000
+ content: "{content}",
50001
+ lifecycleState: "{lifecycleState}",
50002
+ isReshareDisabledByAuthor: "{isReshareDisabledByAuthor}"
48565
50003
  }
48566
50004
  },
48567
- required: ["author"]
48568
- },
48569
- request: {
48570
- method: "GET",
48571
- path: "/rest/posts",
48572
- query: {
48573
- q: "author",
48574
- author: "{author}",
48575
- count: "{count}",
48576
- start: "{start}",
48577
- sortBy: "{sortBy}"
48578
- }
50005
+ cas: "none",
50006
+ externalEffect: true,
50007
+ requiredScopes: [postScope]
48579
50008
  },
48580
- requiredScopes: ["r_organization_social"]
48581
- },
48582
- {
48583
- name: "posts.delete",
48584
- class: "mutation",
48585
- description: "Delete a post by its URL-encoded URN. Idempotent on the URN \u2014 replays after success return 404 and the engine maps that to a no-op.",
48586
- parameters: {
48587
- type: "object",
48588
- properties: {
48589
- postUrn: { type: "string" }
50009
+ {
50010
+ name: "posts.get",
50011
+ class: "read",
50012
+ description: "Read a single post by its URN (e.g. `urn:li:share:1234567890` or `urn:li:ugcPost:1234567890`). The URN must be URL-encoded by the caller.",
50013
+ parameters: {
50014
+ type: "object",
50015
+ properties: {
50016
+ postUrn: {
50017
+ type: "string",
50018
+ description: "URL-encoded URN of the post (urn:li:share:* or urn:li:ugcPost:*)."
50019
+ }
50020
+ },
50021
+ required: ["postUrn"]
48590
50022
  },
48591
- required: ["postUrn"]
50023
+ request: { method: "GET", path: "/rest/posts/{postUrn}" },
50024
+ requiredScopes: ["r_organization_social"]
48592
50025
  },
48593
- request: { method: "DELETE", path: "/rest/posts/{postUrn}" },
48594
- cas: "native-idempotency",
48595
- externalEffect: true,
48596
- requiredScopes: ["w_member_social"]
48597
- },
48598
- {
48599
- name: "comments.list",
48600
- class: "read",
48601
- description: "List comments on a share / post. `shareUrn` is the URL-encoded URN of the parent share (urn:li:share:* or urn:li:ugcPost:*).",
48602
- parameters: {
48603
- type: "object",
48604
- properties: {
48605
- shareUrn: { type: "string" },
48606
- count: { type: "integer", minimum: 1, maximum: 100, default: 50 },
48607
- start: { type: "integer", minimum: 0, default: 0 }
50026
+ {
50027
+ name: "posts.list.byAuthor",
50028
+ class: "read",
50029
+ description: "List posts authored by a given URN (member or organization). Uses the Posts API finder `q=author`.",
50030
+ parameters: {
50031
+ type: "object",
50032
+ properties: {
50033
+ author: {
50034
+ type: "string",
50035
+ description: "URN of the author to list posts for."
50036
+ },
50037
+ count: { type: "integer", minimum: 1, maximum: 100, default: 20 },
50038
+ start: { type: "integer", minimum: 0, default: 0 },
50039
+ sortBy: {
50040
+ type: "string",
50041
+ enum: ["CREATED", "LAST_MODIFIED"],
50042
+ default: "CREATED"
50043
+ }
50044
+ },
50045
+ required: ["author"]
48608
50046
  },
48609
- required: ["shareUrn"]
48610
- },
48611
- request: {
48612
- method: "GET",
48613
- path: "/rest/socialActions/{shareUrn}/comments",
48614
- query: { count: "{count}", start: "{start}" }
50047
+ request: {
50048
+ method: "GET",
50049
+ path: "/rest/posts",
50050
+ query: {
50051
+ q: "author",
50052
+ author: "{author}",
50053
+ count: "{count}",
50054
+ start: "{start}",
50055
+ sortBy: "{sortBy}"
50056
+ }
50057
+ },
50058
+ requiredScopes: ["r_organization_social"]
48615
50059
  },
48616
- requiredScopes: ["r_organization_social"]
48617
- },
48618
- {
48619
- name: "comments.create",
48620
- class: "mutation",
48621
- description: "Create a top-level comment on a share / post. `actor` is the member or organization URN posting the comment; `message.text` is the comment text. Append-only \u2014 caller owns dedupe via idempotencyKey.",
48622
- parameters: {
48623
- type: "object",
48624
- properties: {
48625
- shareUrn: {
48626
- type: "string",
48627
- description: "URL-encoded URN of the parent share (urn:li:share:* or urn:li:ugcPost:*)."
50060
+ {
50061
+ name: "posts.delete",
50062
+ class: "mutation",
50063
+ description: "Delete a post by its URL-encoded URN. Idempotent on the URN \u2014 replays after success return 404 and the engine maps that to a no-op.",
50064
+ parameters: {
50065
+ type: "object",
50066
+ properties: {
50067
+ postUrn: { type: "string" }
48628
50068
  },
48629
- actor: {
48630
- type: "string",
48631
- description: "URN of the commenting member or organization."
50069
+ required: ["postUrn"]
50070
+ },
50071
+ request: { method: "DELETE", path: "/rest/posts/{postUrn}" },
50072
+ cas: "native-idempotency",
50073
+ externalEffect: true,
50074
+ requiredScopes: [postScope]
50075
+ },
50076
+ {
50077
+ name: "comments.list",
50078
+ class: "read",
50079
+ description: "List comments on a share / post. `shareUrn` is the URL-encoded URN of the parent share (urn:li:share:* or urn:li:ugcPost:*).",
50080
+ parameters: {
50081
+ type: "object",
50082
+ properties: {
50083
+ shareUrn: { type: "string" },
50084
+ count: { type: "integer", minimum: 1, maximum: 100, default: 50 },
50085
+ start: { type: "integer", minimum: 0, default: 0 }
48632
50086
  },
48633
- message: {
48634
- type: "object",
48635
- description: "Comment body `{ text: string, attributes?: [...] }`."
50087
+ required: ["shareUrn"]
50088
+ },
50089
+ request: {
50090
+ method: "GET",
50091
+ path: "/rest/socialActions/{shareUrn}/comments",
50092
+ query: { count: "{count}", start: "{start}" }
50093
+ },
50094
+ requiredScopes: ["r_organization_social"]
50095
+ },
50096
+ {
50097
+ name: "comments.create",
50098
+ class: "mutation",
50099
+ description: organizationAccess ? "Create a top-level comment on an organization share / post. `actor` is the organization URN posting the comment; `message.text` is the comment text. Append-only \u2014 caller owns dedupe via idempotencyKey." : "Create a top-level comment on a share / post as the connected member. `actor` is the member URN posting the comment; `message.text` is the comment text. Append-only \u2014 caller owns dedupe via idempotencyKey.",
50100
+ parameters: {
50101
+ type: "object",
50102
+ properties: {
50103
+ shareUrn: {
50104
+ type: "string",
50105
+ description: "URL-encoded URN of the parent share (urn:li:share:* or urn:li:ugcPost:*)."
50106
+ },
50107
+ actor: {
50108
+ type: "string",
50109
+ description: organizationAccess ? "URN of the commenting organization." : "URN of the commenting member."
50110
+ },
50111
+ message: {
50112
+ type: "object",
50113
+ description: "Comment body `{ text: string, attributes?: [...] }`."
50114
+ },
50115
+ parentComment: {
50116
+ type: "string",
50117
+ description: "Optional URN of a parent comment for threaded replies."
50118
+ }
48636
50119
  },
48637
- parentComment: {
48638
- type: "string",
48639
- description: "Optional URN of a parent comment for threaded replies."
50120
+ required: ["shareUrn", "actor", "message"]
50121
+ },
50122
+ request: {
50123
+ method: "POST",
50124
+ path: "/rest/socialActions/{shareUrn}/comments",
50125
+ body: {
50126
+ actor: "{actor}",
50127
+ object: "{shareUrn}",
50128
+ message: "{message}",
50129
+ parentComment: "{parentComment}"
48640
50130
  }
48641
50131
  },
48642
- required: ["shareUrn", "actor", "message"]
48643
- },
48644
- request: {
48645
- method: "POST",
48646
- path: "/rest/socialActions/{shareUrn}/comments",
48647
- body: {
48648
- actor: "{actor}",
48649
- object: "{shareUrn}",
48650
- message: "{message}",
48651
- parentComment: "{parentComment}"
48652
- }
50132
+ cas: "none",
50133
+ externalEffect: true,
50134
+ requiredScopes: [postScope]
48653
50135
  },
48654
- cas: "none",
48655
- externalEffect: true,
48656
- requiredScopes: ["w_member_social"]
48657
- },
48658
- {
48659
- name: "comments.update",
48660
- class: "mutation",
48661
- description: "Edit the text of an existing comment by its URN. Only the original comment actor can edit. Verified via read-after-write because LinkedIn returns no ETag.",
48662
- parameters: {
48663
- type: "object",
48664
- properties: {
48665
- shareUrn: { type: "string" },
48666
- commentUrn: { type: "string", description: "URL-encoded URN of the comment to update." },
48667
- actor: { type: "string" },
48668
- message: { type: "object" }
50136
+ {
50137
+ name: "comments.update",
50138
+ class: "mutation",
50139
+ description: "Edit the text of an existing comment by its URN. Only the original comment actor can edit. Verified via read-after-write because LinkedIn returns no ETag.",
50140
+ parameters: {
50141
+ type: "object",
50142
+ properties: {
50143
+ shareUrn: { type: "string" },
50144
+ commentUrn: { type: "string", description: "URL-encoded URN of the comment to update." },
50145
+ actor: { type: "string" },
50146
+ message: { type: "object" }
50147
+ },
50148
+ required: ["shareUrn", "commentUrn", "actor", "message"]
48669
50149
  },
48670
- required: ["shareUrn", "commentUrn", "actor", "message"]
48671
- },
48672
- request: {
48673
- method: "POST",
48674
- path: "/rest/socialActions/{shareUrn}/comments/{commentUrn}",
48675
- headers: { "X-RestLi-Method": "PARTIAL_UPDATE" },
48676
- body: { actor: "{actor}", message: "{message}" }
48677
- },
48678
- cas: "optimistic-read-verify",
48679
- externalEffect: true,
48680
- requiredScopes: ["w_member_social"]
48681
- },
48682
- {
48683
- name: "comments.delete",
48684
- class: "mutation",
48685
- description: "Delete a comment by URN. `actor` must be the comment author. Idempotent on the URN.",
48686
- parameters: {
48687
- type: "object",
48688
- properties: {
48689
- shareUrn: { type: "string" },
48690
- commentUrn: { type: "string" },
48691
- actor: { type: "string" }
50150
+ request: {
50151
+ method: "POST",
50152
+ path: "/rest/socialActions/{shareUrn}/comments/{commentUrn}",
50153
+ headers: { "X-RestLi-Method": "PARTIAL_UPDATE" },
50154
+ body: { actor: "{actor}", message: "{message}" }
48692
50155
  },
48693
- required: ["shareUrn", "commentUrn", "actor"]
48694
- },
48695
- request: {
48696
- method: "DELETE",
48697
- path: "/rest/socialActions/{shareUrn}/comments/{commentUrn}",
48698
- query: { actor: "{actor}" }
50156
+ cas: "optimistic-read-verify",
50157
+ externalEffect: true,
50158
+ requiredScopes: [postScope]
48699
50159
  },
48700
- cas: "native-idempotency",
48701
- externalEffect: true,
48702
- requiredScopes: ["w_member_social"]
48703
- },
48704
- {
48705
- name: "socialActions.get",
48706
- class: "read",
48707
- description: "Read the aggregate social-action counts (likes, comments) for a share / post URN.",
48708
- parameters: {
48709
- type: "object",
48710
- properties: { shareUrn: { type: "string" } },
48711
- required: ["shareUrn"]
50160
+ {
50161
+ name: "comments.delete",
50162
+ class: "mutation",
50163
+ description: "Delete a comment by URN. `actor` must be the comment author. Idempotent on the URN.",
50164
+ parameters: {
50165
+ type: "object",
50166
+ properties: {
50167
+ shareUrn: { type: "string" },
50168
+ commentUrn: { type: "string" },
50169
+ actor: { type: "string" }
50170
+ },
50171
+ required: ["shareUrn", "commentUrn", "actor"]
50172
+ },
50173
+ request: {
50174
+ method: "DELETE",
50175
+ path: "/rest/socialActions/{shareUrn}/comments/{commentUrn}",
50176
+ query: { actor: "{actor}" }
50177
+ },
50178
+ cas: "native-idempotency",
50179
+ externalEffect: true,
50180
+ requiredScopes: [postScope]
48712
50181
  },
48713
- request: { method: "GET", path: "/rest/socialActions/{shareUrn}" },
48714
- requiredScopes: ["r_organization_social"]
48715
- }
48716
- ]
48717
- });
50182
+ {
50183
+ name: "socialActions.get",
50184
+ class: "read",
50185
+ description: "Read the aggregate social-action counts (likes, comments) for a share / post URN.",
50186
+ parameters: {
50187
+ type: "object",
50188
+ properties: { shareUrn: { type: "string" } },
50189
+ required: ["shareUrn"]
50190
+ },
50191
+ request: { method: "GET", path: "/rest/socialActions/{shareUrn}" },
50192
+ requiredScopes: ["r_organization_social"]
50193
+ }
50194
+ ].filter(
50195
+ // Organization-gated capabilities are not part of the self-serve grant.
50196
+ // Keep them absent from the default manifest so discovery cannot advertise them.
50197
+ ({ requiredScopes }) => organizationAccess || !(requiredScopes ?? []).some((scope) => ORGANIZATION_SCOPE_SET.has(scope))
50198
+ )
50199
+ });
50200
+ }
50201
+ var linkedinConnector = createLinkedinConnector();
48718
50202
 
48719
50203
  // src/connectors/adapters/make.ts
48720
50204
  var makeConnector = declarativeRestConnector({
@@ -49674,7 +51158,7 @@ function microsoftCalendar(opts) {
49674
51158
  return adapter;
49675
51159
  }
49676
51160
  async function getScheduleBusy(input) {
49677
- const target = input.userPrincipal === "me" ? "me" : input.userPrincipal;
51161
+ const target2 = input.userPrincipal === "me" ? "me" : input.userPrincipal;
49678
51162
  const url = "https://graph.microsoft.com/v1.0/me/calendar/getSchedule";
49679
51163
  const res = await fetch(url, {
49680
51164
  method: "POST",
@@ -49683,7 +51167,7 @@ async function getScheduleBusy(input) {
49683
51167
  "content-type": "application/json"
49684
51168
  },
49685
51169
  body: JSON.stringify({
49686
- schedules: [target],
51170
+ schedules: [target2],
49687
51171
  startTime: { dateTime: input.timeMin, timeZone: "UTC" },
49688
51172
  endTime: { dateTime: input.timeMax, timeZone: "UTC" },
49689
51173
  availabilityViewInterval: 30
@@ -54675,6 +56159,9 @@ function notion(opts) {
54675
56159
  if (!clientId || !clientSecret) {
54676
56160
  throw new Error("Notion OAuth client not configured (NOTION_OAUTH_CLIENT_ID / _SECRET)");
54677
56161
  }
56162
+ if (!input.codeVerifier) {
56163
+ throw new Error("notion.exchangeOAuth: missing PKCE code verifier");
56164
+ }
54678
56165
  const body = new URLSearchParams({
54679
56166
  grant_type: "authorization_code",
54680
56167
  code: input.code,
@@ -61446,9 +62933,9 @@ function mutablePath(rootPath, value) {
61446
62933
  }
61447
62934
  async function canonicalizeExistingPath(client, configuredRoot, path) {
61448
62935
  const root = posix.normalize(await client.realPath(configuredRoot));
61449
- const target = posix.normalize(await client.realPath(path));
61450
- assertWithinCanonicalRoot(root, target);
61451
- return target;
62936
+ const target2 = posix.normalize(await client.realPath(path));
62937
+ assertWithinCanonicalRoot(root, target2);
62938
+ return target2;
61452
62939
  }
61453
62940
  async function canonicalizeDestinationPath(client, configuredRoot, path) {
61454
62941
  const root = posix.normalize(await client.realPath(configuredRoot));
@@ -61470,8 +62957,8 @@ async function canonicalizeDestinationPath(client, configuredRoot, path) {
61470
62957
  assertWithinCanonicalRoot(root, destination);
61471
62958
  return destination;
61472
62959
  }
61473
- function assertWithinCanonicalRoot(root, target) {
61474
- if (root !== "/" && target !== root && !target.startsWith(`${root}/`)) {
62960
+ function assertWithinCanonicalRoot(root, target2) {
62961
+ if (root !== "/" && target2 !== root && !target2.startsWith(`${root}/`)) {
61475
62962
  throw new Error("SFTP path resolves outside the configured root");
61476
62963
  }
61477
62964
  }
@@ -67930,6 +69417,9 @@ function twitter(opts) {
67930
69417
  if (!clientId || !clientSecret) {
67931
69418
  throw new Error("Twitter OAuth client not configured (TWITTER_OAUTH_CLIENT_ID / _SECRET)");
67932
69419
  }
69420
+ if (!input.codeVerifier) {
69421
+ throw new Error("twitter.exchangeOAuth: missing PKCE code verifier");
69422
+ }
67933
69423
  const tokens = await twitterTokenRequest(clientId, clientSecret, {
67934
69424
  grant_type: "authorization_code",
67935
69425
  code: input.code,
@@ -67990,6 +69480,733 @@ async function twitterTokenRequest(clientId, clientSecret, params) {
67990
69480
  };
67991
69481
  }
67992
69482
 
69483
+ // src/connectors/adapters/tiktok.ts
69484
+ var AUTHORIZATION_URL = "https://www.tiktok.com/v2/auth/authorize/";
69485
+ var TOKEN_URL20 = "https://open.tiktokapis.com/v2/oauth/token/";
69486
+ var API_BASE_URL = "https://open.tiktokapis.com";
69487
+ var SCOPES14 = ["user.info.basic", "video.list", "video.publish"];
69488
+ var VIDEO_FIELDS = [
69489
+ "id",
69490
+ "create_time",
69491
+ "cover_image_url",
69492
+ "share_url",
69493
+ "video_description",
69494
+ "duration",
69495
+ "height",
69496
+ "width",
69497
+ "title",
69498
+ "embed_link",
69499
+ "like_count",
69500
+ "comment_count",
69501
+ "share_count",
69502
+ "view_count"
69503
+ ].join(",");
69504
+ var PRIVACY_LEVELS = [
69505
+ "PUBLIC_TO_EVERYONE",
69506
+ "MUTUAL_FOLLOW_FRIENDS",
69507
+ "FOLLOWER_OF_CREATOR",
69508
+ "SELF_ONLY"
69509
+ ];
69510
+ var jsonPostHeaders = {
69511
+ "content-type": "application/json; charset=UTF-8"
69512
+ };
69513
+ var TIKTOK_SPEC = {
69514
+ kind: "tiktok",
69515
+ displayName: "TikTok",
69516
+ description: "Read the connected TikTok profile and videos, then publish approved videos or photo posts from verified HTTPS URLs.",
69517
+ auth: {
69518
+ kind: "oauth2",
69519
+ authorizationUrl: AUTHORIZATION_URL,
69520
+ tokenUrl: TOKEN_URL20,
69521
+ scopes: [...SCOPES14],
69522
+ scopeSeparator: ",",
69523
+ pkce: "unsupported",
69524
+ authorizationClientIdParam: "client_key",
69525
+ tokenClientIdParam: "client_key",
69526
+ tokenClientSecretParam: "client_secret",
69527
+ clientIdEnv: "TIKTOK_OAUTH_CLIENT_KEY",
69528
+ clientSecretEnv: "TIKTOK_OAUTH_CLIENT_SECRET",
69529
+ tokenMetadata: { openId: "open_id" }
69530
+ },
69531
+ category: "comms",
69532
+ defaultConsistencyModel: "advisory",
69533
+ baseUrl: API_BASE_URL,
69534
+ credentialsExpiredStatuses: [401],
69535
+ test: {
69536
+ method: "GET",
69537
+ path: "/v2/user/info/",
69538
+ query: { fields: "open_id,union_id,avatar_url,display_name" }
69539
+ },
69540
+ capabilities: [
69541
+ {
69542
+ name: "user.info",
69543
+ class: "read",
69544
+ description: "Read the connected TikTok account identity, display name, and avatar.",
69545
+ parameters: { type: "object", properties: {} },
69546
+ requiredScopes: ["user.info.basic"],
69547
+ request: {
69548
+ method: "GET",
69549
+ path: "/v2/user/info/",
69550
+ query: { fields: "open_id,union_id,avatar_url,display_name" }
69551
+ }
69552
+ },
69553
+ {
69554
+ name: "videos.list",
69555
+ class: "read",
69556
+ description: "List videos for the connected creator, including public URLs, dimensions, duration, and engagement counts.",
69557
+ parameters: {
69558
+ type: "object",
69559
+ properties: {
69560
+ cursor: {
69561
+ type: "integer",
69562
+ minimum: 0,
69563
+ description: "UTC millisecond cursor returned by the previous page."
69564
+ },
69565
+ max_count: {
69566
+ type: "integer",
69567
+ minimum: 1,
69568
+ maximum: 20,
69569
+ default: 10
69570
+ }
69571
+ }
69572
+ },
69573
+ requiredScopes: ["video.list"],
69574
+ request: {
69575
+ method: "POST",
69576
+ path: "/v2/video/list/",
69577
+ query: { fields: VIDEO_FIELDS },
69578
+ headers: jsonPostHeaders,
69579
+ body: { cursor: "{cursor}", max_count: "{max_count}" }
69580
+ }
69581
+ },
69582
+ {
69583
+ name: "videos.query",
69584
+ class: "read",
69585
+ description: "Read up to 20 TikTok videos by their exact video ids.",
69586
+ parameters: {
69587
+ type: "object",
69588
+ properties: {
69589
+ video_ids: {
69590
+ type: "array",
69591
+ minItems: 1,
69592
+ maxItems: 20,
69593
+ uniqueItems: true,
69594
+ items: { type: "string", minLength: 1 }
69595
+ }
69596
+ },
69597
+ required: ["video_ids"]
69598
+ },
69599
+ requiredScopes: ["video.list"],
69600
+ request: {
69601
+ method: "POST",
69602
+ path: "/v2/video/query/",
69603
+ query: { fields: VIDEO_FIELDS },
69604
+ headers: jsonPostHeaders,
69605
+ body: { filters: { video_ids: "{video_ids}" } }
69606
+ }
69607
+ },
69608
+ {
69609
+ name: "publishing.creatorInfo",
69610
+ class: "read",
69611
+ description: "Read the latest creator posting limits, privacy choices, and interaction settings before presenting a publish confirmation.",
69612
+ parameters: { type: "object", properties: {} },
69613
+ requiredScopes: ["video.publish"],
69614
+ request: {
69615
+ method: "POST",
69616
+ path: "/v2/post/publish/creator_info/query/",
69617
+ headers: jsonPostHeaders,
69618
+ body: {}
69619
+ }
69620
+ },
69621
+ {
69622
+ name: "publishing.status",
69623
+ class: "read",
69624
+ description: "Read processing, moderation, and publication status for one publish request.",
69625
+ parameters: {
69626
+ type: "object",
69627
+ properties: {
69628
+ publish_id: { type: "string", minLength: 1, maxLength: 64 }
69629
+ },
69630
+ required: ["publish_id"]
69631
+ },
69632
+ requiredScopes: ["video.publish"],
69633
+ request: {
69634
+ method: "POST",
69635
+ path: "/v2/post/publish/status/fetch/",
69636
+ headers: jsonPostHeaders,
69637
+ body: { publish_id: "{publish_id}" }
69638
+ }
69639
+ },
69640
+ {
69641
+ name: "publishing.videoFromUrl",
69642
+ class: "mutation",
69643
+ description: "Directly publish one approved video from an app-verified HTTPS URL. The adapter refreshes creator limits before it sends the post.",
69644
+ parameters: {
69645
+ type: "object",
69646
+ properties: {
69647
+ video_url: {
69648
+ type: "string",
69649
+ format: "uri",
69650
+ pattern: "^https://",
69651
+ description: "Public HTTPS URL covered by the domain or URL prefix verified in the TikTok app."
69652
+ },
69653
+ video_duration_sec: {
69654
+ type: "number",
69655
+ exclusiveMinimum: 0,
69656
+ description: "Measured video duration used to enforce the creator-specific limit."
69657
+ },
69658
+ privacy_level: { type: "string", enum: [...PRIVACY_LEVELS] },
69659
+ title: { type: "string", maxLength: 2200 },
69660
+ disable_duet: { type: "boolean" },
69661
+ disable_comment: { type: "boolean" },
69662
+ disable_stitch: { type: "boolean" },
69663
+ video_cover_timestamp_ms: { type: "integer", minimum: 0 },
69664
+ brand_content_toggle: {
69665
+ type: "boolean",
69666
+ description: "True for a paid partnership that promotes a third-party business."
69667
+ },
69668
+ brand_organic_toggle: {
69669
+ type: "boolean",
69670
+ description: "True when the post promotes the creator's own business."
69671
+ },
69672
+ is_aigc: {
69673
+ type: "boolean",
69674
+ description: "True when TikTok must label the video as AI-generated content."
69675
+ }
69676
+ },
69677
+ required: [
69678
+ "video_url",
69679
+ "video_duration_sec",
69680
+ "privacy_level",
69681
+ "disable_duet",
69682
+ "disable_comment",
69683
+ "disable_stitch",
69684
+ "brand_content_toggle",
69685
+ "brand_organic_toggle"
69686
+ ]
69687
+ },
69688
+ requiredScopes: ["video.publish"],
69689
+ request: {
69690
+ method: "POST",
69691
+ path: "/v2/post/publish/video/init/",
69692
+ headers: jsonPostHeaders,
69693
+ body: {
69694
+ post_info: {
69695
+ title: "{title}",
69696
+ privacy_level: "{privacy_level}",
69697
+ disable_duet: "{disable_duet}",
69698
+ disable_comment: "{disable_comment}",
69699
+ disable_stitch: "{disable_stitch}",
69700
+ video_cover_timestamp_ms: "{video_cover_timestamp_ms}",
69701
+ brand_content_toggle: "{brand_content_toggle}",
69702
+ brand_organic_toggle: "{brand_organic_toggle}",
69703
+ is_aigc: "{is_aigc}"
69704
+ },
69705
+ source_info: {
69706
+ source: "PULL_FROM_URL",
69707
+ video_url: "{video_url}"
69708
+ }
69709
+ }
69710
+ },
69711
+ cas: "none",
69712
+ externalEffect: true
69713
+ },
69714
+ {
69715
+ name: "publishing.photosFromUrls",
69716
+ class: "mutation",
69717
+ description: "Directly publish 1\u201335 approved photos from app-verified HTTPS URLs. The adapter refreshes creator options before it sends the post.",
69718
+ parameters: {
69719
+ type: "object",
69720
+ properties: {
69721
+ photo_images: {
69722
+ type: "array",
69723
+ minItems: 1,
69724
+ maxItems: 35,
69725
+ items: { type: "string", format: "uri", pattern: "^https://" }
69726
+ },
69727
+ photo_cover_index: { type: "integer", minimum: 0 },
69728
+ privacy_level: { type: "string", enum: [...PRIVACY_LEVELS] },
69729
+ title: { type: "string", maxLength: 90 },
69730
+ description: { type: "string", maxLength: 4e3 },
69731
+ disable_comment: { type: "boolean" },
69732
+ auto_add_music: { type: "boolean" },
69733
+ brand_content_toggle: {
69734
+ type: "boolean",
69735
+ description: "True for a paid partnership that promotes a third-party business."
69736
+ },
69737
+ brand_organic_toggle: {
69738
+ type: "boolean",
69739
+ description: "True when the post promotes the creator's own business."
69740
+ }
69741
+ },
69742
+ required: [
69743
+ "photo_images",
69744
+ "photo_cover_index",
69745
+ "privacy_level",
69746
+ "disable_comment",
69747
+ "auto_add_music",
69748
+ "brand_content_toggle",
69749
+ "brand_organic_toggle"
69750
+ ]
69751
+ },
69752
+ requiredScopes: ["video.publish"],
69753
+ request: {
69754
+ method: "POST",
69755
+ path: "/v2/post/publish/content/init/",
69756
+ headers: jsonPostHeaders,
69757
+ body: {
69758
+ media_type: "PHOTO",
69759
+ post_mode: "DIRECT_POST",
69760
+ post_info: {
69761
+ title: "{title}",
69762
+ description: "{description}",
69763
+ privacy_level: "{privacy_level}",
69764
+ disable_comment: "{disable_comment}",
69765
+ auto_add_music: "{auto_add_music}",
69766
+ brand_content_toggle: "{brand_content_toggle}",
69767
+ brand_organic_toggle: "{brand_organic_toggle}"
69768
+ },
69769
+ source_info: {
69770
+ source: "PULL_FROM_URL",
69771
+ photo_images: "{photo_images}",
69772
+ photo_cover_index: "{photo_cover_index}"
69773
+ }
69774
+ }
69775
+ },
69776
+ cas: "none",
69777
+ externalEffect: true
69778
+ }
69779
+ ]
69780
+ };
69781
+ var tiktokConnector = createTikTokConnector();
69782
+ function tiktok(options) {
69783
+ const adapter = createTikTokConnector();
69784
+ const inFlightRefreshes = /* @__PURE__ */ new Map();
69785
+ const refresh = async (credentials) => {
69786
+ assertOAuthClient(options);
69787
+ if (credentials.kind !== "oauth2" || !credentials.refreshToken) {
69788
+ throw new Error("tiktok.refreshToken: missing refresh token");
69789
+ }
69790
+ const token = await tiktokTokenRequest(
69791
+ options,
69792
+ {
69793
+ grant_type: "refresh_token",
69794
+ refresh_token: credentials.refreshToken
69795
+ },
69796
+ [credentials.refreshToken]
69797
+ );
69798
+ if (!token.expiresIn) {
69799
+ throw new Error("tiktok token request returned an incomplete refresh grant");
69800
+ }
69801
+ return {
69802
+ ...tokenCredentials(token),
69803
+ refreshToken: token.refreshToken ?? credentials.refreshToken
69804
+ };
69805
+ };
69806
+ const withFreshCredentials = async (invocation) => {
69807
+ const credentials = invocation.source.credentials;
69808
+ if (credentials.kind !== "oauth2") return invocation;
69809
+ if (credentials.expiresAt !== void 0 && credentials.expiresAt > Date.now() + 6e4) {
69810
+ return invocation;
69811
+ }
69812
+ if (!credentials.refreshToken) {
69813
+ throw new CredentialsExpired(
69814
+ "TikTok access token expired and no refresh token is available",
69815
+ invocation.source.id
69816
+ );
69817
+ }
69818
+ let pending = inFlightRefreshes.get(invocation.source.id);
69819
+ if (!pending) {
69820
+ let next;
69821
+ const promise = Promise.resolve().then(() => {
69822
+ if (!next.onCredentialsRotated) {
69823
+ throw new Error(
69824
+ "tiktok: credential rotation persistence callback is required before refreshing"
69825
+ );
69826
+ }
69827
+ return refresh(credentials);
69828
+ });
69829
+ next = {
69830
+ promise,
69831
+ onCredentialsRotated: invocation.onCredentialsRotated
69832
+ };
69833
+ pending = next;
69834
+ inFlightRefreshes.set(invocation.source.id, pending);
69835
+ } else if (!pending.onCredentialsRotated && invocation.onCredentialsRotated) {
69836
+ pending.onCredentialsRotated = invocation.onCredentialsRotated;
69837
+ }
69838
+ const current = pending;
69839
+ try {
69840
+ const refreshed = await current.promise;
69841
+ current.persistence ??= Promise.resolve().then(
69842
+ () => current.onCredentialsRotated?.(refreshed)
69843
+ );
69844
+ await current.persistence;
69845
+ return {
69846
+ ...invocation,
69847
+ source: { ...invocation.source, credentials: refreshed }
69848
+ };
69849
+ } finally {
69850
+ if (inFlightRefreshes.get(invocation.source.id) === current) {
69851
+ inFlightRefreshes.delete(invocation.source.id);
69852
+ }
69853
+ }
69854
+ };
69855
+ return {
69856
+ ...adapter,
69857
+ async executeRead(invocation) {
69858
+ return adapter.executeRead(await withFreshCredentials(invocation));
69859
+ },
69860
+ async executeMutation(invocation) {
69861
+ return adapter.executeMutation(await withFreshCredentials(invocation));
69862
+ },
69863
+ async test(source, onCredentialsRotated) {
69864
+ try {
69865
+ const invocation = await withFreshCredentials({
69866
+ source,
69867
+ capabilityName: "user.info",
69868
+ args: {},
69869
+ idempotencyKey: "tiktok-connection-test",
69870
+ onCredentialsRotated
69871
+ });
69872
+ return adapter.test(invocation.source);
69873
+ } catch (error) {
69874
+ return {
69875
+ ok: false,
69876
+ reason: error instanceof Error ? error.message : "unknown error"
69877
+ };
69878
+ }
69879
+ },
69880
+ async exchangeOAuth(input) {
69881
+ assertOAuthClient(options);
69882
+ const token = await tiktokTokenRequest(
69883
+ options,
69884
+ {
69885
+ grant_type: "authorization_code",
69886
+ code: input.code,
69887
+ redirect_uri: input.redirectUri
69888
+ },
69889
+ [input.code]
69890
+ );
69891
+ const grant = requireTikTokAuthorizationGrant(token);
69892
+ return {
69893
+ credentials: tokenCredentials(grant),
69894
+ scopes: grant.scopes,
69895
+ metadata: { openId: grant.openId }
69896
+ };
69897
+ },
69898
+ refreshToken: refresh
69899
+ };
69900
+ }
69901
+ function createTikTokConnector() {
69902
+ const base = declarativeRestConnector(TIKTOK_SPEC);
69903
+ const executeRead2 = async (invocation) => {
69904
+ const result = await base.executeRead(invocation);
69905
+ assertTikTokEnvelope(
69906
+ result.data,
69907
+ invocation.capabilityName,
69908
+ invocation.source.credentials
69909
+ );
69910
+ return result;
69911
+ };
69912
+ return {
69913
+ ...base,
69914
+ executeRead: executeRead2,
69915
+ async executeMutation(invocation) {
69916
+ validatePublishInput(invocation);
69917
+ const creator = await executeRead2({
69918
+ ...invocation,
69919
+ capabilityName: "publishing.creatorInfo",
69920
+ args: {}
69921
+ });
69922
+ validateCreatorLimits(invocation, creator.data);
69923
+ const result = await base.executeMutation(invocation);
69924
+ if (result.status === "committed") {
69925
+ assertTikTokPublishResult(
69926
+ result.data,
69927
+ invocation.capabilityName,
69928
+ invocation.source.credentials
69929
+ );
69930
+ }
69931
+ return result;
69932
+ },
69933
+ async test(source) {
69934
+ try {
69935
+ await executeRead2({
69936
+ source,
69937
+ capabilityName: "user.info",
69938
+ args: {},
69939
+ idempotencyKey: "tiktok-connection-test"
69940
+ });
69941
+ return { ok: true };
69942
+ } catch (error) {
69943
+ return {
69944
+ ok: false,
69945
+ reason: error instanceof Error ? error.message : "unknown error"
69946
+ };
69947
+ }
69948
+ }
69949
+ };
69950
+ }
69951
+ function validatePublishInput(invocation) {
69952
+ if (invocation.capabilityName === "publishing.videoFromUrl") {
69953
+ const url = requiredString7(invocation.args, "video_url");
69954
+ requireHttpsUrl(url, "video_url");
69955
+ const duration2 = requiredNumber(invocation.args, "video_duration_sec");
69956
+ if (duration2 <= 0) throw new Error("tiktok: video_duration_sec must be greater than zero");
69957
+ requiredPrivacy(invocation.args);
69958
+ requiredBoolean(invocation.args, "disable_duet");
69959
+ requiredBoolean(invocation.args, "disable_comment");
69960
+ requiredBoolean(invocation.args, "disable_stitch");
69961
+ requiredBoolean(invocation.args, "brand_content_toggle");
69962
+ requiredBoolean(invocation.args, "brand_organic_toggle");
69963
+ optionalUtf16Length(invocation.args, "title", 2200);
69964
+ return;
69965
+ }
69966
+ if (invocation.capabilityName === "publishing.photosFromUrls") {
69967
+ const photos = invocation.args.photo_images;
69968
+ if (!Array.isArray(photos) || photos.length < 1 || photos.length > 35) {
69969
+ throw new Error("tiktok: photo_images must contain between 1 and 35 URLs");
69970
+ }
69971
+ for (const [index, value] of photos.entries()) {
69972
+ if (typeof value !== "string") {
69973
+ throw new Error(`tiktok: photo_images[${index}] must be a string`);
69974
+ }
69975
+ requireHttpsUrl(value, `photo_images[${index}]`);
69976
+ }
69977
+ const cover = requiredNumber(invocation.args, "photo_cover_index");
69978
+ if (!Number.isInteger(cover) || cover < 0 || cover >= photos.length) {
69979
+ throw new Error("tiktok: photo_cover_index must identify one supplied photo");
69980
+ }
69981
+ requiredPrivacy(invocation.args);
69982
+ requiredBoolean(invocation.args, "disable_comment");
69983
+ requiredBoolean(invocation.args, "auto_add_music");
69984
+ requiredBoolean(invocation.args, "brand_content_toggle");
69985
+ requiredBoolean(invocation.args, "brand_organic_toggle");
69986
+ optionalUtf16Length(invocation.args, "title", 90);
69987
+ optionalUtf16Length(invocation.args, "description", 4e3);
69988
+ return;
69989
+ }
69990
+ throw new Error(`tiktok: unknown mutation capability ${invocation.capabilityName}`);
69991
+ }
69992
+ function validateCreatorLimits(invocation, envelope) {
69993
+ const data4 = readEnvelopeData(envelope, "publishing.creatorInfo");
69994
+ const privacy = requiredString7(invocation.args, "privacy_level");
69995
+ const choices = data4.privacy_level_options;
69996
+ if (!Array.isArray(choices) || !choices.every((value) => typeof value === "string")) {
69997
+ throw new Error("tiktok publishing.creatorInfo returned invalid privacy_level_options");
69998
+ }
69999
+ if (!choices.includes(privacy)) {
70000
+ throw new Error(`tiktok: privacy_level ${privacy} is unavailable for this creator`);
70001
+ }
70002
+ requireDisabledInteraction(invocation.args, data4, "disable_comment", "comment_disabled");
70003
+ if (invocation.capabilityName === "publishing.videoFromUrl") {
70004
+ requireDisabledInteraction(invocation.args, data4, "disable_duet", "duet_disabled");
70005
+ requireDisabledInteraction(invocation.args, data4, "disable_stitch", "stitch_disabled");
70006
+ const maximum = data4.max_video_post_duration_sec;
70007
+ if (typeof maximum !== "number" || !Number.isFinite(maximum) || maximum <= 0) {
70008
+ throw new Error("tiktok publishing.creatorInfo returned an invalid video-duration limit");
70009
+ }
70010
+ const duration2 = requiredNumber(invocation.args, "video_duration_sec");
70011
+ if (duration2 > maximum) {
70012
+ throw new Error(
70013
+ `tiktok: video duration ${duration2}s exceeds this creator's ${maximum}s limit`
70014
+ );
70015
+ }
70016
+ }
70017
+ }
70018
+ function assertTikTokEnvelope(value, capabilityName, credentials) {
70019
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
70020
+ throw new Error(`tiktok ${capabilityName} returned a malformed response`);
70021
+ }
70022
+ const error = value.error;
70023
+ if (!error || typeof error !== "object" || Array.isArray(error)) {
70024
+ throw new Error(`tiktok ${capabilityName} returned no error status`);
70025
+ }
70026
+ const code = error.code;
70027
+ if (code !== "ok") {
70028
+ const message = error.message;
70029
+ const detail = typeof message === "string" && message ? ` \u2014 ${redact2(message.slice(0, 200), credentialValues(credentials))}` : "";
70030
+ const safeCode = redact2(
70031
+ safeProviderValue(code),
70032
+ credentialValues(credentials)
70033
+ );
70034
+ throw new Error(`tiktok ${capabilityName} failed: ${safeCode}${detail}`);
70035
+ }
70036
+ }
70037
+ function requireDisabledInteraction(args, creator, argumentName, creatorField) {
70038
+ const disabled = creator[creatorField];
70039
+ if (typeof disabled !== "boolean") {
70040
+ throw new Error(`tiktok publishing.creatorInfo returned invalid ${creatorField}`);
70041
+ }
70042
+ if (disabled && args[argumentName] !== true) {
70043
+ throw new Error(
70044
+ `tiktok: ${argumentName} must be true because the creator disabled this interaction`
70045
+ );
70046
+ }
70047
+ }
70048
+ function readEnvelopeData(envelope, capabilityName, credentials) {
70049
+ assertTikTokEnvelope(envelope, capabilityName, credentials);
70050
+ const data4 = envelope.data;
70051
+ if (!data4 || typeof data4 !== "object" || Array.isArray(data4)) {
70052
+ throw new Error(`tiktok ${capabilityName} returned malformed data`);
70053
+ }
70054
+ return data4;
70055
+ }
70056
+ function assertTikTokPublishResult(envelope, capabilityName, credentials) {
70057
+ const data4 = readEnvelopeData(envelope, capabilityName, credentials);
70058
+ const publishId = data4.publish_id;
70059
+ if (typeof publishId !== "string" || !publishId.trim() || publishId.length > 64) {
70060
+ throw new Error(`tiktok ${capabilityName} returned an invalid publish_id`);
70061
+ }
70062
+ }
70063
+ function requiredString7(args, name) {
70064
+ const value = args[name];
70065
+ if (typeof value !== "string" || !value) {
70066
+ throw new Error(`tiktok: missing required argument: ${name}`);
70067
+ }
70068
+ return value;
70069
+ }
70070
+ function requiredNumber(args, name) {
70071
+ const value = args[name];
70072
+ if (typeof value !== "number" || !Number.isFinite(value)) {
70073
+ throw new Error(`tiktok: missing required argument: ${name}`);
70074
+ }
70075
+ return value;
70076
+ }
70077
+ function requiredBoolean(args, name) {
70078
+ const value = args[name];
70079
+ if (typeof value !== "boolean") {
70080
+ throw new Error(`tiktok: missing required argument: ${name}`);
70081
+ }
70082
+ return value;
70083
+ }
70084
+ function requiredPrivacy(args) {
70085
+ const value = requiredString7(args, "privacy_level");
70086
+ if (!PRIVACY_LEVELS.includes(value)) {
70087
+ throw new Error(`tiktok: unsupported privacy_level ${value}`);
70088
+ }
70089
+ return value;
70090
+ }
70091
+ function optionalUtf16Length(args, name, maximum) {
70092
+ const value = args[name];
70093
+ if (value === void 0) return;
70094
+ if (typeof value !== "string") throw new Error(`tiktok: ${name} must be a string`);
70095
+ if (value.length > maximum) {
70096
+ throw new Error(`tiktok: ${name} exceeds the ${maximum} UTF-16-unit limit`);
70097
+ }
70098
+ }
70099
+ function requireHttpsUrl(value, name) {
70100
+ let url;
70101
+ try {
70102
+ url = new URL(value);
70103
+ } catch {
70104
+ throw new Error(`tiktok: ${name} must be a valid HTTPS URL`);
70105
+ }
70106
+ if (url.protocol !== "https:" || url.username || url.password) {
70107
+ throw new Error(`tiktok: ${name} must be a valid HTTPS URL`);
70108
+ }
70109
+ }
70110
+ async function tiktokTokenRequest(options, grant, extraRedactions) {
70111
+ const body = new URLSearchParams({
70112
+ client_key: options.clientId,
70113
+ client_secret: options.clientSecret,
70114
+ ...grant
70115
+ });
70116
+ let response;
70117
+ try {
70118
+ response = await fetch(TOKEN_URL20, {
70119
+ method: "POST",
70120
+ headers: {
70121
+ accept: "application/json",
70122
+ "content-type": "application/x-www-form-urlencoded",
70123
+ "cache-control": "no-cache"
70124
+ },
70125
+ body,
70126
+ signal: AbortSignal.timeout(15e3)
70127
+ });
70128
+ } catch (cause) {
70129
+ const message = cause instanceof Error ? cause.message : "unknown transport error";
70130
+ throw new Error(`tiktok token request failed: ${redact2(message, [options.clientId, options.clientSecret, ...extraRedactions])}`);
70131
+ }
70132
+ if (!response.ok) {
70133
+ const detail = await response.text().catch(() => "");
70134
+ throw new Error(
70135
+ `tiktok token request failed: ${response.status} ${response.statusText} \u2014 ${redact2(
70136
+ detail.slice(0, 300),
70137
+ [options.clientId, options.clientSecret, ...extraRedactions]
70138
+ )}`
70139
+ );
70140
+ }
70141
+ const json = await response.json();
70142
+ if (typeof json.access_token !== "string" || !json.access_token) {
70143
+ throw new Error("tiktok token request returned no access_token");
70144
+ }
70145
+ return {
70146
+ accessToken: json.access_token,
70147
+ refreshToken: typeof json.refresh_token === "string" && json.refresh_token ? json.refresh_token : void 0,
70148
+ expiresIn: typeof json.expires_in === "number" && json.expires_in > 0 ? json.expires_in : void 0,
70149
+ scope: typeof json.scope === "string" ? json.scope : void 0,
70150
+ openId: typeof json.open_id === "string" ? json.open_id : void 0
70151
+ };
70152
+ }
70153
+ function tokenCredentials(token) {
70154
+ return {
70155
+ kind: "oauth2",
70156
+ accessToken: token.accessToken,
70157
+ refreshToken: token.refreshToken,
70158
+ expiresAt: token.expiresIn ? Date.now() + token.expiresIn * 1e3 : void 0
70159
+ };
70160
+ }
70161
+ function requireTikTokAuthorizationGrant(token) {
70162
+ const scopes2 = token.scope ? splitScopes(token.scope) : [];
70163
+ if (!token.refreshToken || !token.expiresIn || !token.openId || scopes2.length === 0) {
70164
+ throw new Error(
70165
+ "tiktok token request returned an incomplete authorization grant"
70166
+ );
70167
+ }
70168
+ return { ...token, scopes: scopes2 };
70169
+ }
70170
+ function splitScopes(scope) {
70171
+ return scope.split(",").map((value) => value.trim()).filter(Boolean);
70172
+ }
70173
+ function assertOAuthClient(options) {
70174
+ if (!options.clientId || !options.clientSecret) {
70175
+ throw new Error(
70176
+ "TikTok OAuth client not configured (TIKTOK_OAUTH_CLIENT_KEY / TIKTOK_OAUTH_CLIENT_SECRET)"
70177
+ );
70178
+ }
70179
+ }
70180
+ function redact2(value, secrets) {
70181
+ let redacted = value;
70182
+ for (const secret of secrets) {
70183
+ if (!secret) continue;
70184
+ redacted = redacted.split(secret).join("[REDACTED]");
70185
+ }
70186
+ return redacted;
70187
+ }
70188
+ function credentialValues(credentials) {
70189
+ if (!credentials) return [];
70190
+ switch (credentials.kind) {
70191
+ case "oauth2":
70192
+ return [credentials.accessToken, credentials.refreshToken ?? ""];
70193
+ case "api-key":
70194
+ return [credentials.apiKey];
70195
+ case "hmac":
70196
+ return [credentials.secret];
70197
+ case "custom":
70198
+ return Object.values(credentials.values).filter(
70199
+ (value) => typeof value === "string"
70200
+ );
70201
+ case "none":
70202
+ return [];
70203
+ }
70204
+ }
70205
+ function safeProviderValue(value) {
70206
+ if (typeof value === "string") return value.slice(0, 80);
70207
+ return "unknown_error";
70208
+ }
70209
+
67993
70210
  // src/connectors/adapters/twilio-sms.ts
67994
70211
  var API11 = "https://api.twilio.com/2010-04-01";
67995
70212
  var LOOKUP_API = "https://lookups.twilio.com/v1";
@@ -68450,9 +70667,9 @@ var voucheryIoConnector = declarativeRestConnector({
68450
70667
  });
68451
70668
 
68452
70669
  // src/connectors/adapters/whatsapp-business.ts
68453
- var SCOPES14 = ["whatsapp_business_messaging", "whatsapp_business_management", "business_management"];
70670
+ var SCOPES15 = ["whatsapp_business_messaging", "whatsapp_business_management", "business_management"];
68454
70671
  var AUTH_URL18 = "https://www.facebook.com/v21.0/dialog/oauth";
68455
- var TOKEN_URL20 = "https://graph.facebook.com/v21.0/oauth/access_token";
70672
+ var TOKEN_URL21 = "https://graph.facebook.com/v21.0/oauth/access_token";
68456
70673
  var API12 = "https://graph.facebook.com/v21.0";
68457
70674
  function whatsappBusiness(opts) {
68458
70675
  const { clientId, clientSecret } = opts;
@@ -68464,8 +70681,8 @@ function whatsappBusiness(opts) {
68464
70681
  auth: {
68465
70682
  kind: "oauth2",
68466
70683
  authorizationUrl: AUTH_URL18,
68467
- tokenUrl: TOKEN_URL20,
68468
- scopes: SCOPES14,
70684
+ tokenUrl: TOKEN_URL21,
70685
+ scopes: SCOPES15,
68469
70686
  clientIdEnv: "WHATSAPP_BUSINESS_OAUTH_CLIENT_ID",
68470
70687
  clientSecretEnv: "WHATSAPP_BUSINESS_OAUTH_CLIENT_SECRET"
68471
70688
  },
@@ -68735,7 +70952,7 @@ function whatsappBusiness(opts) {
68735
70952
  throw new Error("WhatsApp Business OAuth client not configured (WHATSAPP_BUSINESS_OAUTH_CLIENT_ID / _SECRET)");
68736
70953
  }
68737
70954
  const tokens = await exchangeAuthorizationCode({
68738
- tokenUrl: TOKEN_URL20,
70955
+ tokenUrl: TOKEN_URL21,
68739
70956
  clientId,
68740
70957
  clientSecret,
68741
70958
  code: input.code,
@@ -68751,7 +70968,7 @@ function whatsappBusiness(opts) {
68751
70968
  refreshToken: tokens.refreshToken,
68752
70969
  expiresAt: tokens.expiresIn ? Date.now() + tokens.expiresIn * 1e3 : void 0
68753
70970
  },
68754
- scopes: tokens.scope?.split(/[,\s]+/) ?? SCOPES14,
70971
+ scopes: tokens.scope?.split(/[,\s]+/) ?? SCOPES15,
68755
70972
  metadata: {}
68756
70973
  };
68757
70974
  },
@@ -78022,8 +80239,8 @@ var discourseConnector = declarativeRestConnector({
78022
80239
  });
78023
80240
 
78024
80241
  // src/connectors/adapters/digital-ocean.ts
78025
- var pagination2 = { page: { type: "integer", minimum: 1 }, perPage: { type: "integer", minimum: 1, maximum: 200 } };
78026
- var paginationQuery = { page: "{page}", per_page: "{perPage}" };
80242
+ var pagination3 = { page: { type: "integer", minimum: 1 }, perPage: { type: "integer", minimum: 1, maximum: 200 } };
80243
+ var paginationQuery2 = { page: "{page}", per_page: "{perPage}" };
78027
80244
  var digitalOceanConnector = declarativeRestConnector({
78028
80245
  kind: "digital-ocean",
78029
80246
  displayName: "DigitalOcean",
@@ -78036,24 +80253,24 @@ var digitalOceanConnector = declarativeRestConnector({
78036
80253
  test: { method: "GET", path: "/v2/account" },
78037
80254
  capabilities: [
78038
80255
  { name: "account.get", class: "read", description: "Read the current account and status.", parameters: { type: "object", properties: {} }, request: { method: "GET", path: "/v2/account" } },
78039
- { name: "projects.list", class: "read", description: "List projects.", parameters: { type: "object", properties: pagination2 }, request: { method: "GET", path: "/v2/projects", query: paginationQuery } },
80256
+ { name: "projects.list", class: "read", description: "List projects.", parameters: { type: "object", properties: pagination3 }, request: { method: "GET", path: "/v2/projects", query: paginationQuery2 } },
78040
80257
  { name: "projects.get", class: "read", description: "Read one project.", parameters: { type: "object", properties: { projectId: { type: "string" } }, required: ["projectId"] }, request: { method: "GET", path: "/v2/projects/{projectId}" } },
78041
80258
  { name: "projects.create", class: "mutation", description: "Create a project.", parameters: { type: "object", properties: { project: { type: "object" } }, required: ["project"] }, request: { method: "POST", path: "/v2/projects", body: "{project}" }, cas: "none", externalEffect: true },
78042
80259
  { name: "projects.update", class: "mutation", description: "Update a project.", parameters: { type: "object", properties: { projectId: { type: "string" }, project: { type: "object" } }, required: ["projectId", "project"] }, request: { method: "PATCH", path: "/v2/projects/{projectId}", body: "{project}" }, cas: "optimistic-read-verify", externalEffect: true },
78043
80260
  { name: "projects.delete", class: "mutation", description: "Delete a project.", parameters: { type: "object", properties: { projectId: { type: "string" } }, required: ["projectId"] }, request: { method: "DELETE", path: "/v2/projects/{projectId}" }, cas: "optimistic-read-verify", externalEffect: true },
78044
- { name: "droplets.list", class: "read", description: "List Droplets.", parameters: { type: "object", properties: { ...pagination2, tagName: { type: "string" }, name: { type: "string" } } }, request: { method: "GET", path: "/v2/droplets", query: { ...paginationQuery, tag_name: "{tagName}", name: "{name}" } } },
80261
+ { name: "droplets.list", class: "read", description: "List Droplets.", parameters: { type: "object", properties: { ...pagination3, tagName: { type: "string" }, name: { type: "string" } } }, request: { method: "GET", path: "/v2/droplets", query: { ...paginationQuery2, tag_name: "{tagName}", name: "{name}" } } },
78045
80262
  { name: "droplets.get", class: "read", description: "Read one Droplet.", parameters: { type: "object", properties: { dropletId: { type: "integer" } }, required: ["dropletId"] }, request: { method: "GET", path: "/v2/droplets/{dropletId}" } },
78046
80263
  { name: "droplets.create", class: "mutation", description: "Create one or more Droplets.", parameters: { type: "object", properties: { droplet: { type: "object" } }, required: ["droplet"] }, request: { method: "POST", path: "/v2/droplets", body: "{droplet}" }, cas: "none", externalEffect: true },
78047
80264
  { name: "droplets.action", class: "mutation", description: "Run a provider-native Droplet action such as power_on, shutdown, snapshot, resize, or rebuild.", parameters: { type: "object", properties: { dropletId: { type: "integer" }, action: { type: "object" } }, required: ["dropletId", "action"] }, request: { method: "POST", path: "/v2/droplets/{dropletId}/actions", body: "{action}" }, cas: "none", externalEffect: true },
78048
80265
  { name: "droplets.delete", class: "mutation", description: "Delete a Droplet.", parameters: { type: "object", properties: { dropletId: { type: "integer" } }, required: ["dropletId"] }, request: { method: "DELETE", path: "/v2/droplets/{dropletId}" }, cas: "optimistic-read-verify", externalEffect: true },
78049
- { name: "volumes.list", class: "read", description: "List block-storage volumes.", parameters: { type: "object", properties: { ...pagination2, region: { type: "string" }, name: { type: "string" } } }, request: { method: "GET", path: "/v2/volumes", query: { ...paginationQuery, region: "{region}", name: "{name}" } } },
80266
+ { name: "volumes.list", class: "read", description: "List block-storage volumes.", parameters: { type: "object", properties: { ...pagination3, region: { type: "string" }, name: { type: "string" } } }, request: { method: "GET", path: "/v2/volumes", query: { ...paginationQuery2, region: "{region}", name: "{name}" } } },
78050
80267
  { name: "volumes.create", class: "mutation", description: "Create a block-storage volume.", parameters: { type: "object", properties: { volume: { type: "object" } }, required: ["volume"] }, request: { method: "POST", path: "/v2/volumes", body: "{volume}" }, cas: "none", externalEffect: true },
78051
80268
  { name: "volumes.delete", class: "mutation", description: "Delete a block-storage volume.", parameters: { type: "object", properties: { volumeId: { type: "string" } }, required: ["volumeId"] }, request: { method: "DELETE", path: "/v2/volumes/{volumeId}" }, cas: "optimistic-read-verify", externalEffect: true },
78052
- { name: "databases.list", class: "read", description: "List managed database clusters.", parameters: { type: "object", properties: { ...pagination2, tagName: { type: "string" } } }, request: { method: "GET", path: "/v2/databases", query: { ...paginationQuery, tag_name: "{tagName}" } } },
80269
+ { name: "databases.list", class: "read", description: "List managed database clusters.", parameters: { type: "object", properties: { ...pagination3, tagName: { type: "string" } } }, request: { method: "GET", path: "/v2/databases", query: { ...paginationQuery2, tag_name: "{tagName}" } } },
78053
80270
  { name: "databases.get", class: "read", description: "Read a managed database cluster.", parameters: { type: "object", properties: { databaseId: { type: "string" } }, required: ["databaseId"] }, request: { method: "GET", path: "/v2/databases/{databaseId}" } },
78054
80271
  { name: "databases.create", class: "mutation", description: "Create a managed database cluster.", parameters: { type: "object", properties: { database: { type: "object" } }, required: ["database"] }, request: { method: "POST", path: "/v2/databases", body: "{database}" }, cas: "none", externalEffect: true },
78055
80272
  { name: "databases.delete", class: "mutation", description: "Delete a managed database cluster.", parameters: { type: "object", properties: { databaseId: { type: "string" } }, required: ["databaseId"] }, request: { method: "DELETE", path: "/v2/databases/{databaseId}" }, cas: "optimistic-read-verify", externalEffect: true },
78056
- { name: "apps.list", class: "read", description: "List App Platform apps.", parameters: { type: "object", properties: pagination2 }, request: { method: "GET", path: "/v2/apps", query: paginationQuery } },
80273
+ { name: "apps.list", class: "read", description: "List App Platform apps.", parameters: { type: "object", properties: pagination3 }, request: { method: "GET", path: "/v2/apps", query: paginationQuery2 } },
78057
80274
  { name: "apps.get", class: "read", description: "Read an App Platform app.", parameters: { type: "object", properties: { appId: { type: "string" } }, required: ["appId"] }, request: { method: "GET", path: "/v2/apps/{appId}" } },
78058
80275
  { name: "apps.create", class: "mutation", description: "Create an App Platform app.", parameters: { type: "object", properties: { spec: { type: "object" } }, required: ["spec"] }, request: { method: "POST", path: "/v2/apps", body: { spec: "{spec}" } }, cas: "none", externalEffect: true },
78059
80276
  { name: "apps.update", class: "mutation", description: "Update an App Platform app specification.", parameters: { type: "object", properties: { appId: { type: "string" }, spec: { type: "object" } }, required: ["appId", "spec"] }, request: { method: "PUT", path: "/v2/apps/{appId}", body: { spec: "{spec}" } }, cas: "optimistic-read-verify", externalEffect: true },
@@ -78062,11 +80279,11 @@ var digitalOceanConnector = declarativeRestConnector({
78062
80279
  });
78063
80280
 
78064
80281
  // src/connectors/adapters/clicksend.ts
78065
- var pagination3 = {
80282
+ var pagination4 = {
78066
80283
  page: { type: "integer", minimum: 1 },
78067
80284
  limit: { type: "integer", minimum: 1 }
78068
80285
  };
78069
- var paginationQuery2 = { page: "{page}", limit: "{limit}" };
80286
+ var paginationQuery3 = { page: "{page}", limit: "{limit}" };
78070
80287
  var listId = { listId: { type: "integer" } };
78071
80288
  var contactId = { contactId: { type: "integer" } };
78072
80289
  var clicksendConnector = declarativeRestConnector({
@@ -78098,8 +80315,8 @@ var clicksendConnector = declarativeRestConnector({
78098
80315
  name: "lists.list",
78099
80316
  class: "read",
78100
80317
  description: "List contact lists.",
78101
- parameters: { type: "object", properties: pagination3 },
78102
- request: { method: "GET", path: "/lists", query: paginationQuery2 }
80318
+ parameters: { type: "object", properties: pagination4 },
80319
+ request: { method: "GET", path: "/lists", query: paginationQuery3 }
78103
80320
  },
78104
80321
  {
78105
80322
  name: "lists.get",
@@ -78149,13 +80366,13 @@ var clicksendConnector = declarativeRestConnector({
78149
80366
  description: "List contacts in a list.",
78150
80367
  parameters: {
78151
80368
  type: "object",
78152
- properties: { ...listId, ...pagination3, updatedAfter: { type: "integer" } },
80369
+ properties: { ...listId, ...pagination4, updatedAfter: { type: "integer" } },
78153
80370
  required: ["listId"]
78154
80371
  },
78155
80372
  request: {
78156
80373
  method: "GET",
78157
80374
  path: "/lists/{listId}/contacts",
78158
- query: { ...paginationQuery2, updated_after: "{updatedAfter}" }
80375
+ query: { ...paginationQuery3, updated_after: "{updatedAfter}" }
78159
80376
  }
78160
80377
  },
78161
80378
  {
@@ -78225,7 +80442,7 @@ var clicksendConnector = declarativeRestConnector({
78225
80442
  query: { type: "string" },
78226
80443
  dateFrom: { type: "integer" },
78227
80444
  dateTo: { type: "integer" },
78228
- ...pagination3
80445
+ ...pagination4
78229
80446
  }
78230
80447
  },
78231
80448
  request: {
@@ -78235,7 +80452,7 @@ var clicksendConnector = declarativeRestConnector({
78235
80452
  q: "{query}",
78236
80453
  date_from: "{dateFrom}",
78237
80454
  date_to: "{dateTo}",
78238
- ...paginationQuery2
80455
+ ...paginationQuery3
78239
80456
  }
78240
80457
  }
78241
80458
  },
@@ -78245,16 +80462,16 @@ var clicksendConnector = declarativeRestConnector({
78245
80462
  description: "List inbound SMS messages.",
78246
80463
  parameters: {
78247
80464
  type: "object",
78248
- properties: { query: { type: "string" }, ...pagination3 }
80465
+ properties: { query: { type: "string" }, ...pagination4 }
78249
80466
  },
78250
- request: { method: "GET", path: "/sms/inbound", query: { q: "{query}", ...paginationQuery2 } }
80467
+ request: { method: "GET", path: "/sms/inbound", query: { q: "{query}", ...paginationQuery3 } }
78251
80468
  },
78252
80469
  {
78253
80470
  name: "sms.receipts.list",
78254
80471
  class: "read",
78255
80472
  description: "List SMS delivery receipts.",
78256
- parameters: { type: "object", properties: pagination3 },
78257
- request: { method: "GET", path: "/sms/receipts", query: paginationQuery2 }
80473
+ parameters: { type: "object", properties: pagination4 },
80474
+ request: { method: "GET", path: "/sms/receipts", query: paginationQuery3 }
78258
80475
  },
78259
80476
  {
78260
80477
  name: "sms.send",
@@ -78290,12 +80507,12 @@ var clicksendConnector = declarativeRestConnector({
78290
80507
  description: "List voice message history.",
78291
80508
  parameters: {
78292
80509
  type: "object",
78293
- properties: { dateFrom: { type: "integer" }, dateTo: { type: "integer" }, ...pagination3 }
80510
+ properties: { dateFrom: { type: "integer" }, dateTo: { type: "integer" }, ...pagination4 }
78294
80511
  },
78295
80512
  request: {
78296
80513
  method: "GET",
78297
80514
  path: "/voice/history",
78298
- query: { date_from: "{dateFrom}", date_to: "{dateTo}", ...paginationQuery2 }
80515
+ query: { date_from: "{dateFrom}", date_to: "{dateTo}", ...paginationQuery3 }
78299
80516
  }
78300
80517
  },
78301
80518
  {
@@ -79465,7 +81682,7 @@ function readQuery2(inv) {
79465
81682
  throw new Error(`Unknown MySQL read capability: ${inv.capabilityName}`);
79466
81683
  }
79467
81684
  function readStatementArgs(args) {
79468
- const statement = requiredString7(args.statement, "statement");
81685
+ const statement = requiredString8(args.statement, "statement");
79469
81686
  if (Buffer.byteLength(statement, "utf8") > 1024 * 1024) throw new Error("statement exceeds the 1 MiB limit");
79470
81687
  const parameters = args.parameters === void 0 ? [] : args.parameters;
79471
81688
  if (!Array.isArray(parameters) || parameters.length > MAX_PARAMETERS) {
@@ -79556,7 +81773,7 @@ function readDatabase(value, source) {
79556
81773
  function queryTimeout(source) {
79557
81774
  return readCredentials7(source).queryTimeoutMs;
79558
81775
  }
79559
- function requiredString7(value, label) {
81776
+ function requiredString8(value, label) {
79560
81777
  const parsed = readOptionalString(value, label);
79561
81778
  if (!parsed) throw new Error(`${label} is required`);
79562
81779
  return parsed;
@@ -79568,7 +81785,7 @@ function requiredCredentialString3(value, label, maxLength) {
79568
81785
  return parsed;
79569
81786
  }
79570
81787
  function readIdentifier2(value, label) {
79571
- const parsed = requiredString7(value, label);
81788
+ const parsed = requiredString8(value, label);
79572
81789
  if (parsed.length > 64) throw new Error(`${label} exceeds 64 characters`);
79573
81790
  return parsed;
79574
81791
  }
@@ -81138,6 +83355,8 @@ var CONNECTOR_ADAPTER_FACTORIES = [
81138
83355
  defineFactoryAdapter(() => segmentConnector, {}),
81139
83356
  defineFactoryAdapter(() => hightouchConnector, {}),
81140
83357
  defineFactoryAdapter(() => datadogConnector, {}),
83358
+ defineFactoryAdapter(() => amplitudeConnector, {}),
83359
+ defineFactoryAdapter(() => cloudflareConnector, {}),
81141
83360
  defineFactoryAdapter(() => discourseConnector, {}),
81142
83361
  defineFactoryAdapter(() => digitalOceanConnector, {}),
81143
83362
  defineFactoryAdapter(() => clicksendConnector, {}),
@@ -81168,6 +83387,10 @@ var CONNECTOR_ADAPTER_FACTORIES = [
81168
83387
  clientId: "TWITTER_OAUTH_CLIENT_ID",
81169
83388
  clientSecret: "TWITTER_OAUTH_CLIENT_SECRET"
81170
83389
  }),
83390
+ defineFactoryAdapter(tiktok, {
83391
+ clientId: "TIKTOK_OAUTH_CLIENT_KEY",
83392
+ clientSecret: "TIKTOK_OAUTH_CLIENT_SECRET"
83393
+ }),
81171
83394
  // Declarative OAuth2 connectors: the manifest already pins clientIdEnv /
81172
83395
  // clientSecretEnv; the envMap re-pins the same names so registration is
81173
83396
  // gated on the OAuth app actually being configured (no half-live connector).
@@ -81195,6 +83418,8 @@ var CONNECTOR_ADAPTER_FACTORIES = [
81195
83418
  // credentials from each connection; OAuth providers are registered only
81196
83419
  // when the shared application credentials are present.
81197
83420
  defineFactoryAdapter(() => amazonEventBridgeConnector, {}),
83421
+ defineFactoryAdapter(() => amazonLambdaConnector, {}),
83422
+ defineFactoryAdapter(() => amazonCloudWatchConnector, {}),
81198
83423
  defineFactoryAdapter(() => amazonS3Connector, {}),
81199
83424
  defineFactoryAdapter(() => amazonSnsConnector, {}),
81200
83425
  defineFactoryAdapter(() => amazonSqsConnector, {}),
@@ -81244,9 +83469,8 @@ var CONNECTOR_ADAPTER_FACTORIES = [
81244
83469
  clientId: "ACUITY_OAUTH_CLIENT_ID",
81245
83470
  clientSecret: "ACUITY_OAUTH_CLIENT_SECRET"
81246
83471
  }),
81247
- defineFactoryAdapter(() => calComConnector, {
81248
- clientId: "CALCOM_OAUTH_CLIENT_ID",
81249
- clientSecret: "CALCOM_OAUTH_CLIENT_SECRET"
83472
+ defineFactoryAdapter(calCom, {
83473
+ clientId: "CALCOM_OAUTH_CLIENT_ID"
81250
83474
  }),
81251
83475
  defineFactoryAdapter(() => savvycalConnector, {
81252
83476
  clientId: "SAVVYCAL_OAUTH_CLIENT_ID",
@@ -146543,7 +148767,10 @@ export {
146543
148767
  adobeSignConnector,
146544
148768
  aircallConnector,
146545
148769
  affinityConnector,
148770
+ amplitudeConnector,
146546
148771
  amazonEventBridgeConnector,
148772
+ amazonCloudWatchConnector,
148773
+ amazonLambdaConnector,
146547
148774
  amazonS3Connector,
146548
148775
  amazonSnsConnector,
146549
148776
  amazonSqsConnector,
@@ -146566,10 +148793,12 @@ export {
146566
148793
  billComConnector,
146567
148794
  billplzConnector,
146568
148795
  calComConnector,
148796
+ calCom,
146569
148797
  calendlyConnector,
146570
148798
  capsuleCrmConnector,
146571
148799
  closeConnector,
146572
148800
  clickupConnector,
148801
+ cloudflareConnector,
146573
148802
  cloudinaryConnector,
146574
148803
  codaConnector,
146575
148804
  confluenceConnector,
@@ -146642,6 +148871,7 @@ export {
146642
148871
  leadConnectorConnector,
146643
148872
  lemonSqueezyConnector,
146644
148873
  linearConnector,
148874
+ createLinkedinConnector,
146645
148875
  linkedinConnector,
146646
148876
  makeConnector,
146647
148877
  microsoft365PeopleConnector,
@@ -146713,6 +148943,8 @@ export {
146713
148943
  typeformConnector,
146714
148944
  twitterConnector,
146715
148945
  twitter,
148946
+ tiktokConnector,
148947
+ tiktok,
146716
148948
  twilioSmsConnector,
146717
148949
  voucheryIoConnector,
146718
148950
  whatsappBusiness,
@@ -147100,4 +149332,4 @@ export {
147100
149332
  getresponseConnector,
147101
149333
  adapters_exports
147102
149334
  };
147103
- //# sourceMappingURL=chunk-CMNY7MMC.js.map
149335
+ //# sourceMappingURL=chunk-HNEEIMQC.js.map