@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.
- package/dist/api/client.js +22 -6
- package/dist/api/index.d.ts +4 -2
- package/dist/api/index.js +5 -4
- package/dist/api/types.d.ts +2 -0
- package/dist/functions/listAuthentications/index.js +1 -4
- package/dist/functions/listAuthentications/schemas.d.ts +2 -0
- package/dist/functions/runAction/index.js +1 -3
- package/dist/functions/runAction/schemas.d.ts +2 -0
- package/dist/sdk.js +17 -29
- package/dist/types/domain.d.ts +1 -0
- package/dist/utils/getTokenFromConfig.d.ts +7 -0
- package/dist/utils/getTokenFromConfig.js +29 -0
- package/package.json +1 -3
- package/src/api/client.ts +30 -5
- package/src/api/index.ts +12 -5
- package/src/api/types.ts +2 -0
- package/src/functions/listAuthentications/index.ts +1 -8
- package/src/functions/listAuthentications/schemas.ts +2 -0
- package/src/functions/runAction/index.ts +1 -6
- package/src/functions/runAction/schemas.ts +2 -0
- package/src/sdk.ts +17 -32
- package/src/types/domain.ts +1 -0
- package/src/utils/getTokenFromConfig.ts +28 -0
package/dist/api/client.js
CHANGED
|
@@ -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 (
|
|
34
|
-
|
|
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
|
}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
24
|
+
getToken?: () => Promise<string | undefined>;
|
|
25
|
+
api?: ApiClient;
|
|
24
26
|
debug?: boolean;
|
|
25
27
|
fetch?: typeof globalThis.fetch;
|
|
26
|
-
}):
|
|
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
|
|
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
|
-
|
|
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
|
});
|
package/dist/api/types.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
73
|
-
getApp: (options) => (0, getApp_1.getApp)({ ...options, api
|
|
74
|
-
listActions: (options = {}) => (0, listActions_1.listActions)({ ...options, api
|
|
75
|
-
getAction: (options) => (0, getAction_1.getAction)({ ...options, api
|
|
76
|
-
runAction: (options) => (0, runAction_1.runAction)({ ...options, api
|
|
77
|
-
listAuthentications: (options = {}) => (0, listAuthentications_1.listAuthentications)({ ...options, api
|
|
78
|
-
findFirstAuthentication: (options = {}) => (0, findFirstAuthentication_1.findFirstAuthentication)({ ...options, api
|
|
79
|
-
findUniqueAuthentication: (options = {}) => (0, findUniqueAuthentication_1.findUniqueAuthentication)({ ...options, api
|
|
80
|
-
listFields: (options) => (0, listFields_1.listFields)({ ...options, api
|
|
81
|
-
generateTypes: (options) => (0, generateTypes_1.generateTypes)({ ...options, api
|
|
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
|
|
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
|
|
90
|
+
token,
|
|
103
91
|
});
|
|
104
92
|
// Compose final SDK - TypeScript will enforce we have all required properties
|
|
105
93
|
const fullSdk = {
|
package/dist/types/domain.d.ts
CHANGED
|
@@ -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.
|
|
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(
|
|
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 (
|
|
51
|
-
|
|
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
|
-
|
|
64
|
+
getToken?: () => Promise<string | undefined>;
|
|
65
|
+
api?: ApiClient;
|
|
59
66
|
debug?: boolean;
|
|
60
67
|
fetch?: typeof globalThis.fetch;
|
|
61
|
-
}):
|
|
68
|
+
}): ApiClient {
|
|
62
69
|
const {
|
|
63
70
|
baseUrl = "https://zapier.com",
|
|
64
|
-
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
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
|
109
|
+
listAuthentications({ ...options, api }),
|
|
124
110
|
findFirstAuthentication: (options = {}) =>
|
|
125
|
-
findFirstAuthentication({ ...options, api
|
|
111
|
+
findFirstAuthentication({ ...options, api }),
|
|
126
112
|
findUniqueAuthentication: (options = {}) =>
|
|
127
|
-
findUniqueAuthentication({ ...options, api
|
|
128
|
-
listFields: (options) => listFields({ ...options, api
|
|
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
|
|
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
|
|
147
|
+
token,
|
|
163
148
|
});
|
|
164
149
|
|
|
165
150
|
// Compose final SDK - TypeScript will enforce we have all required properties
|
package/src/types/domain.ts
CHANGED
|
@@ -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
|
+
}
|