@zapier/zapier-sdk 0.81.1 → 0.82.1
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/CHANGELOG.md +12 -0
- package/README.md +38 -40
- package/dist/experimental.cjs +3504 -3440
- package/dist/experimental.d.mts +2 -6
- package/dist/experimental.d.ts +2 -6
- package/dist/experimental.mjs +3504 -3440
- package/dist/{index-CWi_XjB4.d.mts → index-BEIqfOJR.d.mts} +3352 -1519
- package/dist/{index-CWi_XjB4.d.ts → index-BEIqfOJR.d.ts} +3352 -1519
- package/dist/index.cjs +1748 -31
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1748 -31
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3140,14 +3140,14 @@ var TriggerInboxCommandBaseSchema = zod.z.object({
|
|
|
3140
3140
|
"Abort signal. Aborting cancels in-flight HTTP, releases unprocessed messages, and resolves cleanly. Errors during shutdown still reject."
|
|
3141
3141
|
)
|
|
3142
3142
|
});
|
|
3143
|
-
TriggerInboxCommandBaseSchema.extend({
|
|
3143
|
+
var DrainTriggerInboxSchema = TriggerInboxCommandBaseSchema.extend({
|
|
3144
3144
|
maxMessages: zod.z.number().int().min(1).optional().describe(
|
|
3145
3145
|
"Cap total messages drained. Defaults to draining the inbox until empty."
|
|
3146
3146
|
)
|
|
3147
3147
|
}).describe(
|
|
3148
3148
|
"Drain an existing trigger inbox: lease currently-available messages and process them via onMessage. Returns when the inbox is empty, maxMessages is reached, the abort signal fires, or a fatal error rejects."
|
|
3149
3149
|
);
|
|
3150
|
-
TriggerInboxCommandBaseSchema.extend({
|
|
3150
|
+
var WatchTriggerInboxSchema = TriggerInboxCommandBaseSchema.extend({
|
|
3151
3151
|
maxDrainIntervalSeconds: zod.z.number().int().min(1).optional().describe(
|
|
3152
3152
|
"Maximum seconds between safety drain attempts (default: 300). The watcher subscribes to SSE notifications for near-real-time wake-ups; this interval is the backstop that guarantees forward progress if SSE events are missed or the connection drops undetected."
|
|
3153
3153
|
)
|
|
@@ -6785,11 +6785,11 @@ var runActionPlugin = definePlugin(
|
|
|
6785
6785
|
timeoutMs
|
|
6786
6786
|
});
|
|
6787
6787
|
if (result.errors && result.errors.length > 0) {
|
|
6788
|
-
const
|
|
6788
|
+
const errorMessage2 = result.errors.map(
|
|
6789
6789
|
(error) => error.detail || error.title || "Unknown error"
|
|
6790
6790
|
).join("; ");
|
|
6791
6791
|
throw new ZapierActionError(
|
|
6792
|
-
`Action execution failed: ${
|
|
6792
|
+
`Action execution failed: ${errorMessage2}`,
|
|
6793
6793
|
{ appKey, actionKey }
|
|
6794
6794
|
);
|
|
6795
6795
|
}
|
|
@@ -6931,6 +6931,10 @@ var ConnectionsMapSchema = zod.z.record(zod.z.string(), ConnectionEntrySchema);
|
|
|
6931
6931
|
|
|
6932
6932
|
// src/plugins/manifest/schemas.ts
|
|
6933
6933
|
var DEFAULT_CONFIG_PATH = ".zapierrc";
|
|
6934
|
+
var ManifestEntrySchema = zod.z.object({
|
|
6935
|
+
implementationName: zod.z.string().describe("Base implementation name without version (e.g., 'SlackCLIAPI')"),
|
|
6936
|
+
version: zod.z.string().describe("Version string (e.g., '1.21.1')")
|
|
6937
|
+
});
|
|
6934
6938
|
var ActionEntrySchema = zod.z.object({
|
|
6935
6939
|
appKey: zod.z.string().describe("App key (slug or implementation name)"),
|
|
6936
6940
|
actionKey: zod.z.string().describe("Action key identifier"),
|
|
@@ -6945,15 +6949,7 @@ var ActionEntrySchema = zod.z.object({
|
|
|
6945
6949
|
createdAt: zod.z.string().describe("ISO 8601 timestamp when created")
|
|
6946
6950
|
});
|
|
6947
6951
|
var ManifestSchema = zod.z.object({
|
|
6948
|
-
apps: zod.z.record(
|
|
6949
|
-
zod.z.string(),
|
|
6950
|
-
zod.z.object({
|
|
6951
|
-
implementationName: zod.z.string().describe(
|
|
6952
|
-
"Base implementation name without version (e.g., 'SlackCLIAPI')"
|
|
6953
|
-
),
|
|
6954
|
-
version: zod.z.string().describe("Version string (e.g., '1.21.1')")
|
|
6955
|
-
})
|
|
6956
|
-
).optional(),
|
|
6952
|
+
apps: zod.z.record(zod.z.string(), ManifestEntrySchema).optional(),
|
|
6957
6953
|
actions: zod.z.record(zod.z.string(), ActionEntrySchema).optional().describe("Saved action configurations with their schemas"),
|
|
6958
6954
|
canIncludeSharedConnections: zod.z.boolean().optional().describe("Allow listing shared connections"),
|
|
6959
6955
|
canIncludeSharedTables: zod.z.boolean().optional().describe("Allow listing shared tables"),
|
|
@@ -6979,22 +6975,91 @@ async function toArrayFromAsync(asyncIterable) {
|
|
|
6979
6975
|
}
|
|
6980
6976
|
|
|
6981
6977
|
// src/plugins/manifest/index.ts
|
|
6982
|
-
function
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6978
|
+
function parseManifestSection({
|
|
6979
|
+
section,
|
|
6980
|
+
raw,
|
|
6981
|
+
schema,
|
|
6982
|
+
source
|
|
6983
|
+
}) {
|
|
6984
|
+
if (raw == null) {
|
|
6985
|
+
return void 0;
|
|
6986
|
+
}
|
|
6987
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
6988
|
+
console.warn(`\u26A0\uFE0F Ignoring "${section}" in ${source}: expected an object`);
|
|
6989
|
+
return void 0;
|
|
6990
|
+
}
|
|
6991
|
+
const kept = {};
|
|
6992
|
+
for (const [key2, value] of Object.entries(raw)) {
|
|
6993
|
+
const result = schema.safeParse(value);
|
|
6989
6994
|
if (result.success) {
|
|
6990
|
-
|
|
6995
|
+
kept[key2] = result.data;
|
|
6996
|
+
} else {
|
|
6997
|
+
console.warn(
|
|
6998
|
+
`\u26A0\uFE0F Dropping invalid "${section}" entry "${key2}" in ${source}: ${result.error}`
|
|
6999
|
+
);
|
|
6991
7000
|
}
|
|
6992
|
-
|
|
6993
|
-
|
|
7001
|
+
}
|
|
7002
|
+
return kept;
|
|
7003
|
+
}
|
|
7004
|
+
var MANIFEST_FLAGS = [
|
|
7005
|
+
"canIncludeSharedConnections",
|
|
7006
|
+
"canIncludeSharedTables",
|
|
7007
|
+
"canDeleteTables"
|
|
7008
|
+
];
|
|
7009
|
+
function parseManifestContent(content, source) {
|
|
7010
|
+
let parsed;
|
|
7011
|
+
try {
|
|
7012
|
+
parsed = JSON.parse(content);
|
|
6994
7013
|
} catch (error) {
|
|
6995
7014
|
console.warn(`\u26A0\uFE0F Failed to parse manifest from ${source}:`, error);
|
|
6996
7015
|
return null;
|
|
6997
7016
|
}
|
|
7017
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
7018
|
+
return null;
|
|
7019
|
+
}
|
|
7020
|
+
const raw = parsed;
|
|
7021
|
+
const manifest = {};
|
|
7022
|
+
const apps = parseManifestSection({
|
|
7023
|
+
section: "apps",
|
|
7024
|
+
raw: raw.apps,
|
|
7025
|
+
schema: ManifestEntrySchema,
|
|
7026
|
+
source
|
|
7027
|
+
});
|
|
7028
|
+
if (apps) {
|
|
7029
|
+
manifest.apps = apps;
|
|
7030
|
+
}
|
|
7031
|
+
const actions = parseManifestSection({
|
|
7032
|
+
section: "actions",
|
|
7033
|
+
raw: raw.actions,
|
|
7034
|
+
schema: ActionEntrySchema,
|
|
7035
|
+
source
|
|
7036
|
+
});
|
|
7037
|
+
if (actions) {
|
|
7038
|
+
manifest.actions = actions;
|
|
7039
|
+
}
|
|
7040
|
+
const connections = parseManifestSection({
|
|
7041
|
+
section: "connections",
|
|
7042
|
+
raw: raw.connections,
|
|
7043
|
+
schema: ConnectionEntrySchema,
|
|
7044
|
+
source
|
|
7045
|
+
});
|
|
7046
|
+
if (connections) {
|
|
7047
|
+
manifest.connections = connections;
|
|
7048
|
+
}
|
|
7049
|
+
for (const flag of MANIFEST_FLAGS) {
|
|
7050
|
+
const value = raw[flag];
|
|
7051
|
+
if (value === void 0) {
|
|
7052
|
+
continue;
|
|
7053
|
+
}
|
|
7054
|
+
if (typeof value === "boolean") {
|
|
7055
|
+
manifest[flag] = value;
|
|
7056
|
+
} else {
|
|
7057
|
+
console.warn(
|
|
7058
|
+
`\u26A0\uFE0F Dropping invalid "${flag}" in ${source}: expected a boolean`
|
|
7059
|
+
);
|
|
7060
|
+
}
|
|
7061
|
+
}
|
|
7062
|
+
return manifest;
|
|
6998
7063
|
}
|
|
6999
7064
|
async function readManifestFromFile(filePath) {
|
|
7000
7065
|
try {
|
|
@@ -8752,7 +8817,7 @@ function parseDeprecationDate(value) {
|
|
|
8752
8817
|
}
|
|
8753
8818
|
|
|
8754
8819
|
// src/sdk-version.ts
|
|
8755
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.
|
|
8820
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.82.1" : void 0) || "unknown";
|
|
8756
8821
|
|
|
8757
8822
|
// src/utils/open-url.ts
|
|
8758
8823
|
var nodePrefix = "node:";
|
|
@@ -9456,16 +9521,16 @@ var ZapierApiClient = class {
|
|
|
9456
9521
|
if (typeof errorInfo.data === "string") {
|
|
9457
9522
|
return { message: `${fallbackMessage}: ${errorInfo.data}` };
|
|
9458
9523
|
}
|
|
9459
|
-
const
|
|
9524
|
+
const errorMessage2 = this.extractErrorMessage(errorInfo.data) || fallbackMessage;
|
|
9460
9525
|
if (this.hasErrorArray(errorInfo.data)) {
|
|
9461
9526
|
if (this.isApiErrorArray(errorInfo.data.errors)) {
|
|
9462
9527
|
return {
|
|
9463
|
-
message:
|
|
9528
|
+
message: errorMessage2,
|
|
9464
9529
|
errors: errorInfo.data.errors
|
|
9465
9530
|
};
|
|
9466
9531
|
} else {
|
|
9467
9532
|
return {
|
|
9468
|
-
message:
|
|
9533
|
+
message: errorMessage2,
|
|
9469
9534
|
errors: errorInfo.data.errors.map((e) => ({
|
|
9470
9535
|
status: errorInfo.status,
|
|
9471
9536
|
code: String(errorInfo.status),
|
|
@@ -9475,7 +9540,7 @@ var ZapierApiClient = class {
|
|
|
9475
9540
|
};
|
|
9476
9541
|
}
|
|
9477
9542
|
}
|
|
9478
|
-
return { message:
|
|
9543
|
+
return { message: errorMessage2 };
|
|
9479
9544
|
} catch {
|
|
9480
9545
|
return { message: fallbackMessage };
|
|
9481
9546
|
}
|
|
@@ -10498,6 +10563,1658 @@ var getInputFieldsSchemaDeprecatedPlugin = definePlugin(
|
|
|
10498
10563
|
}
|
|
10499
10564
|
})
|
|
10500
10565
|
);
|
|
10566
|
+
var TriggerInboxStatusSchema = zod.z.union([
|
|
10567
|
+
zod.z.enum([
|
|
10568
|
+
"initializing",
|
|
10569
|
+
"active",
|
|
10570
|
+
"paused",
|
|
10571
|
+
"deleting",
|
|
10572
|
+
"initialization_failure"
|
|
10573
|
+
]),
|
|
10574
|
+
zod.z.string()
|
|
10575
|
+
]).describe("Inbox lifecycle status");
|
|
10576
|
+
var TriggerInboxPausedReasonSchema = zod.z.union([
|
|
10577
|
+
zod.z.enum([
|
|
10578
|
+
"user",
|
|
10579
|
+
"authentication",
|
|
10580
|
+
"authentication_access_revoked",
|
|
10581
|
+
"partner_revoked",
|
|
10582
|
+
"subscribe_failed",
|
|
10583
|
+
"migrate_failed",
|
|
10584
|
+
"abandoned",
|
|
10585
|
+
"unknown",
|
|
10586
|
+
"upstream_failures"
|
|
10587
|
+
]),
|
|
10588
|
+
zod.z.string()
|
|
10589
|
+
]).describe("Why the inbox was paused, if applicable");
|
|
10590
|
+
var TriggerSubscriptionApiSchema = zod.z.object({
|
|
10591
|
+
connection_id: zod.z.union([zod.z.string(), zod.z.number(), zod.z.null()]),
|
|
10592
|
+
app_key: zod.z.string(),
|
|
10593
|
+
action_key: zod.z.string(),
|
|
10594
|
+
inputs: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
10595
|
+
});
|
|
10596
|
+
var TriggerInboxItemSchema = zod.z.object({
|
|
10597
|
+
id: zod.z.string(),
|
|
10598
|
+
created_at: zod.z.string(),
|
|
10599
|
+
// `key` is an API-layer alias over the same nullable `name` column, so it's
|
|
10600
|
+
// always present but can be null — null means no natural key (inbox created
|
|
10601
|
+
// without one, or key cleared on delete).
|
|
10602
|
+
key: zod.z.string().nullable(),
|
|
10603
|
+
/** @deprecated Use `key` instead. */
|
|
10604
|
+
name: zod.z.string().nullable(),
|
|
10605
|
+
status: TriggerInboxStatusSchema,
|
|
10606
|
+
paused_reason: TriggerInboxPausedReasonSchema.nullable(),
|
|
10607
|
+
notification_url: zod.z.string().nullable(),
|
|
10608
|
+
subscription: TriggerSubscriptionApiSchema
|
|
10609
|
+
});
|
|
10610
|
+
|
|
10611
|
+
// src/plugins/triggers/createTriggerInbox/schemas.ts
|
|
10612
|
+
var CreateTriggerInboxDescription = "Create a new trigger inbox subscription. Always creates a new inbox; use ensureTriggerInbox for get-or-create on a stable key.";
|
|
10613
|
+
var CreateTriggerInboxSchema = zod.z.object({
|
|
10614
|
+
key: TriggerInboxKeyPropertySchema.optional().describe(
|
|
10615
|
+
"Optional inbox key. Auto-generated when omitted. Throws a conflict error if the key is already in use by another subscription."
|
|
10616
|
+
),
|
|
10617
|
+
/** @deprecated Use `key` instead. */
|
|
10618
|
+
name: TriggerInboxNamePropertySchema.optional().describe(
|
|
10619
|
+
"Optional inbox name. Auto-generated when omitted. Throws a conflict error if the name is already in use by another subscription."
|
|
10620
|
+
).meta({ deprecated: true }),
|
|
10621
|
+
app: AppPropertySchema,
|
|
10622
|
+
action: ActionPropertySchema,
|
|
10623
|
+
connection: ConnectionPropertySchema.nullable().optional().describe(
|
|
10624
|
+
"Connection alias or connection ID. Optional for triggers that don't require auth."
|
|
10625
|
+
),
|
|
10626
|
+
inputs: InputsPropertySchema.optional().describe(
|
|
10627
|
+
"Input parameters for the trigger subscription"
|
|
10628
|
+
),
|
|
10629
|
+
notificationUrl: zod.z.string().url().optional().describe("Webhook URL to POST to when new messages arrive")
|
|
10630
|
+
}).describe(CreateTriggerInboxDescription);
|
|
10631
|
+
|
|
10632
|
+
// src/formatters/triggerInbox.ts
|
|
10633
|
+
var triggerInboxItemFormatter = {
|
|
10634
|
+
format: (item) => {
|
|
10635
|
+
const details = [
|
|
10636
|
+
{
|
|
10637
|
+
text: `Status: ${item.status}`,
|
|
10638
|
+
style: item.status === "active" ? "accent" : "dim"
|
|
10639
|
+
},
|
|
10640
|
+
{
|
|
10641
|
+
text: `Subscription: ${item.subscription.app_key} / ${item.subscription.action_key}`,
|
|
10642
|
+
style: "dim"
|
|
10643
|
+
}
|
|
10644
|
+
];
|
|
10645
|
+
if (item.paused_reason) {
|
|
10646
|
+
details.push({
|
|
10647
|
+
text: `Paused reason: ${item.paused_reason}`,
|
|
10648
|
+
style: "warning"
|
|
10649
|
+
});
|
|
10650
|
+
}
|
|
10651
|
+
if (item.notification_url) {
|
|
10652
|
+
details.push({
|
|
10653
|
+
text: `Notify: ${item.notification_url}`,
|
|
10654
|
+
style: "dim"
|
|
10655
|
+
});
|
|
10656
|
+
}
|
|
10657
|
+
return {
|
|
10658
|
+
title: item.key ?? item.name ?? `Trigger Inbox ${item.id}`,
|
|
10659
|
+
id: item.id,
|
|
10660
|
+
details
|
|
10661
|
+
};
|
|
10662
|
+
}
|
|
10663
|
+
};
|
|
10664
|
+
|
|
10665
|
+
// src/plugins/triggers/shared.ts
|
|
10666
|
+
var triggersDefaults = {
|
|
10667
|
+
categories: ["trigger"]
|
|
10668
|
+
};
|
|
10669
|
+
|
|
10670
|
+
// src/plugins/triggers/utils.ts
|
|
10671
|
+
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10672
|
+
async function resolveTriggerInboxId({
|
|
10673
|
+
api,
|
|
10674
|
+
inbox
|
|
10675
|
+
}) {
|
|
10676
|
+
if (UUID_REGEX.test(inbox)) {
|
|
10677
|
+
return inbox;
|
|
10678
|
+
}
|
|
10679
|
+
const rawResponse = await api.get("/trigger-inbox/api/v1/inboxes", {
|
|
10680
|
+
searchParams: { key: inbox, limit: "1" },
|
|
10681
|
+
authRequired: true
|
|
10682
|
+
});
|
|
10683
|
+
const response = rawResponse;
|
|
10684
|
+
const id = response.results?.[0]?.id;
|
|
10685
|
+
if (!id) {
|
|
10686
|
+
throw new ZapierResourceNotFoundError(
|
|
10687
|
+
`No trigger inbox with key "${inbox}" found.`,
|
|
10688
|
+
{ resourceType: "trigger_inbox", resourceId: inbox }
|
|
10689
|
+
);
|
|
10690
|
+
}
|
|
10691
|
+
return id;
|
|
10692
|
+
}
|
|
10693
|
+
function extractErrorDetail(data) {
|
|
10694
|
+
if (typeof data !== "object" || data === null) return void 0;
|
|
10695
|
+
const errors = data.errors;
|
|
10696
|
+
if (!Array.isArray(errors) || errors.length === 0) return void 0;
|
|
10697
|
+
const first = errors[0];
|
|
10698
|
+
if (typeof first !== "object" || first === null) return void 0;
|
|
10699
|
+
const detail = first.detail;
|
|
10700
|
+
return typeof detail === "string" ? detail : void 0;
|
|
10701
|
+
}
|
|
10702
|
+
|
|
10703
|
+
// src/plugins/triggers/createTriggerInbox/index.ts
|
|
10704
|
+
var createTriggerInboxPlugin = definePlugin(
|
|
10705
|
+
(sdk) => createPluginMethod(sdk, {
|
|
10706
|
+
...triggersDefaults,
|
|
10707
|
+
name: "createTriggerInbox",
|
|
10708
|
+
type: "create",
|
|
10709
|
+
itemType: "TriggerInbox",
|
|
10710
|
+
inputSchema: CreateTriggerInboxSchema,
|
|
10711
|
+
outputSchema: TriggerInboxItemSchema,
|
|
10712
|
+
formatter: triggerInboxItemFormatter,
|
|
10713
|
+
// actionKeyResolver and inputsResolver depend on actionType, which is
|
|
10714
|
+
// always "read" for triggers. Pin it as a constant resolver so it's
|
|
10715
|
+
// seeded into resolvedParams without polluting the user-facing schema
|
|
10716
|
+
// (where it would leak into the SDK method signature and CLI flags).
|
|
10717
|
+
resolvers: {
|
|
10718
|
+
key: { type: "static", inputType: "text" },
|
|
10719
|
+
app: appKeyResolver,
|
|
10720
|
+
action: actionKeyResolver,
|
|
10721
|
+
connection: connectionIdResolver,
|
|
10722
|
+
inputs: inputsResolver,
|
|
10723
|
+
actionType: { type: "constant", value: "read" }
|
|
10724
|
+
},
|
|
10725
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
10726
|
+
const { api } = sdk2.context;
|
|
10727
|
+
const {
|
|
10728
|
+
app: appKey,
|
|
10729
|
+
action: actionKey,
|
|
10730
|
+
connection,
|
|
10731
|
+
inputs = {},
|
|
10732
|
+
notificationUrl
|
|
10733
|
+
} = options;
|
|
10734
|
+
const key2 = options.key ?? options.name;
|
|
10735
|
+
const resolvedConnectionId = await resolveConnectionId({
|
|
10736
|
+
connection,
|
|
10737
|
+
resolveConnection: sdk2.context.resolveConnection
|
|
10738
|
+
});
|
|
10739
|
+
const selectedApi = await sdk2.context.getVersionedImplementationId(appKey);
|
|
10740
|
+
if (!selectedApi) {
|
|
10741
|
+
throw new ZapierConfigurationError(
|
|
10742
|
+
`No current_implementation_id found for app "${appKey}"`,
|
|
10743
|
+
{ configType: "current_implementation_id" }
|
|
10744
|
+
);
|
|
10745
|
+
}
|
|
10746
|
+
const requestBody = {
|
|
10747
|
+
subscription: {
|
|
10748
|
+
app_key: selectedApi,
|
|
10749
|
+
action_key: actionKey,
|
|
10750
|
+
inputs,
|
|
10751
|
+
connection_id: resolvedConnectionId ?? null
|
|
10752
|
+
}
|
|
10753
|
+
};
|
|
10754
|
+
if (key2 !== void 0) {
|
|
10755
|
+
requestBody.key = key2;
|
|
10756
|
+
}
|
|
10757
|
+
if (notificationUrl !== void 0) {
|
|
10758
|
+
requestBody.notification_url = notificationUrl;
|
|
10759
|
+
}
|
|
10760
|
+
const rawResponse = await api.post(
|
|
10761
|
+
"/trigger-inbox/api/v1/inboxes",
|
|
10762
|
+
requestBody,
|
|
10763
|
+
{
|
|
10764
|
+
authRequired: true,
|
|
10765
|
+
customErrorHandler: ({ status, data }) => {
|
|
10766
|
+
if (status === 409) {
|
|
10767
|
+
const detail = extractErrorDetail(data);
|
|
10768
|
+
return new ZapierConflictError(
|
|
10769
|
+
detail ?? `An inbox with key "${key2}" already exists with a different subscription.`,
|
|
10770
|
+
{ statusCode: status, resourceType: "trigger_inbox" }
|
|
10771
|
+
);
|
|
10772
|
+
}
|
|
10773
|
+
return void 0;
|
|
10774
|
+
}
|
|
10775
|
+
}
|
|
10776
|
+
);
|
|
10777
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
10778
|
+
}
|
|
10779
|
+
})
|
|
10780
|
+
);
|
|
10781
|
+
var EnsureTriggerInboxDescription = "Get-or-create a trigger inbox by key. Idempotent on (user, account, key): returns the existing inbox if a matching subscription is registered, creates a new one otherwise. Throws ZapierConflictError if the key exists with a different subscription.";
|
|
10782
|
+
var EnsureTriggerInboxBaseSchema = zod.z.object({
|
|
10783
|
+
app: AppPropertySchema,
|
|
10784
|
+
action: ActionPropertySchema,
|
|
10785
|
+
connection: ConnectionPropertySchema.nullable().optional().describe(
|
|
10786
|
+
"Connection alias or connection ID. Optional for triggers that don't require auth."
|
|
10787
|
+
),
|
|
10788
|
+
inputs: InputsPropertySchema.optional().describe(
|
|
10789
|
+
"Input parameters for the trigger subscription"
|
|
10790
|
+
),
|
|
10791
|
+
notificationUrl: zod.z.string().url().optional().describe("Webhook URL to POST to when new messages arrive")
|
|
10792
|
+
});
|
|
10793
|
+
var EnsureTriggerInboxSchema = zod.z.object({
|
|
10794
|
+
key: TriggerInboxKeyPropertySchema.describe(
|
|
10795
|
+
"Inbox key; serves as the idempotency key. Required for ensureTriggerInbox \u2014 without one, the API mints a fresh inbox each call (use createTriggerInbox for that path)."
|
|
10796
|
+
)
|
|
10797
|
+
}).merge(EnsureTriggerInboxBaseSchema).describe(EnsureTriggerInboxDescription).meta({ aliases: { name: "key" } });
|
|
10798
|
+
var EnsureTriggerInboxSchemaDeprecated = zod.z.object({
|
|
10799
|
+
name: TriggerInboxNamePropertySchema.describe(
|
|
10800
|
+
"Inbox name; serves as the idempotency key. Required for ensureTriggerInbox \u2014 without one, the API mints a fresh inbox each call (use createTriggerInbox for that path)."
|
|
10801
|
+
)
|
|
10802
|
+
}).merge(EnsureTriggerInboxBaseSchema);
|
|
10803
|
+
var EnsureTriggerInboxInputSchema = zod.z.union([EnsureTriggerInboxSchema, EnsureTriggerInboxSchemaDeprecated]).describe(EnsureTriggerInboxDescription);
|
|
10804
|
+
|
|
10805
|
+
// src/plugins/triggers/ensureTriggerInbox/index.ts
|
|
10806
|
+
var ensureTriggerInboxPlugin = definePlugin(
|
|
10807
|
+
(sdk) => createPluginMethod(sdk, {
|
|
10808
|
+
...triggersDefaults,
|
|
10809
|
+
name: "ensureTriggerInbox",
|
|
10810
|
+
type: "create",
|
|
10811
|
+
itemType: "TriggerInbox",
|
|
10812
|
+
inputSchema: EnsureTriggerInboxInputSchema,
|
|
10813
|
+
outputSchema: TriggerInboxItemSchema,
|
|
10814
|
+
formatter: triggerInboxItemFormatter,
|
|
10815
|
+
// actionKeyResolver and inputsResolver depend on actionType, which is
|
|
10816
|
+
// always "read" for triggers. Pin it as a constant resolver so it's
|
|
10817
|
+
// seeded into resolvedParams without polluting the user-facing schema.
|
|
10818
|
+
resolvers: {
|
|
10819
|
+
key: { type: "static", inputType: "text" },
|
|
10820
|
+
app: appKeyResolver,
|
|
10821
|
+
action: actionKeyResolver,
|
|
10822
|
+
connection: connectionIdResolver,
|
|
10823
|
+
inputs: inputsResolver,
|
|
10824
|
+
actionType: { type: "constant", value: "read" }
|
|
10825
|
+
},
|
|
10826
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
10827
|
+
const { api } = sdk2.context;
|
|
10828
|
+
const {
|
|
10829
|
+
app: appKey,
|
|
10830
|
+
action: actionKey,
|
|
10831
|
+
connection,
|
|
10832
|
+
inputs = {},
|
|
10833
|
+
notificationUrl
|
|
10834
|
+
} = options;
|
|
10835
|
+
const key2 = "key" in options ? options.key : options.name;
|
|
10836
|
+
const resolvedConnectionId = await resolveConnectionId({
|
|
10837
|
+
connection,
|
|
10838
|
+
resolveConnection: sdk2.context.resolveConnection
|
|
10839
|
+
});
|
|
10840
|
+
const selectedApi = await sdk2.context.getVersionedImplementationId(appKey);
|
|
10841
|
+
if (!selectedApi) {
|
|
10842
|
+
throw new ZapierConfigurationError(
|
|
10843
|
+
`No current_implementation_id found for app "${appKey}"`,
|
|
10844
|
+
{ configType: "current_implementation_id" }
|
|
10845
|
+
);
|
|
10846
|
+
}
|
|
10847
|
+
const requestBody = {
|
|
10848
|
+
key: key2,
|
|
10849
|
+
subscription: {
|
|
10850
|
+
app_key: selectedApi,
|
|
10851
|
+
action_key: actionKey,
|
|
10852
|
+
inputs,
|
|
10853
|
+
connection_id: resolvedConnectionId ?? null
|
|
10854
|
+
}
|
|
10855
|
+
};
|
|
10856
|
+
if (notificationUrl !== void 0) {
|
|
10857
|
+
requestBody.notification_url = notificationUrl;
|
|
10858
|
+
}
|
|
10859
|
+
const rawResponse = await api.put(
|
|
10860
|
+
"/trigger-inbox/api/v1/inboxes",
|
|
10861
|
+
requestBody,
|
|
10862
|
+
{
|
|
10863
|
+
authRequired: true,
|
|
10864
|
+
customErrorHandler: ({ status, data }) => {
|
|
10865
|
+
if (status === 409) {
|
|
10866
|
+
const detail = extractErrorDetail(data);
|
|
10867
|
+
return new ZapierConflictError(
|
|
10868
|
+
detail ?? `An inbox with key "${key2}" already exists with a different subscription.`,
|
|
10869
|
+
{ statusCode: status, resourceType: "trigger_inbox" }
|
|
10870
|
+
);
|
|
10871
|
+
}
|
|
10872
|
+
return void 0;
|
|
10873
|
+
}
|
|
10874
|
+
}
|
|
10875
|
+
);
|
|
10876
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
10877
|
+
}
|
|
10878
|
+
})
|
|
10879
|
+
);
|
|
10880
|
+
var ListTriggerInboxesSchema = zod.z.object({
|
|
10881
|
+
key: zod.z.string().min(1).optional().describe(
|
|
10882
|
+
"Filter by inbox key (exact match). Keys are unique per (user, account), so this returns at most one inbox."
|
|
10883
|
+
),
|
|
10884
|
+
/** @deprecated Use `key` instead. */
|
|
10885
|
+
name: zod.z.string().min(1).optional().describe(
|
|
10886
|
+
"Filter by inbox name (exact match). Names are unique per (user, account), so this returns at most one inbox."
|
|
10887
|
+
).meta({ deprecated: true }),
|
|
10888
|
+
status: TriggerInboxStatusSchema.optional().describe(
|
|
10889
|
+
"Filter by inbox status"
|
|
10890
|
+
),
|
|
10891
|
+
pageSize: zod.z.number().int().min(1).optional().describe("Number of inboxes per page"),
|
|
10892
|
+
maxItems: zod.z.number().int().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
10893
|
+
cursor: zod.z.string().optional().describe("Cursor (offset) to start from for pagination")
|
|
10894
|
+
}).describe("List all trigger inboxes for the authenticated user");
|
|
10895
|
+
var ListTriggerInboxesApiResponseSchema = zod.z.object({
|
|
10896
|
+
count: zod.z.number().int(),
|
|
10897
|
+
next: zod.z.string().nullable().optional(),
|
|
10898
|
+
previous: zod.z.string().nullable().optional(),
|
|
10899
|
+
results: zod.z.array(TriggerInboxItemSchema)
|
|
10900
|
+
});
|
|
10901
|
+
|
|
10902
|
+
// src/plugins/triggers/listTriggerInboxes/index.ts
|
|
10903
|
+
var listTriggerInboxesPlugin = definePlugin(
|
|
10904
|
+
(sdk) => createPaginatedPluginMethod(sdk, {
|
|
10905
|
+
...triggersDefaults,
|
|
10906
|
+
...zapierPagination,
|
|
10907
|
+
name: "listTriggerInboxes",
|
|
10908
|
+
type: "list",
|
|
10909
|
+
itemType: "TriggerInbox",
|
|
10910
|
+
inputSchema: ListTriggerInboxesSchema,
|
|
10911
|
+
outputSchema: TriggerInboxItemSchema,
|
|
10912
|
+
formatter: triggerInboxItemFormatter,
|
|
10913
|
+
defaultPageSize: DEFAULT_PAGE_SIZE,
|
|
10914
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
10915
|
+
const { api } = sdk2.context;
|
|
10916
|
+
const searchParams = {};
|
|
10917
|
+
if (options.pageSize !== void 0) {
|
|
10918
|
+
searchParams.limit = options.pageSize.toString();
|
|
10919
|
+
}
|
|
10920
|
+
if (options.cursor) {
|
|
10921
|
+
searchParams.offset = options.cursor;
|
|
10922
|
+
}
|
|
10923
|
+
if (options.status) {
|
|
10924
|
+
searchParams.status = options.status;
|
|
10925
|
+
}
|
|
10926
|
+
const keyFilter = options.key ?? options.name;
|
|
10927
|
+
if (keyFilter) {
|
|
10928
|
+
searchParams.key = keyFilter;
|
|
10929
|
+
}
|
|
10930
|
+
const rawResponse = await api.get("/trigger-inbox/api/v1/inboxes", {
|
|
10931
|
+
searchParams,
|
|
10932
|
+
authRequired: true
|
|
10933
|
+
});
|
|
10934
|
+
const response = ListTriggerInboxesApiResponseSchema.parse(rawResponse);
|
|
10935
|
+
return {
|
|
10936
|
+
data: response.results,
|
|
10937
|
+
next: response.next ?? null
|
|
10938
|
+
};
|
|
10939
|
+
}
|
|
10940
|
+
})
|
|
10941
|
+
);
|
|
10942
|
+
var GetTriggerInboxSchema = zod.z.object({
|
|
10943
|
+
inbox: TriggerInboxPropertySchema
|
|
10944
|
+
}).describe("Get details of a trigger inbox by ID");
|
|
10945
|
+
|
|
10946
|
+
// src/plugins/triggers/getTriggerInbox/index.ts
|
|
10947
|
+
var getTriggerInboxPlugin = definePlugin(
|
|
10948
|
+
(sdk) => createPluginMethod(sdk, {
|
|
10949
|
+
...triggersDefaults,
|
|
10950
|
+
name: "getTriggerInbox",
|
|
10951
|
+
type: "item",
|
|
10952
|
+
itemType: "TriggerInbox",
|
|
10953
|
+
inputSchema: GetTriggerInboxSchema,
|
|
10954
|
+
outputSchema: TriggerInboxItemSchema,
|
|
10955
|
+
formatter: triggerInboxItemFormatter,
|
|
10956
|
+
resolvers: { inbox: triggerInboxResolver },
|
|
10957
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
10958
|
+
const { inbox } = options;
|
|
10959
|
+
const inboxId = await resolveTriggerInboxId({
|
|
10960
|
+
api: sdk2.context.api,
|
|
10961
|
+
inbox
|
|
10962
|
+
});
|
|
10963
|
+
const rawResponse = await sdk2.context.api.get(
|
|
10964
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}`,
|
|
10965
|
+
{
|
|
10966
|
+
authRequired: true,
|
|
10967
|
+
resource: { type: "trigger_inbox", id: inboxId }
|
|
10968
|
+
}
|
|
10969
|
+
);
|
|
10970
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
10971
|
+
}
|
|
10972
|
+
})
|
|
10973
|
+
);
|
|
10974
|
+
var UpdateTriggerInboxSchema = zod.z.object({
|
|
10975
|
+
inbox: TriggerInboxPropertySchema,
|
|
10976
|
+
notificationUrl: zod.z.string().url().nullable().optional().describe(
|
|
10977
|
+
"Webhook URL to POST to when new messages arrive. Pass null to clear."
|
|
10978
|
+
)
|
|
10979
|
+
}).describe("Update settings on an existing trigger inbox");
|
|
10980
|
+
|
|
10981
|
+
// src/plugins/triggers/updateTriggerInbox/index.ts
|
|
10982
|
+
var updateTriggerInboxPlugin = definePlugin(
|
|
10983
|
+
(sdk) => createPluginMethod(sdk, {
|
|
10984
|
+
...triggersDefaults,
|
|
10985
|
+
name: "updateTriggerInbox",
|
|
10986
|
+
type: "update",
|
|
10987
|
+
itemType: "TriggerInbox",
|
|
10988
|
+
inputSchema: UpdateTriggerInboxSchema,
|
|
10989
|
+
outputSchema: TriggerInboxItemSchema,
|
|
10990
|
+
formatter: triggerInboxItemFormatter,
|
|
10991
|
+
resolvers: { inbox: triggerInboxResolver },
|
|
10992
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
10993
|
+
const { inbox, notificationUrl } = options;
|
|
10994
|
+
const inboxId = await resolveTriggerInboxId({
|
|
10995
|
+
api: sdk2.context.api,
|
|
10996
|
+
inbox
|
|
10997
|
+
});
|
|
10998
|
+
const requestBody = {};
|
|
10999
|
+
if (notificationUrl !== void 0) {
|
|
11000
|
+
requestBody.notification_url = notificationUrl;
|
|
11001
|
+
}
|
|
11002
|
+
const rawResponse = await sdk2.context.api.patch(
|
|
11003
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}`,
|
|
11004
|
+
requestBody,
|
|
11005
|
+
{
|
|
11006
|
+
authRequired: true,
|
|
11007
|
+
resource: { type: "trigger_inbox", id: inboxId }
|
|
11008
|
+
}
|
|
11009
|
+
);
|
|
11010
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
11011
|
+
}
|
|
11012
|
+
})
|
|
11013
|
+
);
|
|
11014
|
+
var DeleteTriggerInboxSchema = zod.z.object({
|
|
11015
|
+
inbox: TriggerInboxPropertySchema
|
|
11016
|
+
}).describe("Mark a trigger inbox for deletion");
|
|
11017
|
+
|
|
11018
|
+
// src/plugins/triggers/deleteTriggerInbox/index.ts
|
|
11019
|
+
var deleteTriggerInboxPlugin = definePlugin(
|
|
11020
|
+
(sdk) => createPluginMethod(sdk, {
|
|
11021
|
+
...triggersDefaults,
|
|
11022
|
+
name: "deleteTriggerInbox",
|
|
11023
|
+
type: "delete",
|
|
11024
|
+
itemType: "TriggerInbox",
|
|
11025
|
+
inputSchema: DeleteTriggerInboxSchema,
|
|
11026
|
+
outputSchema: TriggerInboxItemSchema,
|
|
11027
|
+
formatter: triggerInboxItemFormatter,
|
|
11028
|
+
resolvers: { inbox: triggerInboxResolver },
|
|
11029
|
+
confirm: "delete",
|
|
11030
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11031
|
+
const { inbox } = options;
|
|
11032
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11033
|
+
api: sdk2.context.api,
|
|
11034
|
+
inbox
|
|
11035
|
+
});
|
|
11036
|
+
const rawResponse = await sdk2.context.api.delete(
|
|
11037
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}`,
|
|
11038
|
+
void 0,
|
|
11039
|
+
{
|
|
11040
|
+
authRequired: true,
|
|
11041
|
+
resource: { type: "trigger_inbox", id: inboxId }
|
|
11042
|
+
}
|
|
11043
|
+
);
|
|
11044
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
11045
|
+
}
|
|
11046
|
+
})
|
|
11047
|
+
);
|
|
11048
|
+
var PauseTriggerInboxSchema = zod.z.object({
|
|
11049
|
+
inbox: TriggerInboxPropertySchema
|
|
11050
|
+
}).describe("Pause a trigger inbox; events stop being collected");
|
|
11051
|
+
|
|
11052
|
+
// src/plugins/triggers/pauseTriggerInbox/index.ts
|
|
11053
|
+
var pauseTriggerInboxPlugin = definePlugin(
|
|
11054
|
+
(sdk) => createPluginMethod(sdk, {
|
|
11055
|
+
...triggersDefaults,
|
|
11056
|
+
name: "pauseTriggerInbox",
|
|
11057
|
+
type: "update",
|
|
11058
|
+
itemType: "TriggerInbox",
|
|
11059
|
+
inputSchema: PauseTriggerInboxSchema,
|
|
11060
|
+
outputSchema: TriggerInboxItemSchema,
|
|
11061
|
+
formatter: triggerInboxItemFormatter,
|
|
11062
|
+
resolvers: { inbox: triggerInboxResolver },
|
|
11063
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11064
|
+
const { inbox } = options;
|
|
11065
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11066
|
+
api: sdk2.context.api,
|
|
11067
|
+
inbox
|
|
11068
|
+
});
|
|
11069
|
+
const rawResponse = await sdk2.context.api.post(
|
|
11070
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/pause`,
|
|
11071
|
+
void 0,
|
|
11072
|
+
{
|
|
11073
|
+
authRequired: true,
|
|
11074
|
+
resource: { type: "trigger_inbox", id: inboxId }
|
|
11075
|
+
}
|
|
11076
|
+
);
|
|
11077
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
11078
|
+
}
|
|
11079
|
+
})
|
|
11080
|
+
);
|
|
11081
|
+
var ResumeTriggerInboxSchema = zod.z.object({
|
|
11082
|
+
inbox: TriggerInboxPropertySchema
|
|
11083
|
+
}).describe("Resume a paused trigger inbox; events resume being collected");
|
|
11084
|
+
|
|
11085
|
+
// src/plugins/triggers/resumeTriggerInbox/index.ts
|
|
11086
|
+
var resumeTriggerInboxPlugin = definePlugin(
|
|
11087
|
+
(sdk) => createPluginMethod(sdk, {
|
|
11088
|
+
...triggersDefaults,
|
|
11089
|
+
name: "resumeTriggerInbox",
|
|
11090
|
+
type: "update",
|
|
11091
|
+
itemType: "TriggerInbox",
|
|
11092
|
+
inputSchema: ResumeTriggerInboxSchema,
|
|
11093
|
+
outputSchema: TriggerInboxItemSchema,
|
|
11094
|
+
formatter: triggerInboxItemFormatter,
|
|
11095
|
+
resolvers: { inbox: triggerInboxResolver },
|
|
11096
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11097
|
+
const { inbox } = options;
|
|
11098
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11099
|
+
api: sdk2.context.api,
|
|
11100
|
+
inbox
|
|
11101
|
+
});
|
|
11102
|
+
const rawResponse = await sdk2.context.api.post(
|
|
11103
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/resume`,
|
|
11104
|
+
void 0,
|
|
11105
|
+
{
|
|
11106
|
+
authRequired: true,
|
|
11107
|
+
resource: { type: "trigger_inbox", id: inboxId }
|
|
11108
|
+
}
|
|
11109
|
+
);
|
|
11110
|
+
return { data: TriggerInboxItemSchema.parse(rawResponse) };
|
|
11111
|
+
}
|
|
11112
|
+
})
|
|
11113
|
+
);
|
|
11114
|
+
var TriggerMessageStatusSchema = zod.z.union([zod.z.enum(["available", "leased", "acked", "quarantined"]), zod.z.string()]).describe("Message lifecycle status");
|
|
11115
|
+
var TriggerMessageAttributesSchema = zod.z.object({
|
|
11116
|
+
lease_count: zod.z.number().int(),
|
|
11117
|
+
error_message: zod.z.string().nullable(),
|
|
11118
|
+
possible_duplicate_data: zod.z.boolean()
|
|
11119
|
+
});
|
|
11120
|
+
var TriggerMessageItemSchema = zod.z.object({
|
|
11121
|
+
id: zod.z.string(),
|
|
11122
|
+
created_at: zod.z.string(),
|
|
11123
|
+
status: TriggerMessageStatusSchema,
|
|
11124
|
+
message_attributes: TriggerMessageAttributesSchema
|
|
11125
|
+
});
|
|
11126
|
+
var LeasedTriggerMessageItemSchema = TriggerMessageItemSchema.extend({
|
|
11127
|
+
payload: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
11128
|
+
});
|
|
11129
|
+
|
|
11130
|
+
// src/plugins/triggers/listTriggerInboxMessages/schemas.ts
|
|
11131
|
+
var ListTriggerInboxMessagesSchema = zod.z.object({
|
|
11132
|
+
inbox: TriggerInboxPropertySchema,
|
|
11133
|
+
pageSize: zod.z.number().int().min(1).optional().describe("Number of messages per page"),
|
|
11134
|
+
maxItems: zod.z.number().int().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
11135
|
+
cursor: zod.z.string().optional().describe("Pagination cursor")
|
|
11136
|
+
}).describe("List messages in a trigger inbox (no payload, status-only)");
|
|
11137
|
+
var ListTriggerInboxMessagesApiResponseSchema = zod.z.object({
|
|
11138
|
+
next: zod.z.string().nullable().optional(),
|
|
11139
|
+
previous: zod.z.string().nullable().optional(),
|
|
11140
|
+
results: zod.z.array(TriggerMessageItemSchema)
|
|
11141
|
+
});
|
|
11142
|
+
|
|
11143
|
+
// src/formatters/triggerMessage.ts
|
|
11144
|
+
function buildBaseDetails(item) {
|
|
11145
|
+
const details = [
|
|
11146
|
+
{ text: `Status: ${item.status}`, style: "dim" },
|
|
11147
|
+
{
|
|
11148
|
+
text: `Lease count: ${item.message_attributes.lease_count}`,
|
|
11149
|
+
style: "dim"
|
|
11150
|
+
}
|
|
11151
|
+
];
|
|
11152
|
+
if (item.message_attributes.error_message) {
|
|
11153
|
+
details.push({
|
|
11154
|
+
text: `Error: ${item.message_attributes.error_message}`,
|
|
11155
|
+
style: "warning"
|
|
11156
|
+
});
|
|
11157
|
+
}
|
|
11158
|
+
if (item.message_attributes.possible_duplicate_data) {
|
|
11159
|
+
details.push({ text: "Possible duplicate data", style: "warning" });
|
|
11160
|
+
}
|
|
11161
|
+
return details;
|
|
11162
|
+
}
|
|
11163
|
+
var triggerMessageItemFormatter = {
|
|
11164
|
+
format: (item) => ({
|
|
11165
|
+
title: `Message ${item.id}`,
|
|
11166
|
+
id: item.id,
|
|
11167
|
+
details: buildBaseDetails(item)
|
|
11168
|
+
})
|
|
11169
|
+
};
|
|
11170
|
+
|
|
11171
|
+
// src/plugins/triggers/listTriggerInboxMessages/index.ts
|
|
11172
|
+
var listTriggerInboxMessagesPlugin = definePlugin(
|
|
11173
|
+
(sdk) => createPaginatedPluginMethod(sdk, {
|
|
11174
|
+
...triggersDefaults,
|
|
11175
|
+
...zapierPagination,
|
|
11176
|
+
name: "listTriggerInboxMessages",
|
|
11177
|
+
type: "list",
|
|
11178
|
+
itemType: "TriggerMessage",
|
|
11179
|
+
inputSchema: ListTriggerInboxMessagesSchema,
|
|
11180
|
+
outputSchema: TriggerMessageItemSchema,
|
|
11181
|
+
formatter: triggerMessageItemFormatter,
|
|
11182
|
+
defaultPageSize: DEFAULT_PAGE_SIZE,
|
|
11183
|
+
resolvers: { inbox: triggerInboxResolver },
|
|
11184
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11185
|
+
const { inbox, cursor, pageSize } = options;
|
|
11186
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11187
|
+
api: sdk2.context.api,
|
|
11188
|
+
inbox
|
|
11189
|
+
});
|
|
11190
|
+
const searchParams = {};
|
|
11191
|
+
if (pageSize !== void 0) {
|
|
11192
|
+
searchParams.limit = pageSize.toString();
|
|
11193
|
+
}
|
|
11194
|
+
if (cursor) {
|
|
11195
|
+
searchParams.cursor = cursor;
|
|
11196
|
+
}
|
|
11197
|
+
const rawResponse = await sdk2.context.api.get(
|
|
11198
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/messages`,
|
|
11199
|
+
{ searchParams, authRequired: true }
|
|
11200
|
+
);
|
|
11201
|
+
const response = ListTriggerInboxMessagesApiResponseSchema.parse(rawResponse);
|
|
11202
|
+
return {
|
|
11203
|
+
data: response.results,
|
|
11204
|
+
next: response.next ?? null
|
|
11205
|
+
};
|
|
11206
|
+
}
|
|
11207
|
+
})
|
|
11208
|
+
);
|
|
11209
|
+
var LeaseTriggerInboxMessagesSchema = zod.z.object({
|
|
11210
|
+
inbox: TriggerInboxPropertySchema,
|
|
11211
|
+
leaseLimit: LeaseLimitPropertySchema.optional(),
|
|
11212
|
+
leaseSeconds: LeaseSecondsPropertySchema.optional(),
|
|
11213
|
+
signal: zod.z.custom((v) => v instanceof AbortSignal).optional().describe(
|
|
11214
|
+
"Abort signal forwarded to the lease HTTP request. Aborting causes the in-flight request to reject with AbortError."
|
|
11215
|
+
)
|
|
11216
|
+
}).describe(
|
|
11217
|
+
"Lease up to N messages from a trigger inbox. Returns messages plus a lease ID; ack within the lease window to remove from the inbox."
|
|
11218
|
+
);
|
|
11219
|
+
var InboxAttributesSchema = zod.z.object({
|
|
11220
|
+
status: TriggerInboxStatusSchema,
|
|
11221
|
+
paused_reason: TriggerInboxPausedReasonSchema.nullable()
|
|
11222
|
+
});
|
|
11223
|
+
var LeaseTriggerInboxMessagesItemSchema = zod.z.object({
|
|
11224
|
+
lease_id: zod.z.string().nullable(),
|
|
11225
|
+
leased_until: zod.z.string().nullable(),
|
|
11226
|
+
results: zod.z.array(LeasedTriggerMessageItemSchema),
|
|
11227
|
+
inbox_attributes: InboxAttributesSchema
|
|
11228
|
+
});
|
|
11229
|
+
|
|
11230
|
+
// src/plugins/triggers/leaseTriggerInboxMessages/index.ts
|
|
11231
|
+
function parseLeaseConflict(data) {
|
|
11232
|
+
if (typeof data !== "object" || data === null) return {};
|
|
11233
|
+
const detail = data.detail;
|
|
11234
|
+
const inboxAttributes = data.inbox_attributes;
|
|
11235
|
+
let pausedReason;
|
|
11236
|
+
if (typeof inboxAttributes === "object" && inboxAttributes !== null) {
|
|
11237
|
+
const pr = inboxAttributes.paused_reason;
|
|
11238
|
+
if (typeof pr === "string" && pr.length > 0) pausedReason = pr;
|
|
11239
|
+
}
|
|
11240
|
+
return {
|
|
11241
|
+
detail: typeof detail === "string" ? detail : void 0,
|
|
11242
|
+
pausedReason
|
|
11243
|
+
};
|
|
11244
|
+
}
|
|
11245
|
+
var leaseTriggerInboxMessagesPlugin = definePlugin(
|
|
11246
|
+
(sdk) => createPluginMethod(sdk, {
|
|
11247
|
+
...triggersDefaults,
|
|
11248
|
+
name: "leaseTriggerInboxMessages",
|
|
11249
|
+
type: "create",
|
|
11250
|
+
itemType: "TriggerInboxLease",
|
|
11251
|
+
inputSchema: LeaseTriggerInboxMessagesSchema,
|
|
11252
|
+
outputSchema: LeaseTriggerInboxMessagesItemSchema,
|
|
11253
|
+
resolvers: {
|
|
11254
|
+
inbox: triggerInboxResolver,
|
|
11255
|
+
leaseLimit: { type: "static", inputType: "text" },
|
|
11256
|
+
leaseSeconds: { type: "static", inputType: "text" }
|
|
11257
|
+
},
|
|
11258
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11259
|
+
const { inbox, leaseLimit, leaseSeconds, signal } = options;
|
|
11260
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11261
|
+
api: sdk2.context.api,
|
|
11262
|
+
inbox
|
|
11263
|
+
});
|
|
11264
|
+
const requestBody = {};
|
|
11265
|
+
if (leaseLimit !== void 0) {
|
|
11266
|
+
requestBody.lease_limit = leaseLimit;
|
|
11267
|
+
}
|
|
11268
|
+
if (leaseSeconds !== void 0) {
|
|
11269
|
+
requestBody.lease_seconds = leaseSeconds;
|
|
11270
|
+
}
|
|
11271
|
+
const rawResponse = await sdk2.context.api.post(
|
|
11272
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/messages/lease`,
|
|
11273
|
+
requestBody,
|
|
11274
|
+
{
|
|
11275
|
+
authRequired: true,
|
|
11276
|
+
signal,
|
|
11277
|
+
customErrorHandler: ({ status, data }) => {
|
|
11278
|
+
if (status !== 409) return void 0;
|
|
11279
|
+
const { detail, pausedReason } = parseLeaseConflict(data);
|
|
11280
|
+
const baseMessage = detail ?? "Inbox is paused and fully drained";
|
|
11281
|
+
const message = pausedReason ? `${baseMessage} (paused_reason: ${pausedReason})` : baseMessage;
|
|
11282
|
+
return new ZapierConflictError(message, {
|
|
11283
|
+
statusCode: status,
|
|
11284
|
+
resourceType: "trigger_inbox"
|
|
11285
|
+
});
|
|
11286
|
+
}
|
|
11287
|
+
}
|
|
11288
|
+
);
|
|
11289
|
+
return { data: LeaseTriggerInboxMessagesItemSchema.parse(rawResponse) };
|
|
11290
|
+
}
|
|
11291
|
+
})
|
|
11292
|
+
);
|
|
11293
|
+
var AckTriggerInboxMessagesSchema = zod.z.object({
|
|
11294
|
+
inbox: TriggerInboxPropertySchema,
|
|
11295
|
+
lease: LeasePropertySchema,
|
|
11296
|
+
messages: zod.z.array(zod.z.string().min(1)).optional().describe(
|
|
11297
|
+
"Specific message IDs to ack. Omit to ack every message in the lease."
|
|
11298
|
+
)
|
|
11299
|
+
}).describe(
|
|
11300
|
+
"Acknowledge messages from a lease. Acked messages are removed from the inbox; unacked ones return to the available pool when the lease expires."
|
|
11301
|
+
);
|
|
11302
|
+
var AckTriggerInboxMessagesItemSchema = zod.z.object({
|
|
11303
|
+
acked_id: zod.z.string().nullable(),
|
|
11304
|
+
results: zod.z.array(TriggerMessageItemSchema)
|
|
11305
|
+
});
|
|
11306
|
+
|
|
11307
|
+
// src/plugins/triggers/ackTriggerInboxMessages/index.ts
|
|
11308
|
+
var ackTriggerInboxMessagesPlugin = definePlugin(
|
|
11309
|
+
(sdk) => createPluginMethod(sdk, {
|
|
11310
|
+
...triggersDefaults,
|
|
11311
|
+
name: "ackTriggerInboxMessages",
|
|
11312
|
+
type: "create",
|
|
11313
|
+
itemType: "TriggerInboxAck",
|
|
11314
|
+
inputSchema: AckTriggerInboxMessagesSchema,
|
|
11315
|
+
outputSchema: AckTriggerInboxMessagesItemSchema,
|
|
11316
|
+
resolvers: {
|
|
11317
|
+
inbox: triggerInboxResolver,
|
|
11318
|
+
// No way to look up a lease — leases are short-lived, only the
|
|
11319
|
+
// most recent leaseTriggerInboxMessages caller knows the ID.
|
|
11320
|
+
// Static resolver prompts for free-text input.
|
|
11321
|
+
lease: { type: "static", inputType: "text" },
|
|
11322
|
+
messages: triggerMessagesResolver
|
|
11323
|
+
},
|
|
11324
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11325
|
+
const { inbox, lease, messages } = options;
|
|
11326
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11327
|
+
api: sdk2.context.api,
|
|
11328
|
+
inbox
|
|
11329
|
+
});
|
|
11330
|
+
const requestBody = {
|
|
11331
|
+
lease_id: lease
|
|
11332
|
+
};
|
|
11333
|
+
if (messages !== void 0) {
|
|
11334
|
+
requestBody.message_ids = messages;
|
|
11335
|
+
}
|
|
11336
|
+
const rawResponse = await sdk2.context.api.post(
|
|
11337
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/messages/ack`,
|
|
11338
|
+
requestBody,
|
|
11339
|
+
{ authRequired: true }
|
|
11340
|
+
);
|
|
11341
|
+
return { data: AckTriggerInboxMessagesItemSchema.parse(rawResponse) };
|
|
11342
|
+
}
|
|
11343
|
+
})
|
|
11344
|
+
);
|
|
11345
|
+
var ReleaseTriggerInboxMessagesSchema = zod.z.object({
|
|
11346
|
+
inbox: TriggerInboxPropertySchema,
|
|
11347
|
+
lease: LeasePropertySchema,
|
|
11348
|
+
messages: zod.z.array(zod.z.string().min(1)).optional().describe(
|
|
11349
|
+
"Specific message IDs to release. Omit to release every message in the lease."
|
|
11350
|
+
)
|
|
11351
|
+
}).describe(
|
|
11352
|
+
"Release messages from a lease back to the inbox without acknowledging them. Released messages become immediately available for re-leasing. The lease attempt still counts against the per-message lease limit; releasing does not refund the attempt."
|
|
11353
|
+
);
|
|
11354
|
+
var ReleaseTriggerInboxMessagesItemSchema = zod.z.object({
|
|
11355
|
+
released_id: zod.z.string().nullable(),
|
|
11356
|
+
results: zod.z.array(TriggerMessageItemSchema)
|
|
11357
|
+
});
|
|
11358
|
+
|
|
11359
|
+
// src/plugins/triggers/releaseTriggerInboxMessages/index.ts
|
|
11360
|
+
var releaseTriggerInboxMessagesPlugin = definePlugin(
|
|
11361
|
+
(sdk) => createPluginMethod(sdk, {
|
|
11362
|
+
...triggersDefaults,
|
|
11363
|
+
name: "releaseTriggerInboxMessages",
|
|
11364
|
+
type: "create",
|
|
11365
|
+
itemType: "TriggerInboxRelease",
|
|
11366
|
+
inputSchema: ReleaseTriggerInboxMessagesSchema,
|
|
11367
|
+
outputSchema: ReleaseTriggerInboxMessagesItemSchema,
|
|
11368
|
+
resolvers: {
|
|
11369
|
+
inbox: triggerInboxResolver,
|
|
11370
|
+
// No way to look up a lease — leases are short-lived, only the
|
|
11371
|
+
// most recent leaseTriggerInboxMessages caller knows the ID.
|
|
11372
|
+
// Static resolver prompts for free-text input.
|
|
11373
|
+
lease: { type: "static", inputType: "text" },
|
|
11374
|
+
messages: triggerMessagesResolver
|
|
11375
|
+
},
|
|
11376
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
11377
|
+
const { inbox, lease, messages } = options;
|
|
11378
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11379
|
+
api: sdk2.context.api,
|
|
11380
|
+
inbox
|
|
11381
|
+
});
|
|
11382
|
+
const requestBody = {
|
|
11383
|
+
lease_id: lease
|
|
11384
|
+
};
|
|
11385
|
+
if (messages !== void 0) {
|
|
11386
|
+
requestBody.message_ids = messages;
|
|
11387
|
+
}
|
|
11388
|
+
const rawResponse = await sdk2.context.api.post(
|
|
11389
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/messages/release`,
|
|
11390
|
+
requestBody,
|
|
11391
|
+
{ authRequired: true }
|
|
11392
|
+
);
|
|
11393
|
+
return {
|
|
11394
|
+
data: ReleaseTriggerInboxMessagesItemSchema.parse(rawResponse)
|
|
11395
|
+
};
|
|
11396
|
+
}
|
|
11397
|
+
})
|
|
11398
|
+
);
|
|
11399
|
+
|
|
11400
|
+
// src/plugins/triggers/drainTriggerInbox/pipeline.ts
|
|
11401
|
+
function createBatchTracker() {
|
|
11402
|
+
const batches = /* @__PURE__ */ new Map();
|
|
11403
|
+
return {
|
|
11404
|
+
addBatch(id, total) {
|
|
11405
|
+
batches.set(id, { total, inFlight: 0, completed: 0 });
|
|
11406
|
+
},
|
|
11407
|
+
markInFlight(id) {
|
|
11408
|
+
const e = batches.get(id);
|
|
11409
|
+
if (e) e.inFlight++;
|
|
11410
|
+
},
|
|
11411
|
+
/** Decrement inFlight and increment completed. Paired with markInFlight. */
|
|
11412
|
+
markCompleted(id) {
|
|
11413
|
+
const e = batches.get(id);
|
|
11414
|
+
if (!e) return;
|
|
11415
|
+
e.inFlight--;
|
|
11416
|
+
e.completed++;
|
|
11417
|
+
},
|
|
11418
|
+
/** Drop the batch once all items completed; tracker stays small over long drains. */
|
|
11419
|
+
finalizeIfDone(id) {
|
|
11420
|
+
const e = batches.get(id);
|
|
11421
|
+
if (e && e.completed === e.total) batches.delete(id);
|
|
11422
|
+
},
|
|
11423
|
+
inFlightTotal() {
|
|
11424
|
+
let n = 0;
|
|
11425
|
+
for (const e of batches.values()) n += e.inFlight;
|
|
11426
|
+
return n;
|
|
11427
|
+
},
|
|
11428
|
+
/** Items leased but not yet completed (queued + in-flight). */
|
|
11429
|
+
pipelineSize() {
|
|
11430
|
+
let n = 0;
|
|
11431
|
+
for (const e of batches.values()) n += e.total - e.completed;
|
|
11432
|
+
return n;
|
|
11433
|
+
}
|
|
11434
|
+
};
|
|
11435
|
+
}
|
|
11436
|
+
function createWaiter() {
|
|
11437
|
+
const make = () => {
|
|
11438
|
+
let signal;
|
|
11439
|
+
const promise = new Promise((r) => {
|
|
11440
|
+
signal = r;
|
|
11441
|
+
});
|
|
11442
|
+
return { promise, signal };
|
|
11443
|
+
};
|
|
11444
|
+
let current = make();
|
|
11445
|
+
return {
|
|
11446
|
+
wait: () => current.promise,
|
|
11447
|
+
notifyAll: () => {
|
|
11448
|
+
const prev = current;
|
|
11449
|
+
current = make();
|
|
11450
|
+
prev.signal();
|
|
11451
|
+
}
|
|
11452
|
+
};
|
|
11453
|
+
}
|
|
11454
|
+
function addToMap(m, key2, value) {
|
|
11455
|
+
const existing = m.get(key2) ?? [];
|
|
11456
|
+
m.set(key2, [...existing, value]);
|
|
11457
|
+
}
|
|
11458
|
+
async function runBatchedDrainPipeline(options) {
|
|
11459
|
+
const {
|
|
11460
|
+
concurrency,
|
|
11461
|
+
maxItems,
|
|
11462
|
+
leaseSize,
|
|
11463
|
+
fetchBatch,
|
|
11464
|
+
processItem,
|
|
11465
|
+
ackItem,
|
|
11466
|
+
releaseItems
|
|
11467
|
+
} = options;
|
|
11468
|
+
const tracker = createBatchTracker();
|
|
11469
|
+
const waiter = createWaiter();
|
|
11470
|
+
const accumulated = [];
|
|
11471
|
+
const pendingReleases = /* @__PURE__ */ new Map();
|
|
11472
|
+
const queue = [];
|
|
11473
|
+
let totalProcessed = 0;
|
|
11474
|
+
let aborted = false;
|
|
11475
|
+
let exhausted = false;
|
|
11476
|
+
let fetchInProgress = false;
|
|
11477
|
+
let fetchError = void 0;
|
|
11478
|
+
async function tryFetch() {
|
|
11479
|
+
if (fetchInProgress || exhausted || aborted) return;
|
|
11480
|
+
const remainingCap = maxItems !== void 0 ? maxItems - totalProcessed - tracker.pipelineSize() : Number.POSITIVE_INFINITY;
|
|
11481
|
+
if (remainingCap <= 0) return;
|
|
11482
|
+
const requestedSize = Math.min(remainingCap, leaseSize);
|
|
11483
|
+
fetchInProgress = true;
|
|
11484
|
+
try {
|
|
11485
|
+
const result = await fetchBatch(requestedSize);
|
|
11486
|
+
if (result === "exhausted") {
|
|
11487
|
+
exhausted = true;
|
|
11488
|
+
return;
|
|
11489
|
+
}
|
|
11490
|
+
tracker.addBatch(result.id, result.items.length);
|
|
11491
|
+
for (const item of result.items) {
|
|
11492
|
+
queue.push({ item, batchId: result.id });
|
|
11493
|
+
}
|
|
11494
|
+
} catch (err) {
|
|
11495
|
+
fetchError = err;
|
|
11496
|
+
exhausted = true;
|
|
11497
|
+
} finally {
|
|
11498
|
+
fetchInProgress = false;
|
|
11499
|
+
waiter.notifyAll();
|
|
11500
|
+
}
|
|
11501
|
+
}
|
|
11502
|
+
async function processQueueEntry(entry) {
|
|
11503
|
+
tracker.markInFlight(entry.batchId);
|
|
11504
|
+
try {
|
|
11505
|
+
const result = await processItem(entry.item);
|
|
11506
|
+
accumulated.push(result.value);
|
|
11507
|
+
totalProcessed++;
|
|
11508
|
+
if (result.action === "release") {
|
|
11509
|
+
addToMap(pendingReleases, entry.batchId, entry.item.id);
|
|
11510
|
+
}
|
|
11511
|
+
if (result.abort) aborted = true;
|
|
11512
|
+
if (result.action === "ack") {
|
|
11513
|
+
await ackItem(entry.batchId, entry.item.id);
|
|
11514
|
+
}
|
|
11515
|
+
} finally {
|
|
11516
|
+
tracker.markCompleted(entry.batchId);
|
|
11517
|
+
tracker.finalizeIfDone(entry.batchId);
|
|
11518
|
+
waiter.notifyAll();
|
|
11519
|
+
}
|
|
11520
|
+
}
|
|
11521
|
+
async function worker() {
|
|
11522
|
+
while (true) {
|
|
11523
|
+
if (aborted) return;
|
|
11524
|
+
if (maxItems !== void 0 && totalProcessed >= maxItems) return;
|
|
11525
|
+
const entry = queue.shift();
|
|
11526
|
+
if (entry !== void 0) {
|
|
11527
|
+
if (tracker.pipelineSize() < concurrency && !fetchInProgress && !exhausted) {
|
|
11528
|
+
void tryFetch();
|
|
11529
|
+
}
|
|
11530
|
+
await processQueueEntry(entry);
|
|
11531
|
+
continue;
|
|
11532
|
+
}
|
|
11533
|
+
if (!exhausted && !fetchInProgress) void tryFetch();
|
|
11534
|
+
if (queue.length === 0 && !fetchInProgress && (exhausted || aborted) && tracker.inFlightTotal() === 0) {
|
|
11535
|
+
return;
|
|
11536
|
+
}
|
|
11537
|
+
await waiter.wait();
|
|
11538
|
+
}
|
|
11539
|
+
}
|
|
11540
|
+
await tryFetch();
|
|
11541
|
+
if (fetchError !== void 0) throw fetchError;
|
|
11542
|
+
let cleanupError = void 0;
|
|
11543
|
+
try {
|
|
11544
|
+
if (!exhausted || queue.length > 0) {
|
|
11545
|
+
let firstWorkerError = void 0;
|
|
11546
|
+
const workers = Array.from(
|
|
11547
|
+
{ length: concurrency },
|
|
11548
|
+
() => worker().catch((err) => {
|
|
11549
|
+
if (firstWorkerError === void 0) firstWorkerError = err;
|
|
11550
|
+
})
|
|
11551
|
+
);
|
|
11552
|
+
await Promise.all(workers);
|
|
11553
|
+
if (firstWorkerError !== void 0) throw firstWorkerError;
|
|
11554
|
+
}
|
|
11555
|
+
if (fetchError !== void 0) throw fetchError;
|
|
11556
|
+
} finally {
|
|
11557
|
+
while (queue.length > 0) {
|
|
11558
|
+
const entry = queue.shift();
|
|
11559
|
+
addToMap(pendingReleases, entry.batchId, entry.item.id);
|
|
11560
|
+
}
|
|
11561
|
+
for (const [batchId, itemIds] of pendingReleases) {
|
|
11562
|
+
try {
|
|
11563
|
+
await releaseItems(batchId, itemIds);
|
|
11564
|
+
} catch (err) {
|
|
11565
|
+
cleanupError ?? (cleanupError = err);
|
|
11566
|
+
}
|
|
11567
|
+
}
|
|
11568
|
+
}
|
|
11569
|
+
if (cleanupError !== void 0) throw cleanupError;
|
|
11570
|
+
return accumulated;
|
|
11571
|
+
}
|
|
11572
|
+
|
|
11573
|
+
// src/plugins/triggers/drainTriggerInbox/index.ts
|
|
11574
|
+
var nonRetryableDrainErrors = /* @__PURE__ */ new WeakSet();
|
|
11575
|
+
function markNonRetryableDrainError(err) {
|
|
11576
|
+
if (typeof err === "object" && err !== null) {
|
|
11577
|
+
nonRetryableDrainErrors.add(err);
|
|
11578
|
+
}
|
|
11579
|
+
return err;
|
|
11580
|
+
}
|
|
11581
|
+
function isNonRetryableDrainError(err) {
|
|
11582
|
+
return typeof err === "object" && err !== null && nonRetryableDrainErrors.has(err);
|
|
11583
|
+
}
|
|
11584
|
+
function isLeaseExpiredError(err) {
|
|
11585
|
+
if (!(err instanceof ZapierValidationError)) return false;
|
|
11586
|
+
return err.errors?.some((e) => e.code === "lease_expired") ?? false;
|
|
11587
|
+
}
|
|
11588
|
+
async function runDrainPass(options) {
|
|
11589
|
+
const {
|
|
11590
|
+
sdk,
|
|
11591
|
+
inboxId,
|
|
11592
|
+
onMessage,
|
|
11593
|
+
concurrency,
|
|
11594
|
+
leaseLimit,
|
|
11595
|
+
leaseSeconds,
|
|
11596
|
+
maxMessages,
|
|
11597
|
+
releaseOnError,
|
|
11598
|
+
continueOnError,
|
|
11599
|
+
onError,
|
|
11600
|
+
signal
|
|
11601
|
+
} = options;
|
|
11602
|
+
let firstFetch = options.firstFetch;
|
|
11603
|
+
let abortedFromCallback = false;
|
|
11604
|
+
let handlerErrorCaptured = false;
|
|
11605
|
+
let firstHandlerError = void 0;
|
|
11606
|
+
const outcomes = await runBatchedDrainPipeline({
|
|
11607
|
+
concurrency,
|
|
11608
|
+
maxItems: maxMessages,
|
|
11609
|
+
leaseSize: leaseLimit,
|
|
11610
|
+
fetchBatch: async (requestedSize) => {
|
|
11611
|
+
if (signal?.aborted) return "exhausted";
|
|
11612
|
+
let lease;
|
|
11613
|
+
try {
|
|
11614
|
+
({ data: lease } = await sdk.leaseTriggerInboxMessages({
|
|
11615
|
+
inbox: inboxId,
|
|
11616
|
+
leaseLimit: requestedSize,
|
|
11617
|
+
leaseSeconds,
|
|
11618
|
+
signal
|
|
11619
|
+
}));
|
|
11620
|
+
} catch (err) {
|
|
11621
|
+
if (signal?.aborted && isAbortError(err)) return "exhausted";
|
|
11622
|
+
throw err;
|
|
11623
|
+
}
|
|
11624
|
+
if (lease.results.length === 0) {
|
|
11625
|
+
if (firstFetch && lease.inbox_attributes.status === "initialization_failure") {
|
|
11626
|
+
throw markNonRetryableDrainError(
|
|
11627
|
+
new ZapierApiError(
|
|
11628
|
+
`Trigger inbox ${inboxId} is in initialization_failure state \u2014 inspect via getTriggerInbox.`
|
|
11629
|
+
)
|
|
11630
|
+
);
|
|
11631
|
+
}
|
|
11632
|
+
firstFetch = false;
|
|
11633
|
+
return "exhausted";
|
|
11634
|
+
}
|
|
11635
|
+
firstFetch = false;
|
|
11636
|
+
if (!lease.lease_id) return "exhausted";
|
|
11637
|
+
return { id: lease.lease_id, items: lease.results };
|
|
11638
|
+
},
|
|
11639
|
+
processItem: async (message) => {
|
|
11640
|
+
if (signal?.aborted) {
|
|
11641
|
+
return {
|
|
11642
|
+
value: message,
|
|
11643
|
+
action: "release",
|
|
11644
|
+
abort: true
|
|
11645
|
+
};
|
|
11646
|
+
}
|
|
11647
|
+
try {
|
|
11648
|
+
await onMessage(message);
|
|
11649
|
+
return { value: message, action: "ack" };
|
|
11650
|
+
} catch (err) {
|
|
11651
|
+
let action = "ignore";
|
|
11652
|
+
let abort = false;
|
|
11653
|
+
if (err instanceof ZapierAbortDrainSignal) {
|
|
11654
|
+
abort = true;
|
|
11655
|
+
abortedFromCallback = true;
|
|
11656
|
+
if (releaseOnError) action = "release";
|
|
11657
|
+
} else if (err instanceof ZapierReleaseTriggerMessageSignal) {
|
|
11658
|
+
action = "release";
|
|
11659
|
+
} else if (releaseOnError) {
|
|
11660
|
+
action = "release";
|
|
11661
|
+
}
|
|
11662
|
+
if (onError && !(err instanceof ZapierSignal)) {
|
|
11663
|
+
try {
|
|
11664
|
+
await onError(err, message);
|
|
11665
|
+
} catch {
|
|
11666
|
+
}
|
|
11667
|
+
}
|
|
11668
|
+
if (!continueOnError && !(err instanceof ZapierSignal)) {
|
|
11669
|
+
if (!handlerErrorCaptured) {
|
|
11670
|
+
firstHandlerError = err;
|
|
11671
|
+
handlerErrorCaptured = true;
|
|
11672
|
+
}
|
|
11673
|
+
abort = true;
|
|
11674
|
+
}
|
|
11675
|
+
return { value: message, action, abort };
|
|
11676
|
+
}
|
|
11677
|
+
},
|
|
11678
|
+
ackItem: async (leaseId, messageId) => {
|
|
11679
|
+
try {
|
|
11680
|
+
await sdk.ackTriggerInboxMessages({
|
|
11681
|
+
inbox: inboxId,
|
|
11682
|
+
lease: leaseId,
|
|
11683
|
+
messages: [messageId]
|
|
11684
|
+
});
|
|
11685
|
+
} catch (err) {
|
|
11686
|
+
if (!isLeaseExpiredError(err)) throw err;
|
|
11687
|
+
}
|
|
11688
|
+
},
|
|
11689
|
+
releaseItems: async (leaseId, messageIds) => {
|
|
11690
|
+
try {
|
|
11691
|
+
await sdk.releaseTriggerInboxMessages({
|
|
11692
|
+
inbox: inboxId,
|
|
11693
|
+
lease: leaseId,
|
|
11694
|
+
messages: messageIds
|
|
11695
|
+
});
|
|
11696
|
+
} catch (err) {
|
|
11697
|
+
if (!isLeaseExpiredError(err)) throw err;
|
|
11698
|
+
}
|
|
11699
|
+
}
|
|
11700
|
+
});
|
|
11701
|
+
if (handlerErrorCaptured) {
|
|
11702
|
+
throw markNonRetryableDrainError(firstHandlerError);
|
|
11703
|
+
}
|
|
11704
|
+
return { abortedFromCallback, processed: outcomes.length };
|
|
11705
|
+
}
|
|
11706
|
+
function requireOnMessage(onMessage) {
|
|
11707
|
+
if (typeof onMessage !== "function") {
|
|
11708
|
+
throw new ZapierValidationError("onMessage is required.");
|
|
11709
|
+
}
|
|
11710
|
+
return onMessage;
|
|
11711
|
+
}
|
|
11712
|
+
function resolveConcurrencyAndLease(options) {
|
|
11713
|
+
const concurrency = options.concurrency ?? options.leaseLimit ?? 1;
|
|
11714
|
+
const leaseLimit = options.leaseLimit ?? concurrency;
|
|
11715
|
+
return { concurrency, leaseLimit };
|
|
11716
|
+
}
|
|
11717
|
+
var drainTriggerInboxPlugin = definePlugin(
|
|
11718
|
+
(sdk) => {
|
|
11719
|
+
async function drainTriggerInbox(options) {
|
|
11720
|
+
const onMessage = requireOnMessage(options.onMessage);
|
|
11721
|
+
const { concurrency, leaseLimit } = resolveConcurrencyAndLease(options);
|
|
11722
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11723
|
+
api: sdk.context.api,
|
|
11724
|
+
inbox: options.inbox
|
|
11725
|
+
});
|
|
11726
|
+
await runDrainPass({
|
|
11727
|
+
sdk,
|
|
11728
|
+
inboxId,
|
|
11729
|
+
onMessage,
|
|
11730
|
+
concurrency,
|
|
11731
|
+
leaseLimit,
|
|
11732
|
+
leaseSeconds: options.leaseSeconds,
|
|
11733
|
+
maxMessages: options.maxMessages,
|
|
11734
|
+
releaseOnError: options.releaseOnError ?? false,
|
|
11735
|
+
continueOnError: options.continueOnError ?? false,
|
|
11736
|
+
onError: options.onError,
|
|
11737
|
+
signal: options.signal,
|
|
11738
|
+
firstFetch: true
|
|
11739
|
+
});
|
|
11740
|
+
}
|
|
11741
|
+
return {
|
|
11742
|
+
drainTriggerInbox,
|
|
11743
|
+
context: {
|
|
11744
|
+
meta: {
|
|
11745
|
+
drainTriggerInbox: {
|
|
11746
|
+
...triggersDefaults,
|
|
11747
|
+
type: "create",
|
|
11748
|
+
description: "Drain an existing trigger inbox: lease currently-available messages, process each via onMessage, return when the inbox is empty, maxMessages is reached, or the abort signal fires.",
|
|
11749
|
+
itemType: "void",
|
|
11750
|
+
// The doc generator's default for type="create" + itemType
|
|
11751
|
+
// appends "Item" (e.g. "RecordItem"), which would render
|
|
11752
|
+
// "voidItem" here. drainTriggerInbox returns Promise<void>,
|
|
11753
|
+
// so we override.
|
|
11754
|
+
returnType: "void",
|
|
11755
|
+
inputSchema: DrainTriggerInboxSchema,
|
|
11756
|
+
resolvers: {
|
|
11757
|
+
inbox: triggerInboxResolver
|
|
11758
|
+
},
|
|
11759
|
+
// Returns Promise<void>; the CLI ships a hand-written
|
|
11760
|
+
// drain-trigger-inbox plugin that adds presentation flags
|
|
11761
|
+
// (interactive, --json, etc.) around this command.
|
|
11762
|
+
packages: ["sdk"]
|
|
11763
|
+
}
|
|
11764
|
+
}
|
|
11765
|
+
}
|
|
11766
|
+
};
|
|
11767
|
+
}
|
|
11768
|
+
);
|
|
11769
|
+
|
|
11770
|
+
// src/plugins/triggers/watchTriggerInbox/sse.ts
|
|
11771
|
+
async function* readInboxEvents({
|
|
11772
|
+
api,
|
|
11773
|
+
inboxId,
|
|
11774
|
+
signal,
|
|
11775
|
+
onOpen
|
|
11776
|
+
}) {
|
|
11777
|
+
for await (const message of api.fetchJsonStream(
|
|
11778
|
+
`/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/events`,
|
|
11779
|
+
{ method: "GET", signal, authRequired: true, onOpen }
|
|
11780
|
+
)) {
|
|
11781
|
+
if (!message.parsed) continue;
|
|
11782
|
+
const parsed = message.data;
|
|
11783
|
+
if (typeof parsed === "object" && parsed !== null && typeof parsed.inbox_id === "string" && // Only wake on a frame for this inbox. Case-insensitive: the endpoint
|
|
11784
|
+
// echoes the canonical lowercase UUID, but resolveTriggerInboxId passes
|
|
11785
|
+
// a UUID-shaped `inbox` through unchanged, so its casing may differ.
|
|
11786
|
+
parsed.inbox_id.toLowerCase() === inboxId.toLowerCase()) {
|
|
11787
|
+
yield parsed;
|
|
11788
|
+
}
|
|
11789
|
+
}
|
|
11790
|
+
}
|
|
11791
|
+
|
|
11792
|
+
// src/plugins/triggers/watchTriggerInbox/index.ts
|
|
11793
|
+
var SSE_RECONNECT_BACKOFF_MS = [500, 1e3, 2e3, 5e3];
|
|
11794
|
+
var DEFAULT_SAFETY_DRAIN_INTERVAL_MS = 3e5;
|
|
11795
|
+
var SSE_HEALTHY_CONNECTION_MS = 5e3;
|
|
11796
|
+
var ERROR_BACKOFF_CAP = 4;
|
|
11797
|
+
function createDrainLatch() {
|
|
11798
|
+
let pending = false;
|
|
11799
|
+
const make = () => {
|
|
11800
|
+
let resolve2;
|
|
11801
|
+
const promise = new Promise((r) => {
|
|
11802
|
+
resolve2 = r;
|
|
11803
|
+
});
|
|
11804
|
+
return { promise, resolve: resolve2 };
|
|
11805
|
+
};
|
|
11806
|
+
let current = make();
|
|
11807
|
+
return {
|
|
11808
|
+
request() {
|
|
11809
|
+
pending = true;
|
|
11810
|
+
const prev = current;
|
|
11811
|
+
current = make();
|
|
11812
|
+
prev.resolve();
|
|
11813
|
+
},
|
|
11814
|
+
async waitForRequest() {
|
|
11815
|
+
if (pending) {
|
|
11816
|
+
pending = false;
|
|
11817
|
+
return;
|
|
11818
|
+
}
|
|
11819
|
+
await current.promise;
|
|
11820
|
+
pending = false;
|
|
11821
|
+
}
|
|
11822
|
+
};
|
|
11823
|
+
}
|
|
11824
|
+
async function drainRunner({
|
|
11825
|
+
drainOptions,
|
|
11826
|
+
drainRequest,
|
|
11827
|
+
signal,
|
|
11828
|
+
inboxId,
|
|
11829
|
+
debug
|
|
11830
|
+
}) {
|
|
11831
|
+
let firstFetch = true;
|
|
11832
|
+
let consecutiveErrors = 0;
|
|
11833
|
+
let errorAttempts = 0;
|
|
11834
|
+
let drainDegraded = false;
|
|
11835
|
+
while (!signal.aborted) {
|
|
11836
|
+
await drainRequest.waitForRequest();
|
|
11837
|
+
if (signal.aborted) return { kind: "aborted" };
|
|
11838
|
+
let abortedFromCallback = false;
|
|
11839
|
+
try {
|
|
11840
|
+
({ abortedFromCallback } = await runDrainPass({
|
|
11841
|
+
...drainOptions,
|
|
11842
|
+
firstFetch
|
|
11843
|
+
}));
|
|
11844
|
+
} catch (error) {
|
|
11845
|
+
if (signal.aborted) return { kind: "aborted" };
|
|
11846
|
+
const isNonObjectThrow = typeof error !== "object" || error === null;
|
|
11847
|
+
if (isNonObjectThrow || isNonRetryableDrainError(error) || isPermanentHttpError(error)) {
|
|
11848
|
+
return { kind: "error", error };
|
|
11849
|
+
}
|
|
11850
|
+
consecutiveErrors = Math.min(consecutiveErrors + 1, ERROR_BACKOFF_CAP);
|
|
11851
|
+
errorAttempts += 1;
|
|
11852
|
+
const delay = calculateErrorBackoffMs(
|
|
11853
|
+
BASE_ERROR_BACKOFF_MS,
|
|
11854
|
+
consecutiveErrors
|
|
11855
|
+
);
|
|
11856
|
+
const statusCode = errorStatusCode(error);
|
|
11857
|
+
const httpPart = statusCode !== void 0 ? ` (HTTP ${statusCode})` : "";
|
|
11858
|
+
if (!drainDegraded && consecutiveErrors >= ERROR_BACKOFF_CAP) {
|
|
11859
|
+
console.warn(
|
|
11860
|
+
`[zapier-sdk] Draining inbox ${inboxId}${httpPart} is failing repeatedly: ${errorMessage(error)}. Continuing to retry with backoff.`
|
|
11861
|
+
);
|
|
11862
|
+
drainDegraded = true;
|
|
11863
|
+
}
|
|
11864
|
+
if (debug) {
|
|
11865
|
+
console.error(
|
|
11866
|
+
`[zapier-sdk] Retrying drain for inbox ${inboxId} (attempt ${errorAttempts}, retry in ${delay}ms)${httpPart}: ${errorMessage(error)}`
|
|
11867
|
+
);
|
|
11868
|
+
}
|
|
11869
|
+
await sleep(delay, signal);
|
|
11870
|
+
if (signal.aborted) return { kind: "aborted" };
|
|
11871
|
+
drainRequest.request();
|
|
11872
|
+
continue;
|
|
11873
|
+
}
|
|
11874
|
+
firstFetch = false;
|
|
11875
|
+
consecutiveErrors = 0;
|
|
11876
|
+
errorAttempts = 0;
|
|
11877
|
+
drainDegraded = false;
|
|
11878
|
+
if (abortedFromCallback) return { kind: "abortedFromCallback" };
|
|
11879
|
+
}
|
|
11880
|
+
return { kind: "aborted" };
|
|
11881
|
+
}
|
|
11882
|
+
function errorStatusCode(err) {
|
|
11883
|
+
return err instanceof ZapierError ? err.statusCode : void 0;
|
|
11884
|
+
}
|
|
11885
|
+
function errorMessage(err) {
|
|
11886
|
+
return err instanceof Error ? err.message : String(err);
|
|
11887
|
+
}
|
|
11888
|
+
async function sseLoop({
|
|
11889
|
+
api,
|
|
11890
|
+
inboxId,
|
|
11891
|
+
drainRequest,
|
|
11892
|
+
safetyDrainMs,
|
|
11893
|
+
signal,
|
|
11894
|
+
debug
|
|
11895
|
+
}) {
|
|
11896
|
+
let attempt = 0;
|
|
11897
|
+
let degraded = false;
|
|
11898
|
+
while (!signal.aborted) {
|
|
11899
|
+
let connected = false;
|
|
11900
|
+
let connectedAt = 0;
|
|
11901
|
+
let transientError;
|
|
11902
|
+
try {
|
|
11903
|
+
for await (const _event of readInboxEvents({
|
|
11904
|
+
api,
|
|
11905
|
+
inboxId,
|
|
11906
|
+
signal,
|
|
11907
|
+
// SSE is edge-triggered with no replay, so draining on connect is the
|
|
11908
|
+
// only way to pick up messages that arrived before this connection —
|
|
11909
|
+
// including the window left by a prior disconnect.
|
|
11910
|
+
onOpen: () => {
|
|
11911
|
+
connected = true;
|
|
11912
|
+
connectedAt = Date.now();
|
|
11913
|
+
degraded = false;
|
|
11914
|
+
drainRequest.request();
|
|
11915
|
+
}
|
|
11916
|
+
})) {
|
|
11917
|
+
drainRequest.request();
|
|
11918
|
+
}
|
|
11919
|
+
if (connected && Date.now() - connectedAt >= SSE_HEALTHY_CONNECTION_MS) {
|
|
11920
|
+
attempt = 0;
|
|
11921
|
+
}
|
|
11922
|
+
} catch (err) {
|
|
11923
|
+
if (signal.aborted || isAbortError(err)) return;
|
|
11924
|
+
if (isPermanentHttpError(err)) {
|
|
11925
|
+
if (!degraded) {
|
|
11926
|
+
const statusCode = errorStatusCode(err);
|
|
11927
|
+
const errorMsg = errorMessage(err);
|
|
11928
|
+
const httpPart = statusCode !== void 0 ? ` (HTTP ${statusCode})` : "";
|
|
11929
|
+
console.warn(
|
|
11930
|
+
`[zapier-sdk] Real-time wake-ups for inbox ${inboxId}${httpPart} paused: ${errorMsg}. Falling back to the periodic safety drain.`
|
|
11931
|
+
);
|
|
11932
|
+
degraded = true;
|
|
11933
|
+
}
|
|
11934
|
+
attempt = 0;
|
|
11935
|
+
if (signal.aborted) return;
|
|
11936
|
+
await sleep(safetyDrainMs, signal);
|
|
11937
|
+
continue;
|
|
11938
|
+
}
|
|
11939
|
+
if (connected) attempt = 0;
|
|
11940
|
+
transientError = err;
|
|
11941
|
+
}
|
|
11942
|
+
if (signal.aborted) return;
|
|
11943
|
+
const delay = SSE_RECONNECT_BACKOFF_MS[Math.min(attempt, SSE_RECONNECT_BACKOFF_MS.length - 1)];
|
|
11944
|
+
attempt = Math.min(attempt + 1, SSE_RECONNECT_BACKOFF_MS.length - 1);
|
|
11945
|
+
if (transientError !== void 0 && debug) {
|
|
11946
|
+
const statusCode = errorStatusCode(transientError);
|
|
11947
|
+
const errorMsg = errorMessage(transientError);
|
|
11948
|
+
const httpPart = statusCode !== void 0 ? ` (HTTP ${statusCode})` : "";
|
|
11949
|
+
console.error(
|
|
11950
|
+
`[zapier-sdk] Reconnecting real-time wake-ups for inbox ${inboxId} (attempt ${attempt}, retry in ${delay}ms)${httpPart}: ${errorMsg}`
|
|
11951
|
+
);
|
|
11952
|
+
}
|
|
11953
|
+
await sleep(delay, signal);
|
|
11954
|
+
}
|
|
11955
|
+
}
|
|
11956
|
+
async function safetyTimerLoop({
|
|
11957
|
+
safetyDrainMs,
|
|
11958
|
+
drainRequest,
|
|
11959
|
+
signal
|
|
11960
|
+
}) {
|
|
11961
|
+
while (!signal.aborted) {
|
|
11962
|
+
await sleep(safetyDrainMs, signal);
|
|
11963
|
+
if (signal.aborted) return;
|
|
11964
|
+
drainRequest.request();
|
|
11965
|
+
}
|
|
11966
|
+
}
|
|
11967
|
+
var watchTriggerInboxPlugin = definePlugin(
|
|
11968
|
+
(sdk) => {
|
|
11969
|
+
async function watchTriggerInbox(options) {
|
|
11970
|
+
const onMessage = requireOnMessage(options.onMessage);
|
|
11971
|
+
const { concurrency, leaseLimit } = resolveConcurrencyAndLease(options);
|
|
11972
|
+
const inboxId = await resolveTriggerInboxId({
|
|
11973
|
+
api: sdk.context.api,
|
|
11974
|
+
inbox: options.inbox
|
|
11975
|
+
});
|
|
11976
|
+
if (options.signal?.aborted) return;
|
|
11977
|
+
const safetyDrainMs = options.maxDrainIntervalSeconds !== void 0 ? options.maxDrainIntervalSeconds * 1e3 : DEFAULT_SAFETY_DRAIN_INTERVAL_MS;
|
|
11978
|
+
const stop = new AbortController();
|
|
11979
|
+
const combined = combineAbortSignals({
|
|
11980
|
+
handles: [
|
|
11981
|
+
...options.signal ? [{ signal: options.signal, dispose: () => {
|
|
11982
|
+
} }] : [],
|
|
11983
|
+
{ signal: stop.signal, dispose: () => {
|
|
11984
|
+
} }
|
|
11985
|
+
]
|
|
11986
|
+
});
|
|
11987
|
+
const signal = combined?.signal ?? stop.signal;
|
|
11988
|
+
const drainRequest = createDrainLatch();
|
|
11989
|
+
signal.addEventListener("abort", () => drainRequest.request(), {
|
|
11990
|
+
once: true
|
|
11991
|
+
});
|
|
11992
|
+
const debug = sdk.context.options.debug === true;
|
|
11993
|
+
const drainOptions = {
|
|
11994
|
+
sdk,
|
|
11995
|
+
inboxId,
|
|
11996
|
+
onMessage,
|
|
11997
|
+
concurrency,
|
|
11998
|
+
leaseLimit,
|
|
11999
|
+
leaseSeconds: options.leaseSeconds,
|
|
12000
|
+
maxMessages: void 0,
|
|
12001
|
+
releaseOnError: options.releaseOnError ?? false,
|
|
12002
|
+
continueOnError: options.continueOnError ?? false,
|
|
12003
|
+
onError: options.onError,
|
|
12004
|
+
signal
|
|
12005
|
+
};
|
|
12006
|
+
drainRequest.request();
|
|
12007
|
+
const runnerDone = drainRunner({
|
|
12008
|
+
drainOptions,
|
|
12009
|
+
drainRequest,
|
|
12010
|
+
signal,
|
|
12011
|
+
inboxId,
|
|
12012
|
+
debug
|
|
12013
|
+
});
|
|
12014
|
+
const sseDone = sseLoop({
|
|
12015
|
+
api: sdk.context.api,
|
|
12016
|
+
inboxId,
|
|
12017
|
+
drainRequest,
|
|
12018
|
+
safetyDrainMs,
|
|
12019
|
+
signal,
|
|
12020
|
+
debug
|
|
12021
|
+
}).catch(() => {
|
|
12022
|
+
});
|
|
12023
|
+
const safetyDone = safetyTimerLoop({
|
|
12024
|
+
safetyDrainMs,
|
|
12025
|
+
drainRequest,
|
|
12026
|
+
signal
|
|
12027
|
+
}).catch(() => {
|
|
12028
|
+
});
|
|
12029
|
+
let end;
|
|
12030
|
+
try {
|
|
12031
|
+
end = await runnerDone;
|
|
12032
|
+
} finally {
|
|
12033
|
+
stop.abort();
|
|
12034
|
+
await Promise.all([sseDone, safetyDone]);
|
|
12035
|
+
combined?.dispose();
|
|
12036
|
+
}
|
|
12037
|
+
if (end.kind === "error") throw end.error;
|
|
12038
|
+
}
|
|
12039
|
+
return {
|
|
12040
|
+
watchTriggerInbox,
|
|
12041
|
+
context: {
|
|
12042
|
+
meta: {
|
|
12043
|
+
watchTriggerInbox: {
|
|
12044
|
+
...triggersDefaults,
|
|
12045
|
+
type: "create",
|
|
12046
|
+
description: "Continuously consume a trigger inbox: drain currently-available messages via onMessage, then subscribe to SSE notifications for new arrivals until aborted. A periodic safety drain runs every maxDrainIntervalSeconds (default: 300) to guarantee forward progress if SSE events are missed. Resolves cleanly on signal abort or ZapierAbortDrainSignal from a handler. Transient drain failures (5xx, 429, network blips) retry indefinitely with bounded backoff until they succeed or the watch is aborted; it rejects on a fail-fast handler error, an initialization_failure, or a permanent HTTP error. Real-time wake-up health is reported on stderr: a warning when wake-ups pause and the watch falls back to the safety drain, plus (with debug) transient reconnect notices. Persistent drain failures likewise warn once on stderr while bounded-backoff retries continue.",
|
|
12047
|
+
itemType: "void",
|
|
12048
|
+
// See drainTriggerInbox: override the doc generator's default
|
|
12049
|
+
// suffix so the rendered return type is Promise<void>, not
|
|
12050
|
+
// Promise<voidItem>.
|
|
12051
|
+
returnType: "void",
|
|
12052
|
+
inputSchema: WatchTriggerInboxSchema,
|
|
12053
|
+
resolvers: {
|
|
12054
|
+
inbox: triggerInboxResolver
|
|
12055
|
+
},
|
|
12056
|
+
packages: ["sdk"]
|
|
12057
|
+
}
|
|
12058
|
+
}
|
|
12059
|
+
}
|
|
12060
|
+
};
|
|
12061
|
+
}
|
|
12062
|
+
);
|
|
12063
|
+
var ListTriggersSchema = zod.z.object({
|
|
12064
|
+
app: AppPropertySchema.describe(
|
|
12065
|
+
"App key of triggers to list (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
12066
|
+
),
|
|
12067
|
+
pageSize: zod.z.number().min(1).optional().describe("Number of triggers per page"),
|
|
12068
|
+
maxItems: zod.z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
12069
|
+
cursor: zod.z.string().optional().describe("Cursor to start from")
|
|
12070
|
+
}).describe("List all triggers for a specific app");
|
|
12071
|
+
|
|
12072
|
+
// src/plugins/triggers/listTriggers/index.ts
|
|
12073
|
+
var listTriggersPlugin = definePlugin(
|
|
12074
|
+
(sdk) => createPaginatedPluginMethod(sdk, {
|
|
12075
|
+
...triggersDefaults,
|
|
12076
|
+
name: "listTriggers",
|
|
12077
|
+
type: "list",
|
|
12078
|
+
itemType: "Action",
|
|
12079
|
+
inputSchema: ListTriggersSchema,
|
|
12080
|
+
outputSchema: ActionItemSchema,
|
|
12081
|
+
formatter: actionItemFormatter,
|
|
12082
|
+
defaultPageSize: DEFAULT_PAGE_SIZE,
|
|
12083
|
+
resolvers: { app: appKeyResolver },
|
|
12084
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
12085
|
+
return await sdk2.listActions({
|
|
12086
|
+
...options,
|
|
12087
|
+
actionType: "read"
|
|
12088
|
+
});
|
|
12089
|
+
}
|
|
12090
|
+
})
|
|
12091
|
+
);
|
|
12092
|
+
var ListTriggerInputFieldsSchema = zod.z.object({
|
|
12093
|
+
app: AppPropertySchema,
|
|
12094
|
+
action: ActionPropertySchema,
|
|
12095
|
+
connection: ConnectionPropertySchema.optional().describe(
|
|
12096
|
+
"Connection alias or connection ID. Required if the trigger needs a connection to determine available fields."
|
|
12097
|
+
),
|
|
12098
|
+
inputs: InputsPropertySchema.optional().describe(
|
|
12099
|
+
"Current input values that may affect available fields"
|
|
12100
|
+
),
|
|
12101
|
+
pageSize: zod.z.number().min(1).optional().describe("Number of input fields per page"),
|
|
12102
|
+
maxItems: zod.z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
12103
|
+
cursor: zod.z.string().optional().describe("Cursor to start from")
|
|
12104
|
+
}).describe("Get the input fields required for a specific trigger");
|
|
12105
|
+
|
|
12106
|
+
// src/plugins/triggers/listTriggerInputFields/index.ts
|
|
12107
|
+
var listTriggerInputFieldsPlugin = definePlugin(
|
|
12108
|
+
(sdk) => createPaginatedPluginMethod(sdk, {
|
|
12109
|
+
...triggersDefaults,
|
|
12110
|
+
name: "listTriggerInputFields",
|
|
12111
|
+
type: "list",
|
|
12112
|
+
itemType: "RootField",
|
|
12113
|
+
inputSchema: ListTriggerInputFieldsSchema,
|
|
12114
|
+
outputSchema: RootFieldItemSchema,
|
|
12115
|
+
formatter: rootFieldItemFormatter,
|
|
12116
|
+
defaultPageSize: DEFAULT_PAGE_SIZE,
|
|
12117
|
+
// actionKeyResolver and inputsAllOptionalResolver depend on actionType.
|
|
12118
|
+
// Pin it to "read" so they resolve correctly without the user setting it.
|
|
12119
|
+
resolvers: {
|
|
12120
|
+
app: appKeyResolver,
|
|
12121
|
+
action: actionKeyResolver,
|
|
12122
|
+
connection: connectionIdResolver,
|
|
12123
|
+
inputs: inputsAllOptionalResolver,
|
|
12124
|
+
actionType: { type: "constant", value: "read" }
|
|
12125
|
+
},
|
|
12126
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
12127
|
+
return await sdk2.listActionInputFields({
|
|
12128
|
+
...options,
|
|
12129
|
+
actionType: "read"
|
|
12130
|
+
});
|
|
12131
|
+
}
|
|
12132
|
+
})
|
|
12133
|
+
);
|
|
12134
|
+
var ListTriggerInputFieldChoicesSchema = zod.z.object({
|
|
12135
|
+
app: AppPropertySchema,
|
|
12136
|
+
action: ActionPropertySchema,
|
|
12137
|
+
inputField: InputFieldPropertySchema,
|
|
12138
|
+
connection: ConnectionPropertySchema.optional().describe(
|
|
12139
|
+
"Connection alias or connection ID. Required if the trigger needs a connection to populate dynamic dropdown options."
|
|
12140
|
+
),
|
|
12141
|
+
inputs: InputsPropertySchema.optional().describe(
|
|
12142
|
+
"Current input values that may affect available choices"
|
|
12143
|
+
),
|
|
12144
|
+
page: zod.z.number().int().min(0).optional().describe("Page number for paginated results"),
|
|
12145
|
+
pageSize: zod.z.number().min(1).optional().describe("Number of choices per page"),
|
|
12146
|
+
maxItems: zod.z.number().min(1).optional().describe("Maximum total items to return across all pages"),
|
|
12147
|
+
cursor: zod.z.string().optional().describe("Cursor to start from")
|
|
12148
|
+
}).describe(
|
|
12149
|
+
"Get the available choices for a dynamic dropdown input field on a trigger"
|
|
12150
|
+
);
|
|
12151
|
+
|
|
12152
|
+
// src/plugins/triggers/listTriggerInputFieldChoices/index.ts
|
|
12153
|
+
var listTriggerInputFieldChoicesPlugin = definePlugin(
|
|
12154
|
+
(sdk) => createPaginatedPluginMethod(sdk, {
|
|
12155
|
+
...triggersDefaults,
|
|
12156
|
+
name: "listTriggerInputFieldChoices",
|
|
12157
|
+
type: "list",
|
|
12158
|
+
itemType: "InputFieldChoice",
|
|
12159
|
+
inputSchema: ListTriggerInputFieldChoicesSchema,
|
|
12160
|
+
outputSchema: InputFieldChoiceItemSchema,
|
|
12161
|
+
formatter: inputFieldChoiceItemFormatter,
|
|
12162
|
+
defaultPageSize: DEFAULT_PAGE_SIZE,
|
|
12163
|
+
resolvers: {
|
|
12164
|
+
app: appKeyResolver,
|
|
12165
|
+
action: actionKeyResolver,
|
|
12166
|
+
connection: connectionIdResolver,
|
|
12167
|
+
inputField: inputFieldKeyResolver,
|
|
12168
|
+
inputs: inputsAllOptionalResolver,
|
|
12169
|
+
actionType: { type: "constant", value: "read" }
|
|
12170
|
+
},
|
|
12171
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
12172
|
+
return await sdk2.listActionInputFieldChoices({
|
|
12173
|
+
...options,
|
|
12174
|
+
actionType: "read"
|
|
12175
|
+
});
|
|
12176
|
+
}
|
|
12177
|
+
})
|
|
12178
|
+
);
|
|
12179
|
+
var GetTriggerInputFieldsSchemaSchema = zod.z.object({
|
|
12180
|
+
app: AppPropertySchema.describe(
|
|
12181
|
+
"App key (e.g., 'SlackCLIAPI' or slug like 'github') to get the input schema for"
|
|
12182
|
+
),
|
|
12183
|
+
action: ActionPropertySchema.describe(
|
|
12184
|
+
"Trigger action key to get the input schema for"
|
|
12185
|
+
),
|
|
12186
|
+
connection: ConnectionPropertySchema.optional().describe(
|
|
12187
|
+
"Connection alias or connection ID. Required if the trigger needs a connection to determine available fields."
|
|
12188
|
+
),
|
|
12189
|
+
inputs: InputsPropertySchema.optional().describe(
|
|
12190
|
+
"Current input values that may affect the schema (e.g., when fields depend on other field values)"
|
|
12191
|
+
)
|
|
12192
|
+
}).describe(
|
|
12193
|
+
"Get the JSON Schema representation of input fields for a trigger. Returns a JSON Schema object describing the structure, types, and validation rules for the trigger's input parameters."
|
|
12194
|
+
);
|
|
12195
|
+
|
|
12196
|
+
// src/plugins/triggers/getTriggerInputFieldsSchema/index.ts
|
|
12197
|
+
var getTriggerInputFieldsSchemaPlugin = definePlugin(
|
|
12198
|
+
(sdk) => createPluginMethod(sdk, {
|
|
12199
|
+
...triggersDefaults,
|
|
12200
|
+
name: "getTriggerInputFieldsSchema",
|
|
12201
|
+
type: "function",
|
|
12202
|
+
inputSchema: GetTriggerInputFieldsSchemaSchema,
|
|
12203
|
+
resolvers: {
|
|
12204
|
+
app: appKeyResolver,
|
|
12205
|
+
action: actionKeyResolver,
|
|
12206
|
+
connection: connectionIdResolver,
|
|
12207
|
+
inputs: inputsAllOptionalResolver,
|
|
12208
|
+
actionType: { type: "constant", value: "read" }
|
|
12209
|
+
},
|
|
12210
|
+
handler: async ({ sdk: sdk2, options }) => {
|
|
12211
|
+
return sdk2.getActionInputFieldsSchema({
|
|
12212
|
+
...options,
|
|
12213
|
+
actionType: "read"
|
|
12214
|
+
});
|
|
12215
|
+
}
|
|
12216
|
+
})
|
|
12217
|
+
);
|
|
10501
12218
|
var TableApiItemSchema = zod.z.object({
|
|
10502
12219
|
id: zod.z.string(),
|
|
10503
12220
|
name: zod.z.string(),
|
|
@@ -11950,10 +13667,10 @@ var eventEmissionPlugin = definePlugin(
|
|
|
11950
13667
|
registeredListeners.uncaughtException = uncaughtExceptionHandler;
|
|
11951
13668
|
globalThis.process.on("uncaughtException", uncaughtExceptionHandler);
|
|
11952
13669
|
const unhandledRejectionHandler = async (reason, promise) => {
|
|
11953
|
-
const
|
|
13670
|
+
const errorMessage2 = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "Unhandled promise rejection";
|
|
11954
13671
|
const errorStack = reason instanceof Error ? reason.stack : null;
|
|
11955
13672
|
let errorEvent = buildErrorEventWithContext({
|
|
11956
|
-
error_message:
|
|
13673
|
+
error_message: errorMessage2,
|
|
11957
13674
|
error_type: "UnhandledRejection",
|
|
11958
13675
|
error_stack_trace: errorStack,
|
|
11959
13676
|
error_severity: "critical",
|
|
@@ -12079,7 +13796,7 @@ function createZapierSdkWithoutRegistry(options = {}) {
|
|
|
12079
13796
|
return createZapierSdk(options);
|
|
12080
13797
|
}
|
|
12081
13798
|
function createZapierSdkStack(options = {}) {
|
|
12082
|
-
return createZapierCoreStack().use(createOptionsPlugin(options)).use(eventEmissionPlugin).use(apiPlugin).use(manifestPlugin).use(capabilitiesPlugin).use(connectionsPlugin).use(listAppsPlugin).use(getAppPlugin).use(listConnectionsPlugin).use(getConnectionPlugin).use(findFirstConnectionPlugin).use(findUniqueConnectionPlugin).use(getConnectionStartUrlPlugin).use(waitForNewConnectionPlugin).use(createConnectionPlugin).use(listActionsPlugin).use(getActionPlugin).use(listActionInputFieldsPlugin).use(getActionInputFieldsSchemaPlugin).use(listActionInputFieldChoicesPlugin).use(listInputFieldsDeprecatedPlugin).use(getInputFieldsSchemaDeprecatedPlugin).use(listInputFieldChoicesDeprecatedPlugin).use(runActionPlugin).use(listAuthenticationsPlugin).use(getAuthenticationPlugin).use(findFirstAuthenticationPlugin).use(findUniqueAuthenticationPlugin).use(listClientCredentialsPlugin).use(createClientCredentialsPlugin).use(deleteClientCredentialsPlugin).use(fetchPlugin).use(requestPlugin).use(listTablesPlugin).use(getTablePlugin).use(deleteTablePlugin).use(createTablePlugin).use(listTableFieldsPlugin).use(createTableFieldsPlugin).use(deleteTableFieldsPlugin).use(listTableRecordsPlugin).use(getTableRecordPlugin).use(createTableRecordsPlugin).use(deleteTableRecordsPlugin).use(updateTableRecordsPlugin).use(appsPlugin);
|
|
13799
|
+
return createZapierCoreStack().use(createOptionsPlugin(options)).use(eventEmissionPlugin).use(apiPlugin).use(manifestPlugin).use(capabilitiesPlugin).use(connectionsPlugin).use(listAppsPlugin).use(getAppPlugin).use(listConnectionsPlugin).use(getConnectionPlugin).use(findFirstConnectionPlugin).use(findUniqueConnectionPlugin).use(getConnectionStartUrlPlugin).use(waitForNewConnectionPlugin).use(createConnectionPlugin).use(listActionsPlugin).use(getActionPlugin).use(listActionInputFieldsPlugin).use(getActionInputFieldsSchemaPlugin).use(listActionInputFieldChoicesPlugin).use(listInputFieldsDeprecatedPlugin).use(getInputFieldsSchemaDeprecatedPlugin).use(listInputFieldChoicesDeprecatedPlugin).use(runActionPlugin).use(listAuthenticationsPlugin).use(getAuthenticationPlugin).use(findFirstAuthenticationPlugin).use(findUniqueAuthenticationPlugin).use(listClientCredentialsPlugin).use(createClientCredentialsPlugin).use(deleteClientCredentialsPlugin).use(fetchPlugin).use(requestPlugin).use(listTriggerInboxesPlugin).use(createTriggerInboxPlugin).use(ensureTriggerInboxPlugin).use(getTriggerInboxPlugin).use(updateTriggerInboxPlugin).use(deleteTriggerInboxPlugin).use(pauseTriggerInboxPlugin).use(resumeTriggerInboxPlugin).use(listTriggerInboxMessagesPlugin).use(leaseTriggerInboxMessagesPlugin).use(ackTriggerInboxMessagesPlugin).use(releaseTriggerInboxMessagesPlugin).use(drainTriggerInboxPlugin).use(watchTriggerInboxPlugin).use(listTriggersPlugin).use(listTriggerInputFieldsPlugin).use(listTriggerInputFieldChoicesPlugin).use(getTriggerInputFieldsSchemaPlugin).use(listTablesPlugin).use(getTablePlugin).use(deleteTablePlugin).use(createTablePlugin).use(listTableFieldsPlugin).use(createTableFieldsPlugin).use(deleteTableFieldsPlugin).use(listTableRecordsPlugin).use(getTableRecordPlugin).use(createTableRecordsPlugin).use(deleteTableRecordsPlugin).use(updateTableRecordsPlugin).use(appsPlugin);
|
|
12083
13800
|
}
|
|
12084
13801
|
var zapierSdkPlugin = definePlugin({
|
|
12085
13802
|
namespace: "zapier",
|