@zapier/zapier-sdk-cli 0.1.0 → 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/cli.js +15 -11
- package/dist/commands/configPath.d.ts +2 -0
- package/dist/commands/configPath.js +9 -0
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/index.js +4 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +25 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +16 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +16 -0
- package/dist/utils/api/client.d.ts +15 -0
- package/dist/utils/api/client.js +27 -0
- package/dist/utils/auth/ensureValidToken.d.ts +7 -0
- package/dist/utils/auth/ensureValidToken.js +33 -0
- package/dist/utils/auth/getAuthState.d.ts +12 -0
- package/dist/utils/auth/getAuthState.js +17 -0
- package/dist/utils/auth/getJWT.d.ts +2 -0
- package/dist/utils/auth/getJWT.js +13 -0
- package/dist/utils/auth/getLoggedInUser.d.ts +6 -0
- package/dist/utils/auth/getLoggedInUser.js +47 -0
- package/dist/utils/auth/login.d.ts +2 -0
- package/dist/utils/auth/login.js +135 -0
- package/dist/utils/auth/logout.d.ts +2 -0
- package/dist/utils/auth/logout.js +7 -0
- package/dist/utils/auth/refreshJWT.d.ts +2 -0
- package/dist/utils/auth/refreshJWT.js +33 -0
- package/dist/utils/auth/updateLogin.d.ts +7 -0
- package/dist/utils/auth/updateLogin.js +7 -0
- package/dist/utils/cli-generator.js +49 -49
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.js +2 -0
- package/dist/utils/constants.d.ts +5 -0
- package/dist/utils/constants.js +6 -0
- package/dist/utils/getCallablePromise.d.ts +6 -0
- package/dist/utils/getCallablePromise.js +14 -0
- package/dist/utils/getConfigPath.d.ts +1 -0
- package/dist/utils/getConfigPath.js +4 -0
- package/dist/utils/log.d.ts +7 -0
- package/dist/utils/log.js +16 -0
- package/dist/utils/pager.js +10 -20
- package/dist/utils/parameter-resolver.js +34 -41
- package/dist/utils/schema-formatter.js +11 -17
- package/dist/utils/serializeAsync.d.ts +2 -0
- package/dist/utils/serializeAsync.js +16 -0
- package/dist/utils/spinner.d.ts +1 -0
- package/dist/utils/spinner.js +13 -0
- package/package.json +9 -2
- package/src/cli.ts +15 -3
- package/src/commands/configPath.ts +10 -0
- package/src/commands/index.ts +4 -0
- package/src/commands/login.ts +34 -0
- package/src/commands/logout.ts +19 -0
- package/src/commands/whoami.ts +20 -0
- package/src/utils/api/client.ts +44 -0
- package/src/utils/auth/ensureValidToken.ts +35 -0
- package/src/utils/auth/getAuthState.ts +36 -0
- package/src/utils/auth/getJWT.ts +20 -0
- package/src/utils/auth/getLoggedInUser.ts +68 -0
- package/src/utils/auth/login.ts +191 -0
- package/src/utils/auth/logout.ts +9 -0
- package/src/utils/auth/refreshJWT.ts +50 -0
- package/src/utils/auth/updateLogin.ts +19 -0
- package/src/utils/cli-generator.ts +14 -3
- package/src/utils/config.ts +3 -0
- package/src/utils/constants.ts +9 -0
- package/src/utils/getCallablePromise.ts +21 -0
- package/src/utils/getConfigPath.ts +5 -0
- package/src/utils/log.ts +18 -0
- package/src/utils/serializeAsync.ts +26 -0
- package/src/utils/spinner.ts +16 -0
- package/tsconfig.json +2 -2
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, ZAPIER_BASE } from "../constants";
|
|
2
|
+
import api from "../api/client";
|
|
3
|
+
import serializeAsync from "../serializeAsync";
|
|
4
|
+
import { spinPromise } from "../spinner";
|
|
5
|
+
import getAuthState from "./getAuthState";
|
|
6
|
+
import updateLogin from "./updateLogin";
|
|
7
|
+
import logout from "./logout";
|
|
8
|
+
|
|
9
|
+
const refreshJWT = async (): Promise<string> => {
|
|
10
|
+
const state = getAuthState();
|
|
11
|
+
|
|
12
|
+
if (state.status === "logged-out") {
|
|
13
|
+
throw new Error("Unexpected call to refreshJWT while logged out.");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const { data } = await spinPromise(
|
|
18
|
+
api.post<{
|
|
19
|
+
access_token: string;
|
|
20
|
+
refresh_token: string;
|
|
21
|
+
expires_in: number;
|
|
22
|
+
}>(
|
|
23
|
+
`${ZAPIER_BASE}/oauth/token/`,
|
|
24
|
+
{
|
|
25
|
+
client_id: LOGIN_CLIENT_ID,
|
|
26
|
+
refresh_token: state.refresh_token,
|
|
27
|
+
grant_type: "refresh_token",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
headers: {
|
|
31
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
32
|
+
[AUTH_MODE_HEADER]: "no",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
),
|
|
36
|
+
"Refreshing your token...",
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
updateLogin(data);
|
|
40
|
+
|
|
41
|
+
return data.access_token;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Force logout
|
|
44
|
+
logout();
|
|
45
|
+
|
|
46
|
+
throw e;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default serializeAsync(refreshJWT);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { config } from "../config";
|
|
2
|
+
|
|
3
|
+
interface LoginData {
|
|
4
|
+
access_token: string;
|
|
5
|
+
refresh_token: string;
|
|
6
|
+
expires_in: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const updateLogin = ({
|
|
10
|
+
access_token: accessToken,
|
|
11
|
+
refresh_token: refreshToken,
|
|
12
|
+
expires_in: expiresIn,
|
|
13
|
+
}: LoginData) => {
|
|
14
|
+
config.set("login_jwt", accessToken);
|
|
15
|
+
config.set("login_refresh_token", refreshToken);
|
|
16
|
+
config.set("login_expires_at", Date.now() + expiresIn * 1000);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default updateLogin;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { ZapierSdk, hasResolver } from "@zapier/zapier-sdk";
|
|
3
|
+
import { ZapierSdk, hasResolver, isPositional } from "@zapier/zapier-sdk";
|
|
4
4
|
import { SchemaParameterResolver } from "./parameter-resolver";
|
|
5
5
|
import { createPager } from "./pager";
|
|
6
6
|
import { formatItemsFromSchema } from "./schema-formatter";
|
|
@@ -46,6 +46,7 @@ interface CliParameter {
|
|
|
46
46
|
default?: any;
|
|
47
47
|
choices?: string[];
|
|
48
48
|
hasResolver?: boolean;
|
|
49
|
+
isPositional?: boolean;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
// ============================================================================
|
|
@@ -118,6 +119,7 @@ function analyzeZodField(
|
|
|
118
119
|
default: defaultValue,
|
|
119
120
|
choices,
|
|
120
121
|
hasResolver: hasResolver(name),
|
|
122
|
+
isPositional: isPositional(schema),
|
|
121
123
|
};
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -309,6 +311,12 @@ function addCommand(
|
|
|
309
311
|
`<${kebabName}>`,
|
|
310
312
|
param.description || `${kebabName} parameter`,
|
|
311
313
|
);
|
|
314
|
+
} else if (param.isPositional) {
|
|
315
|
+
// Optional parameters marked as positional become optional positional arguments
|
|
316
|
+
command.argument(
|
|
317
|
+
`[${kebabName}]`,
|
|
318
|
+
param.description || `${kebabName} parameter`,
|
|
319
|
+
);
|
|
312
320
|
} else {
|
|
313
321
|
// Optional parameters become flags (whether they have resolvers or not)
|
|
314
322
|
const flags = [`--${kebabName}`];
|
|
@@ -339,10 +347,13 @@ function convertCliArgsToSdkParams(
|
|
|
339
347
|
): Record<string, any> {
|
|
340
348
|
const sdkParams: Record<string, any> = {};
|
|
341
349
|
|
|
342
|
-
// Handle positional arguments (required parameters
|
|
350
|
+
// Handle positional arguments (required parameters or optional positional parameters)
|
|
343
351
|
let argIndex = 0;
|
|
344
352
|
parameters.forEach((param) => {
|
|
345
|
-
if (
|
|
353
|
+
if (
|
|
354
|
+
(param.required || param.isPositional) &&
|
|
355
|
+
argIndex < positionalArgs.length
|
|
356
|
+
) {
|
|
346
357
|
// Use the original camelCase parameter name for the SDK
|
|
347
358
|
sdkParams[param.name] = convertValue(
|
|
348
359
|
positionalArgs[argIndex],
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const ZAPIER_BASE = "https://zapier.com";
|
|
2
|
+
|
|
3
|
+
// OAuth client ID for zapier-sdk CLI
|
|
4
|
+
export const LOGIN_CLIENT_ID = "K5eEnRE9TTmSFATdkkWhKF8NOKwoiOnYAyIqJjae";
|
|
5
|
+
|
|
6
|
+
export const LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
7
|
+
export const LOGIN_TIMEOUT_MS = 300000; // 5 minutes
|
|
8
|
+
|
|
9
|
+
export const AUTH_MODE_HEADER = "X-Auth";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const getCallablePromise = <T>(): {
|
|
2
|
+
promise: Promise<T>;
|
|
3
|
+
resolve: (value: T) => void;
|
|
4
|
+
reject: (reason: unknown) => void;
|
|
5
|
+
} => {
|
|
6
|
+
let resolve: (value: T) => void = () => {};
|
|
7
|
+
let reject: (reason: unknown) => void = () => {};
|
|
8
|
+
|
|
9
|
+
const promise = new Promise<T>((_resolve, _reject) => {
|
|
10
|
+
resolve = _resolve;
|
|
11
|
+
reject = _reject;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
promise,
|
|
16
|
+
resolve,
|
|
17
|
+
reject,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default getCallablePromise;
|
package/src/utils/log.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
|
|
3
|
+
const log = {
|
|
4
|
+
info: (message: string, ...args: any[]) => {
|
|
5
|
+
console.log(chalk.blue("ℹ"), message, ...args);
|
|
6
|
+
},
|
|
7
|
+
error: (message: string, ...args: any[]) => {
|
|
8
|
+
console.error(chalk.red("✖"), message, ...args);
|
|
9
|
+
},
|
|
10
|
+
success: (message: string, ...args: any[]) => {
|
|
11
|
+
console.log(chalk.green("✓"), message, ...args);
|
|
12
|
+
},
|
|
13
|
+
warn: (message: string, ...args: any[]) => {
|
|
14
|
+
console.log(chalk.yellow("⚠"), message, ...args);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default log;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
const promises: Record<string, Promise<unknown>> = {};
|
|
4
|
+
|
|
5
|
+
const serializeAsync =
|
|
6
|
+
<R, A extends []>(
|
|
7
|
+
fn: (...args: A) => Promise<R>,
|
|
8
|
+
): ((...args: A) => Promise<R>) =>
|
|
9
|
+
async (...args: A): Promise<R> => {
|
|
10
|
+
const hash = createHash("sha256")
|
|
11
|
+
.update(fn.toString(), "utf8")
|
|
12
|
+
.digest()
|
|
13
|
+
.toString("hex");
|
|
14
|
+
|
|
15
|
+
const promise = promises[hash];
|
|
16
|
+
|
|
17
|
+
if (!promise) {
|
|
18
|
+
promises[hash] = fn(...args).finally(() => {
|
|
19
|
+
delete promises[hash];
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return promises[hash] as Promise<R>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default serializeAsync;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import ora from "ora";
|
|
2
|
+
|
|
3
|
+
export const spinPromise = async <T>(
|
|
4
|
+
promise: Promise<T>,
|
|
5
|
+
text: string,
|
|
6
|
+
): Promise<T> => {
|
|
7
|
+
const spinner = ora(text).start();
|
|
8
|
+
try {
|
|
9
|
+
const result = await promise;
|
|
10
|
+
spinner.succeed();
|
|
11
|
+
return result;
|
|
12
|
+
} catch (error) {
|
|
13
|
+
spinner.fail();
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
};
|