@zapier/zapier-sdk 0.94.1 → 0.95.0
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 +7 -0
- package/README.md +2 -1
- package/dist/{chunk-XETAS26U.mjs → chunk-JZDH3POI.mjs} +77 -60
- package/dist/{chunk-7NCOFRA6.cjs → chunk-Z7BGM75G.cjs} +77 -60
- package/dist/experimental.cjs +397 -383
- package/dist/experimental.d.mts +4 -0
- package/dist/experimental.d.ts +4 -0
- package/dist/experimental.mjs +19 -5
- package/dist/index.cjs +276 -276
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @zapier/zapier-sdk
|
|
2
2
|
|
|
3
|
+
## 0.95.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 80dc74a: Auto-mode approvals that are escalated to a human reviewer now open the approval URL in the browser automatically and continue polling until the reviewer decides.
|
|
8
|
+
- 6e5189c: Added a `manual` option (experimental) to `publishWorkflowVersion`, exposed in the CLI as `--manual` on `publish-workflow-version`. Pass `manual: true` to publish an on-demand, triggerless workflow version explicitly; pass `trigger` for a triggered one. The two are mutually exclusive — sending both is rejected with a 400.
|
|
9
|
+
|
|
3
10
|
## 0.94.1
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2019,11 +2019,12 @@ Publish a new version of a durable workflow. Enables the workflow by default.
|
|
|
2019
2019
|
| ↳ `ignoreOpenDrafts` | `boolean` | ❌ | — | — | Publish even though the workflow has open draft(s). Without this, the API rejects a direct publish with a 409 while any draft is open, since publishing the draft later would ship its stale content over this version. |
|
|
2020
2020
|
| ↳ `connections` | `object` | ❌ | — | — | Map of connection aliases to Zapier connections used by the workflow. Pass `null` to clear an existing binding. |
|
|
2021
2021
|
| ↳ `appVersions` | `object` | ❌ | — | — | Map of app keys to pinned app implementation/version used by the workflow. Pass `null` to clear an existing binding. |
|
|
2022
|
-
| ↳ `trigger` | `object` | ❌ | — | — | Trigger configuration. When provided, the workflow subscribes to a Zapier trigger;
|
|
2022
|
+
| ↳ `trigger` | `object` | ❌ | — | — | Trigger configuration. When provided, the workflow subscribes to a Zapier trigger; for an on-demand, triggerless workflow, omit this and pass `manual: true` instead. |
|
|
2023
2023
|
| ↳ `selectedApi` | `string` | ❌ | — | — | Zapier app/API identifier (e.g. 'GoogleSheetsAPI'). Required when a trigger is configured. |
|
|
2024
2024
|
| ↳ `action` | `string` | ✅ | — | — | Trigger action key (e.g. 'new_row') |
|
|
2025
2025
|
| ↳ `authenticationId` | `string` | ❌ | — | — | Connection ID for the trigger source. Omit or pass null for no-auth triggers (e.g. Schedule by Zapier). |
|
|
2026
2026
|
| ↳ `params` | `object` | ❌ | — | — | Trigger parameters as a JSON object |
|
|
2027
|
+
| ↳ `manual` | `boolean` | ❌ | — | — | Declare this an on-demand, triggerless workflow version. Pass `manual: true` only when omitting `trigger`; passing both is a contradiction the API rejects with a 400. |
|
|
2027
2028
|
|
|
2028
2029
|
**Returns:** `Promise<WorkflowVersionItem>`
|
|
2029
2030
|
|
|
@@ -6192,7 +6192,7 @@ function parseDeprecationDate(value) {
|
|
|
6192
6192
|
}
|
|
6193
6193
|
|
|
6194
6194
|
// src/sdk-version.ts
|
|
6195
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.
|
|
6195
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.95.0" : void 0) || "unknown";
|
|
6196
6196
|
|
|
6197
6197
|
// src/utils/open-url.ts
|
|
6198
6198
|
var nodePrefix = "node:";
|
|
@@ -6301,7 +6301,11 @@ var PollApprovalResponseSchema = z.object({
|
|
|
6301
6301
|
status: ApprovalStatusSchema,
|
|
6302
6302
|
approval_id: z.string().optional(),
|
|
6303
6303
|
mode: ApprovalModeSchema.optional(),
|
|
6304
|
-
reason: z.string().optional()
|
|
6304
|
+
reason: z.string().optional(),
|
|
6305
|
+
// Present when an auto-mode agent escalated the approval to a human reviewer.
|
|
6306
|
+
// The SDK uses review_status to detect escalation and approval_url to open the browser.
|
|
6307
|
+
review_status: z.enum(["in_review", "escalated"]).optional(),
|
|
6308
|
+
approval_url: z.string().optional()
|
|
6305
6309
|
});
|
|
6306
6310
|
var APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS = 5e3;
|
|
6307
6311
|
function validateSdkPath(path) {
|
|
@@ -7311,6 +7315,7 @@ var ZapierApiClient = class {
|
|
|
7311
7315
|
await openApproval(approval.approval_url);
|
|
7312
7316
|
}
|
|
7313
7317
|
const timeoutMs = this.options.approvalTimeoutMilliseconds ?? this.options.approvalTimeoutMs ?? DEFAULT_APPROVAL_TIMEOUT_MILLISECONDS;
|
|
7318
|
+
const approvalDeadline = Date.now() + timeoutMs;
|
|
7314
7319
|
let streamAbortController;
|
|
7315
7320
|
let streamPromise;
|
|
7316
7321
|
let removeStreamAbortListener;
|
|
@@ -7332,75 +7337,87 @@ var ZapierApiClient = class {
|
|
|
7332
7337
|
emitEvent: (type, payload) => this.emitEvent(type, payload)
|
|
7333
7338
|
});
|
|
7334
7339
|
}
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
),
|
|
7352
|
-
timeoutMs,
|
|
7353
|
-
maxPollingIntervalMs: APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS,
|
|
7354
|
-
signal,
|
|
7355
|
-
isPending: (body2) => {
|
|
7356
|
-
const parsed = PollApprovalResponseSchema.safeParse(body2);
|
|
7357
|
-
return parsed.success && parsed.data.status === "pending_approval";
|
|
7358
|
-
}
|
|
7359
|
-
});
|
|
7360
|
-
} catch (err) {
|
|
7361
|
-
if (!isZapierTimeoutError(err)) {
|
|
7362
|
-
this.emitEvent("approval:error", {
|
|
7363
|
-
approvalId: approval.id,
|
|
7364
|
-
message: err instanceof Error ? err.message : String(err)
|
|
7340
|
+
const fetchApprovalPoll = () => this.withSemaphore(
|
|
7341
|
+
{ url: approval.poll_url, method: "GET", signal },
|
|
7342
|
+
() => this.rawFetchUrl(approval.poll_url, {
|
|
7343
|
+
method: "GET",
|
|
7344
|
+
headers: { Accept: "application/json" },
|
|
7345
|
+
signal
|
|
7346
|
+
})
|
|
7347
|
+
);
|
|
7348
|
+
const pollApprovalUntilComplete = async (isPending, deadlineMs = approvalDeadline) => {
|
|
7349
|
+
try {
|
|
7350
|
+
return await pollUntilComplete({
|
|
7351
|
+
fetchPoll: fetchApprovalPoll,
|
|
7352
|
+
timeoutMs: Math.max(1, deadlineMs - Date.now()),
|
|
7353
|
+
maxPollingIntervalMs: APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS,
|
|
7354
|
+
signal,
|
|
7355
|
+
isPending
|
|
7365
7356
|
});
|
|
7366
|
-
|
|
7357
|
+
} catch (err) {
|
|
7358
|
+
if (!isZapierTimeoutError(err)) {
|
|
7359
|
+
this.emitEvent("approval:error", {
|
|
7360
|
+
approvalId: approval.id,
|
|
7361
|
+
message: err instanceof Error ? err.message : String(err)
|
|
7362
|
+
});
|
|
7363
|
+
throw err;
|
|
7364
|
+
}
|
|
7365
|
+
this.emitEvent("approval:timeout", { approvalId: approval.id });
|
|
7366
|
+
throw new ZapierApprovalError(
|
|
7367
|
+
`Approval timed out after ${timeoutMs / 1e3} seconds`,
|
|
7368
|
+
{
|
|
7369
|
+
approvalId: approval.id,
|
|
7370
|
+
approvalUrl: approval.approval_url,
|
|
7371
|
+
pollUrl: approval.poll_url,
|
|
7372
|
+
streamUrl: approval.stream_url,
|
|
7373
|
+
status: "timeout",
|
|
7374
|
+
cause: err
|
|
7375
|
+
}
|
|
7376
|
+
);
|
|
7367
7377
|
}
|
|
7368
|
-
|
|
7369
|
-
|
|
7378
|
+
};
|
|
7379
|
+
let rawPollResult;
|
|
7380
|
+
try {
|
|
7381
|
+
rawPollResult = await pollApprovalUntilComplete((body2) => {
|
|
7382
|
+
const parsed = PollApprovalResponseSchema.safeParse(body2);
|
|
7383
|
+
if (!parsed.success) return false;
|
|
7384
|
+
if (parsed.data.review_status === "escalated") return false;
|
|
7385
|
+
return parsed.data.status === "pending_approval";
|
|
7370
7386
|
});
|
|
7371
|
-
throw new ZapierApprovalError(
|
|
7372
|
-
`Approval timed out after ${timeoutMs / 1e3} seconds`,
|
|
7373
|
-
{
|
|
7374
|
-
approvalId: approval.id,
|
|
7375
|
-
approvalUrl: approval.approval_url,
|
|
7376
|
-
pollUrl: approval.poll_url,
|
|
7377
|
-
streamUrl: approval.stream_url,
|
|
7378
|
-
status: "timeout",
|
|
7379
|
-
cause: err
|
|
7380
|
-
}
|
|
7381
|
-
);
|
|
7382
7387
|
} finally {
|
|
7383
7388
|
removeStreamAbortListener?.();
|
|
7384
7389
|
streamAbortController?.abort();
|
|
7385
7390
|
await streamPromise;
|
|
7386
7391
|
}
|
|
7387
|
-
const
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7392
|
+
const parsePollResult = (raw) => {
|
|
7393
|
+
const parsed = PollApprovalResponseSchema.safeParse(raw);
|
|
7394
|
+
if (!parsed.success) {
|
|
7395
|
+
const bodyPreview = typeof raw === "string" ? raw : JSON.stringify(raw);
|
|
7396
|
+
this.emitEvent("approval:error", {
|
|
7397
|
+
approvalId: approval.id,
|
|
7398
|
+
message: `Failed to parse approval poll response: ${bodyPreview}`
|
|
7399
|
+
});
|
|
7400
|
+
throw new ZapierApiError(
|
|
7401
|
+
`Failed to parse approval poll response: ${bodyPreview}`,
|
|
7402
|
+
{ statusCode: 0, cause: parsed.error, response: raw }
|
|
7403
|
+
);
|
|
7404
|
+
}
|
|
7405
|
+
return parsed.data;
|
|
7406
|
+
};
|
|
7407
|
+
const pollResult = parsePollResult(rawPollResult);
|
|
7408
|
+
if (pollResult.review_status === "escalated") {
|
|
7409
|
+
const escalationUrl = pollResult.approval_url ?? approval.approval_url;
|
|
7410
|
+
this.emitEvent("approval:escalated", {
|
|
7391
7411
|
approvalId: approval.id,
|
|
7392
|
-
|
|
7412
|
+
approvalUrl: escalationUrl
|
|
7393
7413
|
});
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
}
|
|
7401
|
-
);
|
|
7414
|
+
await openApproval(escalationUrl);
|
|
7415
|
+
const humanRaw = await pollApprovalUntilComplete((body2) => {
|
|
7416
|
+
const parsed = PollApprovalResponseSchema.safeParse(body2);
|
|
7417
|
+
return parsed.success && parsed.data.status === "pending_approval";
|
|
7418
|
+
});
|
|
7419
|
+
Object.assign(pollResult, parsePollResult(humanRaw));
|
|
7402
7420
|
}
|
|
7403
|
-
const pollResult = pollParse.data;
|
|
7404
7421
|
if (pollResult.status === "denied") {
|
|
7405
7422
|
this.emitEvent("approval:denied", {
|
|
7406
7423
|
approvalId: approval.id,
|
|
@@ -6194,7 +6194,7 @@ function parseDeprecationDate(value) {
|
|
|
6194
6194
|
}
|
|
6195
6195
|
|
|
6196
6196
|
// src/sdk-version.ts
|
|
6197
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.
|
|
6197
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.95.0" : void 0) || "unknown";
|
|
6198
6198
|
|
|
6199
6199
|
// src/utils/open-url.ts
|
|
6200
6200
|
var nodePrefix = "node:";
|
|
@@ -6303,7 +6303,11 @@ var PollApprovalResponseSchema = zod.z.object({
|
|
|
6303
6303
|
status: ApprovalStatusSchema,
|
|
6304
6304
|
approval_id: zod.z.string().optional(),
|
|
6305
6305
|
mode: ApprovalModeSchema.optional(),
|
|
6306
|
-
reason: zod.z.string().optional()
|
|
6306
|
+
reason: zod.z.string().optional(),
|
|
6307
|
+
// Present when an auto-mode agent escalated the approval to a human reviewer.
|
|
6308
|
+
// The SDK uses review_status to detect escalation and approval_url to open the browser.
|
|
6309
|
+
review_status: zod.z.enum(["in_review", "escalated"]).optional(),
|
|
6310
|
+
approval_url: zod.z.string().optional()
|
|
6307
6311
|
});
|
|
6308
6312
|
var APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS = 5e3;
|
|
6309
6313
|
function validateSdkPath(path) {
|
|
@@ -7313,6 +7317,7 @@ var ZapierApiClient = class {
|
|
|
7313
7317
|
await openApproval(approval.approval_url);
|
|
7314
7318
|
}
|
|
7315
7319
|
const timeoutMs = this.options.approvalTimeoutMilliseconds ?? this.options.approvalTimeoutMs ?? DEFAULT_APPROVAL_TIMEOUT_MILLISECONDS;
|
|
7320
|
+
const approvalDeadline = Date.now() + timeoutMs;
|
|
7316
7321
|
let streamAbortController;
|
|
7317
7322
|
let streamPromise;
|
|
7318
7323
|
let removeStreamAbortListener;
|
|
@@ -7334,75 +7339,87 @@ var ZapierApiClient = class {
|
|
|
7334
7339
|
emitEvent: (type, payload) => this.emitEvent(type, payload)
|
|
7335
7340
|
});
|
|
7336
7341
|
}
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
),
|
|
7354
|
-
timeoutMs,
|
|
7355
|
-
maxPollingIntervalMs: APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS,
|
|
7356
|
-
signal,
|
|
7357
|
-
isPending: (body2) => {
|
|
7358
|
-
const parsed = PollApprovalResponseSchema.safeParse(body2);
|
|
7359
|
-
return parsed.success && parsed.data.status === "pending_approval";
|
|
7360
|
-
}
|
|
7361
|
-
});
|
|
7362
|
-
} catch (err) {
|
|
7363
|
-
if (!isZapierTimeoutError(err)) {
|
|
7364
|
-
this.emitEvent("approval:error", {
|
|
7365
|
-
approvalId: approval.id,
|
|
7366
|
-
message: err instanceof Error ? err.message : String(err)
|
|
7342
|
+
const fetchApprovalPoll = () => this.withSemaphore(
|
|
7343
|
+
{ url: approval.poll_url, method: "GET", signal },
|
|
7344
|
+
() => this.rawFetchUrl(approval.poll_url, {
|
|
7345
|
+
method: "GET",
|
|
7346
|
+
headers: { Accept: "application/json" },
|
|
7347
|
+
signal
|
|
7348
|
+
})
|
|
7349
|
+
);
|
|
7350
|
+
const pollApprovalUntilComplete = async (isPending, deadlineMs = approvalDeadline) => {
|
|
7351
|
+
try {
|
|
7352
|
+
return await pollUntilComplete({
|
|
7353
|
+
fetchPoll: fetchApprovalPoll,
|
|
7354
|
+
timeoutMs: Math.max(1, deadlineMs - Date.now()),
|
|
7355
|
+
maxPollingIntervalMs: APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS,
|
|
7356
|
+
signal,
|
|
7357
|
+
isPending
|
|
7367
7358
|
});
|
|
7368
|
-
|
|
7359
|
+
} catch (err) {
|
|
7360
|
+
if (!isZapierTimeoutError(err)) {
|
|
7361
|
+
this.emitEvent("approval:error", {
|
|
7362
|
+
approvalId: approval.id,
|
|
7363
|
+
message: err instanceof Error ? err.message : String(err)
|
|
7364
|
+
});
|
|
7365
|
+
throw err;
|
|
7366
|
+
}
|
|
7367
|
+
this.emitEvent("approval:timeout", { approvalId: approval.id });
|
|
7368
|
+
throw new ZapierApprovalError(
|
|
7369
|
+
`Approval timed out after ${timeoutMs / 1e3} seconds`,
|
|
7370
|
+
{
|
|
7371
|
+
approvalId: approval.id,
|
|
7372
|
+
approvalUrl: approval.approval_url,
|
|
7373
|
+
pollUrl: approval.poll_url,
|
|
7374
|
+
streamUrl: approval.stream_url,
|
|
7375
|
+
status: "timeout",
|
|
7376
|
+
cause: err
|
|
7377
|
+
}
|
|
7378
|
+
);
|
|
7369
7379
|
}
|
|
7370
|
-
|
|
7371
|
-
|
|
7380
|
+
};
|
|
7381
|
+
let rawPollResult;
|
|
7382
|
+
try {
|
|
7383
|
+
rawPollResult = await pollApprovalUntilComplete((body2) => {
|
|
7384
|
+
const parsed = PollApprovalResponseSchema.safeParse(body2);
|
|
7385
|
+
if (!parsed.success) return false;
|
|
7386
|
+
if (parsed.data.review_status === "escalated") return false;
|
|
7387
|
+
return parsed.data.status === "pending_approval";
|
|
7372
7388
|
});
|
|
7373
|
-
throw new ZapierApprovalError(
|
|
7374
|
-
`Approval timed out after ${timeoutMs / 1e3} seconds`,
|
|
7375
|
-
{
|
|
7376
|
-
approvalId: approval.id,
|
|
7377
|
-
approvalUrl: approval.approval_url,
|
|
7378
|
-
pollUrl: approval.poll_url,
|
|
7379
|
-
streamUrl: approval.stream_url,
|
|
7380
|
-
status: "timeout",
|
|
7381
|
-
cause: err
|
|
7382
|
-
}
|
|
7383
|
-
);
|
|
7384
7389
|
} finally {
|
|
7385
7390
|
removeStreamAbortListener?.();
|
|
7386
7391
|
streamAbortController?.abort();
|
|
7387
7392
|
await streamPromise;
|
|
7388
7393
|
}
|
|
7389
|
-
const
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7394
|
+
const parsePollResult = (raw) => {
|
|
7395
|
+
const parsed = PollApprovalResponseSchema.safeParse(raw);
|
|
7396
|
+
if (!parsed.success) {
|
|
7397
|
+
const bodyPreview = typeof raw === "string" ? raw : JSON.stringify(raw);
|
|
7398
|
+
this.emitEvent("approval:error", {
|
|
7399
|
+
approvalId: approval.id,
|
|
7400
|
+
message: `Failed to parse approval poll response: ${bodyPreview}`
|
|
7401
|
+
});
|
|
7402
|
+
throw new ZapierApiError(
|
|
7403
|
+
`Failed to parse approval poll response: ${bodyPreview}`,
|
|
7404
|
+
{ statusCode: 0, cause: parsed.error, response: raw }
|
|
7405
|
+
);
|
|
7406
|
+
}
|
|
7407
|
+
return parsed.data;
|
|
7408
|
+
};
|
|
7409
|
+
const pollResult = parsePollResult(rawPollResult);
|
|
7410
|
+
if (pollResult.review_status === "escalated") {
|
|
7411
|
+
const escalationUrl = pollResult.approval_url ?? approval.approval_url;
|
|
7412
|
+
this.emitEvent("approval:escalated", {
|
|
7393
7413
|
approvalId: approval.id,
|
|
7394
|
-
|
|
7414
|
+
approvalUrl: escalationUrl
|
|
7395
7415
|
});
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
}
|
|
7403
|
-
);
|
|
7416
|
+
await openApproval(escalationUrl);
|
|
7417
|
+
const humanRaw = await pollApprovalUntilComplete((body2) => {
|
|
7418
|
+
const parsed = PollApprovalResponseSchema.safeParse(body2);
|
|
7419
|
+
return parsed.success && parsed.data.status === "pending_approval";
|
|
7420
|
+
});
|
|
7421
|
+
Object.assign(pollResult, parsePollResult(humanRaw));
|
|
7404
7422
|
}
|
|
7405
|
-
const pollResult = pollParse.data;
|
|
7406
7423
|
if (pollResult.status === "denied") {
|
|
7407
7424
|
this.emitEvent("approval:denied", {
|
|
7408
7425
|
approvalId: approval.id,
|