@tangle-network/agent-integrations 0.53.25 → 0.53.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/catalog.js +5 -5
- package/dist/{chunk-EXPZGJ4A.js → chunk-4H5F6E7W.js} +691 -124
- package/dist/{chunk-EXPZGJ4A.js.map → chunk-4H5F6E7W.js.map} +1 -1
- package/dist/{chunk-ACAQVJ4F.js → chunk-J7CBKM7C.js} +2 -2
- package/dist/{chunk-OZWBZGDN.js → chunk-LBJJMBVE.js} +2 -1
- package/dist/chunk-LBJJMBVE.js.map +1 -0
- package/dist/{chunk-AE7GYW2O.js → chunk-RUHXNRQU.js} +29 -3
- package/dist/{chunk-AE7GYW2O.js.map → chunk-RUHXNRQU.js.map} +1 -1
- package/dist/{chunk-6NICNEJG.js → chunk-TMYH36VV.js} +3 -3
- package/dist/connectors/adapters/index.d.ts +5 -1
- package/dist/connectors/adapters/index.js +5 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +6 -2
- package/dist/coverage-catalog.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -5
- package/dist/mcp.js +5 -5
- package/dist/registry.js +5 -5
- package/dist/runtime.js +5 -5
- package/dist/specs.js +4 -4
- package/docs/integration-execution-audit.md +22 -20
- package/docs/integration-execution-matrix.json +28 -23
- package/package.json +1 -1
- package/dist/chunk-OZWBZGDN.js.map +0 -1
- /package/dist/{chunk-ACAQVJ4F.js.map → chunk-J7CBKM7C.js.map} +0 -0
- /package/dist/{chunk-6NICNEJG.js.map → chunk-TMYH36VV.js.map} +0 -0
|
@@ -82,6 +82,7 @@ __export(adapters_exports, {
|
|
|
82
82
|
azureAdConnector: () => azureAdConnector,
|
|
83
83
|
azureBlobStorageConnector: () => azureBlobStorageConnector,
|
|
84
84
|
azureCommunicationServicesConnector: () => azureCommunicationServicesConnector,
|
|
85
|
+
azureEventGridConnector: () => azureEventGridConnector,
|
|
85
86
|
azureOpenaiConnector: () => azureOpenaiConnector,
|
|
86
87
|
azureServiceBusConnector: () => azureServiceBusConnector,
|
|
87
88
|
backblazeConnector: () => backblazeConnector,
|
|
@@ -142,6 +143,7 @@ __export(adapters_exports, {
|
|
|
142
143
|
chatsistantConnector: () => chatsistantConnector,
|
|
143
144
|
chatwootConnector: () => chatwootConnector,
|
|
144
145
|
checkoutConnector: () => checkoutConnector,
|
|
146
|
+
chessComConnector: () => chessComConnector,
|
|
145
147
|
circleConnector: () => circleConnector,
|
|
146
148
|
classifyGoogleError: () => classifyGoogleError,
|
|
147
149
|
classifyGoogleReason: () => classifyGoogleReason,
|
|
@@ -740,10 +742,10 @@ function canonicalUri(pathname, service) {
|
|
|
740
742
|
if (!pathname) return "/";
|
|
741
743
|
if (service === "s3") return pathname;
|
|
742
744
|
const segments = [];
|
|
743
|
-
for (const
|
|
744
|
-
if (
|
|
745
|
-
if (
|
|
746
|
-
else segments.push(
|
|
745
|
+
for (const segment2 of pathname.split("/")) {
|
|
746
|
+
if (segment2.length === 0 || segment2 === ".") continue;
|
|
747
|
+
if (segment2 === "..") segments.pop();
|
|
748
|
+
else segments.push(segment2);
|
|
747
749
|
}
|
|
748
750
|
const normalized = `/${segments.join("/")}${segments.length > 0 && pathname.endsWith("/") ? "/" : ""}`;
|
|
749
751
|
return awsUriEncode(normalized).replace(/%2F/g, "/");
|
|
@@ -787,11 +789,11 @@ function declarativeRestConnector(spec) {
|
|
|
787
789
|
const op = readOperation(spec, inv.capabilityName, "read");
|
|
788
790
|
const response = await executeRestRequest(spec, op.request, inv, requiredArgsOf(op.parameters));
|
|
789
791
|
if (response.outcome === "rate-limited") {
|
|
790
|
-
const
|
|
792
|
+
const retryAfterMs7 = response.retryAfterMs ?? DEFAULT_RETRY_AFTER_MS;
|
|
791
793
|
throw new ProviderRateLimited(
|
|
792
|
-
`${spec.displayName} ${inv.capabilityName} rate limit (429); retry after ${
|
|
794
|
+
`${spec.displayName} ${inv.capabilityName} rate limit (429); retry after ${retryAfterMs7}ms`,
|
|
793
795
|
inv.source.id,
|
|
794
|
-
{ status: 429, body: response.data, retryAfterMs:
|
|
796
|
+
{ status: 429, body: response.data, retryAfterMs: retryAfterMs7 }
|
|
795
797
|
);
|
|
796
798
|
}
|
|
797
799
|
if (response.outcome === "conflict") {
|
|
@@ -11929,11 +11931,11 @@ async function azureRequest(credentials, inv, method, pathSegments, query2 = new
|
|
|
11929
11931
|
throw new CredentialsExpired(`Azure Blob Storage rejected credentials (${response.status})`, inv.source.id);
|
|
11930
11932
|
}
|
|
11931
11933
|
if (response.status === 429 || response.status === 503) {
|
|
11932
|
-
const
|
|
11934
|
+
const retryAfterMs7 = retryAfter(response.headers.get("retry-after"));
|
|
11933
11935
|
throw new ProviderRateLimited(
|
|
11934
|
-
`Azure Blob Storage rate limit (${response.status}); retry after ${
|
|
11936
|
+
`Azure Blob Storage rate limit (${response.status}); retry after ${retryAfterMs7}ms`,
|
|
11935
11937
|
inv.source.id,
|
|
11936
|
-
{ status: response.status, retryAfterMs:
|
|
11938
|
+
{ status: response.status, retryAfterMs: retryAfterMs7 }
|
|
11937
11939
|
);
|
|
11938
11940
|
}
|
|
11939
11941
|
if (!response.ok) {
|
|
@@ -12079,7 +12081,7 @@ function requiredContainer(value, allowSystem = true) {
|
|
|
12079
12081
|
function requiredBlobName(value) {
|
|
12080
12082
|
const name = requiredString3(value, "blobName");
|
|
12081
12083
|
if (name.length > 1024) throw new Error("blobName cannot exceed 1024 characters");
|
|
12082
|
-
if (name.split("/").some((
|
|
12084
|
+
if (name.split("/").some((segment2) => segment2 === "." || segment2 === "..")) {
|
|
12083
12085
|
throw new Error("blobName cannot contain dot path segments");
|
|
12084
12086
|
}
|
|
12085
12087
|
return name;
|
|
@@ -12206,6 +12208,317 @@ function numberOrUndefined(value) {
|
|
|
12206
12208
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
12207
12209
|
}
|
|
12208
12210
|
|
|
12211
|
+
// src/connectors/adapters/azure-event-grid.ts
|
|
12212
|
+
import { createHash as createHash3, timingSafeEqual } from "crypto";
|
|
12213
|
+
var API_VERSION2 = "2018-01-01";
|
|
12214
|
+
var MAX_BATCH_BYTES = 1024 * 1024;
|
|
12215
|
+
var MAX_EVENTS = 5e3;
|
|
12216
|
+
var EVENT_GRID_SUFFIXES = [
|
|
12217
|
+
".eventgrid.azure.net",
|
|
12218
|
+
".eventgrid.azure.us",
|
|
12219
|
+
".eventgrid.azure.cn"
|
|
12220
|
+
];
|
|
12221
|
+
var azureEventGridConnector = {
|
|
12222
|
+
manifest: {
|
|
12223
|
+
kind: "azure-event-grid",
|
|
12224
|
+
displayName: "Azure Event Grid",
|
|
12225
|
+
description: "Publish Event Grid and CloudEvents batches to customer topics and authenticate inbound subscription validation and event delivery.",
|
|
12226
|
+
auth: {
|
|
12227
|
+
kind: "api-key",
|
|
12228
|
+
hint: "JSON containing endpoint, accessKey, and deliverySecret. endpoint is the Azure custom topic or domain /api/events URL. Configure deliverySecret as the static x-tangle-eventgrid-secret delivery header on each Event Grid subscription."
|
|
12229
|
+
},
|
|
12230
|
+
category: "webhook",
|
|
12231
|
+
defaultConsistencyModel: "advisory",
|
|
12232
|
+
rateLimit: { requests: 600, windowMs: 6e4, scope: "data-source" },
|
|
12233
|
+
capabilities: [
|
|
12234
|
+
mutationCapability2(
|
|
12235
|
+
"events.publish",
|
|
12236
|
+
"Publish a bounded batch using the native Azure Event Grid event schema.",
|
|
12237
|
+
"Events require id, eventType, subject, eventTime, dataVersion, and data."
|
|
12238
|
+
),
|
|
12239
|
+
mutationCapability2(
|
|
12240
|
+
"cloudEvents.publish",
|
|
12241
|
+
"Publish a bounded CloudEvents 1.0 batch.",
|
|
12242
|
+
"CloudEvents require id, source, type, specversion=1.0, and data."
|
|
12243
|
+
)
|
|
12244
|
+
]
|
|
12245
|
+
},
|
|
12246
|
+
async executeMutation(inv) {
|
|
12247
|
+
const credentials = parseCredentials(inv.source.credentials, inv.source.id);
|
|
12248
|
+
const events = inv.capabilityName === "events.publish" ? eventGridEvents(inv.args.events) : inv.capabilityName === "cloudEvents.publish" ? cloudEvents(inv.args.events) : void 0;
|
|
12249
|
+
if (!events) throw new Error(`azure-event-grid: unknown mutation capability ${inv.capabilityName}`);
|
|
12250
|
+
const body = JSON.stringify(events);
|
|
12251
|
+
if (Buffer.byteLength(body) > MAX_BATCH_BYTES) {
|
|
12252
|
+
throw new Error(`Azure Event Grid batch exceeds ${MAX_BATCH_BYTES} bytes`);
|
|
12253
|
+
}
|
|
12254
|
+
const response = await fetch(publishUrl(credentials.endpoint), {
|
|
12255
|
+
method: "POST",
|
|
12256
|
+
headers: {
|
|
12257
|
+
"aeg-sas-key": credentials.accessKey,
|
|
12258
|
+
"content-type": inv.capabilityName === "cloudEvents.publish" ? "application/cloudevents-batch+json; charset=utf-8" : "application/json; charset=utf-8",
|
|
12259
|
+
accept: "application/json"
|
|
12260
|
+
},
|
|
12261
|
+
body
|
|
12262
|
+
});
|
|
12263
|
+
const responseBody = await readBoundedText(response, 256 * 1024);
|
|
12264
|
+
if (!response.ok) throwEventGridError(response, responseBody, inv);
|
|
12265
|
+
return {
|
|
12266
|
+
status: "committed",
|
|
12267
|
+
data: { accepted: true, count: events.length, requestId: response.headers.get("x-ms-request-id") ?? void 0 },
|
|
12268
|
+
committedAt: Date.now(),
|
|
12269
|
+
idempotentReplay: false
|
|
12270
|
+
};
|
|
12271
|
+
},
|
|
12272
|
+
verifySignature({ headers, source }) {
|
|
12273
|
+
let credentials;
|
|
12274
|
+
try {
|
|
12275
|
+
credentials = parseCredentials(source.credentials, source.id);
|
|
12276
|
+
} catch {
|
|
12277
|
+
return { valid: false, reason: "Azure Event Grid credentials are invalid" };
|
|
12278
|
+
}
|
|
12279
|
+
const provided = headerValue(headers, "x-tangle-eventgrid-secret");
|
|
12280
|
+
if (!provided) return { valid: false, reason: "Missing x-tangle-eventgrid-secret delivery header" };
|
|
12281
|
+
const expectedDigest = createHash3("sha256").update(credentials.deliverySecret).digest();
|
|
12282
|
+
const providedDigest = createHash3("sha256").update(provided).digest();
|
|
12283
|
+
return timingSafeEqual(expectedDigest, providedDigest) ? { valid: true } : { valid: false, reason: "Invalid x-tangle-eventgrid-secret delivery header" };
|
|
12284
|
+
},
|
|
12285
|
+
async handleInboundEvent({ rawBody }) {
|
|
12286
|
+
if (Buffer.byteLength(rawBody) > MAX_BATCH_BYTES) {
|
|
12287
|
+
throw new Error(`Azure Event Grid delivery exceeds ${MAX_BATCH_BYTES} bytes`);
|
|
12288
|
+
}
|
|
12289
|
+
let parsed;
|
|
12290
|
+
try {
|
|
12291
|
+
parsed = JSON.parse(rawBody);
|
|
12292
|
+
} catch {
|
|
12293
|
+
throw new Error("Azure Event Grid delivery body must be valid JSON");
|
|
12294
|
+
}
|
|
12295
|
+
const entries = Array.isArray(parsed) ? parsed : [parsed];
|
|
12296
|
+
if (entries.length > MAX_EVENTS) throw new Error(`Azure Event Grid delivery exceeds ${MAX_EVENTS} events`);
|
|
12297
|
+
const validation = entries.find((entry) => isValidationEvent(entry));
|
|
12298
|
+
if (validation && isRecord(validation.data) && typeof validation.data.validationCode === "string") {
|
|
12299
|
+
return {
|
|
12300
|
+
events: [],
|
|
12301
|
+
response: { status: 200, body: { validationResponse: validation.data.validationCode } }
|
|
12302
|
+
};
|
|
12303
|
+
}
|
|
12304
|
+
return {
|
|
12305
|
+
events: entries.map((entry, index) => inboundEvent(entry, index))
|
|
12306
|
+
};
|
|
12307
|
+
},
|
|
12308
|
+
async test(source) {
|
|
12309
|
+
try {
|
|
12310
|
+
parseCredentials(source.credentials, source.id);
|
|
12311
|
+
return { ok: true };
|
|
12312
|
+
} catch (error) {
|
|
12313
|
+
return { ok: false, reason: error instanceof Error ? error.message : "Azure Event Grid credentials are invalid" };
|
|
12314
|
+
}
|
|
12315
|
+
}
|
|
12316
|
+
};
|
|
12317
|
+
function mutationCapability2(name, description, eventDescription) {
|
|
12318
|
+
return {
|
|
12319
|
+
name,
|
|
12320
|
+
class: "mutation",
|
|
12321
|
+
description,
|
|
12322
|
+
parameters: {
|
|
12323
|
+
type: "object",
|
|
12324
|
+
properties: {
|
|
12325
|
+
events: {
|
|
12326
|
+
type: "array",
|
|
12327
|
+
minItems: 1,
|
|
12328
|
+
maxItems: MAX_EVENTS,
|
|
12329
|
+
description: eventDescription
|
|
12330
|
+
}
|
|
12331
|
+
},
|
|
12332
|
+
required: ["events"]
|
|
12333
|
+
},
|
|
12334
|
+
cas: "none",
|
|
12335
|
+
externalEffect: true
|
|
12336
|
+
};
|
|
12337
|
+
}
|
|
12338
|
+
function parseCredentials(credentials, dataSourceId) {
|
|
12339
|
+
if (credentials.kind !== "api-key") {
|
|
12340
|
+
throw new CredentialsExpired("Azure Event Grid requires a credential JSON bundle", dataSourceId);
|
|
12341
|
+
}
|
|
12342
|
+
let parsed;
|
|
12343
|
+
try {
|
|
12344
|
+
parsed = JSON.parse(credentials.apiKey);
|
|
12345
|
+
} catch {
|
|
12346
|
+
throw new CredentialsExpired("Azure Event Grid credentials must be valid JSON", dataSourceId);
|
|
12347
|
+
}
|
|
12348
|
+
if (!isRecord(parsed)) throw new CredentialsExpired("Azure Event Grid credentials must be a JSON object", dataSourceId);
|
|
12349
|
+
const endpointValue = credentialString(parsed.endpoint, "endpoint", dataSourceId);
|
|
12350
|
+
const accessKey = credentialString(parsed.accessKey, "accessKey", dataSourceId);
|
|
12351
|
+
const deliverySecret = credentialString(parsed.deliverySecret, "deliverySecret", dataSourceId);
|
|
12352
|
+
let endpoint;
|
|
12353
|
+
try {
|
|
12354
|
+
endpoint = new URL(endpointValue);
|
|
12355
|
+
} catch {
|
|
12356
|
+
throw new CredentialsExpired("Azure Event Grid endpoint is invalid", dataSourceId);
|
|
12357
|
+
}
|
|
12358
|
+
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.port || endpoint.search || endpoint.hash || endpoint.pathname.replace(/\/$/, "").toLowerCase() !== "/api/events" || !EVENT_GRID_SUFFIXES.some((suffix) => endpoint.hostname.endsWith(suffix))) {
|
|
12359
|
+
throw new CredentialsExpired("Azure Event Grid endpoint must be a public Azure custom topic or domain /api/events URL", dataSourceId);
|
|
12360
|
+
}
|
|
12361
|
+
if (!canonicalBase64(accessKey) || Buffer.from(accessKey, "base64").length < 16) {
|
|
12362
|
+
throw new CredentialsExpired("Azure Event Grid accessKey must be a valid base64 topic key", dataSourceId);
|
|
12363
|
+
}
|
|
12364
|
+
if (deliverySecret.length < 32 || deliverySecret.length > 4096) {
|
|
12365
|
+
throw new CredentialsExpired("Azure Event Grid deliverySecret must contain 32 to 4096 characters", dataSourceId);
|
|
12366
|
+
}
|
|
12367
|
+
endpoint.pathname = "/api/events";
|
|
12368
|
+
return { endpoint, accessKey, deliverySecret };
|
|
12369
|
+
}
|
|
12370
|
+
function publishUrl(endpoint) {
|
|
12371
|
+
const url = new URL(endpoint);
|
|
12372
|
+
url.searchParams.set("api-version", API_VERSION2);
|
|
12373
|
+
return url;
|
|
12374
|
+
}
|
|
12375
|
+
function eventGridEvents(value) {
|
|
12376
|
+
const entries = eventArray(value);
|
|
12377
|
+
return entries.map((entry, index) => {
|
|
12378
|
+
const result = {
|
|
12379
|
+
id: requiredString4(entry.id, `events[${index}].id`),
|
|
12380
|
+
eventType: requiredString4(entry.eventType, `events[${index}].eventType`),
|
|
12381
|
+
subject: requiredString4(entry.subject, `events[${index}].subject`),
|
|
12382
|
+
eventTime: isoDate(entry.eventTime, `events[${index}].eventTime`),
|
|
12383
|
+
dataVersion: requiredString4(entry.dataVersion, `events[${index}].dataVersion`),
|
|
12384
|
+
data: requiredJsonValue(entry.data, `events[${index}].data`)
|
|
12385
|
+
};
|
|
12386
|
+
if (entry.topic !== void 0) result.topic = requiredString4(entry.topic, `events[${index}].topic`);
|
|
12387
|
+
return result;
|
|
12388
|
+
});
|
|
12389
|
+
}
|
|
12390
|
+
function cloudEvents(value) {
|
|
12391
|
+
const entries = eventArray(value);
|
|
12392
|
+
return entries.map((entry, index) => {
|
|
12393
|
+
if (entry.specversion !== "1.0") throw new Error(`events[${index}].specversion must be 1.0`);
|
|
12394
|
+
const result = {
|
|
12395
|
+
specversion: "1.0",
|
|
12396
|
+
id: requiredString4(entry.id, `events[${index}].id`),
|
|
12397
|
+
source: requiredString4(entry.source, `events[${index}].source`),
|
|
12398
|
+
type: requiredString4(entry.type, `events[${index}].type`),
|
|
12399
|
+
data: requiredJsonValue(entry.data, `events[${index}].data`)
|
|
12400
|
+
};
|
|
12401
|
+
if (entry.subject !== void 0) result.subject = requiredString4(entry.subject, `events[${index}].subject`);
|
|
12402
|
+
if (entry.time !== void 0) result.time = isoDate(entry.time, `events[${index}].time`);
|
|
12403
|
+
if (entry.datacontenttype !== void 0) result.datacontenttype = requiredString4(entry.datacontenttype, `events[${index}].datacontenttype`);
|
|
12404
|
+
if (entry.dataschema !== void 0) result.dataschema = requiredString4(entry.dataschema, `events[${index}].dataschema`);
|
|
12405
|
+
return result;
|
|
12406
|
+
});
|
|
12407
|
+
}
|
|
12408
|
+
function eventArray(value) {
|
|
12409
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > MAX_EVENTS) {
|
|
12410
|
+
throw new Error(`events must contain 1 to ${MAX_EVENTS} entries`);
|
|
12411
|
+
}
|
|
12412
|
+
return value.map((entry, index) => {
|
|
12413
|
+
if (!isRecord(entry)) throw new Error(`events[${index}] must be an object`);
|
|
12414
|
+
return entry;
|
|
12415
|
+
});
|
|
12416
|
+
}
|
|
12417
|
+
function inboundEvent(entry, index) {
|
|
12418
|
+
if (!isRecord(entry)) throw new Error(`Azure Event Grid delivery entry ${index} must be an object`);
|
|
12419
|
+
const eventType = typeof entry.eventType === "string" ? entry.eventType : typeof entry.type === "string" ? entry.type : "azure.event-grid.event";
|
|
12420
|
+
return {
|
|
12421
|
+
eventType,
|
|
12422
|
+
providerEventId: typeof entry.id === "string" ? entry.id : void 0,
|
|
12423
|
+
payload: entry
|
|
12424
|
+
};
|
|
12425
|
+
}
|
|
12426
|
+
function isValidationEvent(value) {
|
|
12427
|
+
return isRecord(value) && value.eventType === "Microsoft.EventGrid.SubscriptionValidationEvent";
|
|
12428
|
+
}
|
|
12429
|
+
function throwEventGridError(response, body, inv) {
|
|
12430
|
+
const redacted = body.replace(/[A-Za-z0-9+/]{32,}={0,2}/g, "[redacted]").slice(0, 500);
|
|
12431
|
+
if (response.status === 401) {
|
|
12432
|
+
throw new CredentialsExpired("Azure Event Grid rejected the topic access key", inv.source.id, {
|
|
12433
|
+
status: response.status,
|
|
12434
|
+
body: redacted
|
|
12435
|
+
});
|
|
12436
|
+
}
|
|
12437
|
+
if (response.status === 403) {
|
|
12438
|
+
throw new ProviderConfigError("Azure Event Grid topic policy rejected publishing", inv.source.id, {
|
|
12439
|
+
status: response.status,
|
|
12440
|
+
body: redacted
|
|
12441
|
+
});
|
|
12442
|
+
}
|
|
12443
|
+
if (response.status === 429 || response.status === 503) {
|
|
12444
|
+
throw new ProviderRateLimited("Azure Event Grid is throttling publishes", inv.source.id, {
|
|
12445
|
+
status: response.status,
|
|
12446
|
+
body: redacted,
|
|
12447
|
+
retryAfterMs: retryAfterMs3(response.headers.get("retry-after"))
|
|
12448
|
+
});
|
|
12449
|
+
}
|
|
12450
|
+
throw new Error(`Azure Event Grid publish failed with HTTP ${response.status}: ${redacted}`);
|
|
12451
|
+
}
|
|
12452
|
+
async function readBoundedText(response, limit) {
|
|
12453
|
+
const declared = Number(response.headers.get("content-length"));
|
|
12454
|
+
if (Number.isFinite(declared) && declared > limit) throw new Error(`Azure Event Grid response exceeds ${limit} bytes`);
|
|
12455
|
+
if (!response.body) return "";
|
|
12456
|
+
const reader = response.body.getReader();
|
|
12457
|
+
const chunks = [];
|
|
12458
|
+
let size = 0;
|
|
12459
|
+
while (true) {
|
|
12460
|
+
const { done, value } = await reader.read();
|
|
12461
|
+
if (done) break;
|
|
12462
|
+
size += value.byteLength;
|
|
12463
|
+
if (size > limit) {
|
|
12464
|
+
await reader.cancel();
|
|
12465
|
+
throw new Error(`Azure Event Grid response exceeds ${limit} bytes`);
|
|
12466
|
+
}
|
|
12467
|
+
chunks.push(value);
|
|
12468
|
+
}
|
|
12469
|
+
const body = new Uint8Array(size);
|
|
12470
|
+
let offset = 0;
|
|
12471
|
+
for (const chunk of chunks) {
|
|
12472
|
+
body.set(chunk, offset);
|
|
12473
|
+
offset += chunk.byteLength;
|
|
12474
|
+
}
|
|
12475
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(body);
|
|
12476
|
+
}
|
|
12477
|
+
function headerValue(headers, name) {
|
|
12478
|
+
const match = Object.entries(headers).find(([key]) => key.toLowerCase() === name.toLowerCase())?.[1];
|
|
12479
|
+
return Array.isArray(match) ? match[0] : match;
|
|
12480
|
+
}
|
|
12481
|
+
function credentialString(value, field, dataSourceId) {
|
|
12482
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
12483
|
+
throw new CredentialsExpired(`Azure Event Grid ${field} is missing`, dataSourceId);
|
|
12484
|
+
}
|
|
12485
|
+
return value.trim();
|
|
12486
|
+
}
|
|
12487
|
+
function requiredString4(value, field) {
|
|
12488
|
+
if (typeof value !== "string" || value.trim() === "" || value.length > 4096) {
|
|
12489
|
+
throw new Error(`${field} must be a non-empty string no longer than 4096 characters`);
|
|
12490
|
+
}
|
|
12491
|
+
return value;
|
|
12492
|
+
}
|
|
12493
|
+
function isoDate(value, field) {
|
|
12494
|
+
const parsed = requiredString4(value, field);
|
|
12495
|
+
const date = new Date(parsed);
|
|
12496
|
+
if (!Number.isFinite(date.getTime())) throw new Error(`${field} must be an ISO 8601 timestamp`);
|
|
12497
|
+
return date.toISOString();
|
|
12498
|
+
}
|
|
12499
|
+
function requiredJsonValue(value, field) {
|
|
12500
|
+
if (value === void 0) throw new Error(`${field} is required`);
|
|
12501
|
+
try {
|
|
12502
|
+
if (JSON.stringify(value) === void 0) throw new Error("not JSON");
|
|
12503
|
+
} catch {
|
|
12504
|
+
throw new Error(`${field} must be JSON-serializable`);
|
|
12505
|
+
}
|
|
12506
|
+
return value;
|
|
12507
|
+
}
|
|
12508
|
+
function canonicalBase64(value) {
|
|
12509
|
+
return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value) && Buffer.from(value, "base64").toString("base64").replace(/=+$/, "") === value.replace(/=+$/, "");
|
|
12510
|
+
}
|
|
12511
|
+
function retryAfterMs3(value) {
|
|
12512
|
+
if (!value) return 6e4;
|
|
12513
|
+
const seconds = Number(value);
|
|
12514
|
+
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
12515
|
+
const date = Date.parse(value);
|
|
12516
|
+
return Number.isFinite(date) ? Math.max(0, date - Date.now()) : 6e4;
|
|
12517
|
+
}
|
|
12518
|
+
function isRecord(value) {
|
|
12519
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12520
|
+
}
|
|
12521
|
+
|
|
12209
12522
|
// src/connectors/adapters/azure-service-bus.ts
|
|
12210
12523
|
import { createHmac as createHmac3 } from "crypto";
|
|
12211
12524
|
var MANAGEMENT_API_VERSION = "2017-04";
|
|
@@ -12249,22 +12562,22 @@ var azureServiceBusConnector = {
|
|
|
12249
12562
|
topic: { type: "string" },
|
|
12250
12563
|
subscription: { type: "string" }
|
|
12251
12564
|
}, ["topic", "subscription"]),
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12565
|
+
mutationCapability3("queues.send", "Send a UTF-8 or base64 message to a queue.", sendProperties("queue"), ["queue", "content"]),
|
|
12566
|
+
mutationCapability3("topics.send", "Publish a UTF-8 or base64 message to a topic.", sendProperties("topic"), ["topic", "content"]),
|
|
12567
|
+
mutationCapability3("queues.receiveDelete", "Receive and permanently delete the next queue message.", {
|
|
12255
12568
|
queue: { type: "string" },
|
|
12256
12569
|
timeoutSeconds: { type: "integer", minimum: 0, maximum: 55 }
|
|
12257
12570
|
}, ["queue"]),
|
|
12258
|
-
|
|
12571
|
+
mutationCapability3("subscriptions.receiveDelete", "Receive and permanently delete the next message from a topic subscription.", {
|
|
12259
12572
|
topic: { type: "string" },
|
|
12260
12573
|
subscription: { type: "string" },
|
|
12261
12574
|
timeoutSeconds: { type: "integer", minimum: 0, maximum: 55 }
|
|
12262
12575
|
}, ["topic", "subscription"]),
|
|
12263
|
-
|
|
12576
|
+
mutationCapability3("queues.deadLetters.receiveDelete", "Receive and permanently delete the next queue dead-letter message.", {
|
|
12264
12577
|
queue: { type: "string" },
|
|
12265
12578
|
timeoutSeconds: { type: "integer", minimum: 0, maximum: 55 }
|
|
12266
12579
|
}, ["queue"]),
|
|
12267
|
-
|
|
12580
|
+
mutationCapability3("subscriptions.deadLetters.receiveDelete", "Receive and permanently delete the next subscription dead-letter message.", {
|
|
12268
12581
|
topic: { type: "string" },
|
|
12269
12582
|
subscription: { type: "string" },
|
|
12270
12583
|
timeoutSeconds: { type: "integer", minimum: 0, maximum: 55 }
|
|
@@ -12383,7 +12696,7 @@ function readCapability2(name, description, properties, required = []) {
|
|
|
12383
12696
|
parameters: { type: "object", properties, ...required.length ? { required } : {} }
|
|
12384
12697
|
};
|
|
12385
12698
|
}
|
|
12386
|
-
function
|
|
12699
|
+
function mutationCapability3(name, description, properties, required) {
|
|
12387
12700
|
return {
|
|
12388
12701
|
name,
|
|
12389
12702
|
class: "mutation",
|
|
@@ -12471,7 +12784,7 @@ function parseConnectionString(credentials, dataSourceId) {
|
|
|
12471
12784
|
}
|
|
12472
12785
|
async function sendMessage(credentials, inv, entityPath) {
|
|
12473
12786
|
enforceEntityPath(credentials, entityPath);
|
|
12474
|
-
const content =
|
|
12787
|
+
const content = requiredString5(inv.args.content, "content", true);
|
|
12475
12788
|
const encoding = inv.args.encoding === void 0 ? "utf-8" : enumValue(inv.args.encoding, "encoding", ["utf-8", "base64"]);
|
|
12476
12789
|
const body = encoding === "base64" ? strictBase64(content) : Buffer.from(content, "utf8");
|
|
12477
12790
|
if (body.byteLength > MAX_MESSAGE_BYTES) {
|
|
@@ -12563,17 +12876,17 @@ ${expiry}`, "utf8").digest("base64");
|
|
|
12563
12876
|
throw new ProviderRateLimited("Azure Service Bus is throttling requests", inv.source.id, {
|
|
12564
12877
|
status: response.status,
|
|
12565
12878
|
body: redactProviderText(text),
|
|
12566
|
-
retryAfterMs:
|
|
12879
|
+
retryAfterMs: retryAfterMs4(response.headers.get("retry-after"))
|
|
12567
12880
|
});
|
|
12568
12881
|
}
|
|
12569
12882
|
throw new Error(`Azure Service Bus request failed with HTTP ${response.status}: ${redactProviderText(text).slice(0, 500)}`);
|
|
12570
12883
|
}
|
|
12571
|
-
function encodePathSegment2(
|
|
12572
|
-
if (
|
|
12573
|
-
return encodeURIComponent(
|
|
12884
|
+
function encodePathSegment2(segment2) {
|
|
12885
|
+
if (segment2 === "$Resources" || segment2 === "$DeadLetterQueue") return segment2;
|
|
12886
|
+
return encodeURIComponent(segment2);
|
|
12574
12887
|
}
|
|
12575
12888
|
function entityName(value, field) {
|
|
12576
|
-
const name =
|
|
12889
|
+
const name = requiredString5(value, field);
|
|
12577
12890
|
if (!/^[A-Za-z0-9][A-Za-z0-9._~-]{0,259}$/.test(name)) {
|
|
12578
12891
|
throw new Error(`${field} must be a valid Azure Service Bus entity name`);
|
|
12579
12892
|
}
|
|
@@ -12608,7 +12921,7 @@ var BROKER_PROPERTY_NAMES = /* @__PURE__ */ new Set([
|
|
|
12608
12921
|
]);
|
|
12609
12922
|
function allowedBrokerProperties(value) {
|
|
12610
12923
|
if (value === void 0) return void 0;
|
|
12611
|
-
if (!
|
|
12924
|
+
if (!isRecord2(value)) throw new Error("brokerProperties must be an object");
|
|
12612
12925
|
const entries = Object.entries(value);
|
|
12613
12926
|
if (entries.length > BROKER_PROPERTY_NAMES.size) throw new Error("brokerProperties contains too many fields");
|
|
12614
12927
|
const result = {};
|
|
@@ -12631,7 +12944,7 @@ var RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
|
12631
12944
|
]);
|
|
12632
12945
|
function applicationPropertyHeaders(value) {
|
|
12633
12946
|
if (value === void 0) return {};
|
|
12634
|
-
if (!
|
|
12947
|
+
if (!isRecord2(value)) throw new Error("applicationProperties must be an object");
|
|
12635
12948
|
const entries = Object.entries(value);
|
|
12636
12949
|
if (entries.length > 64) throw new Error("applicationProperties cannot contain more than 64 entries");
|
|
12637
12950
|
const result = {};
|
|
@@ -12646,10 +12959,10 @@ function applicationPropertyHeaders(value) {
|
|
|
12646
12959
|
if (typeof property === "number" && !Number.isFinite(property)) {
|
|
12647
12960
|
throw new Error(`applicationProperties.${key} must be finite`);
|
|
12648
12961
|
}
|
|
12649
|
-
const
|
|
12650
|
-
size += Buffer.byteLength(key) + Buffer.byteLength(
|
|
12962
|
+
const headerValue2 = requiredHeaderValue(String(property), `applicationProperties.${key}`);
|
|
12963
|
+
size += Buffer.byteLength(key) + Buffer.byteLength(headerValue2);
|
|
12651
12964
|
if (size > 32 * 1024) throw new Error("applicationProperties exceeds 32768 bytes");
|
|
12652
|
-
result[key] =
|
|
12965
|
+
result[key] = headerValue2;
|
|
12653
12966
|
}
|
|
12654
12967
|
return result;
|
|
12655
12968
|
}
|
|
@@ -12668,7 +12981,7 @@ function parseAtomFeed(xml) {
|
|
|
12668
12981
|
};
|
|
12669
12982
|
}
|
|
12670
12983
|
function parseAtomEntry(xml) {
|
|
12671
|
-
const
|
|
12984
|
+
const title2 = xmlValue(xml, "title");
|
|
12672
12985
|
const id2 = xmlValue(xml, "id");
|
|
12673
12986
|
const updated = xmlValue(xml, "updated");
|
|
12674
12987
|
const properties = {};
|
|
@@ -12678,7 +12991,7 @@ function parseAtomEntry(xml) {
|
|
|
12678
12991
|
const raw = decodeXml2(match[2]);
|
|
12679
12992
|
properties[key] = xmlScalar(raw);
|
|
12680
12993
|
}
|
|
12681
|
-
return { title, id: id2, updated, properties };
|
|
12994
|
+
return { title: title2, id: id2, updated, properties };
|
|
12682
12995
|
}
|
|
12683
12996
|
function xmlValue(xml, tag) {
|
|
12684
12997
|
const match = xml.match(new RegExp(`<(?:[A-Za-z0-9]+:)?${tag}\\b[^>]*>([^<]*)<\\/(?:[A-Za-z0-9]+:)?${tag}>`, "i"));
|
|
@@ -12727,14 +13040,14 @@ function strictBase64(value) {
|
|
|
12727
13040
|
}
|
|
12728
13041
|
return Buffer.from(value, "base64");
|
|
12729
13042
|
}
|
|
12730
|
-
function
|
|
13043
|
+
function requiredString5(value, field, allowEmpty = false) {
|
|
12731
13044
|
if (typeof value !== "string" || !allowEmpty && value.trim() === "") {
|
|
12732
13045
|
throw new Error(`${field} must be ${allowEmpty ? "a string" : "a non-empty string"}`);
|
|
12733
13046
|
}
|
|
12734
13047
|
return allowEmpty ? value : value.trim();
|
|
12735
13048
|
}
|
|
12736
13049
|
function requiredHeaderValue(value, field) {
|
|
12737
|
-
const parsed =
|
|
13050
|
+
const parsed = requiredString5(value, field);
|
|
12738
13051
|
if (/\r|\n/.test(parsed) || parsed.length > 4096) throw new Error(`${field} is not a safe header value`);
|
|
12739
13052
|
return parsed;
|
|
12740
13053
|
}
|
|
@@ -12753,7 +13066,7 @@ function enumValue(value, field, choices) {
|
|
|
12753
13066
|
function decodeUtf82(value) {
|
|
12754
13067
|
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
12755
13068
|
}
|
|
12756
|
-
function
|
|
13069
|
+
function retryAfterMs4(value) {
|
|
12757
13070
|
if (!value) return 6e4;
|
|
12758
13071
|
const seconds = Number(value);
|
|
12759
13072
|
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
@@ -12763,7 +13076,7 @@ function retryAfterMs3(value) {
|
|
|
12763
13076
|
function redactProviderText(value) {
|
|
12764
13077
|
return value.replace(/SharedAccessSignature\s+[^\s<]+/gi, "SharedAccessSignature [redacted]").replace(/SharedAccessKey=[^;\s<]+/gi, "SharedAccessKey=[redacted]");
|
|
12765
13078
|
}
|
|
12766
|
-
function
|
|
13079
|
+
function isRecord2(value) {
|
|
12767
13080
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12768
13081
|
}
|
|
12769
13082
|
|
|
@@ -19296,8 +19609,258 @@ var checkoutConnector = declarativeRestConnector({
|
|
|
19296
19609
|
]
|
|
19297
19610
|
});
|
|
19298
19611
|
|
|
19612
|
+
// src/connectors/adapters/chess-com.ts
|
|
19613
|
+
var API_ORIGIN = "https://api.chess.com";
|
|
19614
|
+
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
19615
|
+
var MAX_RESPONSE_BYTES3 = 5 * 1024 * 1024;
|
|
19616
|
+
var USERNAME_PATTERN = /^[A-Za-z0-9_-]{3,25}$/;
|
|
19617
|
+
var SLUG_PATTERN = /^[A-Za-z0-9_-]{1,100}$/;
|
|
19618
|
+
var TITLES = ["GM", "WGM", "IM", "WIM", "FM", "WFM", "NM", "WNM", "CM", "WCM"];
|
|
19619
|
+
var usernameProperty = {
|
|
19620
|
+
type: "string",
|
|
19621
|
+
description: "Chess.com username, without a profile URL.",
|
|
19622
|
+
pattern: USERNAME_PATTERN.source
|
|
19623
|
+
};
|
|
19624
|
+
var slugProperty = {
|
|
19625
|
+
type: "string",
|
|
19626
|
+
description: "Chess.com URL id (the final path segment of the public page URL).",
|
|
19627
|
+
pattern: SLUG_PATTERN.source
|
|
19628
|
+
};
|
|
19629
|
+
var CAPABILITIES = [
|
|
19630
|
+
readCapability3("get.player.profile", "Get the public profile for a Chess.com player.", { username: usernameProperty }, ["username"]),
|
|
19631
|
+
readCapability3("get.player.stats", "Get ratings and game statistics for a Chess.com player.", { username: usernameProperty }, ["username"]),
|
|
19632
|
+
readCapability3("player.current-games", "List a player\u2019s currently ongoing daily games.", { username: usernameProperty }, ["username"]),
|
|
19633
|
+
readCapability3("player.game-archives", "List the monthly game archive URLs available for a player.", { username: usernameProperty }, ["username"]),
|
|
19634
|
+
readCapability3("player.monthly-games", "Get a player\u2019s games for one calendar month as structured JSON.", {
|
|
19635
|
+
username: usernameProperty,
|
|
19636
|
+
year: { type: "integer", minimum: 2007, maximum: 2100 },
|
|
19637
|
+
month: { type: "integer", minimum: 1, maximum: 12 }
|
|
19638
|
+
}, ["username", "year", "month"]),
|
|
19639
|
+
readCapability3("player.monthly-pgn", "Get a player\u2019s games for one calendar month as a PGN document.", {
|
|
19640
|
+
username: usernameProperty,
|
|
19641
|
+
year: { type: "integer", minimum: 2007, maximum: 2100 },
|
|
19642
|
+
month: { type: "integer", minimum: 1, maximum: 12 }
|
|
19643
|
+
}, ["username", "year", "month"]),
|
|
19644
|
+
readCapability3("player.clubs", "List the public clubs a player belongs to.", { username: usernameProperty }, ["username"]),
|
|
19645
|
+
readCapability3("player.matches", "List a player\u2019s current and finished team matches.", { username: usernameProperty }, ["username"]),
|
|
19646
|
+
readCapability3("player.tournaments", "List a player\u2019s current, registered, and finished tournaments.", { username: usernameProperty }, ["username"]),
|
|
19647
|
+
readCapability3("get.daily.puzzle", "Get the current Chess.com daily puzzle.", {}),
|
|
19648
|
+
readCapability3("puzzle.random", "Get a random Chess.com puzzle.", {}),
|
|
19649
|
+
readCapability3("players.titled", "List usernames holding a FIDE or national chess title.", {
|
|
19650
|
+
title: { type: "string", enum: [...TITLES] }
|
|
19651
|
+
}, ["title"]),
|
|
19652
|
+
readCapability3("leaderboards.get", "Get current Chess.com leaderboards.", {}),
|
|
19653
|
+
readCapability3("streamers.list", "List Chess.com streamers and their public channels.", {}),
|
|
19654
|
+
readCapability3("country.get", "Get public information for a country.", {
|
|
19655
|
+
country: { type: "string", description: "Two-letter ISO 3166 country code.", pattern: "^[A-Za-z]{2}$" }
|
|
19656
|
+
}, ["country"]),
|
|
19657
|
+
readCapability3("country.players", "List Chess.com players registered to a country.", {
|
|
19658
|
+
country: { type: "string", description: "Two-letter ISO 3166 country code.", pattern: "^[A-Za-z]{2}$" }
|
|
19659
|
+
}, ["country"]),
|
|
19660
|
+
readCapability3("country.clubs", "List Chess.com clubs registered to a country.", {
|
|
19661
|
+
country: { type: "string", description: "Two-letter ISO 3166 country code.", pattern: "^[A-Za-z]{2}$" }
|
|
19662
|
+
}, ["country"]),
|
|
19663
|
+
readCapability3("club.get", "Get public information for a Chess.com club.", { club: slugProperty }, ["club"]),
|
|
19664
|
+
readCapability3("club.members", "List members of a Chess.com club, grouped by activity.", { club: slugProperty }, ["club"]),
|
|
19665
|
+
readCapability3("club.matches", "List a Chess.com club\u2019s current and finished team matches.", { club: slugProperty }, ["club"]),
|
|
19666
|
+
readCapability3("club.admins", "List public administrators for a Chess.com club.", { club: slugProperty }, ["club"]),
|
|
19667
|
+
readCapability3("tournament.get", "Get public details for a Chess.com tournament.", { tournament: slugProperty }, ["tournament"]),
|
|
19668
|
+
readCapability3("tournament.round", "Get one round of a Chess.com tournament.", {
|
|
19669
|
+
tournament: slugProperty,
|
|
19670
|
+
round: { type: "integer", minimum: 1 }
|
|
19671
|
+
}, ["tournament", "round"]),
|
|
19672
|
+
readCapability3("tournament.group", "Get one group within a Chess.com tournament round.", {
|
|
19673
|
+
tournament: slugProperty,
|
|
19674
|
+
round: { type: "integer", minimum: 1 },
|
|
19675
|
+
group: { type: "integer", minimum: 1 }
|
|
19676
|
+
}, ["tournament", "round", "group"])
|
|
19677
|
+
];
|
|
19678
|
+
var chessComConnector = {
|
|
19679
|
+
manifest: {
|
|
19680
|
+
kind: "chess-com",
|
|
19681
|
+
displayName: "Chess.com",
|
|
19682
|
+
description: "Read public Chess.com profiles, ratings, games, puzzles, leaderboards, clubs, countries, tournaments, and streaming data without credentials.",
|
|
19683
|
+
auth: { kind: "none" },
|
|
19684
|
+
category: "other",
|
|
19685
|
+
defaultConsistencyModel: "cache",
|
|
19686
|
+
rateLimit: { requests: 60, windowMs: 6e4, scope: "data-source" },
|
|
19687
|
+
capabilities: CAPABILITIES
|
|
19688
|
+
},
|
|
19689
|
+
async executeRead(inv) {
|
|
19690
|
+
const path = route(inv.capabilityName, inv.args);
|
|
19691
|
+
const response = await fetch(`${API_ORIGIN}${path}`, {
|
|
19692
|
+
method: "GET",
|
|
19693
|
+
headers: {
|
|
19694
|
+
accept: inv.capabilityName === "player.monthly-pgn" ? "application/x-chess-pgn, text/plain;q=0.9" : "application/json",
|
|
19695
|
+
"user-agent": "Tangle-Integrations/1.0 (+https://tangle.tools)"
|
|
19696
|
+
},
|
|
19697
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)
|
|
19698
|
+
});
|
|
19699
|
+
const body = await readBoundedBody(response);
|
|
19700
|
+
if (!response.ok) {
|
|
19701
|
+
const detail = body.length > 200 ? `${body.slice(0, 200)}\u2026` : body;
|
|
19702
|
+
throw new Error(`Chess.com ${inv.capabilityName} failed: ${response.status} ${detail || response.statusText}`);
|
|
19703
|
+
}
|
|
19704
|
+
return {
|
|
19705
|
+
data: parseBody(body, response.headers.get("content-type")),
|
|
19706
|
+
etag: response.headers.get("etag") ?? response.headers.get("last-modified") ?? void 0,
|
|
19707
|
+
fetchedAt: Date.now()
|
|
19708
|
+
};
|
|
19709
|
+
},
|
|
19710
|
+
async test() {
|
|
19711
|
+
try {
|
|
19712
|
+
const response = await fetch(`${API_ORIGIN}/pub/leaderboards`, {
|
|
19713
|
+
method: "GET",
|
|
19714
|
+
headers: {
|
|
19715
|
+
accept: "application/json",
|
|
19716
|
+
"user-agent": "Tangle-Integrations/1.0 (+https://tangle.tools)"
|
|
19717
|
+
},
|
|
19718
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS)
|
|
19719
|
+
});
|
|
19720
|
+
return response.ok ? { ok: true } : { ok: false, reason: `Chess.com public API returned ${response.status}` };
|
|
19721
|
+
} catch (error) {
|
|
19722
|
+
return { ok: false, reason: error instanceof Error ? error.message : String(error) };
|
|
19723
|
+
}
|
|
19724
|
+
}
|
|
19725
|
+
};
|
|
19726
|
+
function readCapability3(name, description, properties, required = []) {
|
|
19727
|
+
return {
|
|
19728
|
+
name,
|
|
19729
|
+
class: "read",
|
|
19730
|
+
description,
|
|
19731
|
+
parameters: {
|
|
19732
|
+
type: "object",
|
|
19733
|
+
properties,
|
|
19734
|
+
...required.length > 0 ? { required } : {},
|
|
19735
|
+
additionalProperties: false
|
|
19736
|
+
}
|
|
19737
|
+
};
|
|
19738
|
+
}
|
|
19739
|
+
function route(capabilityName, args) {
|
|
19740
|
+
const username = () => segment(args.username, "username", USERNAME_PATTERN);
|
|
19741
|
+
const club = () => segment(args.club, "club", SLUG_PATTERN);
|
|
19742
|
+
const tournament = () => segment(args.tournament, "tournament", SLUG_PATTERN);
|
|
19743
|
+
switch (capabilityName) {
|
|
19744
|
+
case "get.player.profile":
|
|
19745
|
+
return `/pub/player/${username()}`;
|
|
19746
|
+
case "get.player.stats":
|
|
19747
|
+
return `/pub/player/${username()}/stats`;
|
|
19748
|
+
case "player.current-games":
|
|
19749
|
+
return `/pub/player/${username()}/games/current`;
|
|
19750
|
+
case "player.game-archives":
|
|
19751
|
+
return `/pub/player/${username()}/games/archives`;
|
|
19752
|
+
case "player.monthly-games":
|
|
19753
|
+
return `/pub/player/${username()}/games/${integer(args.year, "year", 2007, 2100)}/${month(args.month)}`;
|
|
19754
|
+
case "player.monthly-pgn":
|
|
19755
|
+
return `/pub/player/${username()}/games/${integer(args.year, "year", 2007, 2100)}/${month(args.month)}/pgn`;
|
|
19756
|
+
case "player.clubs":
|
|
19757
|
+
return `/pub/player/${username()}/clubs`;
|
|
19758
|
+
case "player.matches":
|
|
19759
|
+
return `/pub/player/${username()}/matches`;
|
|
19760
|
+
case "player.tournaments":
|
|
19761
|
+
return `/pub/player/${username()}/tournaments`;
|
|
19762
|
+
case "get.daily.puzzle":
|
|
19763
|
+
return "/pub/puzzle";
|
|
19764
|
+
case "puzzle.random":
|
|
19765
|
+
return "/pub/puzzle/random";
|
|
19766
|
+
case "players.titled":
|
|
19767
|
+
return `/pub/titled/${title(args.title)}`;
|
|
19768
|
+
case "leaderboards.get":
|
|
19769
|
+
return "/pub/leaderboards";
|
|
19770
|
+
case "streamers.list":
|
|
19771
|
+
return "/pub/streamers";
|
|
19772
|
+
case "country.get":
|
|
19773
|
+
return `/pub/country/${country(args.country)}`;
|
|
19774
|
+
case "country.players":
|
|
19775
|
+
return `/pub/country/${country(args.country)}/players`;
|
|
19776
|
+
case "country.clubs":
|
|
19777
|
+
return `/pub/country/${country(args.country)}/clubs`;
|
|
19778
|
+
case "club.get":
|
|
19779
|
+
return `/pub/club/${club()}`;
|
|
19780
|
+
case "club.members":
|
|
19781
|
+
return `/pub/club/${club()}/members`;
|
|
19782
|
+
case "club.matches":
|
|
19783
|
+
return `/pub/club/${club()}/matches`;
|
|
19784
|
+
case "club.admins":
|
|
19785
|
+
return `/pub/club/${club()}/admin`;
|
|
19786
|
+
case "tournament.get":
|
|
19787
|
+
return `/pub/tournament/${tournament()}`;
|
|
19788
|
+
case "tournament.round":
|
|
19789
|
+
return `/pub/tournament/${tournament()}/${integer(args.round, "round", 1, 1e6)}`;
|
|
19790
|
+
case "tournament.group":
|
|
19791
|
+
return `/pub/tournament/${tournament()}/${integer(args.round, "round", 1, 1e6)}/${integer(args.group, "group", 1, 1e6)}`;
|
|
19792
|
+
default:
|
|
19793
|
+
throw new Error(`Chess.com does not support capability ${capabilityName}`);
|
|
19794
|
+
}
|
|
19795
|
+
}
|
|
19796
|
+
function segment(value, label, pattern) {
|
|
19797
|
+
if (typeof value !== "string" || !pattern.test(value)) {
|
|
19798
|
+
throw new Error(`${label} has an invalid Chess.com path value`);
|
|
19799
|
+
}
|
|
19800
|
+
return encodeURIComponent(value.toLowerCase());
|
|
19801
|
+
}
|
|
19802
|
+
function integer(value, label, minimum, maximum) {
|
|
19803
|
+
if (!Number.isInteger(value) || value < minimum || value > maximum) {
|
|
19804
|
+
throw new Error(`${label} must be an integer from ${minimum} to ${maximum}`);
|
|
19805
|
+
}
|
|
19806
|
+
return value;
|
|
19807
|
+
}
|
|
19808
|
+
function month(value) {
|
|
19809
|
+
return String(integer(value, "month", 1, 12)).padStart(2, "0");
|
|
19810
|
+
}
|
|
19811
|
+
function country(value) {
|
|
19812
|
+
if (typeof value !== "string" || !/^[A-Za-z]{2}$/.test(value)) {
|
|
19813
|
+
throw new Error("country must be a two-letter ISO 3166 code");
|
|
19814
|
+
}
|
|
19815
|
+
return value.toUpperCase();
|
|
19816
|
+
}
|
|
19817
|
+
function title(value) {
|
|
19818
|
+
if (typeof value !== "string" || !TITLES.includes(value.toUpperCase())) {
|
|
19819
|
+
throw new Error(`title must be one of ${TITLES.join(", ")}`);
|
|
19820
|
+
}
|
|
19821
|
+
return value.toUpperCase();
|
|
19822
|
+
}
|
|
19823
|
+
async function readBoundedBody(response) {
|
|
19824
|
+
const declaredLength = Number(response.headers.get("content-length"));
|
|
19825
|
+
if (Number.isFinite(declaredLength) && declaredLength > MAX_RESPONSE_BYTES3) {
|
|
19826
|
+
throw new Error(`Chess.com response exceeds ${MAX_RESPONSE_BYTES3} bytes`);
|
|
19827
|
+
}
|
|
19828
|
+
if (!response.body) return "";
|
|
19829
|
+
const reader = response.body.getReader();
|
|
19830
|
+
const chunks = [];
|
|
19831
|
+
let total = 0;
|
|
19832
|
+
while (true) {
|
|
19833
|
+
const { done, value } = await reader.read();
|
|
19834
|
+
if (done) break;
|
|
19835
|
+
total += value.byteLength;
|
|
19836
|
+
if (total > MAX_RESPONSE_BYTES3) {
|
|
19837
|
+
await reader.cancel();
|
|
19838
|
+
throw new Error(`Chess.com response exceeds ${MAX_RESPONSE_BYTES3} bytes`);
|
|
19839
|
+
}
|
|
19840
|
+
chunks.push(value);
|
|
19841
|
+
}
|
|
19842
|
+
const bytes = new Uint8Array(total);
|
|
19843
|
+
let offset = 0;
|
|
19844
|
+
for (const chunk of chunks) {
|
|
19845
|
+
bytes.set(chunk, offset);
|
|
19846
|
+
offset += chunk.byteLength;
|
|
19847
|
+
}
|
|
19848
|
+
return new TextDecoder().decode(bytes);
|
|
19849
|
+
}
|
|
19850
|
+
function parseBody(body, contentType) {
|
|
19851
|
+
if (body.length === 0) return null;
|
|
19852
|
+
if (contentType?.includes("json")) {
|
|
19853
|
+
try {
|
|
19854
|
+
return JSON.parse(body);
|
|
19855
|
+
} catch {
|
|
19856
|
+
throw new Error("Chess.com returned malformed JSON");
|
|
19857
|
+
}
|
|
19858
|
+
}
|
|
19859
|
+
return body;
|
|
19860
|
+
}
|
|
19861
|
+
|
|
19299
19862
|
// src/connectors/adapters/docuseal.ts
|
|
19300
|
-
import { createHmac as createHmac4, timingSafeEqual } from "crypto";
|
|
19863
|
+
import { createHmac as createHmac4, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
19301
19864
|
var DEFAULT_BASE = "https://api.docuseal.com";
|
|
19302
19865
|
function readDocuSealCredentials(creds) {
|
|
19303
19866
|
if (creds.kind === "api-key" && typeof creds.apiKey === "string" && creds.apiKey.length > 0) {
|
|
@@ -19426,7 +19989,7 @@ function docuseal(opts = {}) {
|
|
|
19426
19989
|
const a = Buffer.from(sig.toLowerCase(), "utf-8");
|
|
19427
19990
|
const b = Buffer.from(expected, "utf-8");
|
|
19428
19991
|
if (a.length !== b.length) return { valid: false, reason: "invalid_signature" };
|
|
19429
|
-
return
|
|
19992
|
+
return timingSafeEqual2(a, b) ? { valid: true } : { valid: false, reason: "invalid_signature" };
|
|
19430
19993
|
},
|
|
19431
19994
|
async handleInboundEvent({ rawBody }) {
|
|
19432
19995
|
let parsed;
|
|
@@ -23044,7 +23607,7 @@ var frontConnector = declarativeRestConnector({
|
|
|
23044
23607
|
});
|
|
23045
23608
|
|
|
23046
23609
|
// src/connectors/oauth.ts
|
|
23047
|
-
import { createHash as
|
|
23610
|
+
import { createHash as createHash4, randomBytes } from "crypto";
|
|
23048
23611
|
var PENDING_TTL_MS = 10 * 60 * 1e3;
|
|
23049
23612
|
var InMemoryOAuthFlowStore = class {
|
|
23050
23613
|
pendingFlows = /* @__PURE__ */ new Map();
|
|
@@ -23072,7 +23635,7 @@ function startOAuthFlow(input) {
|
|
|
23072
23635
|
const now = input.now ?? Date.now();
|
|
23073
23636
|
store.sweep?.(now);
|
|
23074
23637
|
const codeVerifier = base64Url(randomBytes(48));
|
|
23075
|
-
const codeChallenge = base64Url(
|
|
23638
|
+
const codeChallenge = base64Url(createHash4("sha256").update(codeVerifier).digest());
|
|
23076
23639
|
const state = base64Url(randomBytes(24));
|
|
23077
23640
|
store.put(state, {
|
|
23078
23641
|
codeVerifier,
|
|
@@ -24991,11 +25554,11 @@ var googleCloudStorageConnector = declarativeRestConnector({
|
|
|
24991
25554
|
});
|
|
24992
25555
|
|
|
24993
25556
|
// src/connectors/adapters/google-pubsub.ts
|
|
24994
|
-
import { createHash as
|
|
25557
|
+
import { createHash as createHash5, createSign } from "crypto";
|
|
24995
25558
|
var TOKEN_URL3 = "https://oauth2.googleapis.com/token";
|
|
24996
25559
|
var API_ROOT = "https://pubsub.googleapis.com/v1";
|
|
24997
25560
|
var PUBSUB_SCOPE = "https://www.googleapis.com/auth/pubsub";
|
|
24998
|
-
var
|
|
25561
|
+
var MAX_RESPONSE_BYTES4 = 8 * 1024 * 1024;
|
|
24999
25562
|
var MAX_REQUEST_BYTES = 1e7;
|
|
25000
25563
|
var MAX_TOKEN_CACHE_ENTRIES = 256;
|
|
25001
25564
|
var tokenCache = /* @__PURE__ */ new Map();
|
|
@@ -25016,14 +25579,14 @@ var googlePubSubConnector = {
|
|
|
25016
25579
|
defaultConsistencyModel: "advisory",
|
|
25017
25580
|
rateLimit: { requests: 600, windowMs: 6e4, scope: "data-source" },
|
|
25018
25581
|
capabilities: [
|
|
25019
|
-
|
|
25582
|
+
readCapability4("topics.list", "List topics in the service account project.", {
|
|
25020
25583
|
pageSize: { type: "integer", minimum: 1, maximum: 1e3 },
|
|
25021
25584
|
pageToken: { type: "string" }
|
|
25022
25585
|
}),
|
|
25023
|
-
|
|
25586
|
+
readCapability4("topics.get", "Get one topic and its server-side configuration.", {
|
|
25024
25587
|
topic: { type: "string", description: "Topic ID in the service account project." }
|
|
25025
25588
|
}, ["topic"]),
|
|
25026
|
-
|
|
25589
|
+
mutationCapability4("topics.create", "Create a topic in the service account project.", {
|
|
25027
25590
|
topic: { type: "string" },
|
|
25028
25591
|
labels: { type: "object", additionalProperties: { type: "string" } },
|
|
25029
25592
|
allowedPersistenceRegions: { type: "array", items: { type: "string" } },
|
|
@@ -25031,10 +25594,10 @@ var googlePubSubConnector = {
|
|
|
25031
25594
|
schema: { type: "string", description: "Full Pub/Sub schema resource name." },
|
|
25032
25595
|
schemaEncoding: { type: "string", enum: ["JSON", "BINARY"] }
|
|
25033
25596
|
}, ["topic"]),
|
|
25034
|
-
|
|
25597
|
+
mutationCapability4("topics.delete", "Delete a topic. Existing subscriptions remain but stop receiving messages.", {
|
|
25035
25598
|
topic: { type: "string" }
|
|
25036
25599
|
}, ["topic"]),
|
|
25037
|
-
|
|
25600
|
+
mutationCapability4("messages.publish", "Publish up to 1,000 messages to a topic.", {
|
|
25038
25601
|
topic: { type: "string" },
|
|
25039
25602
|
messages: {
|
|
25040
25603
|
type: "array",
|
|
@@ -25043,14 +25606,14 @@ var googlePubSubConnector = {
|
|
|
25043
25606
|
description: "Messages with either text (UTF-8) or data (base64), plus optional string attributes and orderingKey."
|
|
25044
25607
|
}
|
|
25045
25608
|
}, ["topic", "messages"]),
|
|
25046
|
-
|
|
25609
|
+
readCapability4("subscriptions.list", "List subscriptions in the service account project.", {
|
|
25047
25610
|
pageSize: { type: "integer", minimum: 1, maximum: 1e3 },
|
|
25048
25611
|
pageToken: { type: "string" }
|
|
25049
25612
|
}),
|
|
25050
|
-
|
|
25613
|
+
readCapability4("subscriptions.get", "Get one subscription and its delivery configuration.", {
|
|
25051
25614
|
subscription: { type: "string" }
|
|
25052
25615
|
}, ["subscription"]),
|
|
25053
|
-
|
|
25616
|
+
mutationCapability4("subscriptions.create", "Create a pull subscription for a topic.", {
|
|
25054
25617
|
subscription: { type: "string" },
|
|
25055
25618
|
topic: { type: "string" },
|
|
25056
25619
|
ackDeadlineSeconds: { type: "integer", minimum: 10, maximum: 600 },
|
|
@@ -25066,18 +25629,18 @@ var googlePubSubConnector = {
|
|
|
25066
25629
|
enableExactlyOnceDelivery: { type: "boolean" },
|
|
25067
25630
|
labels: { type: "object", additionalProperties: { type: "string" } }
|
|
25068
25631
|
}, ["subscription", "topic"]),
|
|
25069
|
-
|
|
25632
|
+
mutationCapability4("subscriptions.delete", "Delete a subscription and discard its retained messages.", {
|
|
25070
25633
|
subscription: { type: "string" }
|
|
25071
25634
|
}, ["subscription"]),
|
|
25072
|
-
|
|
25635
|
+
mutationCapability4("messages.pull", "Pull messages and make them temporarily unavailable to other subscribers.", {
|
|
25073
25636
|
subscription: { type: "string" },
|
|
25074
25637
|
maxMessages: { type: "integer", minimum: 1, maximum: 1e3 }
|
|
25075
25638
|
}, ["subscription", "maxMessages"]),
|
|
25076
|
-
|
|
25639
|
+
mutationCapability4("messages.acknowledge", "Acknowledge delivered messages by ack ID.", {
|
|
25077
25640
|
subscription: { type: "string" },
|
|
25078
25641
|
ackIds: { type: "array", minItems: 1, maxItems: 1e3, items: { type: "string" } }
|
|
25079
25642
|
}, ["subscription", "ackIds"]),
|
|
25080
|
-
|
|
25643
|
+
mutationCapability4("messages.modifyAckDeadline", "Change the acknowledgement deadline for delivered messages.", {
|
|
25081
25644
|
subscription: { type: "string" },
|
|
25082
25645
|
ackIds: { type: "array", minItems: 1, maxItems: 1e3, items: { type: "string" } },
|
|
25083
25646
|
ackDeadlineSeconds: { type: "integer", minimum: 0, maximum: 600 }
|
|
@@ -25115,10 +25678,10 @@ var googlePubSubConnector = {
|
|
|
25115
25678
|
if (labels) body.labels = labels;
|
|
25116
25679
|
const regions2 = optionalStringArray(inv.args.allowedPersistenceRegions, "allowedPersistenceRegions");
|
|
25117
25680
|
if (regions2) body.messageStoragePolicy = { allowedPersistenceRegions: regions2 };
|
|
25118
|
-
if (inv.args.kmsKeyName !== void 0) body.kmsKeyName =
|
|
25681
|
+
if (inv.args.kmsKeyName !== void 0) body.kmsKeyName = requiredString6(inv.args.kmsKeyName, "kmsKeyName");
|
|
25119
25682
|
if (inv.args.schema !== void 0) {
|
|
25120
25683
|
body.schemaSettings = {
|
|
25121
|
-
schema:
|
|
25684
|
+
schema: requiredString6(inv.args.schema, "schema"),
|
|
25122
25685
|
...inv.args.schemaEncoding === void 0 ? {} : { encoding: enumValue2(inv.args.schemaEncoding, "schemaEncoding", ["JSON", "BINARY"]) }
|
|
25123
25686
|
};
|
|
25124
25687
|
}
|
|
@@ -25209,7 +25772,7 @@ var googlePubSubConnector = {
|
|
|
25209
25772
|
}
|
|
25210
25773
|
}
|
|
25211
25774
|
};
|
|
25212
|
-
function
|
|
25775
|
+
function readCapability4(name, description, properties, required = []) {
|
|
25213
25776
|
return {
|
|
25214
25777
|
name,
|
|
25215
25778
|
class: "read",
|
|
@@ -25217,7 +25780,7 @@ function readCapability3(name, description, properties, required = []) {
|
|
|
25217
25780
|
parameters: { type: "object", properties, ...required.length ? { required } : {} }
|
|
25218
25781
|
};
|
|
25219
25782
|
}
|
|
25220
|
-
function
|
|
25783
|
+
function mutationCapability4(name, description, properties, required) {
|
|
25221
25784
|
return {
|
|
25222
25785
|
name,
|
|
25223
25786
|
class: "mutation",
|
|
@@ -25237,7 +25800,7 @@ function parseServiceAccountCredentials(credentials, dataSourceId) {
|
|
|
25237
25800
|
} catch {
|
|
25238
25801
|
throw new CredentialsExpired("Google Pub/Sub service-account key must be valid JSON", dataSourceId);
|
|
25239
25802
|
}
|
|
25240
|
-
if (!
|
|
25803
|
+
if (!isRecord3(parsed) || parsed.type !== "service_account") {
|
|
25241
25804
|
throw new CredentialsExpired("Google Pub/Sub requires a Google service_account key", dataSourceId);
|
|
25242
25805
|
}
|
|
25243
25806
|
const projectId = requiredCredentialString(parsed.project_id, "project_id", dataSourceId);
|
|
@@ -25255,7 +25818,7 @@ function parseServiceAccountCredentials(credentials, dataSourceId) {
|
|
|
25255
25818
|
return { projectId, clientEmail, privateKey };
|
|
25256
25819
|
}
|
|
25257
25820
|
async function accessToken(credentials, dataSourceId) {
|
|
25258
|
-
const cacheKey =
|
|
25821
|
+
const cacheKey = createHash5("sha256").update(credentials.clientEmail).update("\0").update(credentials.privateKey).digest("hex");
|
|
25259
25822
|
const cached = tokenCache.get(cacheKey);
|
|
25260
25823
|
if (cached && cached.expiresAt > Date.now() + 6e4) {
|
|
25261
25824
|
tokenCache.delete(cacheKey);
|
|
@@ -25297,8 +25860,8 @@ async function exchangeAccessToken(credentials, dataSourceId, cacheKey) {
|
|
|
25297
25860
|
body: form2
|
|
25298
25861
|
});
|
|
25299
25862
|
const body = await readJson(response, 64 * 1024);
|
|
25300
|
-
if (!response.ok || !
|
|
25301
|
-
const reason =
|
|
25863
|
+
if (!response.ok || !isRecord3(body) || typeof body.access_token !== "string" || body.access_token.trim() === "") {
|
|
25864
|
+
const reason = isRecord3(body) && typeof body.error === "string" ? body.error : void 0;
|
|
25302
25865
|
throw new CredentialsExpired("Google rejected the Pub/Sub service-account grant", dataSourceId, {
|
|
25303
25866
|
status: response.status,
|
|
25304
25867
|
reason,
|
|
@@ -25334,9 +25897,9 @@ async function pubSubRequest(credentials, inv, method, path, query2, body) {
|
|
|
25334
25897
|
},
|
|
25335
25898
|
body: serialized
|
|
25336
25899
|
});
|
|
25337
|
-
const responseBody = await readJson(response,
|
|
25900
|
+
const responseBody = await readJson(response, MAX_RESPONSE_BYTES4);
|
|
25338
25901
|
if (response.ok) return responseBody;
|
|
25339
|
-
const providerError =
|
|
25902
|
+
const providerError = isRecord3(responseBody) && isRecord3(responseBody.error) ? responseBody.error : void 0;
|
|
25340
25903
|
const reason = providerError && typeof providerError.status === "string" ? providerError.status : void 0;
|
|
25341
25904
|
if (response.status === 401) {
|
|
25342
25905
|
throw new CredentialsExpired("Google Pub/Sub credentials were rejected", inv.source.id, {
|
|
@@ -25357,7 +25920,7 @@ async function pubSubRequest(credentials, inv, method, path, query2, body) {
|
|
|
25357
25920
|
status: response.status,
|
|
25358
25921
|
reason,
|
|
25359
25922
|
body: responseBody,
|
|
25360
|
-
retryAfterMs:
|
|
25923
|
+
retryAfterMs: retryAfterMs5(response.headers.get("retry-after"))
|
|
25361
25924
|
});
|
|
25362
25925
|
}
|
|
25363
25926
|
const message = providerError && typeof providerError.message === "string" ? providerError.message : `HTTP ${response.status}`;
|
|
@@ -25373,7 +25936,7 @@ function subscriptionPath(credentials, value) {
|
|
|
25373
25936
|
return `${projectPath(credentials, "subscriptions")}/${encodeURIComponent(resourceId(value, "subscription"))}`;
|
|
25374
25937
|
}
|
|
25375
25938
|
function resourceId(value, field) {
|
|
25376
|
-
const id2 =
|
|
25939
|
+
const id2 = requiredString6(value, field);
|
|
25377
25940
|
if (!/^[A-Za-z][A-Za-z0-9._~+%-]{2,254}$/.test(id2) || id2.toLowerCase().startsWith("goog")) {
|
|
25378
25941
|
throw new Error(`${field} must be a valid Pub/Sub resource ID`);
|
|
25379
25942
|
}
|
|
@@ -25382,7 +25945,7 @@ function resourceId(value, field) {
|
|
|
25382
25945
|
function pagination(args) {
|
|
25383
25946
|
const query2 = new URLSearchParams();
|
|
25384
25947
|
if (args.pageSize !== void 0) query2.set("pageSize", String(boundedInteger2(args.pageSize, "pageSize", 1, 1e3)));
|
|
25385
|
-
if (args.pageToken !== void 0) query2.set("pageToken",
|
|
25948
|
+
if (args.pageToken !== void 0) query2.set("pageToken", requiredString6(args.pageToken, "pageToken"));
|
|
25386
25949
|
return query2;
|
|
25387
25950
|
}
|
|
25388
25951
|
function subscriptionBody(credentials, args) {
|
|
@@ -25391,7 +25954,7 @@ function subscriptionBody(credentials, args) {
|
|
|
25391
25954
|
setOptionalBoolean(body, "retainAckedMessages", args.retainAckedMessages);
|
|
25392
25955
|
setOptionalDuration(body, "messageRetentionDuration", args.messageRetentionDuration);
|
|
25393
25956
|
if (args.expirationTtl !== void 0) body.expirationPolicy = { ttl: duration(args.expirationTtl, "expirationTtl") };
|
|
25394
|
-
if (args.filter !== void 0) body.filter =
|
|
25957
|
+
if (args.filter !== void 0) body.filter = requiredString6(args.filter, "filter");
|
|
25395
25958
|
if (args.deadLetterTopic !== void 0) {
|
|
25396
25959
|
body.deadLetterPolicy = {
|
|
25397
25960
|
deadLetterTopic: topicPath(credentials, args.deadLetterTopic),
|
|
@@ -25417,7 +25980,7 @@ function publishMessages(value) {
|
|
|
25417
25980
|
throw new Error("messages must contain 1 to 1000 entries");
|
|
25418
25981
|
}
|
|
25419
25982
|
return value.map((entry, index) => {
|
|
25420
|
-
if (!
|
|
25983
|
+
if (!isRecord3(entry)) throw new Error(`messages[${index}] must be an object`);
|
|
25421
25984
|
const hasText = typeof entry.text === "string";
|
|
25422
25985
|
const hasData = typeof entry.data === "string";
|
|
25423
25986
|
if (hasText === hasData) throw new Error(`messages[${index}] requires exactly one of text or data`);
|
|
@@ -25425,7 +25988,7 @@ function publishMessages(value) {
|
|
|
25425
25988
|
const message = { data: data4 };
|
|
25426
25989
|
const attributes = optionalStringMap(entry.attributes, `messages[${index}].attributes`);
|
|
25427
25990
|
if (attributes) message.attributes = attributes;
|
|
25428
|
-
if (entry.orderingKey !== void 0) message.orderingKey =
|
|
25991
|
+
if (entry.orderingKey !== void 0) message.orderingKey = requiredString6(entry.orderingKey, `messages[${index}].orderingKey`);
|
|
25429
25992
|
return message;
|
|
25430
25993
|
});
|
|
25431
25994
|
}
|
|
@@ -25466,7 +26029,7 @@ function requiredCredentialString(value, field, dataSourceId) {
|
|
|
25466
26029
|
}
|
|
25467
26030
|
return value.trim();
|
|
25468
26031
|
}
|
|
25469
|
-
function
|
|
26032
|
+
function requiredString6(value, field) {
|
|
25470
26033
|
if (typeof value !== "string" || value.trim() === "") throw new Error(`${field} must be a non-empty string`);
|
|
25471
26034
|
return value.trim();
|
|
25472
26035
|
}
|
|
@@ -25480,7 +26043,7 @@ function requiredStringArray(value, field, maximum) {
|
|
|
25480
26043
|
if (!Array.isArray(value) || value.length < 1 || value.length > maximum) {
|
|
25481
26044
|
throw new Error(`${field} must contain 1 to ${maximum} strings`);
|
|
25482
26045
|
}
|
|
25483
|
-
return value.map((entry, index) =>
|
|
26046
|
+
return value.map((entry, index) => requiredString6(entry, `${field}[${index}]`));
|
|
25484
26047
|
}
|
|
25485
26048
|
function optionalStringArray(value, field) {
|
|
25486
26049
|
if (value === void 0) return void 0;
|
|
@@ -25488,12 +26051,12 @@ function optionalStringArray(value, field) {
|
|
|
25488
26051
|
}
|
|
25489
26052
|
function optionalStringMap(value, field) {
|
|
25490
26053
|
if (value === void 0) return void 0;
|
|
25491
|
-
if (!
|
|
26054
|
+
if (!isRecord3(value)) throw new Error(`${field} must be an object of strings`);
|
|
25492
26055
|
const entries = Object.entries(value);
|
|
25493
26056
|
if (entries.length > 64) throw new Error(`${field} cannot contain more than 64 entries`);
|
|
25494
26057
|
return Object.fromEntries(entries.map(([key, entry]) => [
|
|
25495
|
-
|
|
25496
|
-
|
|
26058
|
+
requiredString6(key, `${field} key`),
|
|
26059
|
+
requiredString6(entry, `${field}.${key}`)
|
|
25497
26060
|
]));
|
|
25498
26061
|
}
|
|
25499
26062
|
function setOptionalInteger(body, key, value, minimum, maximum) {
|
|
@@ -25508,7 +26071,7 @@ function setOptionalDuration(body, key, value) {
|
|
|
25508
26071
|
if (value !== void 0) body[key] = duration(value, key);
|
|
25509
26072
|
}
|
|
25510
26073
|
function duration(value, field) {
|
|
25511
|
-
const parsed =
|
|
26074
|
+
const parsed = requiredString6(value, field);
|
|
25512
26075
|
if (!/^\d+(?:\.\d{1,9})?s$/.test(parsed)) throw new Error(`${field} must be a protobuf duration ending in s`);
|
|
25513
26076
|
return parsed;
|
|
25514
26077
|
}
|
|
@@ -25527,14 +26090,14 @@ function strictBase642(value, field) {
|
|
|
25527
26090
|
function base64UrlJson(value) {
|
|
25528
26091
|
return Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
|
|
25529
26092
|
}
|
|
25530
|
-
function
|
|
26093
|
+
function retryAfterMs5(value) {
|
|
25531
26094
|
if (!value) return 6e4;
|
|
25532
26095
|
const seconds = Number(value);
|
|
25533
26096
|
if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1e3;
|
|
25534
26097
|
const date = Date.parse(value);
|
|
25535
26098
|
return Number.isFinite(date) ? Math.max(0, date - Date.now()) : 6e4;
|
|
25536
26099
|
}
|
|
25537
|
-
function
|
|
26100
|
+
function isRecord3(value) {
|
|
25538
26101
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25539
26102
|
}
|
|
25540
26103
|
|
|
@@ -26184,8 +26747,8 @@ async function getDocument(inv, accessToken4, timeoutMs) {
|
|
|
26184
26747
|
};
|
|
26185
26748
|
}
|
|
26186
26749
|
async function createDocument(inv, accessToken4, timeoutMs) {
|
|
26187
|
-
const { title, body } = inv.args ?? {};
|
|
26188
|
-
if (!
|
|
26750
|
+
const { title: title2, body } = inv.args ?? {};
|
|
26751
|
+
if (!title2 || typeof title2 !== "string") {
|
|
26189
26752
|
throw new Error("google-docs create_document: title is required");
|
|
26190
26753
|
}
|
|
26191
26754
|
const createRes = await fetch(`${API2}/documents`, {
|
|
@@ -26194,7 +26757,7 @@ async function createDocument(inv, accessToken4, timeoutMs) {
|
|
|
26194
26757
|
authorization: `Bearer ${accessToken4}`,
|
|
26195
26758
|
"content-type": "application/json"
|
|
26196
26759
|
},
|
|
26197
|
-
body: JSON.stringify({ title }),
|
|
26760
|
+
body: JSON.stringify({ title: title2 }),
|
|
26198
26761
|
signal: AbortSignal.timeout(timeoutMs)
|
|
26199
26762
|
});
|
|
26200
26763
|
if (!createRes.ok) {
|
|
@@ -27223,9 +27786,9 @@ async function getResponse(inv, accessToken4, timeoutMs) {
|
|
|
27223
27786
|
};
|
|
27224
27787
|
}
|
|
27225
27788
|
async function createForm(inv, accessToken4, timeoutMs) {
|
|
27226
|
-
const { title, documentTitle } = inv.args ?? {};
|
|
27227
|
-
if (!
|
|
27228
|
-
const info = { title };
|
|
27789
|
+
const { title: title2, documentTitle } = inv.args ?? {};
|
|
27790
|
+
if (!title2) throw new Error("google-forms create_form: title is required");
|
|
27791
|
+
const info = { title: title2 };
|
|
27229
27792
|
if (documentTitle) info.documentTitle = documentTitle;
|
|
27230
27793
|
const res = await fetch(`${API4}/forms`, {
|
|
27231
27794
|
method: "POST",
|
|
@@ -27310,7 +27873,7 @@ async function ensureFreshAccessToken5(creds, clientId, clientSecret) {
|
|
|
27310
27873
|
}
|
|
27311
27874
|
|
|
27312
27875
|
// src/connectors/adapters/google-sheets.ts
|
|
27313
|
-
import { createHash as
|
|
27876
|
+
import { createHash as createHash6 } from "crypto";
|
|
27314
27877
|
var SCOPES5 = ["https://www.googleapis.com/auth/spreadsheets"];
|
|
27315
27878
|
var AUTH_URL6 = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
27316
27879
|
var TOKEN_URL7 = "https://oauth2.googleapis.com/token";
|
|
@@ -27583,7 +28146,7 @@ async function fetchAllRows(accessToken4, meta) {
|
|
|
27583
28146
|
function rowFingerprint(values) {
|
|
27584
28147
|
const keys = Object.keys(values).sort();
|
|
27585
28148
|
const blob = keys.map((k) => `${k}=${values[k]}`).join("");
|
|
27586
|
-
return
|
|
28149
|
+
return createHash6("sha256").update(blob).digest("hex").slice(0, 16);
|
|
27587
28150
|
}
|
|
27588
28151
|
function matchesPredicate(row, predicate) {
|
|
27589
28152
|
for (const [k, v] of Object.entries(predicate)) {
|
|
@@ -28437,7 +29000,7 @@ var granolaConnector = declarativeRestConnector({
|
|
|
28437
29000
|
});
|
|
28438
29001
|
|
|
28439
29002
|
// src/connectors/adapters/hellosign.ts
|
|
28440
|
-
import { createHmac as createHmac5, timingSafeEqual as
|
|
29003
|
+
import { createHmac as createHmac5, timingSafeEqual as timingSafeEqual3 } from "crypto";
|
|
28441
29004
|
var SCOPES6 = [
|
|
28442
29005
|
"basic_account_info",
|
|
28443
29006
|
"request_signature",
|
|
@@ -28664,7 +29227,7 @@ function hellosign(opts) {
|
|
|
28664
29227
|
const a = Buffer.from(event.event_hash.toLowerCase(), "utf-8");
|
|
28665
29228
|
const b = Buffer.from(expected.toLowerCase(), "utf-8");
|
|
28666
29229
|
if (a.length !== b.length) return { valid: false, reason: "invalid_signature" };
|
|
28667
|
-
return
|
|
29230
|
+
return timingSafeEqual3(a, b) ? { valid: true } : { valid: false, reason: "invalid_signature" };
|
|
28668
29231
|
},
|
|
28669
29232
|
async handleInboundEvent({ rawBody }) {
|
|
28670
29233
|
const parsed = parseInboundBody(rawBody);
|
|
@@ -29682,7 +30245,7 @@ var ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
|
29682
30245
|
var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
|
|
29683
30246
|
var MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
29684
30247
|
var MAX_TIMEOUT_MS = 6e4;
|
|
29685
|
-
var
|
|
30248
|
+
var DEFAULT_TIMEOUT_MS2 = 15e3;
|
|
29686
30249
|
var httpConnector = {
|
|
29687
30250
|
manifest: {
|
|
29688
30251
|
kind: "http",
|
|
@@ -29717,7 +30280,7 @@ var httpConnector = {
|
|
|
29717
30280
|
},
|
|
29718
30281
|
timeoutMs: {
|
|
29719
30282
|
type: "number",
|
|
29720
|
-
description: `Per-request timeout in milliseconds. Defaults to ${
|
|
30283
|
+
description: `Per-request timeout in milliseconds. Defaults to ${DEFAULT_TIMEOUT_MS2}, capped at ${MAX_TIMEOUT_MS}.`
|
|
29721
30284
|
}
|
|
29722
30285
|
},
|
|
29723
30286
|
required: ["url"]
|
|
@@ -29751,7 +30314,7 @@ var httpConnector = {
|
|
|
29751
30314
|
},
|
|
29752
30315
|
timeoutMs: {
|
|
29753
30316
|
type: "number",
|
|
29754
|
-
description: `Per-request timeout in milliseconds. Defaults to ${
|
|
30317
|
+
description: `Per-request timeout in milliseconds. Defaults to ${DEFAULT_TIMEOUT_MS2}, capped at ${MAX_TIMEOUT_MS}.`
|
|
29755
30318
|
}
|
|
29756
30319
|
},
|
|
29757
30320
|
required: ["url"]
|
|
@@ -29852,7 +30415,7 @@ function readMethod(value, fallback, allowed, capability) {
|
|
|
29852
30415
|
return upper;
|
|
29853
30416
|
}
|
|
29854
30417
|
function readTimeout(value) {
|
|
29855
|
-
if (value === void 0 || value === null) return
|
|
30418
|
+
if (value === void 0 || value === null) return DEFAULT_TIMEOUT_MS2;
|
|
29856
30419
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
29857
30420
|
throw new Error("http.timeoutMs must be a positive finite number");
|
|
29858
30421
|
}
|
|
@@ -38406,9 +38969,9 @@ var NOTION_SPEC = {
|
|
|
38406
38969
|
]
|
|
38407
38970
|
};
|
|
38408
38971
|
async function databasesUpdate(inv) {
|
|
38409
|
-
const { title, properties } = inv.args;
|
|
38972
|
+
const { title: title2, properties } = inv.args;
|
|
38410
38973
|
const body = {};
|
|
38411
|
-
if (
|
|
38974
|
+
if (title2 !== void 0) body.title = "{title}";
|
|
38412
38975
|
if (properties !== void 0) body.properties = "{properties}";
|
|
38413
38976
|
const response = await executeRestRequest(
|
|
38414
38977
|
NOTION_SPEC,
|
|
@@ -43075,7 +43638,7 @@ var ringcentralConnector = declarativeRestConnector({
|
|
|
43075
43638
|
var ALLOWED_SCHEMES2 = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
43076
43639
|
var DEFAULT_LIMIT = 20;
|
|
43077
43640
|
var MAX_LIMIT = 200;
|
|
43078
|
-
var
|
|
43641
|
+
var DEFAULT_TIMEOUT_MS3 = 15e3;
|
|
43079
43642
|
var MAX_BODY_BYTES = 5 * 1024 * 1024;
|
|
43080
43643
|
var READ_CAPABILITIES = [
|
|
43081
43644
|
{
|
|
@@ -43138,12 +43701,12 @@ var rssConnector = {
|
|
|
43138
43701
|
accept: "application/rss+xml, application/atom+xml, application/xml;q=0.9, text/xml;q=0.8, */*;q=0.1",
|
|
43139
43702
|
"user-agent": "tangle-agent-integrations-rss/1.0"
|
|
43140
43703
|
},
|
|
43141
|
-
signal: AbortSignal.timeout(
|
|
43704
|
+
signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS3)
|
|
43142
43705
|
});
|
|
43143
43706
|
if (!res.ok) {
|
|
43144
43707
|
throw new Error(`rss fetch ${res.status} ${res.statusText} for ${url.toString()}`);
|
|
43145
43708
|
}
|
|
43146
|
-
const body = await
|
|
43709
|
+
const body = await readBoundedText2(res, MAX_BODY_BYTES);
|
|
43147
43710
|
const parsed = parseFeed(body, url.toString());
|
|
43148
43711
|
const filtered = filterAndLimit(parsed.entries, since, limit);
|
|
43149
43712
|
const data4 = {
|
|
@@ -43223,7 +43786,7 @@ function readSinceMs(value) {
|
|
|
43223
43786
|
}
|
|
43224
43787
|
return ms;
|
|
43225
43788
|
}
|
|
43226
|
-
async function
|
|
43789
|
+
async function readBoundedText2(res, maxBytes) {
|
|
43227
43790
|
const reader = res.body?.getReader();
|
|
43228
43791
|
if (!reader) return await res.text();
|
|
43229
43792
|
const decoder = new TextDecoder("utf-8", { fatal: false });
|
|
@@ -43282,7 +43845,7 @@ function parseRss(text) {
|
|
|
43282
43845
|
const entries = items.map((item) => {
|
|
43283
43846
|
const guid = firstTagText(item, "guid");
|
|
43284
43847
|
const link = firstTagText(item, "link");
|
|
43285
|
-
const
|
|
43848
|
+
const title2 = firstTagText(item, "title");
|
|
43286
43849
|
const description = firstTagText(item, "description");
|
|
43287
43850
|
const contentEncoded = firstTagText(item, "content:encoded");
|
|
43288
43851
|
const pubDate = firstTagText(item, "pubDate");
|
|
@@ -43291,7 +43854,7 @@ function parseRss(text) {
|
|
|
43291
43854
|
const id2 = decodeXml3(guid) ?? decodeXml3(link) ?? hash(item);
|
|
43292
43855
|
return {
|
|
43293
43856
|
id: id2,
|
|
43294
|
-
title: decodeXml3(
|
|
43857
|
+
title: decodeXml3(title2),
|
|
43295
43858
|
link: decodeXml3(link),
|
|
43296
43859
|
summary: decodeXml3(description),
|
|
43297
43860
|
content: decodeXml3(contentEncoded),
|
|
@@ -43311,7 +43874,7 @@ function parseAtom(text, feedUrl) {
|
|
|
43311
43874
|
const items = collectElements(feedOuter, "entry");
|
|
43312
43875
|
const entries = items.map((item) => {
|
|
43313
43876
|
const id2 = decodeXml3(firstTagText(item, "id"));
|
|
43314
|
-
const
|
|
43877
|
+
const title2 = decodeXml3(firstTagText(item, "title"));
|
|
43315
43878
|
const summary = decodeXml3(firstTagText(item, "summary"));
|
|
43316
43879
|
const contentNode = firstTagText(item, "content");
|
|
43317
43880
|
const published = normalizeDate(decodeXml3(firstTagText(item, "published")));
|
|
@@ -43321,7 +43884,7 @@ function parseAtom(text, feedUrl) {
|
|
|
43321
43884
|
const categories = collectAtomCategories(item);
|
|
43322
43885
|
return {
|
|
43323
43886
|
id: id2 ?? link ?? hash(item),
|
|
43324
|
-
title,
|
|
43887
|
+
title: title2,
|
|
43325
43888
|
link,
|
|
43326
43889
|
summary,
|
|
43327
43890
|
content: decodeXml3(contentNode),
|
|
@@ -46024,7 +46587,7 @@ async function downloadFile(inv, accessToken4) {
|
|
|
46024
46587
|
`slack download_file: file exceeds the ${MAX_INLINE_FILE_BYTES} byte inline limit`
|
|
46025
46588
|
);
|
|
46026
46589
|
}
|
|
46027
|
-
const bytes = await
|
|
46590
|
+
const bytes = await readBoundedBody2(response, MAX_INLINE_FILE_BYTES);
|
|
46028
46591
|
return {
|
|
46029
46592
|
data: {
|
|
46030
46593
|
id: fileId,
|
|
@@ -46044,7 +46607,7 @@ function isSlackPrivateFileUrl(value) {
|
|
|
46044
46607
|
return false;
|
|
46045
46608
|
}
|
|
46046
46609
|
}
|
|
46047
|
-
async function
|
|
46610
|
+
async function readBoundedBody2(response, limitBytes) {
|
|
46048
46611
|
if (!response.body) return new Uint8Array();
|
|
46049
46612
|
const reader = response.body.getReader();
|
|
46050
46613
|
const chunks = [];
|
|
@@ -53227,17 +53790,17 @@ var zohoBookingsConnector = {
|
|
|
53227
53790
|
category: "calendar",
|
|
53228
53791
|
defaultConsistencyModel: "authoritative",
|
|
53229
53792
|
capabilities: [
|
|
53230
|
-
|
|
53231
|
-
|
|
53793
|
+
readCapability5("workspaces.list", "List Zoho Bookings workspaces.", {}),
|
|
53794
|
+
readCapability5("services.list", "List services, optionally within one workspace.", {
|
|
53232
53795
|
workspace_id: { type: "string" }
|
|
53233
53796
|
}),
|
|
53234
|
-
|
|
53797
|
+
readCapability5("resources.list", "List bookable resources, optionally for one service.", {
|
|
53235
53798
|
service_id: { type: "string" }
|
|
53236
53799
|
}),
|
|
53237
|
-
|
|
53800
|
+
readCapability5("staff.list", "List staff, optionally for one service.", {
|
|
53238
53801
|
service_id: { type: "string" }
|
|
53239
53802
|
}),
|
|
53240
|
-
|
|
53803
|
+
readCapability5("appointments.list", "List appointments from a required start time.", {
|
|
53241
53804
|
from_time: {
|
|
53242
53805
|
type: "string",
|
|
53243
53806
|
description: "Zoho timestamp in dd-MMM-yyyy HH:mm:ss format."
|
|
@@ -53247,17 +53810,17 @@ var zohoBookingsConnector = {
|
|
|
53247
53810
|
staff_id: { type: "string" },
|
|
53248
53811
|
status: { type: "string" }
|
|
53249
53812
|
}, ["from_time"]),
|
|
53250
|
-
|
|
53813
|
+
readCapability5("appointments.get", "Read one appointment by booking id.", {
|
|
53251
53814
|
booking_id: { type: "string" }
|
|
53252
53815
|
}, ["booking_id"]),
|
|
53253
|
-
|
|
53816
|
+
readCapability5("availability.fetch", "Fetch open time slots for a service and date.", {
|
|
53254
53817
|
service_id: { type: "string" },
|
|
53255
53818
|
selected_date: { type: "string", description: "Date in YYYY-MM-DD format." },
|
|
53256
53819
|
staff_id: { type: "string" },
|
|
53257
53820
|
group_id: { type: "string" },
|
|
53258
53821
|
resource_id: { type: "string" }
|
|
53259
53822
|
}, ["service_id", "selected_date"]),
|
|
53260
|
-
|
|
53823
|
+
mutationCapability5("appointments.book", "Book an appointment for a customer.", {
|
|
53261
53824
|
service_id: { type: "string" },
|
|
53262
53825
|
from_time: { type: "string", description: "Zoho timestamp in dd-MMM-yyyy HH:mm:ss format." },
|
|
53263
53826
|
customer_details: {
|
|
@@ -53273,13 +53836,13 @@ var zohoBookingsConnector = {
|
|
|
53273
53836
|
additional_fields: { type: "object" },
|
|
53274
53837
|
payment_info: { type: "object" }
|
|
53275
53838
|
}, ["service_id", "from_time", "customer_details"]),
|
|
53276
|
-
|
|
53839
|
+
mutationCapability5("appointments.reschedule", "Move an appointment to a new time, staff member, or group.", {
|
|
53277
53840
|
booking_id: { type: "string" },
|
|
53278
53841
|
start_time: { type: "string", description: "Zoho timestamp in dd-MMM-yyyy HH:mm:ss format." },
|
|
53279
53842
|
staff_id: { type: "string" },
|
|
53280
53843
|
group_id: { type: "string" }
|
|
53281
53844
|
}, ["booking_id"]),
|
|
53282
|
-
|
|
53845
|
+
mutationCapability5("appointments.cancel", "Cancel an appointment by booking id.", {
|
|
53283
53846
|
booking_id: { type: "string" }
|
|
53284
53847
|
}, ["booking_id"])
|
|
53285
53848
|
]
|
|
@@ -53396,7 +53959,7 @@ var zohoBookingsConnector = {
|
|
|
53396
53959
|
}
|
|
53397
53960
|
}
|
|
53398
53961
|
};
|
|
53399
|
-
function
|
|
53962
|
+
function readCapability5(name, description, properties, required = []) {
|
|
53400
53963
|
return {
|
|
53401
53964
|
name,
|
|
53402
53965
|
class: "read",
|
|
@@ -53405,7 +53968,7 @@ function readCapability4(name, description, properties, required = []) {
|
|
|
53405
53968
|
requiredScopes: ["zohobookings.data.READ"]
|
|
53406
53969
|
};
|
|
53407
53970
|
}
|
|
53408
|
-
function
|
|
53971
|
+
function mutationCapability5(name, description, properties, required) {
|
|
53409
53972
|
return {
|
|
53410
53973
|
name,
|
|
53411
53974
|
class: "mutation",
|
|
@@ -53460,7 +54023,7 @@ async function request2(source, path, options) {
|
|
|
53460
54023
|
throw new ProviderRateLimited("Zoho Bookings rate limit (429)", source.id, {
|
|
53461
54024
|
status: 429,
|
|
53462
54025
|
body: responseBody,
|
|
53463
|
-
retryAfterMs:
|
|
54026
|
+
retryAfterMs: retryAfterMs6(response.headers.get("retry-after"))
|
|
53464
54027
|
});
|
|
53465
54028
|
}
|
|
53466
54029
|
if (!response.ok) throw new Error(`zoho-bookings ${options.method} ${path} HTTP ${response.status}`);
|
|
@@ -53505,7 +54068,7 @@ function exactlyOne(args, keys, label) {
|
|
|
53505
54068
|
const present = keys.filter((key) => args[key] !== void 0 && args[key] !== null && args[key] !== "");
|
|
53506
54069
|
if (present.length !== 1) throw new Error(`zoho-bookings: exactly one ${label} is required`);
|
|
53507
54070
|
}
|
|
53508
|
-
function
|
|
54071
|
+
function retryAfterMs6(value) {
|
|
53509
54072
|
if (!value) return 6e4;
|
|
53510
54073
|
const seconds = Number(value);
|
|
53511
54074
|
return Number.isFinite(seconds) && seconds >= 0 ? Math.max(1e3, seconds * 1e3) : 6e4;
|
|
@@ -54644,11 +55207,11 @@ async function request3(source, path, options) {
|
|
|
54644
55207
|
});
|
|
54645
55208
|
}
|
|
54646
55209
|
if (response.status === 429) {
|
|
54647
|
-
const
|
|
55210
|
+
const retryAfterMs7 = parseRetryAfter(response.headers.get("retry-after"));
|
|
54648
55211
|
throw new ProviderRateLimited("Zoho Campaigns rate limit (429)", source.id, {
|
|
54649
55212
|
status: 429,
|
|
54650
55213
|
body: responseBody,
|
|
54651
|
-
retryAfterMs:
|
|
55214
|
+
retryAfterMs: retryAfterMs7
|
|
54652
55215
|
});
|
|
54653
55216
|
}
|
|
54654
55217
|
if (!response.ok) {
|
|
@@ -62301,6 +62864,7 @@ var CONNECTOR_ADAPTER_FACTORIES = [
|
|
|
62301
62864
|
defineFactoryAdapter(() => amazonSqsConnector, {}),
|
|
62302
62865
|
defineFactoryAdapter(() => httpConnector, {}),
|
|
62303
62866
|
defineFactoryAdapter(() => rssConnector, {}),
|
|
62867
|
+
defineFactoryAdapter(() => chessComConnector, {}),
|
|
62304
62868
|
defineFactoryAdapter(() => zapierConnector, {}),
|
|
62305
62869
|
defineFactoryAdapter(() => makeConnector, {}),
|
|
62306
62870
|
defineFactoryAdapter(() => n8nConnector, {}),
|
|
@@ -62308,6 +62872,7 @@ var CONNECTOR_ADAPTER_FACTORIES = [
|
|
|
62308
62872
|
defineFactoryAdapter(() => googleCloudStorageConnector, googleOAuthEnvMap),
|
|
62309
62873
|
defineFactoryAdapter(() => googlePubSubConnector, {}),
|
|
62310
62874
|
defineFactoryAdapter(() => azureBlobStorageConnector, {}),
|
|
62875
|
+
defineFactoryAdapter(() => azureEventGridConnector, {}),
|
|
62311
62876
|
defineFactoryAdapter(() => azureServiceBusConnector, {}),
|
|
62312
62877
|
defineFactoryAdapter(() => backblazeConnector, {}),
|
|
62313
62878
|
defineFactoryAdapter(() => cloudinaryConnector, {}),
|
|
@@ -63082,11 +63647,11 @@ function validateOutboundStartArgs(args) {
|
|
|
63082
63647
|
assertNonEmptyString(args.agentId, "agentId", 128);
|
|
63083
63648
|
assertE164(args.toNumber, "toNumber");
|
|
63084
63649
|
assertE164(args.fromNumber, "fromNumber");
|
|
63085
|
-
if (!
|
|
63650
|
+
if (!isRecord4(args.mission)) throw new Error("phony start_outbound_call requires mission");
|
|
63086
63651
|
const mission = args.mission;
|
|
63087
63652
|
assertNonEmptyString(mission.goal, "mission.goal", 2e3);
|
|
63088
63653
|
if (mission.goal.trim().length < 8) throw new Error("phony start_outbound_call mission.goal must be at least 8 characters");
|
|
63089
|
-
if (mission.successSchema !== void 0 && !
|
|
63654
|
+
if (mission.successSchema !== void 0 && !isRecord4(mission.successSchema)) {
|
|
63090
63655
|
throw new Error("phony start_outbound_call mission.successSchema must be an object when supplied");
|
|
63091
63656
|
}
|
|
63092
63657
|
if (mission.ivrHints !== void 0) {
|
|
@@ -63100,7 +63665,7 @@ function validateOutboundStartArgs(args) {
|
|
|
63100
63665
|
if (args.missionId !== void 0) assertNonEmptyString(args.missionId, "missionId", 128);
|
|
63101
63666
|
if (args.voiceCloneId !== void 0) assertNonEmptyString(args.voiceCloneId, "voiceCloneId", 128);
|
|
63102
63667
|
if (args.callerProfile !== void 0) {
|
|
63103
|
-
if (!
|
|
63668
|
+
if (!isRecord4(args.callerProfile)) throw new Error("phony start_outbound_call callerProfile must be an object");
|
|
63104
63669
|
if (args.callerProfile.userName !== void 0) assertNonEmptyString(args.callerProfile.userName, "callerProfile.userName", 120);
|
|
63105
63670
|
if (args.callerProfile.companyName !== void 0) {
|
|
63106
63671
|
assertNonEmptyString(args.callerProfile.companyName, "callerProfile.companyName", 120);
|
|
@@ -63127,7 +63692,7 @@ function assertOptionalInteger(value, field, min, max) {
|
|
|
63127
63692
|
throw new Error(`phony start_outbound_call ${field} must be an integer between ${min} and ${max}`);
|
|
63128
63693
|
}
|
|
63129
63694
|
}
|
|
63130
|
-
function
|
|
63695
|
+
function isRecord4(value) {
|
|
63131
63696
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
63132
63697
|
}
|
|
63133
63698
|
async function getJson(inv, token, url, label) {
|
|
@@ -142249,6 +142814,7 @@ export {
|
|
|
142249
142814
|
avalaraConnector,
|
|
142250
142815
|
azureAdConnector,
|
|
142251
142816
|
azureBlobStorageConnector,
|
|
142817
|
+
azureEventGridConnector,
|
|
142252
142818
|
azureServiceBusConnector,
|
|
142253
142819
|
basecampConnector,
|
|
142254
142820
|
backblazeConnector,
|
|
@@ -142274,6 +142840,7 @@ export {
|
|
|
142274
142840
|
cashfreePaymentsConnector,
|
|
142275
142841
|
circleConnector,
|
|
142276
142842
|
checkoutConnector,
|
|
142843
|
+
chessComConnector,
|
|
142277
142844
|
docuseal,
|
|
142278
142845
|
docusignConnector,
|
|
142279
142846
|
dialpadConnector,
|
|
@@ -142818,4 +143385,4 @@ export {
|
|
|
142818
143385
|
demandbaseConnector,
|
|
142819
143386
|
adapters_exports
|
|
142820
143387
|
};
|
|
142821
|
-
//# sourceMappingURL=chunk-
|
|
143388
|
+
//# sourceMappingURL=chunk-4H5F6E7W.js.map
|