@zapier/zapier-sdk-cli 0.2.1 → 0.4.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/bin/zapier-sdk.js +1 -1
- package/bin/zsdk.js +1 -1
- package/dist/cli.js +1099 -16
- package/dist/index.js +0 -3
- package/package.json +6 -3
- package/src/cli.ts +1 -1
- package/src/commands/configPath.ts +1 -1
- package/src/commands/login.ts +1 -1
- package/src/commands/logout.ts +1 -1
- package/src/commands/whoami.ts +1 -1
- package/src/utils/auth/login.ts +1 -1
- package/tsconfig.json +1 -1
- package/tsup.config.ts +17 -0
- package/dist/cli.d.ts +0 -2
- package/dist/commands/configPath.d.ts +0 -2
- package/dist/commands/configPath.js +0 -9
- package/dist/commands/index.d.ts +0 -4
- package/dist/commands/index.js +0 -4
- package/dist/commands/login.d.ts +0 -2
- package/dist/commands/login.js +0 -25
- package/dist/commands/logout.d.ts +0 -2
- package/dist/commands/logout.js +0 -16
- package/dist/commands/whoami.d.ts +0 -2
- package/dist/commands/whoami.js +0 -17
- package/dist/index.d.ts +0 -0
- package/dist/utils/api/client.d.ts +0 -15
- package/dist/utils/api/client.js +0 -27
- package/dist/utils/auth/login.d.ts +0 -2
- package/dist/utils/auth/login.js +0 -134
- package/dist/utils/cli-generator.d.ts +0 -3
- package/dist/utils/cli-generator.js +0 -388
- package/dist/utils/constants.d.ts +0 -5
- package/dist/utils/constants.js +0 -6
- package/dist/utils/getCallablePromise.d.ts +0 -6
- package/dist/utils/getCallablePromise.js +0 -14
- package/dist/utils/log.d.ts +0 -7
- package/dist/utils/log.js +0 -16
- package/dist/utils/pager.d.ts +0 -48
- package/dist/utils/pager.js +0 -137
- package/dist/utils/parameter-resolver.d.ts +0 -13
- package/dist/utils/parameter-resolver.js +0 -300
- package/dist/utils/schema-formatter.d.ts +0 -2
- package/dist/utils/schema-formatter.js +0 -71
- package/dist/utils/serializeAsync.d.ts +0 -2
- package/dist/utils/serializeAsync.js +0 -16
- package/dist/utils/spinner.d.ts +0 -1
- package/dist/utils/spinner.js +0 -13
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zapier/zapier-sdk-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Command line interface for Zapier SDK",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
8
|
"bin": {
|
|
@@ -29,19 +30,21 @@
|
|
|
29
30
|
"ora": "^8.2.0",
|
|
30
31
|
"pkce-challenge": "^5.0.0",
|
|
31
32
|
"zod": "^3.25.67",
|
|
32
|
-
"@zapier/zapier-sdk": "0.
|
|
33
|
+
"@zapier/zapier-sdk-cli-login": "0.3.1",
|
|
34
|
+
"@zapier/zapier-sdk": "0.4.0"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@types/express": "^5.0.3",
|
|
36
38
|
"@types/inquirer": "^9.0.8",
|
|
37
39
|
"@types/jsonwebtoken": "^9.0.10",
|
|
38
40
|
"@types/node": "^24.0.1",
|
|
41
|
+
"tsup": "^8.5.0",
|
|
39
42
|
"typescript": "^5.8.3",
|
|
40
43
|
"vitest": "^3.2.3"
|
|
41
44
|
},
|
|
42
45
|
"scripts": {
|
|
43
46
|
"test": "vitest",
|
|
44
|
-
"build": "
|
|
47
|
+
"build": "tsup",
|
|
45
48
|
"clean": "rm -rf dist",
|
|
46
49
|
"rebuild": "pnpm clean && pnpm build",
|
|
47
50
|
"dev": "tsx src/cli.ts",
|
package/src/cli.ts
CHANGED
package/src/commands/login.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import login from "../utils/auth/login";
|
|
3
|
-
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
3
|
+
import { getLoggedInUser } from "@zapier/zapier-sdk-cli-login";
|
|
4
4
|
|
|
5
5
|
export function createLoginCommand(): Command {
|
|
6
6
|
return new Command("login")
|
package/src/commands/logout.ts
CHANGED
package/src/commands/whoami.ts
CHANGED
package/src/utils/auth/login.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { spinPromise } from "../spinner";
|
|
|
14
14
|
import log from "../log";
|
|
15
15
|
import api from "../api/client";
|
|
16
16
|
import getCallablePromise from "../getCallablePromise";
|
|
17
|
-
import { updateLogin, logout } from "@zapier/zapier-sdk";
|
|
17
|
+
import { updateLogin, logout } from "@zapier/zapier-sdk-cli-login";
|
|
18
18
|
|
|
19
19
|
const findAvailablePort = (): Promise<number> => {
|
|
20
20
|
return new Promise((resolve, reject) => {
|
package/tsconfig.json
CHANGED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ["src/index.ts", "src/cli.ts"],
|
|
5
|
+
format: ["esm"],
|
|
6
|
+
dts: false,
|
|
7
|
+
clean: true,
|
|
8
|
+
splitting: false,
|
|
9
|
+
sourcemap: false,
|
|
10
|
+
outDir: "dist",
|
|
11
|
+
// Keep as .js for Node.js compatibility since package.json has type: module
|
|
12
|
+
outExtension({ format }) {
|
|
13
|
+
return {
|
|
14
|
+
js: ".js",
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
});
|
package/dist/cli.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { getConfigPath } from "@zapier/zapier-sdk";
|
|
3
|
-
export function createConfigPathCommand() {
|
|
4
|
-
return new Command("get-config-path")
|
|
5
|
-
.description("Show the path to the configuration file")
|
|
6
|
-
.action(async () => {
|
|
7
|
-
console.log(`Configuration file: ${getConfigPath()}`);
|
|
8
|
-
});
|
|
9
|
-
}
|
package/dist/commands/index.d.ts
DELETED
package/dist/commands/index.js
DELETED
package/dist/commands/login.d.ts
DELETED
package/dist/commands/login.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import login from "../utils/auth/login";
|
|
3
|
-
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
4
|
-
export function createLoginCommand() {
|
|
5
|
-
return new Command("login")
|
|
6
|
-
.description("Log in to Zapier to access your account")
|
|
7
|
-
.option("--timeout <seconds>", "Login timeout in seconds (default: 300)", "300")
|
|
8
|
-
.action(async (options) => {
|
|
9
|
-
try {
|
|
10
|
-
const timeoutSeconds = parseInt(options.timeout, 10);
|
|
11
|
-
if (isNaN(timeoutSeconds) || timeoutSeconds <= 0) {
|
|
12
|
-
throw new Error("Timeout must be a positive number");
|
|
13
|
-
}
|
|
14
|
-
await login(timeoutSeconds * 1000); // Convert to milliseconds
|
|
15
|
-
const user = await getLoggedInUser();
|
|
16
|
-
console.log(`✅ Successfully logged in as ${user.email}`);
|
|
17
|
-
// Force immediate exit to prevent hanging (especially in development with tsx)
|
|
18
|
-
setTimeout(() => process.exit(0), 100);
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
console.error("❌ Login failed:", error instanceof Error ? error.message : "Unknown error");
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
package/dist/commands/logout.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { logout } from "@zapier/zapier-sdk";
|
|
3
|
-
export function createLogoutCommand() {
|
|
4
|
-
return new Command("logout")
|
|
5
|
-
.description("Log out of your Zapier account")
|
|
6
|
-
.action(async () => {
|
|
7
|
-
try {
|
|
8
|
-
logout();
|
|
9
|
-
console.log("✅ Successfully logged out");
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
console.error("❌ Logout failed:", error instanceof Error ? error.message : "Unknown error");
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
}
|
package/dist/commands/whoami.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { getLoggedInUser } from "@zapier/zapier-sdk";
|
|
3
|
-
import { spinPromise } from "../utils/spinner";
|
|
4
|
-
export function createWhoamiCommand() {
|
|
5
|
-
return new Command("whoami")
|
|
6
|
-
.description("Show current login status and user information")
|
|
7
|
-
.action(async () => {
|
|
8
|
-
try {
|
|
9
|
-
const user = await spinPromise(getLoggedInUser(), "Checking login status...");
|
|
10
|
-
console.log(`✅ Logged in as ${user.email} (Account ID: ${user.accountId})`);
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
console.log("❌ Not logged in. Use 'zapier-sdk login' to authenticate.");
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
package/dist/index.d.ts
DELETED
|
File without changes
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface ApiResponse<T = any> {
|
|
2
|
-
data: T;
|
|
3
|
-
status: number;
|
|
4
|
-
}
|
|
5
|
-
export declare const createApiClient: () => {
|
|
6
|
-
post: <T = any>(url: string, data: any, options?: {
|
|
7
|
-
headers?: Record<string, string>;
|
|
8
|
-
}) => Promise<ApiResponse<T>>;
|
|
9
|
-
};
|
|
10
|
-
declare const api: {
|
|
11
|
-
post: <T = any>(url: string, data: any, options?: {
|
|
12
|
-
headers?: Record<string, string>;
|
|
13
|
-
}) => Promise<ApiResponse<T>>;
|
|
14
|
-
};
|
|
15
|
-
export default api;
|
package/dist/utils/api/client.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export const createApiClient = () => {
|
|
2
|
-
const post = async (url, data, options = {}) => {
|
|
3
|
-
const { headers = {} } = options;
|
|
4
|
-
const response = await fetch(url, {
|
|
5
|
-
method: "POST",
|
|
6
|
-
headers: {
|
|
7
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
8
|
-
Connection: "close",
|
|
9
|
-
...headers,
|
|
10
|
-
},
|
|
11
|
-
body: new URLSearchParams(data),
|
|
12
|
-
});
|
|
13
|
-
if (!response.ok) {
|
|
14
|
-
throw new Error(`${response.status} ${response.statusText}`);
|
|
15
|
-
}
|
|
16
|
-
const responseData = await response.json();
|
|
17
|
-
return {
|
|
18
|
-
data: responseData,
|
|
19
|
-
status: response.status,
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
return {
|
|
23
|
-
post,
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
const api = createApiClient();
|
|
27
|
-
export default api;
|
package/dist/utils/auth/login.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import open from "open";
|
|
2
|
-
import crypto from "node:crypto";
|
|
3
|
-
import express from "express";
|
|
4
|
-
import pkceChallenge from "pkce-challenge";
|
|
5
|
-
import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, LOGIN_PORTS, LOGIN_TIMEOUT_MS, ZAPIER_BASE, } from "../constants";
|
|
6
|
-
import { spinPromise } from "../spinner";
|
|
7
|
-
import log from "../log";
|
|
8
|
-
import api from "../api/client";
|
|
9
|
-
import getCallablePromise from "../getCallablePromise";
|
|
10
|
-
import { updateLogin, logout } from "@zapier/zapier-sdk";
|
|
11
|
-
const findAvailablePort = () => {
|
|
12
|
-
return new Promise((resolve, reject) => {
|
|
13
|
-
let portIndex = 0;
|
|
14
|
-
const tryPort = (port) => {
|
|
15
|
-
const server = express().listen(port, () => {
|
|
16
|
-
server.close();
|
|
17
|
-
resolve(port);
|
|
18
|
-
});
|
|
19
|
-
server.on("error", (err) => {
|
|
20
|
-
if (err.code === "EADDRINUSE") {
|
|
21
|
-
if (portIndex < LOGIN_PORTS.length) {
|
|
22
|
-
// Try next predefined port
|
|
23
|
-
tryPort(LOGIN_PORTS[portIndex++]);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
// All configured ports are busy
|
|
27
|
-
reject(new Error(`All configured OAuth callback ports are busy: ${LOGIN_PORTS.join(", ")}. Please try again later or close applications using these ports.`));
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
reject(err);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
if (LOGIN_PORTS.length > 0) {
|
|
36
|
-
tryPort(LOGIN_PORTS[portIndex++]);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
reject(new Error("No OAuth callback ports configured"));
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
|
-
const generateRandomString = () => {
|
|
44
|
-
const array = new Uint32Array(28);
|
|
45
|
-
crypto.getRandomValues(array);
|
|
46
|
-
return Array.from(array, (dec) => ("0" + dec.toString(16)).substring(-2)).join("");
|
|
47
|
-
};
|
|
48
|
-
const login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
|
|
49
|
-
// Force logout
|
|
50
|
-
logout();
|
|
51
|
-
// Find an available port
|
|
52
|
-
const availablePort = await findAvailablePort();
|
|
53
|
-
const redirectUri = `http://localhost:${availablePort}/oauth`;
|
|
54
|
-
log.info(`Using port ${availablePort} for OAuth callback`);
|
|
55
|
-
const { promise: promisedCode, resolve: setCode } = getCallablePromise();
|
|
56
|
-
const app = express();
|
|
57
|
-
app.get("/oauth", (req, res) => {
|
|
58
|
-
setCode(String(req.query.code));
|
|
59
|
-
// Set headers to prevent keep-alive
|
|
60
|
-
res.setHeader("Connection", "close");
|
|
61
|
-
res.end("You can now close this tab and return to the CLI.");
|
|
62
|
-
});
|
|
63
|
-
const server = app.listen(availablePort);
|
|
64
|
-
// Track connections to force close them if needed
|
|
65
|
-
const connections = new Set();
|
|
66
|
-
server.on("connection", (conn) => {
|
|
67
|
-
connections.add(conn);
|
|
68
|
-
conn.on("close", () => connections.delete(conn));
|
|
69
|
-
});
|
|
70
|
-
// Set up signal handlers for graceful shutdown
|
|
71
|
-
const cleanup = () => {
|
|
72
|
-
server.close();
|
|
73
|
-
log.info("\n❌ Login cancelled by user");
|
|
74
|
-
process.exit(0);
|
|
75
|
-
};
|
|
76
|
-
process.on("SIGINT", cleanup);
|
|
77
|
-
process.on("SIGTERM", cleanup);
|
|
78
|
-
const { code_verifier: codeVerifier, code_challenge: codeChallenge } = await pkceChallenge();
|
|
79
|
-
const authUrl = `${ZAPIER_BASE}/oauth/authorize/?${new URLSearchParams({
|
|
80
|
-
response_type: "code",
|
|
81
|
-
client_id: LOGIN_CLIENT_ID,
|
|
82
|
-
redirect_uri: redirectUri,
|
|
83
|
-
scope: "internal offline_access",
|
|
84
|
-
state: generateRandomString(),
|
|
85
|
-
code_challenge: codeChallenge,
|
|
86
|
-
code_challenge_method: "S256",
|
|
87
|
-
}).toString()}`;
|
|
88
|
-
log.info("Opening your browser to log in.");
|
|
89
|
-
log.info("If it doesn't open, visit:", authUrl);
|
|
90
|
-
open(authUrl);
|
|
91
|
-
try {
|
|
92
|
-
await spinPromise(Promise.race([
|
|
93
|
-
promisedCode,
|
|
94
|
-
new Promise((_resolve, reject) => setTimeout(() => {
|
|
95
|
-
reject(new Error(`Login timed out after ${Math.round(timeoutMs / 1000)} seconds.`));
|
|
96
|
-
}, timeoutMs)),
|
|
97
|
-
]), "Waiting for you to login and authorize");
|
|
98
|
-
}
|
|
99
|
-
finally {
|
|
100
|
-
// Remove signal handlers
|
|
101
|
-
process.off("SIGINT", cleanup);
|
|
102
|
-
process.off("SIGTERM", cleanup);
|
|
103
|
-
// Close server with timeout and force-close connections if needed
|
|
104
|
-
await new Promise((resolve) => {
|
|
105
|
-
const timeout = setTimeout(() => {
|
|
106
|
-
log.info("Server close timed out, forcing connection shutdown...");
|
|
107
|
-
// Force close all connections
|
|
108
|
-
connections.forEach((conn) => conn.destroy());
|
|
109
|
-
resolve();
|
|
110
|
-
}, 1000); // 1 second timeout
|
|
111
|
-
server.close(() => {
|
|
112
|
-
clearTimeout(timeout);
|
|
113
|
-
resolve();
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
log.info("Exchanging authorization code for tokens...");
|
|
118
|
-
const { data } = await api.post(`${ZAPIER_BASE}/oauth/token/`, {
|
|
119
|
-
grant_type: "authorization_code",
|
|
120
|
-
code: await promisedCode,
|
|
121
|
-
redirect_uri: redirectUri,
|
|
122
|
-
client_id: LOGIN_CLIENT_ID,
|
|
123
|
-
code_verifier: codeVerifier,
|
|
124
|
-
}, {
|
|
125
|
-
headers: {
|
|
126
|
-
[AUTH_MODE_HEADER]: "no",
|
|
127
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
updateLogin(data);
|
|
131
|
-
log.info("Token exchange completed successfully");
|
|
132
|
-
return data.access_token;
|
|
133
|
-
};
|
|
134
|
-
export default login;
|