@zapier/zapier-sdk 0.1.1 → 0.2.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.
@@ -11,7 +11,7 @@ const auth_1 = require("./auth");
11
11
  const debug_1 = require("./debug");
12
12
  const polling_1 = require("./polling");
13
13
  function createZapierApi(options) {
14
- const { baseUrl, token, debug = false, fetch: originalFetch = globalThis.fetch, } = options;
14
+ const { baseUrl, token, getToken, debug = false, fetch: originalFetch = globalThis.fetch, } = options;
15
15
  const debugLog = (0, debug_1.createDebugLogger)(debug);
16
16
  const fetch = (0, debug_1.createDebugFetch)({ originalFetch, debugLog });
17
17
  // Helper to build full URLs
@@ -25,13 +25,23 @@ function createZapierApi(options) {
25
25
  return url.toString();
26
26
  }
27
27
  // Helper to build headers
28
- function buildHeaders(options = {}) {
28
+ async function buildHeaders(options = {}) {
29
29
  const headers = {
30
30
  ...options.headers,
31
31
  };
32
32
  // Add auth header if token provided and not explicitly disabled
33
- if (token && options.authRequired !== false) {
34
- headers.Authorization = (0, auth_1.getAuthorizationHeader)(token);
33
+ if (options.authRequired !== false) {
34
+ let resolvedToken = token;
35
+ // Token resolution precedence: explicit token > getToken() > env var
36
+ if (!resolvedToken && getToken) {
37
+ resolvedToken = await getToken();
38
+ }
39
+ if (!resolvedToken) {
40
+ resolvedToken = process.env.ZAPIER_TOKEN;
41
+ }
42
+ if (resolvedToken) {
43
+ headers.Authorization = (0, auth_1.getAuthorizationHeader)(resolvedToken);
44
+ }
35
45
  }
36
46
  return headers;
37
47
  }
@@ -58,7 +68,7 @@ function createZapierApi(options) {
58
68
  // Helper to perform HTTP requests with JSON handling
59
69
  async function fetchJson(method, path, data, options = {}) {
60
70
  const url = buildUrl(path, options.searchParams);
61
- const headers = buildHeaders(options);
71
+ const headers = await buildHeaders(options);
62
72
  // Add Content-Type for JSON requests with body data
63
73
  if (data && typeof data === "object") {
64
74
  headers["Content-Type"] = "application/json";
@@ -85,7 +95,7 @@ function createZapierApi(options) {
85
95
  },
86
96
  async poll(path, options = {}) {
87
97
  const url = buildUrl(path, options.searchParams);
88
- const headers = buildHeaders(options);
98
+ const headers = await buildHeaders(options);
89
99
  return (0, polling_1.pollUntilComplete)({
90
100
  fetch,
91
101
  url,
@@ -98,5 +108,11 @@ function createZapierApi(options) {
98
108
  resultExtractor: options.resultExtractor,
99
109
  });
100
110
  },
111
+ requireAuthTo(operation) {
112
+ // Check if any authentication method is available
113
+ if (!token && !getToken && !process.env.ZAPIER_TOKEN) {
114
+ throw new Error(`Authentication token is required to ${operation}. Please provide token in options or set ZAPIER_TOKEN environment variable.`);
115
+ }
116
+ },
101
117
  };
102
118
  }
@@ -6,6 +6,7 @@
6
6
  * polling, and provides consistent patterns across all services.
7
7
  */
8
8
  export type { ApiClient, ApiClientOptions, RequestOptions, PollOptions, DebugLogger, Integration, Action, Trigger, Field, Choice, ActionExecutionResult, ActionField, ActionFieldChoice, NeedsRequest, NeedsResponse, Authentication, AuthenticationsResponse, } from "./types";
9
+ import type { ApiClient } from "./types";
9
10
  export { isJwt, getAuthorizationHeader } from "./auth";
10
11
  export { createDebugLogger, createDebugFetch } from "./debug";
11
12
  export { pollUntilComplete } from "./polling";
@@ -20,7 +21,8 @@ export declare function generateRequestId(): string;
20
21
  export declare function getOrCreateApiClient(config: {
21
22
  baseUrl?: string;
22
23
  token?: string;
23
- api?: import("./types").ApiClient;
24
+ getToken?: () => Promise<string | undefined>;
25
+ api?: ApiClient;
24
26
  debug?: boolean;
25
27
  fetch?: typeof globalThis.fetch;
26
- }): import("./types").ApiClient;
28
+ }): ApiClient;
package/dist/api/index.js CHANGED
@@ -24,6 +24,8 @@ Object.defineProperty(exports, "pollUntilComplete", { enumerable: true, get: fun
24
24
  // Re-export the main client factory
25
25
  var client_1 = require("./client");
26
26
  Object.defineProperty(exports, "createZapierApi", { enumerable: true, get: function () { return client_1.createZapierApi; } });
27
+ // Import for local use
28
+ const client_2 = require("./client");
27
29
  // Utility Functions
28
30
  function generateRequestId() {
29
31
  return Math.random().toString(36).substring(2) + Date.now().toString(36);
@@ -35,16 +37,15 @@ function generateRequestId() {
35
37
  * @returns ApiClient instance
36
38
  */
37
39
  function getOrCreateApiClient(config) {
38
- const { baseUrl = "https://zapier.com", token = process.env.ZAPIER_TOKEN, api: providedApi, debug = false, fetch: customFetch, } = config;
40
+ const { baseUrl = "https://zapier.com", token, getToken, api: providedApi, debug = false, fetch: customFetch, } = config;
39
41
  // Use provided API client or create a new one
40
42
  if (providedApi) {
41
43
  return providedApi;
42
44
  }
43
- // Import createZapierApi locally to avoid circular imports
44
- const { createZapierApi } = require("./client");
45
- return createZapierApi({
45
+ return (0, client_2.createZapierApi)({
46
46
  baseUrl,
47
47
  token,
48
+ getToken,
48
49
  debug,
49
50
  fetch: customFetch,
50
51
  });
@@ -8,6 +8,7 @@
8
8
  export interface ApiClientOptions {
9
9
  baseUrl: string;
10
10
  token?: string;
11
+ getToken?: () => Promise<string | undefined>;
11
12
  debug?: boolean;
12
13
  fetch?: typeof globalThis.fetch;
13
14
  }
@@ -17,6 +18,7 @@ export interface ApiClient {
17
18
  put: (path: string, data?: any, options?: RequestOptions) => Promise<any>;
18
19
  delete: (path: string, options?: RequestOptions) => Promise<any>;
19
20
  poll: (path: string, options?: PollOptions) => Promise<any>;
21
+ requireAuthTo: (operation: string) => void;
20
22
  }
21
23
  export interface RequestOptions {
22
24
  headers?: Record<string, string>;
@@ -13,11 +13,8 @@ const getApp_1 = require("../getApp");
13
13
  * @returns Promise<Authentication[]> with pagination metadata
14
14
  */
15
15
  async function listAuthentications(options = {}) {
16
- const { token } = options;
17
- if (!token && !process.env.ZAPIER_TOKEN) {
18
- throw new Error("Authentication token is required to list authentications. Please provide token in options or set ZAPIER_TOKEN environment variable.");
19
- }
20
16
  const api = (0, api_1.getOrCreateApiClient)(options);
17
+ api.requireAuthTo("list authentications");
21
18
  // Local function to handle the actual API fetching
22
19
  const listAuthenticationsInternal = async (options = {}) => {
23
20
  // Build search parameters
@@ -30,6 +30,8 @@ export type ListAuthenticationsOptions = z.infer<typeof ListAuthenticationsSchem
30
30
  baseUrl?: string;
31
31
  /** Authentication token */
32
32
  token?: string;
33
+ /** Function to dynamically resolve authentication token */
34
+ getToken?: () => Promise<string | undefined>;
33
35
  /** Optional pre-instantiated API client */
34
36
  api?: any;
35
37
  /** Enable debug logging */
@@ -15,10 +15,8 @@ const getApp_1 = require("../getApp");
15
15
  */
16
16
  async function runAction(options) {
17
17
  const { appKey, actionType, actionKey, inputs, authenticationId: providedAuthenticationId, token, } = options;
18
- if (!token && !process.env.ZAPIER_TOKEN) {
19
- throw new Error("Authentication token is required to run actions. Please provide token in options or set ZAPIER_TOKEN environment variable.");
20
- }
21
18
  const api = (0, api_1.getOrCreateApiClient)(options);
19
+ api.requireAuthTo("run actions");
22
20
  // Validate that the action exists
23
21
  const actionData = await (0, getAction_1.getAction)({
24
22
  ...options,
@@ -24,6 +24,8 @@ export type RunActionOptions = z.infer<typeof RunActionSchema> & {
24
24
  baseUrl?: string;
25
25
  /** Authentication token */
26
26
  token?: string;
27
+ /** Function to dynamically resolve authentication token */
28
+ getToken?: () => Promise<string | undefined>;
27
29
  /** Optional pre-instantiated API client */
28
30
  api?: any;
29
31
  /** Enable debug logging */
package/dist/sdk.js CHANGED
@@ -43,24 +43,12 @@ const functionRegistry = [
43
43
  // Import plugin functions
44
44
  const index_1 = require("./plugins/apps/index");
45
45
  function createBaseZapierSdk(options = {}) {
46
- // Auto-load .env files (searches up directory tree)
47
- try {
48
- const { findUpSync } = require("find-up");
49
- const envPath = findUpSync(".env");
50
- if (envPath) {
51
- require("dotenv").config({ path: envPath, quiet: true });
52
- }
53
- }
54
- catch {
55
- // Silently fail if dotenv/find-up not available or .env not found
56
- }
57
- const { fetch: customFetch = globalThis.fetch, baseUrl = "https://zapier.com", token, debug = false, } = options;
58
- // If no token provided, try to get it from environment variable
59
- const finalToken = token || process.env.ZAPIER_TOKEN;
46
+ const { fetch: customFetch = globalThis.fetch, baseUrl = "https://zapier.com", token, getToken, debug = false, } = options;
60
47
  // Create the API client
61
48
  const api = (0, api_1.createZapierApi)({
62
49
  baseUrl,
63
- token: finalToken,
50
+ token,
51
+ getToken,
64
52
  debug,
65
53
  fetch: customFetch,
66
54
  });
@@ -69,16 +57,16 @@ function createBaseZapierSdk(options = {}) {
69
57
  // Registry for CLI
70
58
  __registry: functionRegistry,
71
59
  // Function implementations with API config injection
72
- listApps: (options = {}) => (0, listApps_1.listApps)({ ...options, api, token: finalToken }),
73
- getApp: (options) => (0, getApp_1.getApp)({ ...options, api, token: finalToken }),
74
- listActions: (options = {}) => (0, listActions_1.listActions)({ ...options, api, token: finalToken }),
75
- getAction: (options) => (0, getAction_1.getAction)({ ...options, api, token: finalToken }),
76
- runAction: (options) => (0, runAction_1.runAction)({ ...options, api, token: finalToken }),
77
- listAuthentications: (options = {}) => (0, listAuthentications_1.listAuthentications)({ ...options, api, token: finalToken }),
78
- findFirstAuthentication: (options = {}) => (0, findFirstAuthentication_1.findFirstAuthentication)({ ...options, api, token: finalToken }),
79
- findUniqueAuthentication: (options = {}) => (0, findUniqueAuthentication_1.findUniqueAuthentication)({ ...options, api, token: finalToken }),
80
- listFields: (options) => (0, listFields_1.listFields)({ ...options, api, token: finalToken }),
81
- generateTypes: (options) => (0, generateTypes_1.generateTypes)({ ...options, api, token: finalToken }),
60
+ listApps: (options = {}) => (0, listApps_1.listApps)({ ...options, api }),
61
+ getApp: (options) => (0, getApp_1.getApp)({ ...options, api }),
62
+ listActions: (options = {}) => (0, listActions_1.listActions)({ ...options, api }),
63
+ getAction: (options) => (0, getAction_1.getAction)({ ...options, api }),
64
+ runAction: (options) => (0, runAction_1.runAction)({ ...options, api }),
65
+ listAuthentications: (options = {}) => (0, listAuthentications_1.listAuthentications)({ ...options, api }),
66
+ findFirstAuthentication: (options = {}) => (0, findFirstAuthentication_1.findFirstAuthentication)({ ...options, api }),
67
+ findUniqueAuthentication: (options = {}) => (0, findUniqueAuthentication_1.findUniqueAuthentication)({ ...options, api }),
68
+ listFields: (options) => (0, listFields_1.listFields)({ ...options, api }),
69
+ generateTypes: (options) => (0, generateTypes_1.generateTypes)({ ...options, api }),
82
70
  bundleCode: (options) => (0, bundleCode_1.bundleCode)(options), // No API config needed
83
71
  };
84
72
  return sdk;
@@ -87,19 +75,19 @@ function createZapierSdk(options = {}) {
87
75
  // Create base SDK
88
76
  const baseSdk = createBaseZapierSdk(options);
89
77
  // Extract options needed for plugins
90
- const { fetch: customFetch = globalThis.fetch, baseUrl = "https://zapier.com", token, debug = false, } = options;
91
- const finalToken = token || process.env.ZAPIER_TOKEN;
78
+ const { fetch: customFetch = globalThis.fetch, baseUrl = "https://zapier.com", token, getToken, debug = false, } = options;
92
79
  // Create the API client for plugins
93
80
  const api = (0, api_1.createZapierApi)({
94
81
  baseUrl,
95
- token: finalToken,
82
+ token,
83
+ getToken,
96
84
  debug,
97
85
  fetch: customFetch,
98
86
  });
99
87
  // Create plugins directly - TypeScript will enforce correct implementation
100
88
  const appsPlugin = (0, index_1.createAppsPlugin)({
101
89
  api,
102
- token: finalToken,
90
+ token,
103
91
  });
104
92
  // Compose final SDK - TypeScript will enforce we have all required properties
105
93
  const fullSdk = {
@@ -8,6 +8,7 @@ export interface AuthObject {
8
8
  }
9
9
  export interface BaseSdkOptions {
10
10
  token?: string;
11
+ getToken?: () => Promise<string | undefined>;
11
12
  fetch?: typeof fetch;
12
13
  baseUrl?: string;
13
14
  debug?: boolean;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Attempts to read the JWT token from the CLI config file.
3
+ * This is a synchronous function that only returns valid, non-expired tokens.
4
+ * For token refresh logic, the CLI should handle that separately.
5
+ * Returns undefined if config file doesn't exist, token is not available, or token is expired.
6
+ */
7
+ export declare function getTokenFromConfig(): string | undefined;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTokenFromConfig = getTokenFromConfig;
4
+ /**
5
+ * Attempts to read the JWT token from the CLI config file.
6
+ * This is a synchronous function that only returns valid, non-expired tokens.
7
+ * For token refresh logic, the CLI should handle that separately.
8
+ * Returns undefined if config file doesn't exist, token is not available, or token is expired.
9
+ */
10
+ function getTokenFromConfig() {
11
+ try {
12
+ // Dynamically import conf to avoid dependency issues if not installed
13
+ const Conf = require("conf");
14
+ const config = new Conf({ projectName: "zapier-sdk-cli" });
15
+ // Get the stored JWT token
16
+ const jwt = config.get("login_jwt");
17
+ const expiresAt = config.get("login_expires_at");
18
+ // Check if token exists and is not expired (with 30s buffer)
19
+ if (jwt && expiresAt && expiresAt > Date.now() + 30 * 1000) {
20
+ return jwt;
21
+ }
22
+ // Token is missing or expired - return undefined so SDK will require explicit auth
23
+ return undefined;
24
+ }
25
+ catch {
26
+ // Config package not available or other error - silently fail
27
+ return undefined;
28
+ }
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Complete Zapier SDK - combines all Zapier SDK packages",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,9 +18,7 @@
18
18
  "access": "restricted"
19
19
  },
20
20
  "dependencies": {
21
- "dotenv": "^17.0.0",
22
21
  "esbuild": "^0.25.5",
23
- "find-up": "^7.0.0",
24
22
  "zod": "^3.25.67"
25
23
  },
26
24
  "devDependencies": {
package/src/api/client.ts CHANGED
@@ -19,6 +19,7 @@ export function createZapierApi(options: ApiClientOptions): ApiClient {
19
19
  const {
20
20
  baseUrl,
21
21
  token,
22
+ getToken,
22
23
  debug = false,
23
24
  fetch: originalFetch = globalThis.fetch,
24
25
  } = options;
@@ -41,14 +42,29 @@ export function createZapierApi(options: ApiClientOptions): ApiClient {
41
42
  }
42
43
 
43
44
  // Helper to build headers
44
- function buildHeaders(options: RequestOptions = {}): Record<string, string> {
45
+ async function buildHeaders(
46
+ options: RequestOptions = {},
47
+ ): Promise<Record<string, string>> {
45
48
  const headers: Record<string, string> = {
46
49
  ...options.headers,
47
50
  };
48
51
 
49
52
  // Add auth header if token provided and not explicitly disabled
50
- if (token && options.authRequired !== false) {
51
- headers.Authorization = getAuthorizationHeader(token);
53
+ if (options.authRequired !== false) {
54
+ let resolvedToken = token;
55
+
56
+ // Token resolution precedence: explicit token > getToken() > env var
57
+ if (!resolvedToken && getToken) {
58
+ resolvedToken = await getToken();
59
+ }
60
+
61
+ if (!resolvedToken) {
62
+ resolvedToken = process.env.ZAPIER_TOKEN;
63
+ }
64
+
65
+ if (resolvedToken) {
66
+ headers.Authorization = getAuthorizationHeader(resolvedToken);
67
+ }
52
68
  }
53
69
 
54
70
  return headers;
@@ -87,7 +103,7 @@ export function createZapierApi(options: ApiClientOptions): ApiClient {
87
103
  options: RequestOptions = {},
88
104
  ): Promise<any> {
89
105
  const url = buildUrl(path, options.searchParams);
90
- const headers = buildHeaders(options);
106
+ const headers = await buildHeaders(options);
91
107
 
92
108
  // Add Content-Type for JSON requests with body data
93
109
  if (data && typeof data === "object") {
@@ -130,7 +146,7 @@ export function createZapierApi(options: ApiClientOptions): ApiClient {
130
146
 
131
147
  async poll(path: string, options: PollOptions = {}): Promise<any> {
132
148
  const url = buildUrl(path, options.searchParams);
133
- const headers = buildHeaders(options);
149
+ const headers = await buildHeaders(options);
134
150
 
135
151
  return pollUntilComplete({
136
152
  fetch,
@@ -144,5 +160,14 @@ export function createZapierApi(options: ApiClientOptions): ApiClient {
144
160
  resultExtractor: options.resultExtractor,
145
161
  });
146
162
  },
163
+
164
+ requireAuthTo(operation: string): void {
165
+ // Check if any authentication method is available
166
+ if (!token && !getToken && !process.env.ZAPIER_TOKEN) {
167
+ throw new Error(
168
+ `Authentication token is required to ${operation}. Please provide token in options or set ZAPIER_TOKEN environment variable.`,
169
+ );
170
+ }
171
+ },
147
172
  };
148
173
  }
package/src/api/index.ts CHANGED
@@ -29,6 +29,9 @@ export type {
29
29
  AuthenticationsResponse,
30
30
  } from "./types";
31
31
 
32
+ // Import for local use
33
+ import type { ApiClient } from "./types";
34
+
32
35
  // Re-export authentication utilities
33
36
  export { isJwt, getAuthorizationHeader } from "./auth";
34
37
 
@@ -41,6 +44,9 @@ export { pollUntilComplete } from "./polling";
41
44
  // Re-export the main client factory
42
45
  export { createZapierApi } from "./client";
43
46
 
47
+ // Import for local use
48
+ import { createZapierApi } from "./client";
49
+
44
50
  // Utility Functions
45
51
  export function generateRequestId(): string {
46
52
  return Math.random().toString(36).substring(2) + Date.now().toString(36);
@@ -55,13 +61,15 @@ export function generateRequestId(): string {
55
61
  export function getOrCreateApiClient(config: {
56
62
  baseUrl?: string;
57
63
  token?: string;
58
- api?: import("./types").ApiClient;
64
+ getToken?: () => Promise<string | undefined>;
65
+ api?: ApiClient;
59
66
  debug?: boolean;
60
67
  fetch?: typeof globalThis.fetch;
61
- }): import("./types").ApiClient {
68
+ }): ApiClient {
62
69
  const {
63
70
  baseUrl = "https://zapier.com",
64
- token = process.env.ZAPIER_TOKEN,
71
+ token,
72
+ getToken,
65
73
  api: providedApi,
66
74
  debug = false,
67
75
  fetch: customFetch,
@@ -72,11 +80,10 @@ export function getOrCreateApiClient(config: {
72
80
  return providedApi;
73
81
  }
74
82
 
75
- // Import createZapierApi locally to avoid circular imports
76
- const { createZapierApi } = require("./client");
77
83
  return createZapierApi({
78
84
  baseUrl,
79
85
  token,
86
+ getToken,
80
87
  debug,
81
88
  fetch: customFetch,
82
89
  });
package/src/api/types.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  export interface ApiClientOptions {
14
14
  baseUrl: string;
15
15
  token?: string;
16
+ getToken?: () => Promise<string | undefined>;
16
17
  debug?: boolean;
17
18
  fetch?: typeof globalThis.fetch;
18
19
  }
@@ -23,6 +24,7 @@ export interface ApiClient {
23
24
  put: (path: string, data?: any, options?: RequestOptions) => Promise<any>;
24
25
  delete: (path: string, options?: RequestOptions) => Promise<any>;
25
26
  poll: (path: string, options?: PollOptions) => Promise<any>;
27
+ requireAuthTo: (operation: string) => void;
26
28
  }
27
29
 
28
30
  export interface RequestOptions {
@@ -18,15 +18,8 @@ import type { ListAuthenticationsOptions } from "./schemas";
18
18
  export async function listAuthentications(
19
19
  options: Partial<ListAuthenticationsOptions> = {},
20
20
  ): Promise<Authentication[]> {
21
- const { token } = options;
22
-
23
- if (!token && !process.env.ZAPIER_TOKEN) {
24
- throw new Error(
25
- "Authentication token is required to list authentications. Please provide token in options or set ZAPIER_TOKEN environment variable.",
26
- );
27
- }
28
-
29
21
  const api = getOrCreateApiClient(options);
22
+ api.requireAuthTo("list authentications");
30
23
 
31
24
  // Local function to handle the actual API fetching
32
25
  const listAuthenticationsInternal = async (
@@ -44,6 +44,8 @@ export type ListAuthenticationsOptions = z.infer<
44
44
  baseUrl?: string;
45
45
  /** Authentication token */
46
46
  token?: string;
47
+ /** Function to dynamically resolve authentication token */
48
+ getToken?: () => Promise<string | undefined>;
47
49
  /** Optional pre-instantiated API client */
48
50
  api?: any;
49
51
  /** Enable debug logging */
@@ -25,13 +25,8 @@ export async function runAction(
25
25
  token,
26
26
  } = options;
27
27
 
28
- if (!token && !process.env.ZAPIER_TOKEN) {
29
- throw new Error(
30
- "Authentication token is required to run actions. Please provide token in options or set ZAPIER_TOKEN environment variable.",
31
- );
32
- }
33
-
34
28
  const api = getOrCreateApiClient(options);
29
+ api.requireAuthTo("run actions");
35
30
 
36
31
  // Validate that the action exists
37
32
  const actionData = await getAction({
@@ -27,6 +27,8 @@ export type RunActionOptions = z.infer<typeof RunActionSchema> & {
27
27
  baseUrl?: string;
28
28
  /** Authentication token */
29
29
  token?: string;
30
+ /** Function to dynamically resolve authentication token */
31
+ getToken?: () => Promise<string | undefined>;
30
32
  /** Optional pre-instantiated API client */
31
33
  api?: any;
32
34
  /** Enable debug logging */
package/src/sdk.ts CHANGED
@@ -77,31 +77,19 @@ export interface ZapierSdkOptions extends BaseSdkOptions {}
77
77
  function createBaseZapierSdk(
78
78
  options: ZapierSdkOptions = {},
79
79
  ): BaseZapierSdkWithFunctions {
80
- // Auto-load .env files (searches up directory tree)
81
- try {
82
- const { findUpSync } = require("find-up");
83
- const envPath = findUpSync(".env");
84
- if (envPath) {
85
- require("dotenv").config({ path: envPath, quiet: true });
86
- }
87
- } catch {
88
- // Silently fail if dotenv/find-up not available or .env not found
89
- }
90
-
91
80
  const {
92
81
  fetch: customFetch = globalThis.fetch,
93
82
  baseUrl = "https://zapier.com",
94
83
  token,
84
+ getToken,
95
85
  debug = false,
96
86
  } = options;
97
87
 
98
- // If no token provided, try to get it from environment variable
99
- const finalToken = token || process.env.ZAPIER_TOKEN;
100
-
101
88
  // Create the API client
102
89
  const api = createZapierApi({
103
90
  baseUrl,
104
- token: finalToken,
91
+ token,
92
+ getToken,
105
93
  debug,
106
94
  fetch: customFetch,
107
95
  });
@@ -112,22 +100,19 @@ function createBaseZapierSdk(
112
100
  __registry: functionRegistry,
113
101
 
114
102
  // Function implementations with API config injection
115
- listApps: (options = {}) =>
116
- listApps({ ...options, api, token: finalToken }),
117
- getApp: (options) => getApp({ ...options, api, token: finalToken }),
118
- listActions: (options = {}) =>
119
- listActions({ ...options, api, token: finalToken }),
120
- getAction: (options) => getAction({ ...options, api, token: finalToken }),
121
- runAction: (options) => runAction({ ...options, api, token: finalToken }),
103
+ listApps: (options = {}) => listApps({ ...options, api }),
104
+ getApp: (options) => getApp({ ...options, api }),
105
+ listActions: (options = {}) => listActions({ ...options, api }),
106
+ getAction: (options) => getAction({ ...options, api }),
107
+ runAction: (options) => runAction({ ...options, api }),
122
108
  listAuthentications: (options = {}) =>
123
- listAuthentications({ ...options, api, token: finalToken }),
109
+ listAuthentications({ ...options, api }),
124
110
  findFirstAuthentication: (options = {}) =>
125
- findFirstAuthentication({ ...options, api, token: finalToken }),
111
+ findFirstAuthentication({ ...options, api }),
126
112
  findUniqueAuthentication: (options = {}) =>
127
- findUniqueAuthentication({ ...options, api, token: finalToken }),
128
- listFields: (options) => listFields({ ...options, api, token: finalToken }),
129
- generateTypes: (options) =>
130
- generateTypes({ ...options, api, token: finalToken }),
113
+ findUniqueAuthentication({ ...options, api }),
114
+ listFields: (options) => listFields({ ...options, api }),
115
+ generateTypes: (options) => generateTypes({ ...options, api }),
131
116
  bundleCode: (options) => bundleCode(options), // No API config needed
132
117
  };
133
118
 
@@ -143,15 +128,15 @@ export function createZapierSdk(options: ZapierSdkOptions = {}): ZapierSdk {
143
128
  fetch: customFetch = globalThis.fetch,
144
129
  baseUrl = "https://zapier.com",
145
130
  token,
131
+ getToken,
146
132
  debug = false,
147
133
  } = options;
148
134
 
149
- const finalToken = token || process.env.ZAPIER_TOKEN;
150
-
151
135
  // Create the API client for plugins
152
136
  const api = createZapierApi({
153
137
  baseUrl,
154
- token: finalToken,
138
+ token,
139
+ getToken,
155
140
  debug,
156
141
  fetch: customFetch,
157
142
  });
@@ -159,7 +144,7 @@ export function createZapierSdk(options: ZapierSdkOptions = {}): ZapierSdk {
159
144
  // Create plugins directly - TypeScript will enforce correct implementation
160
145
  const appsPlugin = createAppsPlugin({
161
146
  api,
162
- token: finalToken,
147
+ token,
163
148
  });
164
149
 
165
150
  // Compose final SDK - TypeScript will enforce we have all required properties
@@ -26,6 +26,7 @@ export interface AuthObject {
26
26
 
27
27
  export interface BaseSdkOptions {
28
28
  token?: string;
29
+ getToken?: () => Promise<string | undefined>;
29
30
  fetch?: typeof fetch;
30
31
  baseUrl?: string;
31
32
  debug?: boolean;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Attempts to read the JWT token from the CLI config file.
3
+ * This is a synchronous function that only returns valid, non-expired tokens.
4
+ * For token refresh logic, the CLI should handle that separately.
5
+ * Returns undefined if config file doesn't exist, token is not available, or token is expired.
6
+ */
7
+ export function getTokenFromConfig(): string | undefined {
8
+ try {
9
+ // Dynamically import conf to avoid dependency issues if not installed
10
+ const Conf = require("conf");
11
+ const config = new Conf({ projectName: "zapier-sdk-cli" });
12
+
13
+ // Get the stored JWT token
14
+ const jwt = config.get("login_jwt") as string | undefined;
15
+ const expiresAt = config.get("login_expires_at") as number | undefined;
16
+
17
+ // Check if token exists and is not expired (with 30s buffer)
18
+ if (jwt && expiresAt && expiresAt > Date.now() + 30 * 1000) {
19
+ return jwt;
20
+ }
21
+
22
+ // Token is missing or expired - return undefined so SDK will require explicit auth
23
+ return undefined;
24
+ } catch {
25
+ // Config package not available or other error - silently fail
26
+ return undefined;
27
+ }
28
+ }