@zapier/zapier-sdk-cli 0.2.0 → 0.3.1

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 (50) hide show
  1. package/bin/zapier-sdk.js +1 -1
  2. package/bin/zsdk.js +1 -1
  3. package/dist/cli.js +3 -5
  4. package/dist/commands/configPath.js +1 -1
  5. package/dist/commands/index.d.ts +4 -4
  6. package/dist/commands/index.js +4 -4
  7. package/dist/commands/login.js +2 -2
  8. package/dist/commands/logout.js +1 -1
  9. package/dist/commands/whoami.js +3 -2
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +1 -1
  12. package/dist/utils/auth/login.js +6 -7
  13. package/dist/utils/cli-generator.js +3 -3
  14. package/package.json +3 -3
  15. package/src/cli.ts +3 -5
  16. package/src/commands/configPath.ts +1 -1
  17. package/src/commands/index.ts +4 -4
  18. package/src/commands/login.ts +2 -2
  19. package/src/commands/logout.ts +1 -1
  20. package/src/commands/whoami.ts +7 -2
  21. package/src/utils/auth/login.ts +6 -7
  22. package/src/utils/cli-generator.ts +3 -3
  23. package/tsconfig.json +2 -2
  24. package/dist/utils/auth/ensureValidToken.d.ts +0 -7
  25. package/dist/utils/auth/ensureValidToken.js +0 -33
  26. package/dist/utils/auth/getAuthState.d.ts +0 -12
  27. package/dist/utils/auth/getAuthState.js +0 -17
  28. package/dist/utils/auth/getJWT.d.ts +0 -2
  29. package/dist/utils/auth/getJWT.js +0 -13
  30. package/dist/utils/auth/getLoggedInUser.d.ts +0 -6
  31. package/dist/utils/auth/getLoggedInUser.js +0 -47
  32. package/dist/utils/auth/logout.d.ts +0 -2
  33. package/dist/utils/auth/logout.js +0 -7
  34. package/dist/utils/auth/refreshJWT.d.ts +0 -2
  35. package/dist/utils/auth/refreshJWT.js +0 -33
  36. package/dist/utils/auth/updateLogin.d.ts +0 -7
  37. package/dist/utils/auth/updateLogin.js +0 -7
  38. package/dist/utils/config.d.ts +0 -2
  39. package/dist/utils/config.js +0 -2
  40. package/dist/utils/getConfigPath.d.ts +0 -1
  41. package/dist/utils/getConfigPath.js +0 -4
  42. package/src/utils/auth/ensureValidToken.ts +0 -35
  43. package/src/utils/auth/getAuthState.ts +0 -36
  44. package/src/utils/auth/getJWT.ts +0 -20
  45. package/src/utils/auth/getLoggedInUser.ts +0 -68
  46. package/src/utils/auth/logout.ts +0 -9
  47. package/src/utils/auth/refreshJWT.ts +0 -50
  48. package/src/utils/auth/updateLogin.ts +0 -19
  49. package/src/utils/config.ts +0 -3
  50. package/src/utils/getConfigPath.ts +0 -5
package/bin/zapier-sdk.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // Import the CLI from the compiled TypeScript
4
- require("../dist/cli.js");
4
+ import "../dist/cli.js";
package/bin/zsdk.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // Import the CLI from the compiled TypeScript
4
- require("../dist/cli.js");
4
+ import "../dist/cli.js";
package/dist/cli.js CHANGED
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
3
  import { createZapierSdk } from "@zapier/zapier-sdk";
4
- import { generateCliCommands } from "./utils/cli-generator";
5
- import { ensureValidToken } from "./utils/auth/ensureValidToken";
6
- import { createLoginCommand, createLogoutCommand, createWhoamiCommand, createConfigPathCommand, } from "./commands";
4
+ import { generateCliCommands } from "./utils/cli-generator.js";
5
+ import { createLoginCommand, createLogoutCommand, createWhoamiCommand, createConfigPathCommand, } from "./commands/index.js";
7
6
  const program = new Command();
8
7
  program
9
8
  .name("zapier-sdk")
@@ -12,9 +11,8 @@ program
12
11
  .option("--debug", "Enable debug logging");
13
12
  // Check for debug flag early
14
13
  const isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
15
- // Create SDK instance with dynamic token resolution
14
+ // Create SDK instance - automatically handles token resolution
16
15
  const sdk = createZapierSdk({
17
- getToken: ensureValidToken,
18
16
  debug: isDebugMode,
19
17
  });
20
18
  // Add auth commands before generating SDK commands
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { getConfigPath } from "../utils/getConfigPath";
2
+ import { getConfigPath } from "@zapier/zapier-sdk";
3
3
  export function createConfigPathCommand() {
4
4
  return new Command("get-config-path")
5
5
  .description("Show the path to the configuration file")
@@ -1,4 +1,4 @@
1
- export { createLoginCommand } from "./login";
2
- export { createLogoutCommand } from "./logout";
3
- export { createWhoamiCommand } from "./whoami";
4
- export { createConfigPathCommand } from "./configPath";
1
+ export { createLoginCommand } from "./login.js";
2
+ export { createLogoutCommand } from "./logout.js";
3
+ export { createWhoamiCommand } from "./whoami.js";
4
+ export { createConfigPathCommand } from "./configPath.js";
@@ -1,4 +1,4 @@
1
- export { createLoginCommand } from "./login";
2
- export { createLogoutCommand } from "./logout";
3
- export { createWhoamiCommand } from "./whoami";
4
- export { createConfigPathCommand } from "./configPath";
1
+ export { createLoginCommand } from "./login.js";
2
+ export { createLogoutCommand } from "./logout.js";
3
+ export { createWhoamiCommand } from "./whoami.js";
4
+ export { createConfigPathCommand } from "./configPath.js";
@@ -1,6 +1,6 @@
1
1
  import { Command } from "commander";
2
- import login from "../utils/auth/login";
3
- import getLoggedInUser from "../utils/auth/getLoggedInUser";
2
+ import login from "../utils/auth/login.js";
3
+ import { getLoggedInUser } from "@zapier/zapier-sdk";
4
4
  export function createLoginCommand() {
5
5
  return new Command("login")
6
6
  .description("Log in to Zapier to access your account")
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import logout from "../utils/auth/logout";
2
+ import { logout } from "@zapier/zapier-sdk";
3
3
  export function createLogoutCommand() {
4
4
  return new Command("logout")
5
5
  .description("Log out of your Zapier account")
@@ -1,11 +1,12 @@
1
1
  import { Command } from "commander";
2
- import getLoggedInUser from "../utils/auth/getLoggedInUser";
2
+ import { getLoggedInUser } from "@zapier/zapier-sdk";
3
+ import { spinPromise } from "../utils/spinner.js";
3
4
  export function createWhoamiCommand() {
4
5
  return new Command("whoami")
5
6
  .description("Show current login status and user information")
6
7
  .action(async () => {
7
8
  try {
8
- const user = await getLoggedInUser();
9
+ const user = await spinPromise(getLoggedInUser(), "Checking login status...");
9
10
  console.log(`✅ Logged in as ${user.email} (Account ID: ${user.accountId})`);
10
11
  }
11
12
  catch {
package/dist/index.d.ts CHANGED
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";
1
+ export {};
2
2
  // Main exports for the CLI package
3
3
  // All CLI functionality is now schema-driven via generateCLICommands
@@ -2,13 +2,12 @@ import open from "open";
2
2
  import crypto from "node:crypto";
3
3
  import express from "express";
4
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 from "./updateLogin";
11
- import logout from "./logout";
5
+ import { AUTH_MODE_HEADER, LOGIN_CLIENT_ID, LOGIN_PORTS, LOGIN_TIMEOUT_MS, ZAPIER_BASE, } from "../constants.js";
6
+ import { spinPromise } from "../spinner.js";
7
+ import log from "../log.js";
8
+ import api from "../api/client.js";
9
+ import getCallablePromise from "../getCallablePromise.js";
10
+ import { updateLogin, logout } from "@zapier/zapier-sdk";
12
11
  const findAvailablePort = () => {
13
12
  return new Promise((resolve, reject) => {
14
13
  let portIndex = 0;
@@ -1,8 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { hasResolver, isPositional } from "@zapier/zapier-sdk";
3
- import { SchemaParameterResolver } from "./parameter-resolver";
4
- import { createPager } from "./pager";
5
- import { formatItemsFromSchema } from "./schema-formatter";
3
+ import { SchemaParameterResolver } from "./parameter-resolver.js";
4
+ import { createPager } from "./pager.js";
5
+ import { formatItemsFromSchema } from "./schema-formatter.js";
6
6
  import chalk from "chalk";
7
7
  import util from "util";
8
8
  // ============================================================================
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk-cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
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": {
@@ -22,7 +23,6 @@
22
23
  "chalk": "^5.3.0",
23
24
  "cli-table3": "^0.6.5",
24
25
  "commander": "^12.0.0",
25
- "conf": "^14.0.0",
26
26
  "express": "^5.1.0",
27
27
  "inquirer": "^12.6.3",
28
28
  "jsonwebtoken": "^9.0.2",
@@ -30,7 +30,7 @@
30
30
  "ora": "^8.2.0",
31
31
  "pkce-challenge": "^5.0.0",
32
32
  "zod": "^3.25.67",
33
- "@zapier/zapier-sdk": "0.2.0"
33
+ "@zapier/zapier-sdk": "0.3.1"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/express": "^5.0.3",
package/src/cli.ts CHANGED
@@ -2,14 +2,13 @@
2
2
 
3
3
  import { Command } from "commander";
4
4
  import { createZapierSdk } from "@zapier/zapier-sdk";
5
- import { generateCliCommands } from "./utils/cli-generator";
6
- import { ensureValidToken } from "./utils/auth/ensureValidToken";
5
+ import { generateCliCommands } from "./utils/cli-generator.js";
7
6
  import {
8
7
  createLoginCommand,
9
8
  createLogoutCommand,
10
9
  createWhoamiCommand,
11
10
  createConfigPathCommand,
12
- } from "./commands";
11
+ } from "./commands/index.js";
13
12
 
14
13
  const program = new Command();
15
14
 
@@ -23,9 +22,8 @@ program
23
22
  const isDebugMode =
24
23
  process.env.DEBUG === "true" || process.argv.includes("--debug");
25
24
 
26
- // Create SDK instance with dynamic token resolution
25
+ // Create SDK instance - automatically handles token resolution
27
26
  const sdk = createZapierSdk({
28
- getToken: ensureValidToken,
29
27
  debug: isDebugMode,
30
28
  });
31
29
 
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { getConfigPath } from "../utils/getConfigPath";
2
+ import { getConfigPath } from "@zapier/zapier-sdk";
3
3
 
4
4
  export function createConfigPathCommand(): Command {
5
5
  return new Command("get-config-path")
@@ -1,4 +1,4 @@
1
- export { createLoginCommand } from "./login";
2
- export { createLogoutCommand } from "./logout";
3
- export { createWhoamiCommand } from "./whoami";
4
- export { createConfigPathCommand } from "./configPath";
1
+ export { createLoginCommand } from "./login.js";
2
+ export { createLogoutCommand } from "./logout.js";
3
+ export { createWhoamiCommand } from "./whoami.js";
4
+ export { createConfigPathCommand } from "./configPath.js";
@@ -1,6 +1,6 @@
1
1
  import { Command } from "commander";
2
- import login from "../utils/auth/login";
3
- import getLoggedInUser from "../utils/auth/getLoggedInUser";
2
+ import login from "../utils/auth/login.js";
3
+ import { getLoggedInUser } from "@zapier/zapier-sdk";
4
4
 
5
5
  export function createLoginCommand(): Command {
6
6
  return new Command("login")
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import logout from "../utils/auth/logout";
2
+ import { logout } from "@zapier/zapier-sdk";
3
3
 
4
4
  export function createLogoutCommand(): Command {
5
5
  return new Command("logout")
@@ -1,12 +1,17 @@
1
1
  import { Command } from "commander";
2
- import getLoggedInUser from "../utils/auth/getLoggedInUser";
2
+ import { getLoggedInUser } from "@zapier/zapier-sdk";
3
+ import { spinPromise } from "../utils/spinner.js";
3
4
 
4
5
  export function createWhoamiCommand(): Command {
5
6
  return new Command("whoami")
6
7
  .description("Show current login status and user information")
7
8
  .action(async () => {
8
9
  try {
9
- const user = await getLoggedInUser();
10
+ const user = await spinPromise(
11
+ getLoggedInUser(),
12
+ "Checking login status...",
13
+ );
14
+
10
15
  console.log(
11
16
  `✅ Logged in as ${user.email} (Account ID: ${user.accountId})`,
12
17
  );
@@ -9,13 +9,12 @@ import {
9
9
  LOGIN_PORTS,
10
10
  LOGIN_TIMEOUT_MS,
11
11
  ZAPIER_BASE,
12
- } from "../constants";
13
- import { spinPromise } from "../spinner";
14
- import log from "../log";
15
- import api from "../api/client";
16
- import getCallablePromise from "../getCallablePromise";
17
- import updateLogin from "./updateLogin";
18
- import logout from "./logout";
12
+ } from "../constants.js";
13
+ import { spinPromise } from "../spinner.js";
14
+ import log from "../log.js";
15
+ import api from "../api/client.js";
16
+ import getCallablePromise from "../getCallablePromise.js";
17
+ import { updateLogin, logout } from "@zapier/zapier-sdk";
19
18
 
20
19
  const findAvailablePort = (): Promise<number> => {
21
20
  return new Promise((resolve, reject) => {
@@ -1,9 +1,9 @@
1
1
  import { Command } from "commander";
2
2
  import { z } from "zod";
3
3
  import { ZapierSdk, hasResolver, isPositional } from "@zapier/zapier-sdk";
4
- import { SchemaParameterResolver } from "./parameter-resolver";
5
- import { createPager } from "./pager";
6
- import { formatItemsFromSchema } from "./schema-formatter";
4
+ import { SchemaParameterResolver } from "./parameter-resolver.js";
5
+ import { createPager } from "./pager.js";
6
+ import { formatItemsFromSchema } from "./schema-formatter.js";
7
7
  import chalk from "chalk";
8
8
  import util from "util";
9
9
 
package/tsconfig.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
- "module": "ES2020",
5
- "moduleResolution": "bundler",
4
+ "module": "Node16",
5
+ "moduleResolution": "node16",
6
6
  "strict": true,
7
7
  "noUnusedLocals": true,
8
8
  "noUnusedParameters": true,
@@ -1,7 +0,0 @@
1
- /**
2
- * Ensures we have a valid, non-expired JWT token.
3
- * Will attempt to refresh expired tokens automatically.
4
- * Falls back to ZAPIER_TOKEN environment variable if no stored login.
5
- * Returns undefined if no token is available or refresh fails.
6
- */
7
- export declare const ensureValidToken: () => Promise<string | undefined>;
@@ -1,33 +0,0 @@
1
- import getAuthState from "./getAuthState";
2
- import refreshJWT from "./refreshJWT";
3
- /**
4
- * Ensures we have a valid, non-expired JWT token.
5
- * Will attempt to refresh expired tokens automatically.
6
- * Falls back to ZAPIER_TOKEN environment variable if no stored login.
7
- * Returns undefined if no token is available or refresh fails.
8
- */
9
- export const ensureValidToken = async () => {
10
- try {
11
- const state = getAuthState();
12
- if (state.status === "logged-out") {
13
- // Fall back to environment variable if not logged in
14
- return process.env.ZAPIER_TOKEN;
15
- }
16
- if (state.status === "expired") {
17
- // Attempt to refresh the token
18
- try {
19
- return await refreshJWT();
20
- }
21
- catch {
22
- // If refresh fails, fall back to environment variable
23
- return process.env.ZAPIER_TOKEN;
24
- }
25
- }
26
- // Status is "logged-in", return the valid token
27
- return state.jwt;
28
- }
29
- catch {
30
- // If any error occurs, fall back to environment variable
31
- return process.env.ZAPIER_TOKEN;
32
- }
33
- };
@@ -1,12 +0,0 @@
1
- type Status = {
2
- status: "logged-in";
3
- jwt: string;
4
- refresh_token: string;
5
- } | {
6
- status: "expired";
7
- refresh_token: string;
8
- } | {
9
- status: "logged-out";
10
- };
11
- declare const getAuthState: () => Status;
12
- export default getAuthState;
@@ -1,17 +0,0 @@
1
- import { config } from "../config";
2
- const getAuthState = () => {
3
- const jwt = config.get("login_jwt");
4
- const refreshToken = config.get("login_refresh_token");
5
- const expiresAt = config.get("login_expires_at");
6
- if (!jwt || !refreshToken || !expiresAt) {
7
- return { status: "logged-out" };
8
- }
9
- if (expiresAt > Date.now() + 30 * 1000) {
10
- return { status: "logged-in", jwt, refresh_token: refreshToken };
11
- }
12
- return {
13
- status: "expired",
14
- refresh_token: refreshToken,
15
- };
16
- };
17
- export default getAuthState;
@@ -1,2 +0,0 @@
1
- declare const getJWT: () => Promise<string>;
2
- export default getJWT;
@@ -1,13 +0,0 @@
1
- import getAuthState from "./getAuthState";
2
- import refreshJWT from "./refreshJWT";
3
- const getJWT = async () => {
4
- const state = getAuthState();
5
- if (state.status === "logged-out") {
6
- throw new Error("Expected getJWT to only be called when user has logged in.");
7
- }
8
- if (state.status === "expired") {
9
- return await refreshJWT();
10
- }
11
- return state.jwt;
12
- };
13
- export default getJWT;
@@ -1,6 +0,0 @@
1
- declare const getLoggedInUser: () => Promise<{
2
- accountId: number;
3
- customUserId: number;
4
- email: string;
5
- }>;
6
- export default getLoggedInUser;
@@ -1,47 +0,0 @@
1
- import jsonwebtoken from "jsonwebtoken";
2
- import getJWT from "./getJWT";
3
- const decodeJWTOrThrow = (jwt) => {
4
- if (typeof jwt !== "string") {
5
- throw new Error("Expected JWT to be a string");
6
- }
7
- const decodedJWT = jsonwebtoken.decode(jwt, { complete: true });
8
- if (!decodedJWT) {
9
- throw new Error("Could not decode JWT");
10
- }
11
- if (typeof decodedJWT.payload === "string") {
12
- throw new Error("Did not expect JWT payload to be a string");
13
- }
14
- return decodedJWT;
15
- };
16
- const getLoggedInUser = async () => {
17
- const jwt = await getJWT();
18
- let decodedJwt = decodeJWTOrThrow(jwt);
19
- if (decodedJwt.payload["sub_type"] == "service") {
20
- decodedJwt = decodeJWTOrThrow(decodedJwt.payload["njwt"]);
21
- }
22
- if (typeof decodedJwt.payload["zap:acc"] !== "string") {
23
- throw new Error("JWT payload does not contain accountId");
24
- }
25
- const accountId = parseInt(decodedJwt.payload["zap:acc"], 10);
26
- if (isNaN(accountId)) {
27
- throw new Error("JWT accountId is not a number");
28
- }
29
- if (decodedJwt.payload["sub_type"] !== "customuser" ||
30
- typeof decodedJwt.payload["sub"] !== "string") {
31
- throw new Error("JWT payload does not contain customUserId");
32
- }
33
- const customUserId = parseInt(decodedJwt.payload["sub"], 10);
34
- if (isNaN(customUserId)) {
35
- throw new Error("JWT customUserId is not a number");
36
- }
37
- const email = decodedJwt.payload["zap:uname"];
38
- if (typeof email !== "string") {
39
- throw new Error("JWT payload does not contain email");
40
- }
41
- return {
42
- accountId,
43
- customUserId,
44
- email,
45
- };
46
- };
47
- export default getLoggedInUser;
@@ -1,2 +0,0 @@
1
- declare const logout: () => void;
2
- export default logout;
@@ -1,7 +0,0 @@
1
- import { config } from "../config";
2
- const logout = () => {
3
- config.delete("login_jwt");
4
- config.delete("login_refresh_token");
5
- config.delete("login_expires_at");
6
- };
7
- export default logout;
@@ -1,2 +0,0 @@
1
- declare const _default: () => Promise<string>;
2
- export default _default;
@@ -1,33 +0,0 @@
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
- const refreshJWT = async () => {
9
- const state = getAuthState();
10
- if (state.status === "logged-out") {
11
- throw new Error("Unexpected call to refreshJWT while logged out.");
12
- }
13
- try {
14
- const { data } = await spinPromise(api.post(`${ZAPIER_BASE}/oauth/token/`, {
15
- client_id: LOGIN_CLIENT_ID,
16
- refresh_token: state.refresh_token,
17
- grant_type: "refresh_token",
18
- }, {
19
- headers: {
20
- "Content-Type": "application/x-www-form-urlencoded",
21
- [AUTH_MODE_HEADER]: "no",
22
- },
23
- }), "Refreshing your token...");
24
- updateLogin(data);
25
- return data.access_token;
26
- }
27
- catch (e) {
28
- // Force logout
29
- logout();
30
- throw e;
31
- }
32
- };
33
- export default serializeAsync(refreshJWT);
@@ -1,7 +0,0 @@
1
- interface LoginData {
2
- access_token: string;
3
- refresh_token: string;
4
- expires_in: number;
5
- }
6
- declare const updateLogin: ({ access_token: accessToken, refresh_token: refreshToken, expires_in: expiresIn, }: LoginData) => void;
7
- export default updateLogin;
@@ -1,7 +0,0 @@
1
- import { config } from "../config";
2
- const updateLogin = ({ access_token: accessToken, refresh_token: refreshToken, expires_in: expiresIn, }) => {
3
- config.set("login_jwt", accessToken);
4
- config.set("login_refresh_token", refreshToken);
5
- config.set("login_expires_at", Date.now() + expiresIn * 1000);
6
- };
7
- export default updateLogin;
@@ -1,2 +0,0 @@
1
- import Conf from "conf";
2
- export declare const config: Conf<Record<string, unknown>>;
@@ -1,2 +0,0 @@
1
- import Conf from "conf";
2
- export const config = new Conf({ projectName: "zapier-sdk-cli" });
@@ -1 +0,0 @@
1
- export declare const getConfigPath: () => string;
@@ -1,4 +0,0 @@
1
- import { config } from "./config";
2
- export const getConfigPath = () => {
3
- return config.path;
4
- };
@@ -1,35 +0,0 @@
1
- import getAuthState from "./getAuthState";
2
- import refreshJWT from "./refreshJWT";
3
-
4
- /**
5
- * Ensures we have a valid, non-expired JWT token.
6
- * Will attempt to refresh expired tokens automatically.
7
- * Falls back to ZAPIER_TOKEN environment variable if no stored login.
8
- * Returns undefined if no token is available or refresh fails.
9
- */
10
- export const ensureValidToken = async (): Promise<string | undefined> => {
11
- try {
12
- const state = getAuthState();
13
-
14
- if (state.status === "logged-out") {
15
- // Fall back to environment variable if not logged in
16
- return process.env.ZAPIER_TOKEN;
17
- }
18
-
19
- if (state.status === "expired") {
20
- // Attempt to refresh the token
21
- try {
22
- return await refreshJWT();
23
- } catch {
24
- // If refresh fails, fall back to environment variable
25
- return process.env.ZAPIER_TOKEN;
26
- }
27
- }
28
-
29
- // Status is "logged-in", return the valid token
30
- return state.jwt;
31
- } catch {
32
- // If any error occurs, fall back to environment variable
33
- return process.env.ZAPIER_TOKEN;
34
- }
35
- };
@@ -1,36 +0,0 @@
1
- import { config } from "../config";
2
-
3
- type Status =
4
- | {
5
- status: "logged-in";
6
- jwt: string;
7
- refresh_token: string;
8
- }
9
- | {
10
- status: "expired";
11
- refresh_token: string;
12
- }
13
- | {
14
- status: "logged-out";
15
- };
16
-
17
- const getAuthState = (): Status => {
18
- const jwt = config.get("login_jwt") as string | undefined;
19
- const refreshToken = config.get("login_refresh_token") as string | undefined;
20
- const expiresAt = config.get("login_expires_at") as number | undefined;
21
-
22
- if (!jwt || !refreshToken || !expiresAt) {
23
- return { status: "logged-out" };
24
- }
25
-
26
- if (expiresAt > Date.now() + 30 * 1000) {
27
- return { status: "logged-in", jwt, refresh_token: refreshToken };
28
- }
29
-
30
- return {
31
- status: "expired",
32
- refresh_token: refreshToken,
33
- };
34
- };
35
-
36
- export default getAuthState;
@@ -1,20 +0,0 @@
1
- import getAuthState from "./getAuthState";
2
- import refreshJWT from "./refreshJWT";
3
-
4
- const getJWT = async (): Promise<string> => {
5
- const state = getAuthState();
6
-
7
- if (state.status === "logged-out") {
8
- throw new Error(
9
- "Expected getJWT to only be called when user has logged in.",
10
- );
11
- }
12
-
13
- if (state.status === "expired") {
14
- return await refreshJWT();
15
- }
16
-
17
- return state.jwt;
18
- };
19
-
20
- export default getJWT;
@@ -1,68 +0,0 @@
1
- import jsonwebtoken, { JwtPayload } from "jsonwebtoken";
2
- import getJWT from "./getJWT";
3
-
4
- const decodeJWTOrThrow = (jwt: unknown): JwtPayload => {
5
- if (typeof jwt !== "string") {
6
- throw new Error("Expected JWT to be a string");
7
- }
8
-
9
- const decodedJWT = jsonwebtoken.decode(jwt, { complete: true });
10
-
11
- if (!decodedJWT) {
12
- throw new Error("Could not decode JWT");
13
- }
14
-
15
- if (typeof decodedJWT.payload === "string") {
16
- throw new Error("Did not expect JWT payload to be a string");
17
- }
18
-
19
- return decodedJWT;
20
- };
21
-
22
- const getLoggedInUser = async (): Promise<{
23
- accountId: number;
24
- customUserId: number;
25
- email: string;
26
- }> => {
27
- const jwt = await getJWT();
28
-
29
- let decodedJwt = decodeJWTOrThrow(jwt);
30
-
31
- if (decodedJwt.payload["sub_type"] == "service") {
32
- decodedJwt = decodeJWTOrThrow(decodedJwt.payload["njwt"]);
33
- }
34
-
35
- if (typeof decodedJwt.payload["zap:acc"] !== "string") {
36
- throw new Error("JWT payload does not contain accountId");
37
- }
38
-
39
- const accountId = parseInt(decodedJwt.payload["zap:acc"], 10);
40
- if (isNaN(accountId)) {
41
- throw new Error("JWT accountId is not a number");
42
- }
43
-
44
- if (
45
- decodedJwt.payload["sub_type"] !== "customuser" ||
46
- typeof decodedJwt.payload["sub"] !== "string"
47
- ) {
48
- throw new Error("JWT payload does not contain customUserId");
49
- }
50
-
51
- const customUserId = parseInt(decodedJwt.payload["sub"], 10);
52
- if (isNaN(customUserId)) {
53
- throw new Error("JWT customUserId is not a number");
54
- }
55
-
56
- const email = decodedJwt.payload["zap:uname"];
57
- if (typeof email !== "string") {
58
- throw new Error("JWT payload does not contain email");
59
- }
60
-
61
- return {
62
- accountId,
63
- customUserId,
64
- email,
65
- };
66
- };
67
-
68
- export default getLoggedInUser;
@@ -1,9 +0,0 @@
1
- import { config } from "../config";
2
-
3
- const logout = () => {
4
- config.delete("login_jwt");
5
- config.delete("login_refresh_token");
6
- config.delete("login_expires_at");
7
- };
8
-
9
- export default logout;
@@ -1,50 +0,0 @@
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);
@@ -1,19 +0,0 @@
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,3 +0,0 @@
1
- import Conf from "conf";
2
-
3
- export const config = new Conf({ projectName: "zapier-sdk-cli" });
@@ -1,5 +0,0 @@
1
- import { config } from "./config";
2
-
3
- export const getConfigPath = (): string => {
4
- return config.path;
5
- };