@zapier/zapier-sdk 0.18.4 → 1.0.2

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 (57) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +12 -3
  3. package/dist/api/client.d.ts.map +1 -1
  4. package/dist/api/client.js +11 -6
  5. package/dist/api/client.test.js +82 -27
  6. package/dist/api/index.d.ts +3 -2
  7. package/dist/api/index.d.ts.map +1 -1
  8. package/dist/api/index.js +2 -3
  9. package/dist/api/schemas.d.ts +5 -5
  10. package/dist/api/types.d.ts +8 -3
  11. package/dist/api/types.d.ts.map +1 -1
  12. package/dist/auth.d.ts +54 -26
  13. package/dist/auth.d.ts.map +1 -1
  14. package/dist/auth.js +211 -39
  15. package/dist/auth.test.js +338 -64
  16. package/dist/constants.d.ts +14 -0
  17. package/dist/constants.d.ts.map +1 -1
  18. package/dist/constants.js +14 -0
  19. package/dist/credentials.d.ts +57 -0
  20. package/dist/credentials.d.ts.map +1 -0
  21. package/dist/credentials.js +174 -0
  22. package/dist/index.cjs +346 -48
  23. package/dist/index.d.mts +213 -29
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +5 -0
  27. package/dist/index.mjs +326 -47
  28. package/dist/plugins/api/index.d.ts +2 -0
  29. package/dist/plugins/api/index.d.ts.map +1 -1
  30. package/dist/plugins/api/index.js +8 -4
  31. package/dist/plugins/eventEmission/index.d.ts.map +1 -1
  32. package/dist/plugins/eventEmission/index.js +1 -3
  33. package/dist/plugins/eventEmission/index.test.js +14 -17
  34. package/dist/plugins/getAction/schemas.d.ts +1 -1
  35. package/dist/plugins/getInputFieldsSchema/schemas.d.ts +1 -1
  36. package/dist/plugins/listActions/index.test.js +1 -0
  37. package/dist/plugins/listActions/schemas.d.ts +1 -1
  38. package/dist/plugins/listInputFieldChoices/schemas.d.ts +1 -1
  39. package/dist/plugins/listInputFields/schemas.d.ts +1 -1
  40. package/dist/plugins/manifest/index.d.ts.map +1 -1
  41. package/dist/plugins/manifest/index.js +10 -2
  42. package/dist/plugins/manifest/index.test.js +46 -6
  43. package/dist/plugins/runAction/schemas.d.ts +1 -1
  44. package/dist/schemas/Action.d.ts +1 -1
  45. package/dist/sdk.d.ts +1 -0
  46. package/dist/sdk.d.ts.map +1 -1
  47. package/dist/sdk.test.js +5 -4
  48. package/dist/types/credentials.d.ts +65 -0
  49. package/dist/types/credentials.d.ts.map +1 -0
  50. package/dist/types/credentials.js +42 -0
  51. package/dist/types/properties.d.ts +1 -1
  52. package/dist/types/sdk.d.ts +12 -3
  53. package/dist/types/sdk.d.ts.map +1 -1
  54. package/dist/utils/logging.d.ts +13 -0
  55. package/dist/utils/logging.d.ts.map +1 -0
  56. package/dist/utils/logging.js +20 -0
  57. package/package.json +2 -2
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Credentials Resolution
3
+ *
4
+ * This module provides the core logic for resolving credentials from various sources:
5
+ * - Explicit credentials option
6
+ * - Deprecated token option
7
+ * - Environment variables (new and deprecated)
8
+ * - CLI login stored tokens
9
+ */
10
+ import { isCredentialsFunction, isCredentialsObject, } from "./types/credentials";
11
+ import { logDeprecation } from "./utils/logging";
12
+ import { getZapierBaseUrl } from "./utils/url-utils";
13
+ import { ZAPIER_CREDENTIALS, ZAPIER_CREDENTIALS_CLIENT_ID, ZAPIER_CREDENTIALS_CLIENT_SECRET, ZAPIER_CREDENTIALS_BASE_URL, ZAPIER_CREDENTIALS_SCOPE, ZAPIER_TOKEN, ZAPIER_AUTH_BASE_URL, ZAPIER_AUTH_CLIENT_ID, } from "./constants";
14
+ /**
15
+ * Derive the auth base URL from the SDK base URL.
16
+ * Returns the Zapier root domain (e.g., https://zapier.com from https://api.zapier.com).
17
+ */
18
+ function deriveAuthBaseUrl(sdkBaseUrl) {
19
+ if (!sdkBaseUrl)
20
+ return undefined;
21
+ return getZapierBaseUrl(sdkBaseUrl);
22
+ }
23
+ /**
24
+ * Normalize a credentials object by ensuring it has a type and resolved baseUrl.
25
+ */
26
+ function normalizeCredentialsObject(obj, sdkBaseUrl) {
27
+ // Resolve baseUrl: use credentials baseUrl, or derive from SDK baseUrl
28
+ const resolvedBaseUrl = obj.baseUrl || deriveAuthBaseUrl(sdkBaseUrl);
29
+ // Explicitly construct the correct typed object to satisfy TypeScript
30
+ if (obj.type === "client_credentials" ||
31
+ ("clientSecret" in obj && obj.clientSecret)) {
32
+ return {
33
+ type: "client_credentials",
34
+ clientId: obj.clientId,
35
+ clientSecret: obj.clientSecret,
36
+ baseUrl: resolvedBaseUrl,
37
+ scope: obj.scope,
38
+ };
39
+ }
40
+ return {
41
+ type: "pkce",
42
+ clientId: obj.clientId,
43
+ baseUrl: resolvedBaseUrl,
44
+ scope: obj.scope,
45
+ };
46
+ }
47
+ /**
48
+ * Resolve credentials from environment variables.
49
+ *
50
+ * Precedence:
51
+ * 1. ZAPIER_CREDENTIALS (string token)
52
+ * 2. ZAPIER_CREDENTIALS_CLIENT_ID + ZAPIER_CREDENTIALS_CLIENT_SECRET (client credentials)
53
+ * 3. ZAPIER_CREDENTIALS_CLIENT_ID alone (PKCE)
54
+ * 4. Deprecated ZAPIER_TOKEN, ZAPIER_AUTH_* vars (with warnings)
55
+ *
56
+ * @param sdkBaseUrl - SDK base URL used to derive auth base URL if not specified
57
+ */
58
+ export function resolveCredentialsFromEnv(sdkBaseUrl) {
59
+ // 1. Check ZAPIER_CREDENTIALS (string token only)
60
+ if (ZAPIER_CREDENTIALS) {
61
+ return ZAPIER_CREDENTIALS;
62
+ }
63
+ // 2. Check ZAPIER_CREDENTIALS_* individual vars
64
+ if (ZAPIER_CREDENTIALS_CLIENT_ID) {
65
+ const resolvedBaseUrl = ZAPIER_CREDENTIALS_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
66
+ // Infer type from presence of clientSecret
67
+ if (ZAPIER_CREDENTIALS_CLIENT_SECRET) {
68
+ return {
69
+ type: "client_credentials",
70
+ clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
71
+ clientSecret: ZAPIER_CREDENTIALS_CLIENT_SECRET,
72
+ baseUrl: resolvedBaseUrl,
73
+ scope: ZAPIER_CREDENTIALS_SCOPE,
74
+ };
75
+ }
76
+ else {
77
+ return {
78
+ type: "pkce",
79
+ clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
80
+ baseUrl: resolvedBaseUrl,
81
+ scope: ZAPIER_CREDENTIALS_SCOPE,
82
+ };
83
+ }
84
+ }
85
+ // 3. Check deprecated env vars (with warnings)
86
+ if (ZAPIER_TOKEN) {
87
+ logDeprecation("ZAPIER_TOKEN is deprecated. Use ZAPIER_CREDENTIALS instead.");
88
+ return ZAPIER_TOKEN;
89
+ }
90
+ if (ZAPIER_AUTH_CLIENT_ID) {
91
+ logDeprecation("ZAPIER_AUTH_CLIENT_ID is deprecated. Use ZAPIER_CREDENTIALS_CLIENT_ID instead.");
92
+ if (ZAPIER_AUTH_BASE_URL) {
93
+ logDeprecation("ZAPIER_AUTH_BASE_URL is deprecated. Use ZAPIER_CREDENTIALS_BASE_URL instead.");
94
+ }
95
+ const resolvedBaseUrl = ZAPIER_AUTH_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
96
+ return {
97
+ type: "pkce",
98
+ clientId: ZAPIER_AUTH_CLIENT_ID,
99
+ baseUrl: resolvedBaseUrl,
100
+ };
101
+ }
102
+ return undefined;
103
+ }
104
+ /**
105
+ * Resolve credentials from all possible sources.
106
+ *
107
+ * Precedence:
108
+ * 1. Explicit credentials option
109
+ * 2. Deprecated token option (with warning)
110
+ * 3. Environment variables
111
+ * 4. CLI login stored token (handled separately in auth.ts)
112
+ *
113
+ * If credentials is a function, it is called and must return
114
+ * a string or credentials object (not another function).
115
+ *
116
+ * The baseUrl option is used to derive the auth base URL if not
117
+ * specified in credentials.
118
+ */
119
+ export async function resolveCredentials(options = {}) {
120
+ const { baseUrl } = options;
121
+ // 1. Check explicit credentials option
122
+ if (options.credentials !== undefined) {
123
+ // If it's a function, call it
124
+ if (isCredentialsFunction(options.credentials)) {
125
+ const resolved = await options.credentials();
126
+ // Validate that the function didn't return another function
127
+ if (typeof resolved === "function") {
128
+ throw new Error("Credentials function returned another function. " +
129
+ "Credentials functions must return a string or credentials object.");
130
+ }
131
+ // Normalize object if needed
132
+ if (isCredentialsObject(resolved)) {
133
+ return normalizeCredentialsObject(resolved, baseUrl);
134
+ }
135
+ return resolved;
136
+ }
137
+ // If it's an object, normalize it
138
+ if (isCredentialsObject(options.credentials)) {
139
+ return normalizeCredentialsObject(options.credentials, baseUrl);
140
+ }
141
+ // It's a string token
142
+ return options.credentials;
143
+ }
144
+ // 2. Check deprecated token option (with warning)
145
+ if (options.token !== undefined) {
146
+ logDeprecation("The `token` option is deprecated. Use `credentials` instead.");
147
+ return options.token;
148
+ }
149
+ // 3. Check environment variables
150
+ const envCredentials = resolveCredentialsFromEnv(baseUrl);
151
+ if (envCredentials !== undefined) {
152
+ return envCredentials;
153
+ }
154
+ // 4. CLI login is handled separately in auth.ts
155
+ return undefined;
156
+ }
157
+ /**
158
+ * Extract the base URL from credentials for use in auth flows.
159
+ */
160
+ export function getBaseUrlFromCredentials(credentials) {
161
+ if (credentials && isCredentialsObject(credentials)) {
162
+ return credentials.baseUrl;
163
+ }
164
+ return undefined;
165
+ }
166
+ /**
167
+ * Extract the client ID from credentials for use in auth flows.
168
+ */
169
+ export function getClientIdFromCredentials(credentials) {
170
+ if (credentials && isCredentialsObject(credentials)) {
171
+ return credentials.clientId;
172
+ }
173
+ return undefined;
174
+ }
package/dist/index.cjs CHANGED
@@ -58,6 +58,14 @@ function isPositional(schema) {
58
58
  // src/constants.ts
59
59
  var ZAPIER_BASE_URL = process.env.ZAPIER_BASE_URL || "https://zapier.com";
60
60
  var MAX_PAGE_LIMIT = 1e4;
61
+ var ZAPIER_CREDENTIALS = process.env.ZAPIER_CREDENTIALS;
62
+ var ZAPIER_CREDENTIALS_CLIENT_ID = process.env.ZAPIER_CREDENTIALS_CLIENT_ID;
63
+ var ZAPIER_CREDENTIALS_CLIENT_SECRET = process.env.ZAPIER_CREDENTIALS_CLIENT_SECRET;
64
+ var ZAPIER_CREDENTIALS_BASE_URL = process.env.ZAPIER_CREDENTIALS_BASE_URL;
65
+ var ZAPIER_CREDENTIALS_SCOPE = process.env.ZAPIER_CREDENTIALS_SCOPE;
66
+ var ZAPIER_TOKEN = process.env.ZAPIER_TOKEN;
67
+ var ZAPIER_AUTH_BASE_URL = process.env.ZAPIER_AUTH_BASE_URL;
68
+ var ZAPIER_AUTH_CLIENT_ID = process.env.ZAPIER_AUTH_CLIENT_ID;
61
69
 
62
70
  // src/types/properties.ts
63
71
  var AppKeyPropertySchema = withPositional(
@@ -2751,8 +2759,11 @@ async function readManifestFromFile(filePath) {
2751
2759
  const resolvedPath = await resolve(filePath);
2752
2760
  const content = await readFile(resolvedPath);
2753
2761
  return parseManifestContent(content, resolvedPath);
2754
- } catch {
2755
- console.warn(`\u26A0\uFE0F Failed to read manifest from ${filePath}`);
2762
+ } catch (error) {
2763
+ const isFileNotFound = error && typeof error === "object" && "code" in error && error.code === "ENOENT" || error instanceof Error && error.message.includes("File not found");
2764
+ if (!isFileNotFound) {
2765
+ console.warn(`\u26A0\uFE0F Failed to read manifest from ${filePath}`);
2766
+ }
2756
2767
  return null;
2757
2768
  }
2758
2769
  }
@@ -3465,36 +3476,29 @@ async function pollUntilComplete(options) {
3465
3476
  }
3466
3477
  }
3467
3478
 
3468
- // src/auth.ts
3469
- function getTokenFromEnv() {
3470
- return process.env.ZAPIER_TOKEN;
3479
+ // src/types/credentials.ts
3480
+ function isClientCredentials(credentials) {
3481
+ return typeof credentials === "object" && credentials !== null && "clientId" in credentials && "clientSecret" in credentials;
3471
3482
  }
3472
- async function getTokenFromCliLogin(options = {}) {
3473
- try {
3474
- const { getToken } = await import('@zapier/zapier-sdk-cli-login');
3475
- return await getToken(options);
3476
- } catch {
3477
- return void 0;
3478
- }
3483
+ function isPkceCredentials(credentials) {
3484
+ return typeof credentials === "object" && credentials !== null && "clientId" in credentials && !("clientSecret" in credentials);
3479
3485
  }
3480
- async function getTokenFromEnvOrConfig(options = {}) {
3481
- const envToken = getTokenFromEnv();
3482
- if (envToken) {
3483
- return envToken;
3484
- }
3485
- return getTokenFromCliLogin(options);
3486
+ function isCredentialsObject(credentials) {
3487
+ return typeof credentials === "object" && credentials !== null && "clientId" in credentials;
3486
3488
  }
3487
- async function resolveAuthToken(options = {}) {
3488
- if (options.token) {
3489
- return options.token;
3490
- }
3491
- if (options.getToken) {
3492
- const token = await options.getToken();
3493
- if (token) {
3494
- return token;
3495
- }
3496
- }
3497
- return getTokenFromEnvOrConfig(options);
3489
+ function isCredentialsFunction(credentials) {
3490
+ return typeof credentials === "function";
3491
+ }
3492
+
3493
+ // src/utils/logging.ts
3494
+ var loggedDeprecations = /* @__PURE__ */ new Set();
3495
+ function logDeprecation(message) {
3496
+ if (loggedDeprecations.has(message)) return;
3497
+ loggedDeprecations.add(message);
3498
+ console.warn(`[zapier-sdk] Deprecation: ${message}`);
3499
+ }
3500
+ function resetDeprecationWarnings() {
3501
+ loggedDeprecations.clear();
3498
3502
  }
3499
3503
 
3500
3504
  // src/utils/url-utils.ts
@@ -3543,6 +3547,278 @@ function getTrackingBaseUrl({
3543
3547
  return ZAPIER_BASE_URL;
3544
3548
  }
3545
3549
 
3550
+ // src/credentials.ts
3551
+ function deriveAuthBaseUrl(sdkBaseUrl) {
3552
+ if (!sdkBaseUrl) return void 0;
3553
+ return getZapierBaseUrl(sdkBaseUrl);
3554
+ }
3555
+ function normalizeCredentialsObject(obj, sdkBaseUrl) {
3556
+ const resolvedBaseUrl = obj.baseUrl || deriveAuthBaseUrl(sdkBaseUrl);
3557
+ if (obj.type === "client_credentials" || "clientSecret" in obj && obj.clientSecret) {
3558
+ return {
3559
+ type: "client_credentials",
3560
+ clientId: obj.clientId,
3561
+ clientSecret: obj.clientSecret,
3562
+ baseUrl: resolvedBaseUrl,
3563
+ scope: obj.scope
3564
+ };
3565
+ }
3566
+ return {
3567
+ type: "pkce",
3568
+ clientId: obj.clientId,
3569
+ baseUrl: resolvedBaseUrl,
3570
+ scope: obj.scope
3571
+ };
3572
+ }
3573
+ function resolveCredentialsFromEnv(sdkBaseUrl) {
3574
+ if (ZAPIER_CREDENTIALS) {
3575
+ return ZAPIER_CREDENTIALS;
3576
+ }
3577
+ if (ZAPIER_CREDENTIALS_CLIENT_ID) {
3578
+ const resolvedBaseUrl = ZAPIER_CREDENTIALS_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
3579
+ if (ZAPIER_CREDENTIALS_CLIENT_SECRET) {
3580
+ return {
3581
+ type: "client_credentials",
3582
+ clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
3583
+ clientSecret: ZAPIER_CREDENTIALS_CLIENT_SECRET,
3584
+ baseUrl: resolvedBaseUrl,
3585
+ scope: ZAPIER_CREDENTIALS_SCOPE
3586
+ };
3587
+ } else {
3588
+ return {
3589
+ type: "pkce",
3590
+ clientId: ZAPIER_CREDENTIALS_CLIENT_ID,
3591
+ baseUrl: resolvedBaseUrl,
3592
+ scope: ZAPIER_CREDENTIALS_SCOPE
3593
+ };
3594
+ }
3595
+ }
3596
+ if (ZAPIER_TOKEN) {
3597
+ logDeprecation(
3598
+ "ZAPIER_TOKEN is deprecated. Use ZAPIER_CREDENTIALS instead."
3599
+ );
3600
+ return ZAPIER_TOKEN;
3601
+ }
3602
+ if (ZAPIER_AUTH_CLIENT_ID) {
3603
+ logDeprecation(
3604
+ "ZAPIER_AUTH_CLIENT_ID is deprecated. Use ZAPIER_CREDENTIALS_CLIENT_ID instead."
3605
+ );
3606
+ if (ZAPIER_AUTH_BASE_URL) {
3607
+ logDeprecation(
3608
+ "ZAPIER_AUTH_BASE_URL is deprecated. Use ZAPIER_CREDENTIALS_BASE_URL instead."
3609
+ );
3610
+ }
3611
+ const resolvedBaseUrl = ZAPIER_AUTH_BASE_URL || deriveAuthBaseUrl(sdkBaseUrl);
3612
+ return {
3613
+ type: "pkce",
3614
+ clientId: ZAPIER_AUTH_CLIENT_ID,
3615
+ baseUrl: resolvedBaseUrl
3616
+ };
3617
+ }
3618
+ return void 0;
3619
+ }
3620
+ async function resolveCredentials(options = {}) {
3621
+ const { baseUrl } = options;
3622
+ if (options.credentials !== void 0) {
3623
+ if (isCredentialsFunction(options.credentials)) {
3624
+ const resolved = await options.credentials();
3625
+ if (typeof resolved === "function") {
3626
+ throw new Error(
3627
+ "Credentials function returned another function. Credentials functions must return a string or credentials object."
3628
+ );
3629
+ }
3630
+ if (isCredentialsObject(resolved)) {
3631
+ return normalizeCredentialsObject(resolved, baseUrl);
3632
+ }
3633
+ return resolved;
3634
+ }
3635
+ if (isCredentialsObject(options.credentials)) {
3636
+ return normalizeCredentialsObject(options.credentials, baseUrl);
3637
+ }
3638
+ return options.credentials;
3639
+ }
3640
+ if (options.token !== void 0) {
3641
+ logDeprecation(
3642
+ "The `token` option is deprecated. Use `credentials` instead."
3643
+ );
3644
+ return options.token;
3645
+ }
3646
+ const envCredentials = resolveCredentialsFromEnv(baseUrl);
3647
+ if (envCredentials !== void 0) {
3648
+ return envCredentials;
3649
+ }
3650
+ return void 0;
3651
+ }
3652
+ function getBaseUrlFromCredentials(credentials) {
3653
+ if (credentials && isCredentialsObject(credentials)) {
3654
+ return credentials.baseUrl;
3655
+ }
3656
+ return void 0;
3657
+ }
3658
+ function getClientIdFromCredentials(credentials) {
3659
+ if (credentials && isCredentialsObject(credentials)) {
3660
+ return credentials.clientId;
3661
+ }
3662
+ return void 0;
3663
+ }
3664
+
3665
+ // src/auth.ts
3666
+ var tokenCache = /* @__PURE__ */ new Map();
3667
+ var pendingExchanges = /* @__PURE__ */ new Map();
3668
+ function clearTokenCache() {
3669
+ tokenCache.clear();
3670
+ pendingExchanges.clear();
3671
+ }
3672
+ var TOKEN_EXPIRATION_BUFFER = 5 * 60 * 1e3;
3673
+ function getCachedToken(clientId) {
3674
+ const cached = tokenCache.get(clientId);
3675
+ if (!cached) return void 0;
3676
+ if (cached.expiresAt > Date.now() + TOKEN_EXPIRATION_BUFFER) {
3677
+ return cached.accessToken;
3678
+ }
3679
+ tokenCache.delete(clientId);
3680
+ return void 0;
3681
+ }
3682
+ function cacheToken(clientId, accessToken, expiresIn) {
3683
+ tokenCache.set(clientId, {
3684
+ accessToken,
3685
+ expiresAt: Date.now() + expiresIn * 1e3
3686
+ });
3687
+ }
3688
+ function invalidateCachedToken(clientId) {
3689
+ tokenCache.delete(clientId);
3690
+ }
3691
+ function getTokenEndpointUrl(baseUrl) {
3692
+ const base = baseUrl || ZAPIER_BASE_URL;
3693
+ return `${base}/oauth/token/`;
3694
+ }
3695
+ async function exchangeClientCredentials(options) {
3696
+ const { clientId, clientSecret, baseUrl, scope, onEvent } = options;
3697
+ const fetchFn = options.fetch || globalThis.fetch;
3698
+ const tokenUrl = getTokenEndpointUrl(baseUrl);
3699
+ onEvent?.({
3700
+ type: "auth_exchanging",
3701
+ payload: {
3702
+ message: "Exchanging client credentials for token...",
3703
+ operation: "client_credentials"
3704
+ },
3705
+ timestamp: Date.now()
3706
+ });
3707
+ const response = await fetchFn(tokenUrl, {
3708
+ method: "POST",
3709
+ headers: {
3710
+ "Content-Type": "application/x-www-form-urlencoded"
3711
+ },
3712
+ body: new URLSearchParams({
3713
+ grant_type: "client_credentials",
3714
+ client_id: clientId,
3715
+ client_secret: clientSecret,
3716
+ scope: scope || "external",
3717
+ audience: "zapier.com"
3718
+ })
3719
+ });
3720
+ if (!response.ok) {
3721
+ const errorText = await response.text();
3722
+ onEvent?.({
3723
+ type: "auth_error",
3724
+ payload: {
3725
+ message: `Client credentials exchange failed: ${response.status}`,
3726
+ error: errorText,
3727
+ operation: "client_credentials"
3728
+ },
3729
+ timestamp: Date.now()
3730
+ });
3731
+ throw new Error(
3732
+ `Client credentials exchange failed: ${response.status} ${response.statusText}`
3733
+ );
3734
+ }
3735
+ const data = await response.json();
3736
+ if (!data.access_token) {
3737
+ throw new Error("Client credentials response missing access_token");
3738
+ }
3739
+ const expiresIn = data.expires_in || 3600;
3740
+ cacheToken(clientId, data.access_token, expiresIn);
3741
+ onEvent?.({
3742
+ type: "auth_success",
3743
+ payload: {
3744
+ message: "Client credentials exchange successful",
3745
+ operation: "client_credentials"
3746
+ },
3747
+ timestamp: Date.now()
3748
+ });
3749
+ return data.access_token;
3750
+ }
3751
+ async function getTokenFromCliLogin(options) {
3752
+ try {
3753
+ const cliLogin = await import('@zapier/zapier-sdk-cli-login');
3754
+ return await cliLogin.getToken(options);
3755
+ } catch {
3756
+ return void 0;
3757
+ }
3758
+ }
3759
+ async function resolveAuthToken(options = {}) {
3760
+ const credentials = await resolveCredentials({
3761
+ credentials: options.credentials,
3762
+ token: options.token
3763
+ });
3764
+ if (credentials !== void 0) {
3765
+ return resolveAuthTokenFromCredentials(credentials, options);
3766
+ }
3767
+ return getTokenFromCliLogin({
3768
+ onEvent: options.onEvent,
3769
+ fetch: options.fetch
3770
+ });
3771
+ }
3772
+ async function resolveAuthTokenFromCredentials(credentials, options) {
3773
+ if (typeof credentials === "string") {
3774
+ return credentials;
3775
+ }
3776
+ if (isClientCredentials(credentials)) {
3777
+ const { clientId } = credentials;
3778
+ const cached = getCachedToken(clientId);
3779
+ if (cached) {
3780
+ return cached;
3781
+ }
3782
+ const pending = pendingExchanges.get(clientId);
3783
+ if (pending) {
3784
+ return pending;
3785
+ }
3786
+ const exchangePromise = exchangeClientCredentials({
3787
+ clientId: credentials.clientId,
3788
+ clientSecret: credentials.clientSecret,
3789
+ baseUrl: credentials.baseUrl || options.baseUrl,
3790
+ scope: credentials.scope,
3791
+ fetch: options.fetch,
3792
+ onEvent: options.onEvent
3793
+ }).finally(() => {
3794
+ pendingExchanges.delete(clientId);
3795
+ });
3796
+ pendingExchanges.set(clientId, exchangePromise);
3797
+ return exchangePromise;
3798
+ }
3799
+ if (isPkceCredentials(credentials)) {
3800
+ const storedToken = await getTokenFromCliLogin({
3801
+ onEvent: options.onEvent,
3802
+ fetch: options.fetch,
3803
+ credentials
3804
+ });
3805
+ if (storedToken) {
3806
+ return storedToken;
3807
+ }
3808
+ throw new Error(
3809
+ "PKCE credentials require interactive login. Please run the 'login' command with the CLI first, or use client_credentials flow."
3810
+ );
3811
+ }
3812
+ throw new Error("Unknown credentials type");
3813
+ }
3814
+ async function invalidateCredentialsToken(options) {
3815
+ const resolved = await resolveCredentials(options);
3816
+ const clientId = getClientIdFromCredentials(resolved);
3817
+ if (clientId) {
3818
+ invalidateCachedToken(clientId);
3819
+ }
3820
+ }
3821
+
3546
3822
  // src/api/client.ts
3547
3823
  var pathConfig = {
3548
3824
  // e.g. /relay -> https://sdkapi.zapier.com/api/v0/sdk/relay/...
@@ -3600,13 +3876,11 @@ var ZapierApiClient = class {
3600
3876
  // Helper to get a token from the different places it could be gotten
3601
3877
  async getAuthToken() {
3602
3878
  return resolveAuthToken({
3879
+ credentials: this.options.credentials,
3603
3880
  token: this.options.token,
3604
- getToken: this.options.getToken,
3605
3881
  onEvent: this.options.onEvent,
3606
3882
  fetch: this.options.fetch,
3607
- baseUrl: this.options.baseUrl,
3608
- authBaseUrl: this.options.authBaseUrl,
3609
- authClientId: this.options.authClientId
3883
+ baseUrl: this.options.baseUrl
3610
3884
  });
3611
3885
  }
3612
3886
  // Helper to handle responses
@@ -3644,10 +3918,16 @@ var ZapierApiClient = class {
3644
3918
  if (response.status === 401 || response.status === 403) {
3645
3919
  if (wasMissingAuthToken) {
3646
3920
  throw new ZapierAuthenticationError(
3647
- `Authentication required (HTTP ${response.status}). Please provide a token in options or set ZAPIER_TOKEN environment variable.`,
3921
+ `Authentication required (HTTP ${response.status}). Please provide credentials in options or set ZAPIER_CREDENTIALS environment variable.`,
3648
3922
  errorOptions
3649
3923
  );
3650
3924
  }
3925
+ if (response.status === 401) {
3926
+ await invalidateCredentialsToken({
3927
+ credentials: this.options.credentials,
3928
+ token: this.options.token
3929
+ });
3930
+ }
3651
3931
  throw new ZapierAuthenticationError(message, errorOptions);
3652
3932
  }
3653
3933
  if (response.status === 400) {
@@ -3783,7 +4063,7 @@ var ZapierApiClient = class {
3783
4063
  if (options.authRequired) {
3784
4064
  if (headers.get("Authorization") == null && authToken == null) {
3785
4065
  throw new ZapierAuthenticationError(
3786
- `Authentication required but no token available. Please set ZAPIER_TOKEN, or run the 'login' command with the CLI.`
4066
+ `Authentication required but no credentials available. Please set ZAPIER_CREDENTIALS, or run the 'login' command with the CLI.`
3787
4067
  );
3788
4068
  }
3789
4069
  }
@@ -3859,27 +4139,28 @@ var apiPlugin = (params) => {
3859
4139
  const {
3860
4140
  fetch: customFetch = globalThis.fetch,
3861
4141
  baseUrl = ZAPIER_BASE_URL,
3862
- authBaseUrl,
3863
- authClientId,
4142
+ credentials,
3864
4143
  token,
3865
- getToken,
3866
4144
  onEvent,
3867
4145
  debug = false
3868
4146
  } = params.context.options;
3869
4147
  const api = createZapierApi({
3870
4148
  baseUrl,
3871
- authBaseUrl,
3872
- authClientId,
4149
+ credentials,
3873
4150
  token,
3874
- getToken,
3875
4151
  debug,
3876
4152
  fetch: customFetch,
3877
4153
  onEvent
3878
4154
  });
3879
4155
  return {
3880
4156
  context: {
3881
- api
4157
+ api,
3882
4158
  // Provide API client in context for other plugins to use
4159
+ resolveCredentials: () => resolveCredentials({
4160
+ credentials,
4161
+ token,
4162
+ baseUrl
4163
+ })
3883
4164
  }
3884
4165
  };
3885
4166
  };
@@ -4473,7 +4754,7 @@ function getCpuTime() {
4473
4754
 
4474
4755
  // package.json
4475
4756
  var package_default = {
4476
- version: "0.18.4"};
4757
+ version: "1.0.2"};
4477
4758
 
4478
4759
  // src/plugins/eventEmission/builders.ts
4479
4760
  function createBaseEvent(context = {}) {
@@ -4646,11 +4927,9 @@ var eventEmissionPlugin = ({ context }) => {
4646
4927
  const getUserContext = (async () => {
4647
4928
  try {
4648
4929
  const token = await resolveAuthToken({
4930
+ credentials: context.options.credentials,
4649
4931
  token: context.options.token,
4650
- getToken: context.options.getToken,
4651
4932
  baseUrl: context.options.baseUrl,
4652
- authBaseUrl: context.options.authBaseUrl,
4653
- authClientId: context.options.authClientId,
4654
4933
  onEvent: context.options.onEvent,
4655
4934
  fetch: context.options.fetch
4656
4935
  });
@@ -4929,7 +5208,15 @@ exports.OutputPropertySchema = OutputPropertySchema;
4929
5208
  exports.ParamsPropertySchema = ParamsPropertySchema;
4930
5209
  exports.RelayFetchSchema = RelayFetchSchema;
4931
5210
  exports.RelayRequestSchema = RelayRequestSchema;
5211
+ exports.ZAPIER_AUTH_BASE_URL = ZAPIER_AUTH_BASE_URL;
5212
+ exports.ZAPIER_AUTH_CLIENT_ID = ZAPIER_AUTH_CLIENT_ID;
4932
5213
  exports.ZAPIER_BASE_URL = ZAPIER_BASE_URL;
5214
+ exports.ZAPIER_CREDENTIALS = ZAPIER_CREDENTIALS;
5215
+ exports.ZAPIER_CREDENTIALS_BASE_URL = ZAPIER_CREDENTIALS_BASE_URL;
5216
+ exports.ZAPIER_CREDENTIALS_CLIENT_ID = ZAPIER_CREDENTIALS_CLIENT_ID;
5217
+ exports.ZAPIER_CREDENTIALS_CLIENT_SECRET = ZAPIER_CREDENTIALS_CLIENT_SECRET;
5218
+ exports.ZAPIER_CREDENTIALS_SCOPE = ZAPIER_CREDENTIALS_SCOPE;
5219
+ exports.ZAPIER_TOKEN = ZAPIER_TOKEN;
4933
5220
  exports.ZapierActionError = ZapierActionError;
4934
5221
  exports.ZapierApiError = ZapierApiError;
4935
5222
  exports.ZapierAppNotFoundError = ZapierAppNotFoundError;
@@ -4954,6 +5241,7 @@ exports.buildApplicationLifecycleEvent = buildApplicationLifecycleEvent;
4954
5241
  exports.buildErrorEvent = buildErrorEvent;
4955
5242
  exports.buildErrorEventWithContext = buildErrorEventWithContext;
4956
5243
  exports.buildMethodCalledEvent = buildMethodCalledEvent;
5244
+ exports.clearTokenCache = clearTokenCache;
4957
5245
  exports.createBaseEvent = createBaseEvent;
4958
5246
  exports.createFunction = createFunction;
4959
5247
  exports.createSdk = createSdk;
@@ -4968,7 +5256,9 @@ exports.generateEventId = generateEventId;
4968
5256
  exports.getActionPlugin = getActionPlugin;
4969
5257
  exports.getAppPlugin = getAppPlugin;
4970
5258
  exports.getAuthenticationPlugin = getAuthenticationPlugin;
5259
+ exports.getBaseUrlFromCredentials = getBaseUrlFromCredentials;
4971
5260
  exports.getCiPlatform = getCiPlatform;
5261
+ exports.getClientIdFromCredentials = getClientIdFromCredentials;
4972
5262
  exports.getCpuTime = getCpuTime;
4973
5263
  exports.getCurrentTimestamp = getCurrentTimestamp;
4974
5264
  exports.getMemoryUsage = getMemoryUsage;
@@ -4978,22 +5268,30 @@ exports.getPreferredManifestEntryKey = getPreferredManifestEntryKey;
4978
5268
  exports.getProfilePlugin = getProfilePlugin;
4979
5269
  exports.getReleaseId = getReleaseId;
4980
5270
  exports.getTokenFromCliLogin = getTokenFromCliLogin;
4981
- exports.getTokenFromEnv = getTokenFromEnv;
4982
- exports.getTokenFromEnvOrConfig = getTokenFromEnvOrConfig;
4983
5271
  exports.inputFieldKeyResolver = inputFieldKeyResolver;
4984
5272
  exports.inputsAllOptionalResolver = inputsAllOptionalResolver;
4985
5273
  exports.inputsResolver = inputsResolver;
5274
+ exports.invalidateCachedToken = invalidateCachedToken;
5275
+ exports.invalidateCredentialsToken = invalidateCredentialsToken;
4986
5276
  exports.isCi = isCi;
5277
+ exports.isClientCredentials = isClientCredentials;
5278
+ exports.isCredentialsFunction = isCredentialsFunction;
5279
+ exports.isCredentialsObject = isCredentialsObject;
5280
+ exports.isPkceCredentials = isPkceCredentials;
4987
5281
  exports.isPositional = isPositional;
4988
5282
  exports.listActionsPlugin = listActionsPlugin;
4989
5283
  exports.listAppsPlugin = listAppsPlugin;
4990
5284
  exports.listAuthenticationsPlugin = listAuthenticationsPlugin;
4991
5285
  exports.listInputFieldsPlugin = listInputFieldsPlugin;
5286
+ exports.logDeprecation = logDeprecation;
4992
5287
  exports.manifestPlugin = manifestPlugin;
4993
5288
  exports.readManifestFromFile = readManifestFromFile;
4994
5289
  exports.registryPlugin = registryPlugin;
4995
5290
  exports.requestPlugin = requestPlugin;
5291
+ exports.resetDeprecationWarnings = resetDeprecationWarnings;
4996
5292
  exports.resolveAuthToken = resolveAuthToken;
5293
+ exports.resolveCredentials = resolveCredentials;
5294
+ exports.resolveCredentialsFromEnv = resolveCredentialsFromEnv;
4997
5295
  exports.runActionPlugin = runActionPlugin;
4998
5296
  exports.toSnakeCase = toSnakeCase;
4999
5297
  exports.toTitleCase = toTitleCase;