@zapier/zapier-sdk 0.42.1 → 0.43.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/api/client.d.ts.map +1 -1
  3. package/dist/api/client.js +309 -35
  4. package/dist/api/types.d.ts +29 -0
  5. package/dist/api/types.d.ts.map +1 -1
  6. package/dist/constants.d.ts +25 -0
  7. package/dist/constants.d.ts.map +1 -1
  8. package/dist/constants.js +32 -0
  9. package/dist/index.cjs +431 -38
  10. package/dist/index.d.mts +79 -1
  11. package/dist/index.mjs +427 -39
  12. package/dist/plugins/api/index.d.ts.map +1 -1
  13. package/dist/plugins/api/index.js +5 -1
  14. package/dist/plugins/createClientCredentials/index.d.ts.map +1 -1
  15. package/dist/plugins/createClientCredentials/index.js +1 -0
  16. package/dist/plugins/createClientCredentials/schemas.d.ts +1 -0
  17. package/dist/plugins/createClientCredentials/schemas.d.ts.map +1 -1
  18. package/dist/plugins/createClientCredentials/schemas.js +6 -0
  19. package/dist/plugins/fetch/index.d.ts.map +1 -1
  20. package/dist/plugins/fetch/index.js +15 -1
  21. package/dist/plugins/runAction/index.d.ts.map +1 -1
  22. package/dist/plugins/runAction/index.js +12 -1
  23. package/dist/types/errors.d.ts +37 -0
  24. package/dist/types/errors.d.ts.map +1 -1
  25. package/dist/types/errors.js +18 -0
  26. package/dist/types/sdk.d.ts +7 -0
  27. package/dist/types/sdk.d.ts.map +1 -1
  28. package/dist/types/sdk.js +20 -0
  29. package/dist/utils/open-approval.d.ts +2 -0
  30. package/dist/utils/open-approval.d.ts.map +1 -0
  31. package/dist/utils/open-approval.js +13 -0
  32. package/dist/utils/open-url.d.ts +3 -0
  33. package/dist/utils/open-url.d.ts.map +1 -0
  34. package/dist/utils/open-url.js +72 -0
  35. package/package.json +3 -1
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { buildHttpRequestContext, buildActionRunContext } from '@zapier/policy-context';
2
3
  import { ListAppsQuerySchema, AppItemSchema as AppItemSchema$1 } from '@zapier/zapier-sdk-core/v0/schemas/apps';
3
4
  import { ListConnectionsQuerySchema as ListConnectionsQuerySchema$1, ConnectionItemSchema as ConnectionItemSchema$1 } from '@zapier/zapier-sdk-core/v0/schemas/connections';
4
5
  import { ListClientCredentialsQuerySchema as ListClientCredentialsQuerySchema$1, CreateClientCredentialsRequestSchema, ClientCredentialsItemSchema as ClientCredentialsItemSchema$1, ClientCredentialsCreatedItemSchema as ClientCredentialsCreatedItemSchema$1 } from '@zapier/zapier-sdk-core/v0/schemas/client-credentials';
@@ -56,6 +57,16 @@ function parseIntEnvVar(name) {
56
57
  }
57
58
  var ZAPIER_MAX_NETWORK_RETRIES = parseIntEnvVar("ZAPIER_MAX_NETWORK_RETRIES") ?? 3;
58
59
  var ZAPIER_MAX_NETWORK_RETRY_DELAY_MS = parseIntEnvVar("ZAPIER_MAX_NETWORK_RETRY_DELAY_MS") ?? 6e4;
60
+ function getZapierIsInteractive() {
61
+ return globalThis.process?.env?.ZAPIER_IS_INTERACTIVE === "true";
62
+ }
63
+ function getZapierApprovalMode() {
64
+ const value = globalThis.process?.env?.ZAPIER_APPROVAL_MODE;
65
+ if (value === "poll" || value === "fail") return value;
66
+ return void 0;
67
+ }
68
+ var DEFAULT_APPROVAL_TIMEOUT_MS = 10 * 60 * 1e3;
69
+ var DEFAULT_MAX_APPROVAL_RETRIES = 2;
59
70
 
60
71
  // src/types/properties.ts
61
72
  var AppKeyPropertySchema = withPositional(
@@ -224,6 +235,17 @@ var ZapierRateLimitError = class extends ZapierError {
224
235
  this.retries = options.retries ?? 0;
225
236
  }
226
237
  };
238
+ var ZapierApprovalError = class extends ZapierError {
239
+ constructor(message, options = {}) {
240
+ super(message, options);
241
+ this.name = "ZapierApprovalError";
242
+ this.code = "ZAPIER_APPROVAL_ERROR";
243
+ this.approvalId = options.approvalId;
244
+ this.approvalStatus = options.status;
245
+ this.approvalUrl = options.approvalUrl;
246
+ this.pollUrl = options.pollUrl;
247
+ }
248
+ };
227
249
  var ZapierRelayError = class extends ZapierError {
228
250
  constructor(message, options = {}) {
229
251
  super(message, options);
@@ -268,6 +290,10 @@ ${context.join(", ")}`;
268
290
  if (error instanceof ZapierBundleError && error.buildErrors && error.buildErrors.length > 0) {
269
291
  message += "\n\nBuild errors:\n" + error.buildErrors.map((err) => ` \u2022 ${err}`).join("\n");
270
292
  }
293
+ if (error instanceof ZapierApprovalError && error.approvalUrl) {
294
+ message += `
295
+ Approval URL: ${error.approvalUrl}`;
296
+ }
271
297
  if (error instanceof ZapierRateLimitError) {
272
298
  const { limit, remaining, retryAfterMs } = error.rateLimit;
273
299
  const parts = [];
@@ -975,18 +1001,27 @@ var fetchPlugin = (sdk) => {
975
1001
  if (maxTime !== void 0) {
976
1002
  headers["X-Zapier-Sdk-Max-Time"] = String(maxTime);
977
1003
  }
1004
+ const upstreamUrl = new URL(url).toString();
1005
+ const method = (fetchInit.method ?? "GET").toUpperCase();
978
1006
  const abortHandle = buildAbortHandle({
979
1007
  maxTimeSeconds: maxTime,
980
1008
  callerSignal: fetchInit.signal
981
1009
  });
982
1010
  try {
983
1011
  const result = await api.fetch(relayPath, {
984
- method: fetchInit.method ?? "GET",
1012
+ method,
985
1013
  body: fetchInit.body,
986
1014
  headers,
987
1015
  redirect: fetchInit.redirect,
988
1016
  signal: abortHandle?.signal,
989
- authRequired: true
1017
+ authRequired: true,
1018
+ approvalContext: () => buildHttpRequestContext({
1019
+ method,
1020
+ url: upstreamUrl,
1021
+ headers,
1022
+ body: typeof fetchInit.body === "string" ? fetchInit.body : void 0,
1023
+ connection_id: resolvedConnectionId ? String(resolvedConnectionId) : void 0
1024
+ })
990
1025
  });
991
1026
  const relayError = result.headers.get("x-relay-error");
992
1027
  if (relayError) {
@@ -3672,7 +3707,9 @@ var listClientCredentialsPlugin = (sdk) => {
3672
3707
  };
3673
3708
  };
3674
3709
  var CreateClientCredentialsSchema = CreateClientCredentialsRequestSchema.omit({ allowed_scopes: true }).extend({
3675
- allowedScopes: z.array(z.enum(["credentials", "external"])).default(["external"]).describe("Scopes to allow for these credentials")
3710
+ allowedScopes: z.array(z.enum(["credentials", "external"])).default(["external"]).describe("Scopes to allow for these credentials"),
3711
+ // Temporarily hidden while we finalise work to make approvals/policies customer-facing.
3712
+ policy: z.record(z.string(), z.unknown()).optional().describe("Policy document (JSON) to attach to the credentials").meta({ deprecated: true })
3676
3713
  }).describe("Create new client credentials for the authenticated user");
3677
3714
 
3678
3715
  // src/plugins/createClientCredentials/index.ts
@@ -3683,7 +3720,8 @@ var createClientCredentialsPlugin = (sdk) => {
3683
3720
  "/api/v0/client-credentials",
3684
3721
  {
3685
3722
  name: options.name,
3686
- allowed_scopes: options.allowedScopes
3723
+ allowed_scopes: options.allowedScopes,
3724
+ ...options.policy && { policy: options.policy }
3687
3725
  },
3688
3726
  {
3689
3727
  customErrorHandler: ({ status }) => {
@@ -4106,8 +4144,6 @@ var RunActionSchemaDeprecated = z.object({
4106
4144
  actionKey: ActionKeyPropertySchema
4107
4145
  }).merge(RunActionBaseSchema);
4108
4146
  var RunActionInputSchema = z.union([RunActionSchema, RunActionSchemaDeprecated]).describe(RunActionDescription);
4109
-
4110
- // src/plugins/runAction/index.ts
4111
4147
  async function executeAction(actionOptions) {
4112
4148
  const {
4113
4149
  api,
@@ -4138,7 +4174,18 @@ async function executeAction(actionOptions) {
4138
4174
  };
4139
4175
  const runData = await api.post(
4140
4176
  "/zapier/api/actions/v1/runs",
4141
- runRequest
4177
+ runRequest,
4178
+ {
4179
+ approvalContext: () => buildActionRunContext({
4180
+ selected_api: selectedApi,
4181
+ action_type: actionType,
4182
+ action_key: actionKey,
4183
+ connection_id: connectionId != null ? String(connectionId) : void 0,
4184
+ // Cast: inputs is Record<string, unknown> at the SDK surface, but
4185
+ // buildActionRunContext coerces to JsonValue at runtime via zod.
4186
+ inputs: executionOptions.inputs ?? {}
4187
+ })
4188
+ }
4142
4189
  );
4143
4190
  const runId = runData.data.id;
4144
4191
  return await api.poll(`/zapier/api/actions/v1/runs/${runId}`, {
@@ -5687,7 +5734,89 @@ async function invalidateCredentialsToken(options) {
5687
5734
  }
5688
5735
  }
5689
5736
 
5690
- // src/api/client.ts
5737
+ // src/utils/open-url.ts
5738
+ var nodePrefix = "node:";
5739
+ async function loadChildProcess() {
5740
+ return import(`${nodePrefix}child_process`);
5741
+ }
5742
+ async function loadProcess() {
5743
+ return import(`${nodePrefix}process`);
5744
+ }
5745
+ var openUrl = async (url) => {
5746
+ if (typeof url !== "string") {
5747
+ throw new TypeError("Expected `url` to be a string");
5748
+ }
5749
+ let parsed;
5750
+ try {
5751
+ parsed = new URL(url);
5752
+ } catch {
5753
+ throw new Error(`Invalid URL: ${url}`);
5754
+ }
5755
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
5756
+ throw new Error(`Refusing to open non-http(s) URL: ${parsed.protocol}`);
5757
+ }
5758
+ const target = parsed.toString();
5759
+ if (typeof globalThis.window !== "undefined" && typeof globalThis.window.open === "function") {
5760
+ globalThis.window.open(target, "_blank", "noopener");
5761
+ return;
5762
+ }
5763
+ let spawn;
5764
+ let platform;
5765
+ try {
5766
+ const [cp, proc] = await Promise.all([loadChildProcess(), loadProcess()]);
5767
+ spawn = cp.spawn;
5768
+ platform = proc.platform;
5769
+ } catch {
5770
+ throw new Error(
5771
+ "openUrl: no supported runtime. window.open is unavailable and node:child_process could not be loaded."
5772
+ );
5773
+ }
5774
+ if (typeof spawn !== "function") {
5775
+ throw new Error(
5776
+ "openUrl: child_process.spawn is not available in this runtime"
5777
+ );
5778
+ }
5779
+ let command;
5780
+ let args;
5781
+ if (platform === "darwin") {
5782
+ command = "open";
5783
+ args = [target];
5784
+ } else if (platform === "win32") {
5785
+ command = "rundll32";
5786
+ args = ["url.dll,FileProtocolHandler", target];
5787
+ } else {
5788
+ throw new Error(`Unsupported platform: ${platform}`);
5789
+ }
5790
+ const child = spawn(command, args, {
5791
+ stdio: "ignore",
5792
+ detached: true,
5793
+ windowsHide: true
5794
+ });
5795
+ child.once("error", () => {
5796
+ });
5797
+ child.unref();
5798
+ };
5799
+ var open_url_default = openUrl;
5800
+
5801
+ // src/utils/open-approval.ts
5802
+ async function openApproval(url) {
5803
+ console.error(`Approval required. Opening browser: ${url}`);
5804
+ try {
5805
+ await open_url_default(url);
5806
+ } catch {
5807
+ }
5808
+ }
5809
+ var ApprovalStatusSchema = z.enum(["pending_approval", "approved", "denied"]);
5810
+ var CreateApprovalResponseSchema = z.object({
5811
+ status: ApprovalStatusSchema,
5812
+ approval_id: z.string(),
5813
+ approval_url: z.string().url(),
5814
+ poll_url: z.string().url()
5815
+ });
5816
+ var PollApprovalResponseSchema = z.object({
5817
+ status: ApprovalStatusSchema,
5818
+ approval_id: z.string()
5819
+ });
5691
5820
  function parseRateLimitHeaders(response) {
5692
5821
  const info = {};
5693
5822
  const retryAfter = response.headers.get("retry-after");
@@ -5748,16 +5877,23 @@ var pathConfig = {
5748
5877
  var ZapierApiClient = class {
5749
5878
  constructor(options) {
5750
5879
  this.options = options;
5751
- this.fetch = async (path, init) => {
5752
- if (!path.startsWith("/")) {
5753
- throw new ZapierValidationError(
5754
- `fetch expects a path starting with '/', got: ${path}`
5755
- );
5756
- }
5880
+ /**
5881
+ * Perform a request against an already-resolved URL.
5882
+ *
5883
+ * Does auth, header merging, and 429 retry — all the cross-cutting
5884
+ * concerns that every Zapier-bound HTTP call needs. Callers that have a
5885
+ * path (e.g. `/relay/...`) should use `rawFetch` instead, which does
5886
+ * path → URL resolution and delegates here.
5887
+ *
5888
+ * Exposed as a separate helper so call sites with a server-supplied
5889
+ * absolute URL (e.g. an approval poll URL) can still share the same
5890
+ * auth/retry pipeline instead of reaching for `this.options.fetch`
5891
+ * directly and drifting.
5892
+ */
5893
+ this.rawFetchUrl = async (url, init, pathConfig2) => {
5757
5894
  if (init?.body && (isPlainObject(init.body) || Array.isArray(init.body))) {
5758
5895
  init.body = JSON.stringify(init.body);
5759
5896
  }
5760
- const { url, pathConfig: pathConfig2 } = this.buildUrl(path, init?.searchParams);
5761
5897
  const builtHeaders = await this.buildHeaders(
5762
5898
  init,
5763
5899
  pathConfig2
@@ -5776,30 +5912,114 @@ var ZapierApiClient = class {
5776
5912
  ...init,
5777
5913
  headers: mergedHeaders
5778
5914
  });
5779
- if (response.status === 429) {
5780
- const rateLimitInfo = parseRateLimitHeaders(response);
5781
- const delayMs = rateLimitInfo.retryAfterMs ?? calculateExponentialBackoffMs(retries + 1);
5782
- if (delayMs > this.maxNetworkRetryDelayMs || retries >= this.maxNetworkRetries) {
5783
- throw new ZapierRateLimitError("Rate limited", {
5784
- statusCode: 429,
5785
- rateLimit: rateLimitInfo,
5786
- retries
5787
- });
5788
- }
5789
- retries++;
5790
- this.emitEvent("api:rate_limit_retry", {
5791
- retry: retries,
5792
- maxNetworkRetries: this.maxNetworkRetries,
5793
- delayMs,
5794
- path,
5795
- method: init?.method ?? "GET",
5796
- rateLimit: rateLimitInfo
5915
+ if (response.status !== 429) {
5916
+ return response;
5917
+ }
5918
+ const rateLimitInfo = parseRateLimitHeaders(response);
5919
+ const delayMs = rateLimitInfo.retryAfterMs ?? calculateExponentialBackoffMs(retries + 1);
5920
+ if (delayMs > this.maxNetworkRetryDelayMs || retries >= this.maxNetworkRetries) {
5921
+ throw new ZapierRateLimitError("Rate limited", {
5922
+ statusCode: 429,
5923
+ rateLimit: rateLimitInfo,
5924
+ retries
5925
+ });
5926
+ }
5927
+ retries++;
5928
+ this.emitEvent("api:rate_limit_retry", {
5929
+ retry: retries,
5930
+ maxNetworkRetries: this.maxNetworkRetries,
5931
+ delayMs,
5932
+ path: url,
5933
+ method: init?.method ?? "GET",
5934
+ rateLimit: rateLimitInfo
5935
+ });
5936
+ await sleep(delayMs);
5937
+ }
5938
+ };
5939
+ /**
5940
+ * Perform a request with auth, header merging, and rate-limit (429) retries.
5941
+ * Does NOT handle 403 approval_required — that's routed by `fetch`.
5942
+ */
5943
+ this.rawFetch = async (path, init) => {
5944
+ if (!path.startsWith("/")) {
5945
+ throw new ZapierValidationError(
5946
+ `fetch expects a path starting with '/', got: ${path}`
5947
+ );
5948
+ }
5949
+ const { url, pathConfig: pathConfig2 } = this.buildUrl(path, init?.searchParams);
5950
+ return this.rawFetchUrl(url, init, pathConfig2);
5951
+ };
5952
+ /**
5953
+ * Approval-aware HTTP fetch.
5954
+ *
5955
+ * Wraps `rawFetch` with the backend's just-in-time approval protocol. The
5956
+ * backend signals approval state via a 403 response with an
5957
+ * `x-zapier-error-type` header:
5958
+ *
5959
+ * - `request_denied_by_policy` → a policy rule permanently blocks the
5960
+ * request; no human can approve it. Throw.
5961
+ * - `approval_required` → the request needs human approval; the
5962
+ * SDK creates an approval, opens the URL
5963
+ * (poll mode), waits for resolution, and
5964
+ * retries the original request.
5965
+ * - anything else → not our concern, pass through.
5966
+ *
5967
+ * The retry loop exists because a single user action can legitimately
5968
+ * require multiple sequential approvals (e.g. policies that approve one
5969
+ * step at a time). Each iteration is either a first attempt or a post-
5970
+ * approval retry; `maxApprovalRetries` bounds the loop as a runaway-loop
5971
+ * safeguard.
5972
+ *
5973
+ * Loop accounting: `attempt` counts rawFetch calls, not approval rounds.
5974
+ * With `maxRetries = N` we perform up to `N + 1` rawFetch calls and at
5975
+ * most `N` approval rounds. The `attempt === maxRetries` guard ensures we
5976
+ * don't run an (N+1)th approval round we'll never consume — if the final
5977
+ * retry still returns `approval_required`, we break out and throw
5978
+ * `max_retries_exceeded` instead.
5979
+ */
5980
+ this.fetch = async (path, init) => {
5981
+ const maxRetries = this.options.maxApprovalRetries ?? DEFAULT_MAX_APPROVAL_RETRIES;
5982
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
5983
+ const response = await this.rawFetch(path, init);
5984
+ if (response.status !== 403) return response;
5985
+ const errorType = response.headers.get("x-zapier-error-type");
5986
+ if (errorType === "request_denied_by_policy") {
5987
+ const { data } = await this.parseResult(response);
5988
+ const { message, errors } = this.parseErrorResponse({
5989
+ status: response.status,
5990
+ statusText: response.statusText,
5991
+ data
5797
5992
  });
5798
- await sleep(delayMs);
5799
- continue;
5993
+ throw new ZapierApprovalError(
5994
+ message || "Request explicitly denied by policy",
5995
+ {
5996
+ status: "policy_denied",
5997
+ statusCode: response.status,
5998
+ errors
5999
+ }
6000
+ );
6001
+ }
6002
+ if (errorType !== "approval_required") return response;
6003
+ if (attempt === maxRetries) break;
6004
+ const isInteractive = this.options.isInteractive ?? getZapierIsInteractive();
6005
+ if (!isInteractive) {
6006
+ throw new ZapierApprovalError(
6007
+ "Approval required but session is not interactive",
6008
+ { status: "approval_required" }
6009
+ );
6010
+ }
6011
+ if (!init?.approvalContext) {
6012
+ throw new ZapierApiError(
6013
+ `Received 403 approval_required for ${path}, but the caller did not provide an approvalContext builder. Every approval-capable request must pass approvalContext so the SDK can create the approval with the correct policy context.`,
6014
+ { statusCode: 403 }
6015
+ );
5800
6016
  }
5801
- return response;
6017
+ await this.runOneApprovalRound(init.approvalContext);
5802
6018
  }
6019
+ throw new ZapierApprovalError(
6020
+ `Exceeded maximum approval retries (${maxRetries}) for ${path}`,
6021
+ { status: "max_retries_exceeded" }
6022
+ );
5803
6023
  };
5804
6024
  this.get = async (path, options = {}) => {
5805
6025
  return this.fetchJson("GET", path, void 0, options);
@@ -6084,6 +6304,156 @@ var ZapierApiClient = class {
6084
6304
  }
6085
6305
  return result;
6086
6306
  }
6307
+ /**
6308
+ * Run a single approval round: create the approval, open the URL (poll mode)
6309
+ * or throw (fail mode), poll until resolved, and emit events. Throws on
6310
+ * denied/timeout/unexpected status. Returns on approved.
6311
+ */
6312
+ async runOneApprovalRound(buildContext) {
6313
+ const context = buildContext();
6314
+ let approvalResponse;
6315
+ try {
6316
+ approvalResponse = await this.rawFetch("/api/v0/approvals", {
6317
+ method: "POST",
6318
+ headers: {
6319
+ "Content-Type": "application/json",
6320
+ Accept: "application/json"
6321
+ },
6322
+ body: JSON.stringify({ context })
6323
+ });
6324
+ } catch (err) {
6325
+ throw new ZapierApiError("Failed to create approval request", {
6326
+ statusCode: 0,
6327
+ cause: err
6328
+ });
6329
+ }
6330
+ if (!approvalResponse.ok) {
6331
+ const body2 = await approvalResponse.text().catch(() => void 0);
6332
+ throw new ZapierApiError(
6333
+ `Failed to create approval request: ${approvalResponse.status}`,
6334
+ { statusCode: approvalResponse.status, response: body2 }
6335
+ );
6336
+ }
6337
+ let body;
6338
+ try {
6339
+ body = await approvalResponse.text();
6340
+ } catch (err) {
6341
+ throw new ZapierApiError("Failed to read approval response body", {
6342
+ statusCode: approvalResponse.status,
6343
+ cause: err
6344
+ });
6345
+ }
6346
+ let approval;
6347
+ try {
6348
+ approval = CreateApprovalResponseSchema.parse(JSON.parse(body));
6349
+ } catch (err) {
6350
+ throw new ZapierApiError(`Failed to parse approval response: ${body}`, {
6351
+ statusCode: approvalResponse.status,
6352
+ cause: err,
6353
+ response: body
6354
+ });
6355
+ }
6356
+ const sdkapiOrigin = new URL(this.buildUrl("/api/v0/approvals").url).origin;
6357
+ const browserOrigin = getZapierBaseUrl(this.options.baseUrl) ?? sdkapiOrigin;
6358
+ const assertApprovalOrigin = (url, expectedOrigin, label) => {
6359
+ let parsed;
6360
+ try {
6361
+ parsed = new URL(url);
6362
+ } catch {
6363
+ throw new ZapierApiError(`Invalid approval ${label}: ${url}`, {
6364
+ statusCode: approvalResponse.status,
6365
+ response: body
6366
+ });
6367
+ }
6368
+ if (parsed.origin !== expectedOrigin) {
6369
+ throw new ZapierApiError(
6370
+ `Approval ${label} origin ${parsed.origin} does not match expected ${expectedOrigin}`,
6371
+ { statusCode: approvalResponse.status, response: body }
6372
+ );
6373
+ }
6374
+ };
6375
+ assertApprovalOrigin(approval.poll_url, sdkapiOrigin, "poll_url");
6376
+ assertApprovalOrigin(approval.approval_url, browserOrigin, "approval_url");
6377
+ this.emitEvent("approval:required", {
6378
+ approvalId: approval.approval_id,
6379
+ approvalUrl: approval.approval_url
6380
+ });
6381
+ const approvalMode = this.options.approvalMode ?? getZapierApprovalMode();
6382
+ if (approvalMode === "fail") {
6383
+ throw new ZapierApprovalError("This request requires approval.", {
6384
+ approvalId: approval.approval_id,
6385
+ approvalUrl: approval.approval_url,
6386
+ pollUrl: approval.poll_url,
6387
+ status: "pending"
6388
+ });
6389
+ }
6390
+ await openApproval(approval.approval_url);
6391
+ const timeoutMs = this.options.approvalTimeoutMs ?? DEFAULT_APPROVAL_TIMEOUT_MS;
6392
+ let rawPollResult;
6393
+ try {
6394
+ rawPollResult = await pollUntilComplete({
6395
+ // poll_url is an absolute URL supplied by the server, so we use
6396
+ // rawFetchUrl directly (skipping path resolution) but still share
6397
+ // auth + interactive-header + 429-retry with the rest of the SDK.
6398
+ fetchPoll: () => this.rawFetchUrl(approval.poll_url, {
6399
+ method: "GET",
6400
+ headers: { Accept: "application/json" }
6401
+ }),
6402
+ timeoutMs,
6403
+ isPending: (body2) => {
6404
+ const parsed = PollApprovalResponseSchema.safeParse(body2);
6405
+ return parsed.success && parsed.data.status === "pending_approval";
6406
+ }
6407
+ });
6408
+ } catch (err) {
6409
+ if (!(err instanceof ZapierTimeoutError)) {
6410
+ throw err;
6411
+ }
6412
+ this.emitEvent("approval:timeout", {
6413
+ approvalId: approval.approval_id
6414
+ });
6415
+ throw new ZapierApprovalError(
6416
+ `Approval timed out after ${timeoutMs / 1e3} seconds`,
6417
+ {
6418
+ approvalId: approval.approval_id,
6419
+ approvalUrl: approval.approval_url,
6420
+ pollUrl: approval.poll_url,
6421
+ status: "timeout",
6422
+ cause: err
6423
+ }
6424
+ );
6425
+ }
6426
+ const pollParse = PollApprovalResponseSchema.safeParse(rawPollResult);
6427
+ if (!pollParse.success) {
6428
+ const bodyPreview = typeof rawPollResult === "string" ? rawPollResult : JSON.stringify(rawPollResult);
6429
+ throw new ZapierApiError(
6430
+ `Failed to parse approval poll response: ${bodyPreview}`,
6431
+ {
6432
+ statusCode: 0,
6433
+ cause: pollParse.error,
6434
+ response: rawPollResult
6435
+ }
6436
+ );
6437
+ }
6438
+ const pollResult = pollParse.data;
6439
+ if (pollResult.status === "denied") {
6440
+ this.emitEvent("approval:denied", {
6441
+ approvalId: approval.approval_id
6442
+ });
6443
+ throw new ZapierApprovalError("Request denied by user", {
6444
+ approvalId: approval.approval_id,
6445
+ status: "denied"
6446
+ });
6447
+ }
6448
+ if (pollResult.status !== "approved") {
6449
+ throw new ZapierApiError(
6450
+ `Unexpected approval status received: ${pollResult.status}`
6451
+ );
6452
+ }
6453
+ this.emitEvent("approval:approved", {
6454
+ approvalId: approval.approval_id
6455
+ });
6456
+ }
6087
6457
  };
6088
6458
  var createZapierApi = (options) => {
6089
6459
  const { debug = false, fetch: originalFetch = globalThis.fetch } = options;
@@ -6106,7 +6476,11 @@ var apiPlugin = (sdk) => {
6106
6476
  onEvent,
6107
6477
  debug = false,
6108
6478
  maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES,
6109
- maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS
6479
+ maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS,
6480
+ isInteractive,
6481
+ approvalTimeoutMs,
6482
+ maxApprovalRetries,
6483
+ approvalMode
6110
6484
  } = sdk.context.options;
6111
6485
  const api = createZapierApi({
6112
6486
  baseUrl,
@@ -6116,7 +6490,11 @@ var apiPlugin = (sdk) => {
6116
6490
  fetch: customFetch,
6117
6491
  onEvent,
6118
6492
  maxNetworkRetries,
6119
- maxNetworkRetryDelayMs
6493
+ maxNetworkRetryDelayMs,
6494
+ isInteractive,
6495
+ approvalTimeoutMs,
6496
+ maxApprovalRetries,
6497
+ approvalMode
6120
6498
  });
6121
6499
  return {
6122
6500
  context: {
@@ -8668,6 +9046,16 @@ var BaseSdkOptionsSchema = z.object({
8668
9046
  * Default is 60000 (60 seconds).
8669
9047
  */
8670
9048
  maxNetworkRetryDelayMs: z.number().optional().describe("Max delay in ms to wait for retry (default: 60000).").meta({ valueHint: "ms" }),
9049
+ isInteractive: z.boolean().optional().describe(
9050
+ "Whether this session is interactive (user can visit approval URLs). Defaults to ZAPIER_IS_INTERACTIVE env var."
9051
+ ).meta({ internal: true }),
9052
+ approvalTimeoutMs: z.number().optional().describe("Timeout in ms for approval polling. Default: 600000 (10 min).").meta({ valueHint: "ms", internal: true }),
9053
+ maxApprovalRetries: z.number().optional().describe(
9054
+ "Maximum number of sequential approval rounds per request (one per gating policy) before giving up. Default: 2."
9055
+ ).meta({ internal: true }),
9056
+ approvalMode: z.enum(["poll", "fail"]).optional().describe(
9057
+ 'Approval flow behavior. "poll" opens browser and polls (default). "fail" creates the approval and throws immediately with the approval URL.'
9058
+ ).meta({ internal: true }),
8671
9059
  // Internal
8672
9060
  manifestPath: z.string().optional().describe("Path to a .zapierrc manifest file for app version locking.").meta({ internal: true }),
8673
9061
  manifest: z.custom().optional().describe("Manifest for app version locking.").meta({ internal: true }),
@@ -8682,4 +9070,4 @@ var BaseSdkOptionsSchema = z.object({
8682
9070
  // Use credentials instead
8683
9071
  });
8684
9072
 
8685
- export { ActionKeyPropertySchema, ActionPropertySchema, ActionTimeoutMsPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppPropertySchema, AppsPropertySchema, AuthenticationIdPropertySchema, BaseSdkOptionsSchema, CONTEXT_CACHE_MAX_SIZE, CONTEXT_CACHE_TTL_MS, ClientCredentialsObjectSchema, ConnectionEntrySchema, ConnectionIdPropertySchema, ConnectionPropertySchema, ConnectionsMapSchema, ConnectionsPropertySchema, CredentialsFunctionSchema, CredentialsObjectSchema, CredentialsSchema, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_CONFIG_PATH, DEFAULT_PAGE_SIZE, DebugPropertySchema, FieldsPropertySchema, InputFieldPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, PkceCredentialsObjectSchema, RecordPropertySchema, RecordsPropertySchema, RelayFetchSchema, RelayRequestSchema, ResolvedCredentialsSchema, TablePropertySchema, TablesPropertySchema, ZAPIER_BASE_URL, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierRateLimitError, ZapierRelayError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, connectionIdGenericResolver as authenticationIdGenericResolver, connectionIdResolver as authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildCapabilityMessage, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, clearTokenCache, clientCredentialsNameResolver, clientIdResolver, connectionIdGenericResolver, connectionIdResolver, connectionsPlugin, createBaseEvent, createClientCredentialsPlugin, createFunction, createOptionsPlugin, createSdk, createTableFieldsPlugin, createTablePlugin, createTableRecordsPlugin, createZapierSdk, createZapierSdkWithoutRegistry, deleteClientCredentialsPlugin, deleteTableFieldsPlugin, deleteTablePlugin, deleteTableRecordsPlugin, fetchPlugin, findFirstConnectionPlugin, findManifestEntry, findUniqueConnectionPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getBaseUrlFromCredentials, getCiPlatform, getClientIdFromCredentials, getConnectionPlugin, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTablePlugin, getTableRecordPlugin, getTokenFromCliLogin, injectCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isCliLoginAvailable, isClientCredentials, isCredentialsFunction, isCredentialsObject, isPkceCredentials, isPositional, listActionsPlugin, listAppsPlugin, listClientCredentialsPlugin, listConnectionsPlugin, listInputFieldsPlugin, listTableFieldsPlugin, listTableRecordsPlugin, listTablesPlugin, logDeprecation, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, runActionPlugin, runWithTelemetryContext, tableFieldIdsResolver, tableFieldsResolver, tableFiltersResolver, tableIdResolver, tableNameResolver, tableRecordIdResolver, tableRecordIdsResolver, tableRecordsResolver, tableSortResolver, tableUpdateRecordsResolver, toSnakeCase, toTitleCase, updateTableRecordsPlugin };
9073
+ export { ActionKeyPropertySchema, ActionPropertySchema, ActionTimeoutMsPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppPropertySchema, AppsPropertySchema, AuthenticationIdPropertySchema, BaseSdkOptionsSchema, CONTEXT_CACHE_MAX_SIZE, CONTEXT_CACHE_TTL_MS, ClientCredentialsObjectSchema, ConnectionEntrySchema, ConnectionIdPropertySchema, ConnectionPropertySchema, ConnectionsMapSchema, ConnectionsPropertySchema, CredentialsFunctionSchema, CredentialsObjectSchema, CredentialsSchema, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_APPROVAL_TIMEOUT_MS, DEFAULT_CONFIG_PATH, DEFAULT_MAX_APPROVAL_RETRIES, DEFAULT_PAGE_SIZE, DebugPropertySchema, FieldsPropertySchema, InputFieldPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, PkceCredentialsObjectSchema, RecordPropertySchema, RecordsPropertySchema, RelayFetchSchema, RelayRequestSchema, ResolvedCredentialsSchema, TablePropertySchema, TablesPropertySchema, ZAPIER_BASE_URL, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierApprovalError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierRateLimitError, ZapierRelayError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, connectionIdGenericResolver as authenticationIdGenericResolver, connectionIdResolver as authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildCapabilityMessage, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, clearTokenCache, clientCredentialsNameResolver, clientIdResolver, connectionIdGenericResolver, connectionIdResolver, connectionsPlugin, createBaseEvent, createClientCredentialsPlugin, createFunction, createOptionsPlugin, createSdk, createTableFieldsPlugin, createTablePlugin, createTableRecordsPlugin, createZapierSdk, createZapierSdkWithoutRegistry, deleteClientCredentialsPlugin, deleteTableFieldsPlugin, deleteTablePlugin, deleteTableRecordsPlugin, fetchPlugin, findFirstConnectionPlugin, findManifestEntry, findUniqueConnectionPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getBaseUrlFromCredentials, getCiPlatform, getClientIdFromCredentials, getConnectionPlugin, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTablePlugin, getTableRecordPlugin, getTokenFromCliLogin, getZapierApprovalMode, getZapierIsInteractive, injectCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isCliLoginAvailable, isClientCredentials, isCredentialsFunction, isCredentialsObject, isPkceCredentials, isPositional, listActionsPlugin, listAppsPlugin, listClientCredentialsPlugin, listConnectionsPlugin, listInputFieldsPlugin, listTableFieldsPlugin, listTableRecordsPlugin, listTablesPlugin, logDeprecation, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, runActionPlugin, runWithTelemetryContext, tableFieldIdsResolver, tableFieldsResolver, tableFiltersResolver, tableIdResolver, tableNameResolver, tableRecordIdResolver, tableRecordIdsResolver, tableRecordsResolver, tableSortResolver, tableUpdateRecordsResolver, toSnakeCase, toTitleCase, updateTableRecordsPlugin };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAQnE,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG;AAG3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE;QACP,GAAG,EAAE,SAAS,CAAC;QACf,kBAAkB,EAAE,MAAM,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;KACpE,CAAC;CACH;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAC5B;IAAE,OAAO,EAAE;QAAE,OAAO,EAAE,cAAc,CAAA;KAAE,CAAA;CAAE,EACxC,iBAAiB,CAsClB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAQnE,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG;AAG3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE;QACP,GAAG,EAAE,SAAS,CAAC;QACf,kBAAkB,EAAE,MAAM,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;KACpE,CAAC;CACH;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAC5B;IAAE,OAAO,EAAE;QAAE,OAAO,EAAE,cAAc,CAAA;KAAE,CAAA;CAAE,EACxC,iBAAiB,CA8ClB,CAAC"}
@@ -3,7 +3,7 @@ import { resolveCredentials } from "../../credentials";
3
3
  import { ZAPIER_BASE_URL, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, } from "../../constants";
4
4
  export const apiPlugin = (sdk) => {
5
5
  // Extract all options - everything passed to the plugin
6
- const { fetch: customFetch = globalThis.fetch, baseUrl = ZAPIER_BASE_URL, credentials, token, onEvent, debug = false, maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES, maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, } = sdk.context.options;
6
+ const { fetch: customFetch = globalThis.fetch, baseUrl = ZAPIER_BASE_URL, credentials, token, onEvent, debug = false, maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES, maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, isInteractive, approvalTimeoutMs, maxApprovalRetries, approvalMode, } = sdk.context.options;
7
7
  // Create the API client - it will handle token resolution internally
8
8
  const api = createZapierApi({
9
9
  baseUrl,
@@ -14,6 +14,10 @@ export const apiPlugin = (sdk) => {
14
14
  onEvent,
15
15
  maxNetworkRetries,
16
16
  maxNetworkRetryDelayMs,
17
+ isInteractive,
18
+ approvalTimeoutMs,
19
+ maxApprovalRetries,
20
+ approvalMode,
17
21
  });
18
22
  // Return flat structure with context only
19
23
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/createClientCredentials/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,6BAA6B,EAC7B,KAAK,8BAA8B,EACnC,KAAK,6BAA6B,EACnC,MAAM,WAAW,CAAC;AAInB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAK9D,MAAM,WAAW,qCAAqC;IACpD,uBAAuB,EAAE,CACvB,OAAO,EAAE,8BAA8B,KACpC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAC5C,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,uBAAuB,EAAE;gBACvB,WAAW,EAAE,OAAO,6BAA6B,CAAC;aACnD,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAChD;IACE,OAAO,EAAE;QACP,GAAG,EAAE,SAAS,CAAC;KAChB,CAAC;CACH,GAAG,qBAAqB,EACzB,qCAAqC,CAkEtC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/createClientCredentials/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,6BAA6B,EAC7B,KAAK,8BAA8B,EACnC,KAAK,6BAA6B,EACnC,MAAM,WAAW,CAAC;AAInB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAK9D,MAAM,WAAW,qCAAqC;IACpD,uBAAuB,EAAE,CACvB,OAAO,EAAE,8BAA8B,KACpC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAC5C,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,uBAAuB,EAAE;gBACvB,WAAW,EAAE,OAAO,6BAA6B,CAAC;aACnD,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAChD;IACE,OAAO,EAAE;QACP,GAAG,EAAE,SAAS,CAAC;KAChB,CAAC;CACH,GAAG,qBAAqB,EACzB,qCAAqC,CAmEtC,CAAC"}
@@ -10,6 +10,7 @@ export const createClientCredentialsPlugin = (sdk) => {
10
10
  const response = await api.post("/api/v0/client-credentials", {
11
11
  name: options.name,
12
12
  allowed_scopes: options.allowedScopes,
13
+ ...(options.policy && { policy: options.policy }),
13
14
  }, {
14
15
  customErrorHandler: ({ status }) => {
15
16
  if (status === 401) {
@@ -8,6 +8,7 @@ export declare const CreateClientCredentialsSchema: z.ZodObject<{
8
8
  external: "external";
9
9
  credentials: "credentials";
10
10
  }>>>;
11
+ policy: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
11
12
  }, z.core.$strip>;
12
13
  export type CreateClientCredentialsOptions = z.infer<typeof CreateClientCredentialsSchema> & FunctionOptions;
13
14
  export interface CreateClientCredentialsResult {
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/createClientCredentials/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uDAAuD,CAAC;AAE1G,OAAO,KAAK,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,eAAO,MAAM,6BAA6B;;;;;;iBAQ+B,CAAC;AAG1E,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAClD,OAAO,6BAA6B,CACrC,GACC,eAAe,CAAC;AAGlB,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,4BAA4B,CAAC;CACpC;AAGD,MAAM,MAAM,4BAA4B,GACpC,yBAAyB,GACzB,cAAc,GACd,qBAAqB,GACrB,kBAAkB,CAAC;AAGvB,MAAM,WAAW,kCAAkC;IACjD,uBAAuB,EAAE,CACvB,OAAO,EAAE,8BAA8B,KACpC,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC7C"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/createClientCredentials/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uDAAuD,CAAC;AAE1G,OAAO,KAAK,EACV,yBAAyB,EACzB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,eAAO,MAAM,6BAA6B;;;;;;;iBAc+B,CAAC;AAG1E,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAClD,OAAO,6BAA6B,CACrC,GACC,eAAe,CAAC;AAGlB,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,4BAA4B,CAAC;CACpC;AAGD,MAAM,MAAM,4BAA4B,GACpC,yBAAyB,GACzB,cAAc,GACd,qBAAqB,GACrB,kBAAkB,CAAC;AAGvB,MAAM,WAAW,kCAAkC;IACjD,uBAAuB,EAAE,CACvB,OAAO,EAAE,8BAA8B,KACpC,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC7C"}
@@ -6,5 +6,11 @@ export const CreateClientCredentialsSchema = CreateClientCredentialsRequestSchem
6
6
  .array(z.enum(["credentials", "external"]))
7
7
  .default(["external"])
8
8
  .describe("Scopes to allow for these credentials"),
9
+ // Temporarily hidden while we finalise work to make approvals/policies customer-facing.
10
+ policy: z
11
+ .record(z.string(), z.unknown())
12
+ .optional()
13
+ .describe("Policy document (JSON) to attach to the credentials")
14
+ .meta({ deprecated: true }),
9
15
  })
10
16
  .describe("Create new client credentials for the authenticated user");