From 7e77002892e26205a6796e1c9844837c9ac8283f Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Thu, 20 Nov 2025 15:23:59 -0300 Subject: [PATCH 1/6] Updating SDK package README --- packages/sdk/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/sdk/README.md b/packages/sdk/README.md index f9438aaaeb30b..09a5b3456594e 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -1,3 +1,5 @@ +**Note:** this package is now maintained in the [pipedream-sdk-typescript](https://github.com/PipedreamHQ/pipedream-sdk-typescript) repository. Visit that to view the most up-to-date code of the SDK. + # `@pipedream/sdk` TypeScript SDK for [Pipedream](https://pipedream.com). [See the From 97454ce44a4255adc3defb4c97d534124f604a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Falc=C3=A3o?= <48412907+GTFalcao@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:13:49 -0300 Subject: [PATCH 2/6] Update packages/sdk/README.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- packages/sdk/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 09a5b3456594e..742abe248320f 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -1,5 +1,9 @@ -**Note:** this package is now maintained in the [pipedream-sdk-typescript](https://github.com/PipedreamHQ/pipedream-sdk-typescript) repository. Visit that to view the most up-to-date code of the SDK. +# `@pipedream/sdk` +> **Note:** This package is now maintained in the +> [pipedream-sdk-typescript](https://github.com/PipedreamHQ/pipedream-sdk-typescript) +> repository. Visit that to view the most up-to-date code of the SDK. +> # `@pipedream/sdk` TypeScript SDK for [Pipedream](https://pipedream.com). [See the From 7d266299a4f3ea7ab1d91cda87442712a26efe0a Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Thu, 20 Nov 2025 21:16:48 -0300 Subject: [PATCH 3/6] md fix --- packages/sdk/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 742abe248320f..dd11556fb2de3 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -3,8 +3,6 @@ > **Note:** This package is now maintained in the > [pipedream-sdk-typescript](https://github.com/PipedreamHQ/pipedream-sdk-typescript) > repository. Visit that to view the most up-to-date code of the SDK. -> -# `@pipedream/sdk` TypeScript SDK for [Pipedream](https://pipedream.com). [See the docs](https://pipedream.com/docs/connect) for usage instructions. From 409e6ea4077f733da45ae8e7a44de3d8d0178e74 Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Fri, 21 Nov 2025 14:11:14 -0300 Subject: [PATCH 4/6] Deleting rest of sdk package --- packages/sdk/.eslintignore | 1 - packages/sdk/.tool-versions | 1 - packages/sdk/CHANGELOG.md | 368 --- packages/sdk/CONTRIBUTING.md | 96 - packages/sdk/examples/browser/Makefile | 8 - packages/sdk/examples/browser/index.html | 20 - packages/sdk/examples/server/Makefile | 2 - packages/sdk/examples/server/index.mjs | 10 - packages/sdk/jest.config.js | 31 - packages/sdk/package.json | 68 - packages/sdk/scripts/updateVersion.js | 13 - packages/sdk/src/browser/index.ts | 357 --- .../sdk/src/server/__tests__/server.test.ts | 875 ------- packages/sdk/src/server/cli.ts | 269 --- packages/sdk/src/server/index.ts | 491 ---- packages/sdk/src/shared/component.ts | 279 --- packages/sdk/src/shared/index.ts | 2041 ----------------- packages/sdk/src/shared/shims.d.ts | 5 - packages/sdk/src/version.ts | 2 - packages/sdk/tsconfig.browser.json | 23 - packages/sdk/tsconfig.node.json | 31 - packages/sdk/tsup.browser.config.js | 15 - packages/sdk/tsup.server.cjs.config.js | 16 - packages/sdk/tsup.server.esm.config.js | 13 - 24 files changed, 5035 deletions(-) delete mode 100644 packages/sdk/.eslintignore delete mode 100644 packages/sdk/.tool-versions delete mode 100644 packages/sdk/CHANGELOG.md delete mode 100644 packages/sdk/CONTRIBUTING.md delete mode 100644 packages/sdk/examples/browser/Makefile delete mode 100644 packages/sdk/examples/browser/index.html delete mode 100644 packages/sdk/examples/server/Makefile delete mode 100644 packages/sdk/examples/server/index.mjs delete mode 100644 packages/sdk/jest.config.js delete mode 100644 packages/sdk/package.json delete mode 100644 packages/sdk/scripts/updateVersion.js delete mode 100644 packages/sdk/src/browser/index.ts delete mode 100644 packages/sdk/src/server/__tests__/server.test.ts delete mode 100644 packages/sdk/src/server/cli.ts delete mode 100644 packages/sdk/src/server/index.ts delete mode 100644 packages/sdk/src/shared/component.ts delete mode 100644 packages/sdk/src/shared/index.ts delete mode 100644 packages/sdk/src/shared/shims.d.ts delete mode 100644 packages/sdk/src/version.ts delete mode 100644 packages/sdk/tsconfig.browser.json delete mode 100644 packages/sdk/tsconfig.node.json delete mode 100644 packages/sdk/tsup.browser.config.js delete mode 100644 packages/sdk/tsup.server.cjs.config.js delete mode 100644 packages/sdk/tsup.server.esm.config.js diff --git a/packages/sdk/.eslintignore b/packages/sdk/.eslintignore deleted file mode 100644 index 1521c8b7652b1..0000000000000 --- a/packages/sdk/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/packages/sdk/.tool-versions b/packages/sdk/.tool-versions deleted file mode 100644 index 38ba13262919f..0000000000000 --- a/packages/sdk/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -nodejs 22.10.0 diff --git a/packages/sdk/CHANGELOG.md b/packages/sdk/CHANGELOG.md deleted file mode 100644 index d5125e8b1675b..0000000000000 --- a/packages/sdk/CHANGELOG.md +++ /dev/null @@ -1,368 +0,0 @@ - - -# Changelog - -## [1.8.0] - 2025-08-13 - -### Added - -- Added `categoryIds` parameter to `getApps` method for filtering - apps by category IDs -- Added `getAppCategories` method to retrieve available app categories - -## [1.7.0] - 2025-07-03 - -### Added - -- Added optional scope parameter to backendClient creation. - -## [1.6.11] - 2025-07-02 - -### Added - -- Added `stash` to `V1Component` - -## [1.6.10] - 2025-07-01 - -### Added - -- Added `sortKey` and `sortDirection` options to the `getApps` method - -## [1.6.9] - 2025-06-10 - -### Added - -- Added types for the missing configurable props - -## Changed - -- Fixed the `Defaultable` type to correctly handle arrays -- Fixed the `ConfigurablePropTimer` type to define cron expressions and - time intervals -- Marked the `auth` field in the SQL prop type as optional -- Fixed the `App` type to include the `description` field returned by the API -- Fixed the `GetAppsResponse` type to include the pagination stuff - -## [1.6.8] - 2025-06-07 - -### Added - -- Added `endpoint_url` field to the component metadata, providing the URL to the - HTTP interface of the component. -- Added missing pagination fields to the `GetComponentsResponse` and - `GetAccountsResponse` types. - -## [1.6.7] - 2025-06-06 - -### Added - -- Added `stashId` option to the `runAction` method, which allows files to be - persisted between action runs. - -## [1.6.6] - 2025-06-05 - -### Added - -- Added support for `sql` prop type for `connect-react` package - -## [1.6.5] - 2025-06-02 - -### Changed - -- Fix the `deployTrigger` method so that it sends the workflow ID to the API - -## [1.6.4] - 2025-05-30 - -### Added - -- Added `onClose` callback to `connectAccount` method that receives a - `ConnectStatus` object with `successful` and `completed` boolean properties - -## [1.6.3] - 2025-05-20b - -### Added - -- Added `rawAccessToken` getter to `BackendClient` - -## [1.6.2] - 2025-05-20a - -### Added - -- Added ability to create a `BackendClient` with just an `AccessToken` - -## [1.6.1] - 2025-05-20 - -### Added - -- Added `rawToken` getter to `BrowserClient` - -### Changed - -- changed `GetComponentsResponse` type to include `configurable_props` - -## [1.6.0] - 2025-04-30 - -### Added - -- Added `configuredProps` argument to the `updateTrigger` method. - -### Changed - -- Corrected the return type of `updateTrigger`. -- Changed the type of property values of `ConfigureComponentContext` from - explicit `any` to `unknown`. - -## [1.5.5] - 2025-04-28 - -### Changed - -- Types and documentation around `configureComponent` `prevContext` and `context`. - -## [1.5.4] - 2025-04-25 - -### Added - -- Changed server-side authorized requests to refresh its auth token if it expires - within 1 second. - -## [1.5.3] - 2025-04-18 - -### Added - -- Added `ProxyResponse` type for makeProxyRequest -- changed the location of connect DEBUG calls so they'll still show in the - error case. - -## [1.5.2] - 2025-04-15 - -### Added - -- PD_SDK_DEBUG env var. Set it to true to enable debugging of Pipedream Connect - API requests. Simple sanitization is performed to prevent sensitive field leakage - but use caution. - -## [1.5.1] - 2025-04-15 - -### Added - -- `withLabel` to `BaseConfigurableProp` type definition -- documentation describing various fields in `BaseConfigurableProp` -- `featured_weight` to `App` type definition now that API returns this value - -## [1.5.0] - 2025-04-08 - -### Added - -- Added support for the `query` option to the `configureComponent` method, - enabling API-based search using the specified query. - -## [1.4.0] - 2025-03-12 - -### Changed - -- Added `description` and `component_type` to `V1Component` - -## [1.3.3] - 2025-02-5 - -### Changed - -- Add makeProxyRequest function to BaseClient - -## [1.3.2] - 2025-02-3 - -### Changed - -- Add getEnvironment function to BaseClient - -## [1.3.1] - 2025-01-30 - -### Changed - -- Fix cjs build to transpile and include `oauth4webapi` - -## [1.3.0] - 2025-01-30 - -### Added - -- Edge compatible (or closer to it) by replacing `simple-oauth2` with `oauth4webapi` -- Output esm and cjs instead of just cjs -- Minimized bundle size - -### Chore - -- Modernized package to be type: "module" -- Removed `jest-fetch-mock` - -## [1.2.1] - 2025-01-24 - -### Added - -- New types related to API paginated responses -- New type for a prop configuration options - -### Changed - -- Fixed the types of the trigger retrieval and deployment methods in the backend - client to correctly reflect the actual response (which is nested inside a - `data` field). - -## [1.2.0] - 2025-01-23 - -### Added - -- New methods and types to interact with the deployed triggers API - -## [1.1.6] - 2025-01-21 - -### Changed - -- Fixed the docs of the `getAccountById` method in the backend client to remove - arguments that are not actually supported. - -## [1.1.5] - 2025-01-14 - -### Changed - -- Corrected the return type of `reloadComponentProps` - -## [1.1.4] - 2025-01-08 - -### Added - -- Add pagination parameters to component configuration (`page` and `prevContext`) - -## [1.1.3] - 2024-12-13 - -### Added - -- Can now filter `getApps` by whether app `hasComponents`, - `hasActions`, or `hasTriggers` in the registry - -## [1.1.2] - 2024-12-12 - -### Changed - -- Fixed the docstring referring to the `componentConfigure` and - `reloadComponentProps` methods of the components API - -## [1.1.1] - 2024-12-11 - -### Changed - -- Remove deprecated asynchronous response handling code. - -## [1.1.0] - 2024-12-10 - -### Added - -- Documented the public methods and types for the components API - -### Changed - -- Renamed the methods involved with the components API (e.g. - `componentConfigure` -> `configureComponent`) -- Renamed the types used for passing options and accessing responses from the - components API endpoints (e.g. `ComponentRequestResponse` -> - `GetComponentResponse`) -- Marked the renamed methods and types as deprecated - -## [1.0.12] - 2024-12-06 - -### Added - -- Allow passing `before`, `after` pagination cursors for apps, accounts, - components endpoints - -## [1.0.11] - 2024-12-06 - -### Added - -- Configurable `limit` option for apps, accounts, components endpoints - -## [1.0.10] - 2024-12-04 - -### Changed - -- Handle correct casing of `stringOptions` in configure prop response - -## [1.0.9] - 2024-12-04 - -### Added - -- `triggerDeploy` preview API -- `client.version` and `x-pd-sdk-version` header - -## [1.0.8] - 2024-11-29 - -### Changed - -- Fix fallback WebSocket import (for new components API) - -## [1.0.7] - 2024-11-21 - -### Changed - -- The backend client now correctly uses asynchronous messaging to handle long - running operations. -- Updated the backend command line tool to respect the `ENVIRONMENT` env variable - if set. - -## [1.0.6] - 2024-11-20 - -### Changed - -- Use client Connect tokens to make api calls directly from the client. -- Deprecated the `environments` property on `createFrontendClient` since it is - now stored in the token - -## [1.0.5] - 2024-11-18 - -### Changed - -- The backend client used to default to `production` if the environment was not - specified. Now `environment` is a required argument for `createBackendClient` - and must be one of `production` or `development`. - -## [1.0.4] - 2024-11-15 - -### Changed - -- Improved the docs of the `getAccountById` method in the backend client to - clarify the behavior of the new argument. - -- Fixed the exported `HTTPAuthType` enum so that it can be used by the consumers - of the SDK. - -## [1.0.3] - 2024-11-14 - -### Added - -- Added a new argument to the `getAccountById` method in the backend client to - allow the client to retrieve the credentials of the corresponding account. - -## [1.0.2] - 2024-11-14 - -### Changed - -- Deprecated the `environment_name` field in the `ConnectTokenOpts` type, as it - is no longer used by the SDK nor the Connect API. The environment name is now - exclusively determined by the `environment` field in the `BackendClientOpts` - type, read during the client creation. - -### Added - -- Added a new optional flag to `RequestOptions` called `fullResponse`, which - allows the user to get the full HTTP response object, including the headers - and status code. - -## [1.0.0] - 2024-11-01 - -### Changed - -- Renamed the server-side client class from `ServerClient` to `BackendClient` to - better indicate its purpose. -- Removed the `oauthClient` optional argument to the `BackendClient` constructor -- Renamed the client factory methods so that developers can know exactly the - kind of client they are creating. -- Removed project-key-based authentication in favor of a more secure - token-based authentication using OAuth. diff --git a/packages/sdk/CONTRIBUTING.md b/packages/sdk/CONTRIBUTING.md deleted file mode 100644 index db2171db77866..0000000000000 --- a/packages/sdk/CONTRIBUTING.md +++ /dev/null @@ -1,96 +0,0 @@ -# How to Contribute to the SDK - -## Local Environment Setup - -### Global Dependencies - -Clone the repo (ideally your own fork of it) and initialize the global -dependencies like Node.js, NPM, etc. We use [`asdf`](https://asdf-vm.com/) to -manage these, so assuming we're located in this directory (i.e. `packages/sdk/`) -we can run the following command to install them: - -```shell -asdf install -``` - -If you prefer to use another tool make sure you use the same versions that are -specified in the `.tool-versions` files [in this current directory, and -recursively going up until you reach the root of the -repo](https://asdf-vm.com/guide/getting-started.html#_6-set-a-version). - -### Local Dependencies - -You can install the package's dependencies by using `pnpm` or `npm`: - -```shell -pnpm install -``` - -Since other packages in this repository already use `pnpm`, we recommend you use -it in this case too to keep your `node_modules` footprint low. - -## Build the Package - -There's a script that you can invoke with `pnpm` to build the package artifacts: - -```shell -pnpm build -``` - -You can also watch the code for changes, and automatically build a new artifact -after each change with the `watch` script: - -```shell -pnpm watch -``` - -### Use the Package - -You can use pnpm's `link` command to point other code to your local version of -this package during development. This lets you test the SDK in other local apps, -end-to-end. - -In this `packages/sdk/` directory: - -```shell -pnpm link --global -``` - -> [!NOTE] -When using the version of Node.js specified in -[`.tool-versions`](./.tool-versions) (via `asdf`), the command above will -install the package in the `asdf` Node.js environment. To use this package -elsewhere, you'll need to use the same version of Node.js. Please reference the -latest version of [the `.tool-versions` file](./.tool-versions) and add that to -the `.tool-versions` file in your local project where you'd like to use the SDK. - -For example, in your app's directory: - -```shell -# Replace /path/to/pipedream with the actual path to this repository -grep nodejs /path/to/pipedream/packages/sdk/.tool-versions >> .tool-versions -asdf install -pnpm install @pipedream/sdk -``` - -Then, link the SDK package to it's local path: - -```shell -pnpm link @pipedream/sdk -``` - -To confirm you successfully installed the correct version of the SDK, and that -it's tied to your local copy of the Pipedream SDK: - -```shell -ls -l node_modules/@pipedream -``` - -You should see an output like this one (notice the last line): - -```text -total 0 -drwxr-xr-x 9 jay staff 288 30 Oct 14:01 mysql -drwxr-xr-x 10 jay staff 320 30 Oct 14:01 platform -lrwxr-xr-x 1 jay staff 31 30 Oct 14:06 sdk -> ../../../pipedream/packages/sdk -``` diff --git a/packages/sdk/examples/browser/Makefile b/packages/sdk/examples/browser/Makefile deleted file mode 100644 index 31dc6402c352d..0000000000000 --- a/packages/sdk/examples/browser/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -default: - make -j2 server delayed-open - -server: - cd ../.. && python -m http.server - -delayed-open: - sleep 1 && xdg-open http://localhost:8000/examples/browser/index.html diff --git a/packages/sdk/examples/browser/index.html b/packages/sdk/examples/browser/index.html deleted file mode 100644 index 14ca5d69c402c..0000000000000 --- a/packages/sdk/examples/browser/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - -

Load SDK in browser

- - - - diff --git a/packages/sdk/examples/server/Makefile b/packages/sdk/examples/server/Makefile deleted file mode 100644 index ff7b4a60c3538..0000000000000 --- a/packages/sdk/examples/server/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -default: - @node index.mjs diff --git a/packages/sdk/examples/server/index.mjs b/packages/sdk/examples/server/index.mjs deleted file mode 100644 index deb30ff419124..0000000000000 --- a/packages/sdk/examples/server/index.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import { createBackendClient } from "../../dist/server/server/index.js"; - -const client = createBackendClient({ - environment: "development", - credentials: { - clientId: "not-empty", - clientSecret: "not-empty", - }, -}); -console.log("sdk version: " + client.version); diff --git a/packages/sdk/jest.config.js b/packages/sdk/jest.config.js deleted file mode 100644 index 67e93f088a952..0000000000000 --- a/packages/sdk/jest.config.js +++ /dev/null @@ -1,31 +0,0 @@ -export default { - testEnvironment: "node", - roots: [ - "/src", - ], - testMatch: [ - "**/__tests__/**/*.ts", - "**/?(*.)+(spec|test).ts", - ], - moduleFileExtensions: [ - "ts", - "js", - ], - moduleNameMapper: { - "^(.+)\\.js$": "$1", - }, - extensionsToTreatAsEsm: [ - ".ts", - ], - transform: { - // '^.+\\.[tj]sx?$' to process ts,js,tsx,jsx with `ts-jest` - // '^.+\\.m?[tj]sx?$' to process ts,js,tsx,jsx,mts,mjs,mtsx,mjsx with `ts-jest` - "^.+\\.[jt]sx?$": [ - "ts-jest", - { - tsconfig: "tsconfig.node.json", - useESM: true, - }, - ], - }, -}; diff --git a/packages/sdk/package.json b/packages/sdk/package.json deleted file mode 100644 index 5f01499c23dab..0000000000000 --- a/packages/sdk/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "@pipedream/sdk", - "type": "module", - "version": "1.8.0", - "description": "Pipedream SDK", - "main": "./dist/server.js", - "module": "./dist/server.js", - "types": "./dist/server.d.ts", - "browser": "./dist/browser.js", - "exports": { - ".": { - "types": "./dist/server.d.ts", - "browser": "./dist/browser.js", - "import": "./dist/server.js", - "require": "./dist/server.cjs", - "default": "./dist/server.js" - }, - "./server": { - "types": "./dist/server.d.ts", - "import": "./dist/server.js", - "require": "./dist/server.cjs" - }, - "./browser": { - "types": "./dist/browser.d.ts", - "import": "./dist/browser.js", - "require": "./dist/browser.cjs" - } - }, - "engines": { - "node": ">=18.0.0" - }, - "keywords": [ - "pipedream" - ], - "license": "SEE LICENSE IN LICENSE", - "publishConfig": { - "access": "public" - }, - "scripts": { - "prepublish": "pnpm run build", - "prebuild": "node scripts/updateVersion.js", - "build": "rm -rf dist && pnpm run prebuild && tsup --config tsup.server.cjs.config.js && tsup --config tsup.server.esm.config.js && tsup --config tsup.browser.config.js", - "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest", - "watch": "nodemon --watch src --exec 'pnpm run build'", - "cli": "node dist/server/cli.js" - }, - "files": [ - "dist" - ], - "devDependencies": { - "@types/jest": "^29.5.13", - "@types/node": "^20.17.6", - "@types/rails__actioncable": "^6.1.11", - "@types/ws": "^8.5.13", - "jest": "^29.7.0", - "lodash.isequal": "^4.5.0", - "nodemon": "^3.1.7", - "ts-jest": "^29.2.5", - "tsup": "^8.3.6", - "typescript": "^5.6" - }, - "dependencies": { - "@rails/actioncable": "^8.0.0", - "commander": "^12.1.0", - "oauth4webapi": "^3.1.4", - "ws": "^8.18.0" - } -} diff --git a/packages/sdk/scripts/updateVersion.js b/packages/sdk/scripts/updateVersion.js deleted file mode 100644 index 4b6ed8894a5e3..0000000000000 --- a/packages/sdk/scripts/updateVersion.js +++ /dev/null @@ -1,13 +0,0 @@ -import fs from "fs"; -import cp from "child_process"; - -if (!process.env.CI) { - // make sure people building locally automatically do not track changes to version file - cp.execSync("git update-index --skip-worktree src/version.ts"); -} - -const pkg = JSON.parse(String(fs.readFileSync("./package.json", "utf8"))) -const versionTsPath = "./src/version.ts"; -const data = String(fs.readFileSync(versionTsPath, "utf8")); -const newData = data.replace(/"(.*)"/, `"${pkg.version}"`); -fs.writeFileSync(versionTsPath, newData); diff --git a/packages/sdk/src/browser/index.ts b/packages/sdk/src/browser/index.ts deleted file mode 100644 index 38a9bf439b7bb..0000000000000 --- a/packages/sdk/src/browser/index.ts +++ /dev/null @@ -1,357 +0,0 @@ -// This code is meant to be run client-side. Never provide project keys to the -// browser client, or make API requests to the Pipedream API to fetch -// credentials. The browser client is meant for initiating browser-specific -// operations, like connecting accounts via Pipedream Connect. See the server/ -// directory for the server client. - -import { - AccountsRequestResponse, - BaseClient, - GetAccountOpts, - type ConnectTokenResponse, -} from "../shared/index.js"; -export type * from "../shared/index.js"; - -/** - * Options for creating a browser-side client. This is used to configure the - * BrowserClient instance. - */ -type CreateBrowserClientOpts = { - /** - * @deprecated environment is set on the server when generating the client token - */ - environment?: string; - - /** - * The frontend host URL. Used by Pipedream employees only. Defaults to - * "pipedream.com" if not provided. - */ - frontendHost?: string; - - /** - * The API host URL. Used by Pipedream employees. Defaults to - * "api.pipedream.com" if not provided. - */ - apiHost?: string; - - /** - * Will be called whenever we need a new token. - * - * The callback function should return the response from - * `serverClient.createConnectToken`. - */ - tokenCallback?: TokenCallback; - - /** - * An external user ID associated with the token. - */ - externalUserId?: string; -}; - -export type TokenCallback = (opts: { - externalUserId: string; -}) => Promise; - -/** - * The name slug for an app, a unique, human-readable identifier like "github" - * or "google_sheets". Find this in the Authentication section for any app's - * page at https://pipedream.com/apps. For more information about name slugs, - * see https://pipedream.com/docs/connect/quickstart#find-your-apps-name-slug. - */ -type AppNameSlug = string; - -/** - * The result of a successful connection. - */ -type ConnectResult = { - /** - * The unique identifier of the connected account. - */ - id: string; -}; - -/** - * The status when the Connect dialog is closed. - */ -type ConnectStatus = { - /** - * Whether the connection was successful (account was connected). - */ - successful: boolean; - /** - * Whether the connection process was completed (vs user closing early). - */ - completed: boolean; -}; - -/** - * Custom error class for handling connection errors. - */ -class ConnectError extends Error {} - -/** - * Options for starting the connection process. - */ -type StartConnectOpts = { - /** - * The token used for authenticating the connection. - * - * Optional if client already initialized with token - */ - token?: string; - - /** - * The app to connect to, either as an ID or an object containing the ID. - */ - app: AppNameSlug; - - /** - * The OAuth app ID to connect to. - */ - oauthAppId?: string; - - /** - * Callback function to be called upon successful connection. - * - * @param res - The result of the connection. - */ - onSuccess?: (res: ConnectResult) => void; - - /** - * Callback function to be called if an error occurs during the connection. - * - * @param err - The error that occurred during the connection. - */ - onError?: (err: ConnectError) => void; - - /** - * Callback function to be called when the Connect iFrame is closed. - * - * @param status - The status of the connection when closed. - */ - onClose?: (status: ConnectStatus) => void; -}; - -/** - * Creates a new instance of `BrowserClient` with the provided options. - * - * @example - * ```typescript - const client = createFrontendClient({ - tokenCallback, - externalUserId, - }); - * ``` - * @param opts - The options for creating the browser client. - * @returns A new instance of `BrowserClient`. - */ -export function createFrontendClient(opts: CreateBrowserClientOpts = {}) { - return new BrowserClient(opts); -} - -/** - * A client for interacting with the Pipedream Connect API from the browser. - */ -export class BrowserClient extends BaseClient { - private baseURL: string; - private iframeURL: string; - private iframe?: HTMLIFrameElement; - private iframeId = 0; - private tokenCallback?: TokenCallback; - private _token?: string; - private _tokenExpiresAt?: Date; - private _tokenRequest?: Promise; - externalUserId?: string; - - /** - * Constructs a new `BrowserClient` instance. - * - * @param opts - The options for configuring the browser client. - */ - constructor(opts: CreateBrowserClientOpts) { - super(opts); - this.baseURL = `https://${opts.frontendHost || "pipedream.com"}`; - this.iframeURL = `${this.baseURL}/_static/connect.html`; - this.tokenCallback = opts.tokenCallback; - this.externalUserId = opts.externalUserId; - } - - private async token() { - if ( - this._token && - this._tokenExpiresAt && - this._tokenExpiresAt > new Date() - ) { - return this._token; - } - - if (this._tokenRequest) { - return this._tokenRequest; - } - - const tokenCallback = this.tokenCallback; - const externalUserId = this.externalUserId; - - if (!tokenCallback) { - throw new Error("No token callback provided"); - } - if (!externalUserId) { - throw new Error("No external user ID provided"); - } - - // Ensure only one token request is in-flight at a time. - this._tokenRequest = (async () => { - const { - token, expires_at, - } = await tokenCallback({ - externalUserId: externalUserId, - }); - this._token = token; - this._tokenExpiresAt = new Date(expires_at); - this._tokenRequest = undefined; - return token; - })(); - - return this._tokenRequest; - } - - private refreshToken() { - this._token = undefined; - } - - /** - * Retrieves the raw token string. - * - * @return {string} The raw token value. - */ - public rawToken(): string | undefined { - return this._token; - } - - /** - * Initiates the process of connecting an account. - * - * @param opts - The options for starting the connection process. - * - * @example - * ```typescript - * client.connectAccount({ - * token: "your-token", - * app: "your-app-id", - * onSuccess: (res) => { - * console.log("Connected account ID:", res.id); - * }, - * onError: (err) => { - * console.error("Connection error:", err); - * }, - * onClose: (status) => { - * if (!status.successful) { - * console.log("User closed without connecting"); - * } - * }, - * }); - * ``` - */ - public async connectAccount(opts: StartConnectOpts) { - let connectionSuccessful = false; - let connectionCompleted = false; - - const onMessage = (e: MessageEvent) => { - switch (e.data?.type) { - case "success": - connectionSuccessful = true; - connectionCompleted = true; - opts.onSuccess?.({ - id: e.data?.authProvisionId, - }); - break; - case "error": - connectionCompleted = true; - opts.onError?.(new ConnectError(e.data.error)); - break; - case "close": - this.cleanup(onMessage); - opts.onClose?.({ - successful: connectionSuccessful, - completed: connectionCompleted, - }); - break; - default: - break; - } - }; - - window.addEventListener("message", onMessage); - - try { - await this.createIframe(opts); - } catch (err) { - opts.onError?.(err as ConnectError); - } - this.refreshToken(); // token expires once it's used to create a connected account. We need to get a new token for the next requests. - } - - /** - * Cleans up the iframe and message event listener after the connection - * process is complete. - * - * @param onMessage - The message event handler to remove. - */ - private cleanup(onMessage: (e: MessageEvent) => void) { - this.iframe?.remove(); - window.removeEventListener("message", onMessage); - } - - /** - * Creates an iframe for the connection process and appends it to the document - * body. - * - * @param opts - The options for starting the connection process. - * - * @throws {ConnectError} If the app option is not a string. - */ - private async createIframe(opts: StartConnectOpts) { - const token = opts.token || (await this.token()); - const qp = new URLSearchParams({ - token, - }); - - if (typeof opts.app === "string") { - qp.set("app", opts.app); - } else { - throw new ConnectError("Object app not yet supported"); - } - - if (opts.oauthAppId) { - qp.set("oauthAppId", opts.oauthAppId); - } - - const iframe = document.createElement("iframe"); - iframe.id = `pipedream-connect-iframe-${this.iframeId++}`; - iframe.title = "Pipedream Connect"; - iframe.src = `${this.iframeURL}?${qp.toString()}`; - iframe.style.cssText = - "position:fixed;inset:0;z-index:2147483647;border:0;display:block;overflow:hidden auto"; - iframe.width = "100%"; - iframe.height = "100%"; - - iframe.onload = () => { - this.iframe = iframe; - }; - - document.body.appendChild(iframe); - } - - protected async authHeaders(): Promise { - if (!(await this.token())) { - throw new Error("No token provided"); - } - return `Bearer ${await this.token()}`; - } - - public getAccounts( - params?: Omit, - ): Promise { - return super.getAccounts(params); - } -} diff --git a/packages/sdk/src/server/__tests__/server.test.ts b/packages/sdk/src/server/__tests__/server.test.ts deleted file mode 100644 index 18efed23bcc54..0000000000000 --- a/packages/sdk/src/server/__tests__/server.test.ts +++ /dev/null @@ -1,875 +0,0 @@ -import { jest } from "@jest/globals" -import { - BackendClient, - BackendClientOpts, - createBackendClient, - HTTPAuthType, -} from "../index.js"; -import isEqual from "lodash.isequal" - -const fetchMock = setupFetchMock() // see bottom of file - -const projectId = "proj_abc123"; -const clientParams: BackendClientOpts = { - environment: "production", - credentials: { - clientId: "test-client-id", - clientSecret: "test-client-secret", - }, - projectId, -}; - -let client: BackendClient; -let customDomainClient: BackendClient; - -beforeEach(() => { - client = new BackendClient( - clientParams, - ); - customDomainClient = new BackendClient({ - ...clientParams, - workflowDomain: "example.com", - }); -}); - -afterEach(() => { - jest.clearAllMocks(); -}); - -describe("BackendClient", () => { - describe("createBackendClient", () => { - it("should mock the createBackendClient method and return a BackendClient instance", () => { - const client = createBackendClient(clientParams); - expect(client).toBeInstanceOf(BackendClient); - }); - }); - - describe("makeRequest", () => { - it("should make a GET request successfully", async () => { - fetchMock.expect({ - request: { - url: "https://api.pipedream.com/v1/test-path", - }, - response: { - json: { - data: "test-response", - }, - }, - }) - - const result = await client.makeRequest("/test-path", { - method: "GET", - }); - - expect(result).toEqual({ - data: "test-response", - }); - }); - - it("should make a POST request with JSON body", async () => { - fetchMock.expect({ - request: { - url: "https://api.pipedream.com/v1/test-path", - json: { - key: "value", - }, - }, - response: { - json: { - success: true, - }, - }, - }) - - const result = await client.makeRequest("/test-path", { - method: "POST", - body: { - key: "value", - }, - }); - - expect(result).toEqual({ - success: true, - }); - }); - - it("should handle non-200 HTTP responses", async () => { - fetchMock.expect({ - request: { - url: "https://api.pipedream.com/v1/bad-path", - }, - response: new Response("Not Found", { - status: 404, - headers: { - "Content-Type": "text/plain", - }, - }), - }); - - await expect(client.makeRequest("/bad-path")).rejects.toThrow("HTTP error! status: 404, body: Not Found"); - }); - }); - - describe("makeAuthorizedRequest", () => { - it("should include OAuth Authorization header and make an API request", async () => { - const accessToken = fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: "https://api.pipedream.com/v1/test-path", - headersContaining: { - authorization: `Bearer ${accessToken}`, - }, - }, - response: { - json: { - success: true, - }, - }, - }) - - const result = await client["makeAuthorizedRequest"]("/test-path"); - - expect(result).toEqual({ - success: true, - }); - }); - - it("should handle OAuth token retrieval failure", async () => { - fetchMock.expectAccessTokenFailure(); - await expect(client.makeAuthorizedRequest("/test-path")).rejects.toThrow(); - }); - }); - - describe("makeConnectRequest", () => { - it("should include Connect Authorization header and make a request", async () => { - const accessToken = fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/test-path`, - headersContaining: { - authorization: `Bearer ${accessToken}`, - }, - }, - response: { - json: { - success: true, - }, - }, - }) - - const result = await client["makeConnectRequest"]("/test-path"); - - expect(result).toEqual({ - success: true, - }); - }); - }); - - describe("createConnectToken", () => { - it("should create a connect token", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/tokens`, - headersContaining: { - "X-PD-Environment": "production", - }, - json: { - external_user_id: "user-id", - external_id: "user-id", - }, - }, - response: { - json: { - token: "connect-token", - expires_at: "2024-01-01T00:00:00Z", - }, - }, - }); - - const result = await client.createConnectToken({ - external_user_id: "user-id", - }); - - expect(result).toEqual({ - token: "connect-token", - expires_at: "2024-01-01T00:00:00Z", - }); - }); - - it("should create a connect token with optional redirect URIs", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/tokens`, - json: { - external_user_id: "user-id", - success_redirect_uri: "https://example.com/success", - error_redirect_uri: "https://example.com/error", - external_id: "user-id", - }, - }, - response: { - json: { - token: "connect-token-with-redirects", - expires_at: "2024-01-01T00:00:00Z", - }, - }, - }); - - const result = await client.createConnectToken({ - external_user_id: "user-id", - success_redirect_uri: "https://example.com/success", - error_redirect_uri: "https://example.com/error", - }); - - expect(result).toEqual({ - token: "connect-token-with-redirects", - expires_at: "2024-01-01T00:00:00Z", - }); - }); - }); - - describe("getAccounts", () => { - it("should retrieve accounts", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts?include_credentials=true`, - }, - response: { - json: { - data: [ - { - id: "account-1", - name: "Test Account", - }, - ], - }, - }, - }) - - const result = await client.getAccounts({ - include_credentials: true, - }); - - expect(result.data).toEqual([ - { - id: "account-1", - name: "Test Account", - }, - ]); - }); - }); - - describe("getAccountById", () => { - it("should retrieve a specific account by ID", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts/account-1`, - }, - response: { - json: { - id: "account-1", - name: "Test Account", - }, - }, - }); - - const result = await client.getAccountById("account-1"); - - expect(result).toEqual({ - id: "account-1", - name: "Test Account", - }); - }); - - it("should include credentials when the flag is set", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts/account-1?include_credentials=true`, - }, - response: { - json: { - id: "account-1", - name: "Test Account", - credentials: {}, - }, - }, - }); - - const result = await client.getAccountById("account-1", { - include_credentials: true, - }); - - expect(result).toEqual({ - id: "account-1", - name: "Test Account", - credentials: {}, - }); - }); - }); - - describe("Get accounts by app", () => { - it("should retrieve accounts associated with a specific app", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts?app=app-1`, - }, - response: { - json: [ - { - id: "account-1", - name: "Test Account", - }, - ], - }, - }); - - const result = await client.getAccounts({ - app: "app-1", - }); - - expect(result).toEqual([ - { - id: "account-1", - name: "Test Account", - }, - ]); - }); - }); - - describe("Get accounts by external user ID", () => { - it("should retrieve accounts associated with a specific external ID", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts?external_user_id=external-id-1`, - }, - response: { - json: [ - { - id: "account-1", - name: "Test Account", - }, - ], - }, - }); - - const result = await client.getAccounts({ - external_user_id: "external-id-1", - }); - - expect(result).toEqual([ - { - id: "account-1", - name: "Test Account", - }, - ]); - }); - }); - - describe("deleteAccount", () => { - it("should delete a specific account by ID", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - method: "DELETE", - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts/account-1`, - }, - response: { - status: 204, - }, - }); - - await client.deleteAccount("account-1"); - }); - }); - - describe("deleteAccountsByApp", () => { - it("should delete all accounts associated with a specific app", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - method: "DELETE", - url: `https://api.pipedream.com/v1/connect/${projectId}/accounts/app/app-1`, - }, - response: { - status: 204, - }, - }); - - await client.deleteAccountsByApp("app-1"); - }); - }); - - describe("deleteExternalUser", () => { - it("should delete all accounts associated with a specific external ID", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - method: "DELETE", - url: `https://api.pipedream.com/v1/connect/${projectId}/users/external-id-1`, - }, - response: { - status: 204, - }, - }); - - await client.deleteExternalUser("external-id-1"); - }); - }); - - describe("getProjectInfo", () => { - it("should retrieve project info", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - method: "GET", - url: `https://api.pipedream.com/v1/connect/${projectId}/projects/info`, - }, - response: { - json: { - apps: [ - { - id: "app-1", - name_slug: "test-app", - }, - ], - }, - }, - }) - - const result = await client.getProjectInfo(); - - expect(result).toEqual({ - apps: [ - { - id: "app-1", - name_slug: "test-app", - }, - ], - }); - }); - }); - - describe("invokeWorkflow", () => { - beforeEach(() => { - client = new BackendClient({ - ...clientParams, - workflowDomain: "example.com", - }); - }); - - it("should invoke a workflow with provided URL and body, with no auth type", async () => { - fetchMock.expect({ - request: { - method: "POST", - url: "https://example.com/workflow", - json: { - foo: "bar", - }, - headersContaining: { - "X-PD-Environment": "production", - }, - }, - response: { - json: { - result: "workflow-response", - }, - }, - }) - - const result = await client.invokeWorkflow("https://example.com/workflow", { - body: { - foo: "bar", - }, - }); - - expect(result).toEqual({ - result: "workflow-response", - }); - }); - - it("should invoke a workflow with OAuth auth type", async () => { - const token = "" + Math.random() - fetchMock.expectAccessTokenSuccess({ - accessToken: token, - }); - fetchMock.expect({ - request: { - url: "https://example.com/workflow", - headersContaining: { - authorization: `Bearer ${token}`, - }, - }, - response: { - json: { - result: "workflow-response", - }, - }, - }) - - const result = await client.invokeWorkflow("https://example.com/workflow", {}, HTTPAuthType.OAuth); - - expect(result).toEqual({ - result: "workflow-response", - }); - }); - - it("should invoke a workflow with static bearer auth type", async () => { - const token = "" + Math.random() - fetchMock.expect({ - request: { - url: "https://example.com/workflow", - headersContaining: { - Authorization: `Bearer ${token}`, - }, - }, - response: { - json: { - result: "workflow-response", - }, - }, - }) - - const result = await client.invokeWorkflow("https://example.com/workflow", { - headers: { - "Authorization": `Bearer ${token}`, - }, - }, HTTPAuthType.StaticBearer); - - expect(result).toEqual({ - result: "workflow-response", - }); - }); - }); - - describe("OAuth Token Handling", () => { - it("should refresh token when expired", async () => { - // First request will get the expired token and fetch a new one - fetchMock.expectAccessTokenFailure(); - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: "https://api.pipedream.com/v1/test-path", - }, - response: { - json: { - success: true, - }, - }, - }) - - const result1 = await client["makeAuthorizedRequest"]("/test-path"); - - expect(result1).toEqual({ - success: true, - }); - }); - }); - - describe("invokeWorkflowForExternalUser", () => { - let client: BackendClient; - - beforeEach(() => { - client = new BackendClient({ - ...clientParams, - workflowDomain: "example.com", - }); - }); - - it("should include externalUserId and environment headers", async () => { - fetchMock.expectAccessTokenSuccess(); - fetchMock.expect({ - request: { - url: "https://example.com/workflow", - headersContaining: { - "X-PD-External-User-ID": "external-user-id", - "X-PD-Environment": "production", - }, - }, - response: { - json: { - result: "workflow-response", - }, - }, - }) - - const result = await client.invokeWorkflowForExternalUser("https://example.com/workflow", "external-user-id", { - body: { - foo: "bar", - }, - }); - - expect(result).toEqual({ - result: "workflow-response", - }); - }); - - it("should throw error when externalUserId is missing", async () => { - await expect(client.invokeWorkflowForExternalUser("https://example.com/workflow", "", { - body: { - foo: "bar", - }, - })).rejects.toThrow("External user ID is required"); - }); - - it("should throw error when externalUserId is blank", async () => { - await expect(client.invokeWorkflowForExternalUser("https://example.com/workflow", " ", { - body: { - foo: "bar", - }, - })).rejects.toThrow("External user ID is required"); - }); - - it("should throw error when the URL is blank", async () => { - await expect(client.invokeWorkflowForExternalUser(" ", "external-user-id", { - body: { - foo: "bar", - }, - })).rejects.toThrow("Workflow URL is required"); - }); - }); - - describe("BackendClient - buildWorkflowUrl", () => { - describe("Validations", () => { - it("should throw an error when the input is blank", () => { - expect(() => client["buildWorkflowUrl"](" ")).toThrow("URL or endpoint ID is required"); - }); - - it("should throw an error when the URL doesn't match the workflow domain", () => { - const url = "https://example.com"; - expect(() => client["buildWorkflowUrl"](url)).toThrow("Invalid workflow domain"); - }); - - it("should throw an error when the endpoint ID doesn't match the expected format", () => { - const input = "foo123"; - expect(() => client["buildWorkflowUrl"](input)).toThrow("Invalid endpoint ID format"); - }); - }); - - describe("Default domain (m.pipedream.net)", () => { - it("should return full URL if input is a full URL with protocol", () => { - const input = "https://en123.m.pipedream.net"; - const expected = "https://en123.m.pipedream.net/"; - expect(client["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should return full URL if input is a URL without protocol", () => { - const input = "en123.m.pipedream.net"; - const expected = "https://en123.m.pipedream.net/"; - expect(client["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should construct URL with 'm.pipedream.net' if input is an endpoint ID", () => { - const input = "en123"; - const expected = "https://en123.m.pipedream.net"; - expect(client["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should handle input with a path in full URL with protocol", () => { - const input = "https://en123.m.pipedream.net/foo"; - const expected = "https://en123.m.pipedream.net/foo"; - expect(client["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should handle input with a path when no protocol is provided", () => { - const input = "en123.m.pipedream.net/foo"; - const expected = "https://en123.m.pipedream.net/foo"; - expect(client["buildWorkflowUrl"](input)).toBe(expected); - }); - }); - - describe("Custom domain (example.com)", () => { - it("should return full URL if input is a full URL with protocol", () => { - const input = "https://en123.example.com"; - const expected = "https://en123.example.com/"; - expect(customDomainClient["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should return full URL if input is a URL without protocol", () => { - const input = "en123.example.com"; - const expected = "https://en123.example.com/"; - expect(customDomainClient["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should construct URL with 'example.com' if input is an endpoint ID", () => { - const input = "en123"; - const expected = "https://en123.example.com"; - expect(customDomainClient["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should handle input with a path in full URL with protocol", () => { - const input = "https://en123.example.com/foo"; - const expected = "https://en123.example.com/foo"; - expect(customDomainClient["buildWorkflowUrl"](input)).toBe(expected); - }); - - it("should handle input with a path when no protocol is provided", () => { - const input = "en123.example.com/foo"; - const expected = "https://en123.example.com/foo"; - expect(customDomainClient["buildWorkflowUrl"](input)).toBe(expected); - }); - }); - }); -}); - -type ExpectRequest = { - method?: string - url?: string | RegExp - json?: Record - headersContaining?: Record -} -type MockResponse = - | Response - | { status?: number; json?: unknown } -type IfOpts = { - method: string - url: string - headers: Record // NonNullable - json?: unknown // body json - // XXX etc. -} -function setupFetchMock() { - let intercepts: { - if: (opts: IfOpts) => boolean - response: () => Response - }[] = [] - - const jsonResponse = (o: unknown, opts?: { status?: number }) => { - return new Response(JSON.stringify(o), { - status: opts?.status, - headers: { - "content-type": "application/json", - }, - }) - } - - beforeEach(() => { - intercepts = []; - // without these generics this fails typecheck and can't figure out why - jest.spyOn(global, "fetch").mockImplementation(jest.fn(async (...args: Parameters) => { // eslint-disable-line @typescript-eslint/no-explicit-any - const [ - url, - init, - ] = args - let json: unknown - if (init?.body && typeof init.body === "string") { - try { - json = JSON.parse(init.body) - } catch { - // pass - } - } - if (url instanceof Request) { - throw new Error("not supported") - } - const ifOpts: IfOpts = { - method: init?.method || "GET", - url: url.toString(), - headers: init?.headers as Record || {}, - json, - } - for (let i = 0; i < intercepts.length; i++) { - const intercept = intercepts[i] - if (intercept.if(ifOpts)) { - intercepts.splice(i, 1) - return intercept.response() - } - } - throw new Error(`Request to ${url} not intercepted`) - }) as jest.Mock); - }) - - afterEach(() => { - if (intercepts.length) { - throw new Error("Expected requests not yet intercepted") - } - }) - - // const _expect = (opts: { if: (opts: IfOpts) => boolean, jsonResponse?: any, response?: Response }) => { - const _expect = (opts: { request: ExpectRequest, response: MockResponse }) => { - const { - method, url, headersContaining, json, - } = opts.request - intercepts.push({ - if: (ifOpts) => { - if (method && ifOpts.method !== method) return false - if (url) { - if (typeof url === "string") return url === ifOpts.url - if (url instanceof RegExp) return !!ifOpts.url.match(url) - throw new Error(`unexpected type for request.url: ${url}`) - } - if (headersContaining) { - for (const header in headersContaining) { - if (ifOpts.headers[header.toLowerCase()] !== headersContaining[header.toLowerCase()]) { - return false - } - } - } - if (json && !isEqual(json, ifOpts.json)) { - return false - } - return true - }, - response: () => { - if (opts.response instanceof Response) { - return opts.response - } - if (opts.response.json) { - return jsonResponse(opts.response.json, { - status: opts.response.status, - // XXX... - }) - } - return new Response(null, { - status: opts.response.status, - headers: { - "content-type": "text/plain", - }, - }) - }, - }) - } - - const expectAccessTokenSuccess = (opts?: { accessToken?: string; expiresIn?: number }) => { - const accessToken = opts?.accessToken || "" + Math.random() - _expect({ - request: { - url: /\/v1\/oauth\/token$/, - }, - response: { - json: { - access_token: accessToken, - token_type: "Bearer", - expires_in: opts?.expiresIn ?? 3600, - }, - }, - }) - return accessToken - } - - const expectAccessTokenFailure = () => { - _expect({ - request: { - url: /\/v1\/oauth\/token$/, - }, - response: new Response("", { - status: 401, - headers: { - "content-type": "application/json", - }, - }), - }) - } - - return { - expect: _expect, - expectAccessTokenSuccess, - expectAccessTokenFailure, - } -} diff --git a/packages/sdk/src/server/cli.ts b/packages/sdk/src/server/cli.ts deleted file mode 100644 index 92831a663921a..0000000000000 --- a/packages/sdk/src/server/cli.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { createBackendClient } from "./index.js"; -import { program } from "commander"; - -const { - CLIENT_ID, CLIENT_SECRET, PROJECT_ID, API_HOST, ENVIRONMENT, -} = process.env; - -if (!CLIENT_ID || !CLIENT_SECRET || !PROJECT_ID) { - console.error("Error: Missing required environment variables (CLIENT_ID, CLIENT_SECRET, PROJECT_ID)."); - process.exit(1); -} - -const client = createBackendClient({ - credentials: { - clientId: CLIENT_ID, - clientSecret: CLIENT_SECRET, - }, - projectId: PROJECT_ID, - apiHost: API_HOST, - environment: ENVIRONMENT === "production" - ? "production" - : "development", -}); - -program - .name("connect-cli") - .description("CLI for interacting with the Pipedream Connect API") - .version("1.0.0"); - -const handleError = (error: unknown, message: string) => { - if (error instanceof Error) { - console.error(`${message}:`, error.message); - } else { - console.error(`${message}:`, String(error)); - } -}; - -program - .command("list-project-info") - .description("List information about the project, including linked apps.") - .action(async () => { - try { - const projectInfo = await client.getProjectInfo(); - console.log(JSON.stringify(projectInfo, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch project info"); - } - }); - -program - .command("delete-account ") - .description("Delete an account by its ID.") - .action(async (accountId) => { - try { - await client.deleteAccount(accountId); - console.log(`Account with ID ${accountId} has been deleted.`); - } catch (error) { - handleError(error, "Failed to delete account"); - } - }); - -program - .command("delete-accounts-by-app ") - .description("Delete all accounts associated with a specific app.") - .action(async (appId) => { - try { - await client.deleteAccountsByApp(appId); - console.log(`All accounts associated with app ID ${appId} have been deleted.`); - } catch (error) { - handleError(error, "Failed to delete accounts by app"); - } - }); - -program - .command("delete-external-user ") - .description("Delete all accounts associated with a specific external ID.") - .action(async (externalId) => { - try { - await client.deleteExternalUser(externalId); - console.log(`All accounts associated with external ID ${externalId} have been deleted.`); - } catch (error) { - handleError(error, "Failed to delete external user"); - } - }); - -program - .command("create-connect-token ") - .description("Create a new Pipedream Connect token.") - .option("--success-redirect-uri ", "URL to redirect the user to upon successful connection") - .option("--error-redirect-uri ", "URL to redirect the user to upon failed connection") - .option("--webhook-uri ", "Webhook URI that Pipedream can invoke on success or failure of connection requests") - .option("--allowed-origins ", "Comma-separated list of allowed origins") - .action(async (externalUserId, options) => { - try { - const tokenResponse = await client.createConnectToken({ - external_user_id: externalUserId, - success_redirect_uri: options.successRedirectUri, - error_redirect_uri: options.errorRedirectUri, - webhook_uri: options.webhookUri, - allowed_origins: options.allowedOrigins - ? options.allowedOrigins.split(",") - : undefined, - }); - console.log(JSON.stringify(tokenResponse, null, 2)); - } catch (error) { - handleError(error, "Failed to create connect token"); - } - }); - -program - .command("get-accounts") - .description("Retrieve the list of accounts associated with the project.") - .option("--include-credentials ", "Include credentials in the response") - .action(async (options) => { - try { - const params = options.includeCredentials - ? { - include_credentials: options.includeCredentials, - } - : {}; - const accounts = await client.getAccounts(params); - console.log(JSON.stringify(accounts, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch accounts"); - } - }); - -program - .command("get-account-by-id ") - .description("Retrieve a specific account by ID.") - .action(async (accountId) => { - try { - const account = await client.getAccountById(accountId); - console.log(JSON.stringify(account, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch account by ID"); - } - }); - -program - .command("list-apps") - .description("Retrieve the list of apps.") - .option("--query ", "Query string to filter apps") - .action(async (options) => { - try { - const apps = await client.apps({ - q: options.query, - }); - console.log(JSON.stringify(apps, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch apps"); - } - }); - -program - .command("get-app ") - .description("Retrieve a specific app by ID or name slug.") - .action(async (idOrNameSlug) => { - try { - const app = await client.app(idOrNameSlug); - console.log(JSON.stringify(app, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch app"); - } - }); - -program - .command("list-components") - .description("Retrieve the list of components.") - .option("--app ", "Filter components by app") - .option("--query ", "Query string to filter components") - .option("--component-type ", "Filter components by type (trigger or action)") - .action(async (options) => { - try { - const components = await client.components({ - app: options.app, - q: options.query, - componentType: options.componentType, - }); - console.log(JSON.stringify(components, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch components"); - } - }); - -program - .command("get-component ") - .description("Retrieve a specific component by key.") - .action(async (key) => { - try { - const component = await client.component({ - key, - }); - console.log(JSON.stringify(component, null, 2)); - } catch (error) { - handleError(error, "Failed to fetch component"); - } - }); - -program - .command("configure-component") - .description("Configure a component.") - .requiredOption("--user-id ", "User ID") - .requiredOption("--component-id ", "Component ID") - .requiredOption("--prop-name ", "Property name") - .requiredOption("--configured-props ", "Configured properties as JSON string") - .option("--dynamic-props-id ", "Dynamic properties ID") - .action(async (options) => { - try { - const configuredProps = JSON.parse(options.configuredProps); - const response = await client.componentConfigure({ - userId: options.userId, - componentId: options.componentId, - propName: options.propName, - configuredProps, - dynamicPropsId: options.dynamicPropsId, - }); - console.log(JSON.stringify(response, null, 2)); - } catch (error) { - handleError(error, "Failed to configure component"); - } - }); - -program - .command("reload-component-props") - .description("Reload component properties.") - .requiredOption("--user-id ", "User ID") - .requiredOption("--component-id ", "Component ID") - .requiredOption("--configured-props ", "Configured properties as JSON string") - .option("--dynamic-props-id ", "Dynamic properties ID") - .action(async (options) => { - try { - const configuredProps = JSON.parse(options.configuredProps); - const response = await client.componentReloadProps({ - userId: options.userId, - componentId: options.componentId, - configuredProps, - dynamicPropsId: options.dynamicPropsId, - }); - console.log(JSON.stringify(response, null, 2)); - } catch (error) { - handleError(error, "Failed to reload component properties"); - } - }); - -program - .command("run-action") - .description("Run an action.") - .requiredOption("--user-id ", "User ID") - .requiredOption("--action-id ", "Action ID") - .requiredOption("--configured-props ", "Configured properties as JSON string") - .option("--dynamic-props-id ", "Dynamic properties ID") - .action(async (options) => { - try { - const configuredProps = JSON.parse(options.configuredProps); - const response = await client.actionRun({ - userId: options.userId, - actionId: options.actionId, - configuredProps, - dynamicPropsId: options.dynamicPropsId, - }); - console.log(JSON.stringify(response, null, 2)); - } catch (error) { - handleError(error, "Failed to run action"); - } - }); - -// Parse and execute commands -program.parse(process.argv); diff --git a/packages/sdk/src/server/index.ts b/packages/sdk/src/server/index.ts deleted file mode 100644 index 610f424652b4f..0000000000000 --- a/packages/sdk/src/server/index.ts +++ /dev/null @@ -1,491 +0,0 @@ -// This code is meant to be run server-side, where you can securely store your -// Pipedream project's public and secret keys and access customer credentials. -// See the browser/ directory for the browser client. - -import * as oauth from "oauth4webapi"; -import { - Account, BaseClient, type AppInfo, type ConnectTokenResponse, type RequestOptions, -} from "../shared/index.js"; -export * from "../shared/index.js"; - -/** - * OAuth credentials for your Pipedream account, containing client ID and - * secret. - */ -export type OAuthCredentials = { - clientId: string; - clientSecret: string; -}; - -/** - * The environment in which the server client is running. - */ -export type ProjectEnvironment = "development" | "production"; - -/** - * Options for creating a server-side client. - * This is used to configure the ServerClient instance. - */ -export type BackendClientOpts = { - /** - * The environment in which the server client is running (e.g., "production", - * "development"). - */ - environment?: ProjectEnvironment; - - /** - * The credentials to use for authentication against the Pipedream API. - */ - credentials: OAuthCredentials | { - accessToken: string; - }; - - /** - * The base project ID tied to relevant API requests - */ - projectId: string; - - /** - * The API host URL. Used by Pipedream employees. Defaults to - * "api.pipedream.com" if not provided. - */ - apiHost?: string; - - /** - * Base domain for workflows. Used for custom domains: - * https://pipedream.com/docs/workflows/domains - */ - workflowDomain?: string; - - /** - * OAuth scope to request when obtaining access tokens - */ - scope?: string[]; -}; - -/** - * Options for creating a Connect token. - */ -export type ConnectTokenCreateOpts = { - /** - * The ID of the user in your system. - */ - external_user_id: string; - - /** - * The optional url to redirect the user to upon successful connection. - */ - success_redirect_uri?: string; - - /** - * The optional url to redirect the user to upon failed connection. - */ - error_redirect_uri?: string; - - /** - * An optional webhook uri that Pipedream can invoke on success or failure of - * connection requests. - */ - webhook_uri?: string; - - /** - * Specify which origins can use the token to call the Pipedream API. - */ - allowed_origins?: string[]; -}; - -/** - * Response received after requesting a project's info. - */ -export type ProjectInfoResponse = { - /** - * An array of apps linked to the project. - */ - apps: AppInfo[]; -}; - -/** - * Parameters for the retrieval of an account from the Connect API - */ -export type GetAccountByIdOpts = { - /** - * Whether to retrieve the account's credentials or not. - */ - include_credentials?: boolean; -}; - -/** - * Options used to determine the external user and account to be used in Connect Proxy API - */ -export type ProxyApiOpts = { - /** - * Search parameters to be added to the proxy request. external_user_id and account_id are required. - */ - searchParams: Record; -}; - -/** - * fetch-like options for the Target of the Connect Proxy Api Request - */ -export type ProxyTargetApiOpts = { - /** - * http method for the request - */ - method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; - /** - * http headers for the request - */ - headers?: Record; - /** - * http body for the request - */ - body?: string; -}; - -/** - * object that contains the url and options for the target of the Connect Proxy Api Request - */ -export type ProxyTargetApiRequest = { - /** - * URL for the target of the request. Search parameters must be included here. - */ - url: string; - /** - * fetch-like options for the target of the Connect Proxy Request - */ - options: ProxyTargetApiOpts; -}; - -/** - * The parsed response body from a proxied API request. - * - * If the response has a Content-Type of application/json, the body will be parsed - * and returned as an object. Otherwise the type will be a string. - */ -export type ProxyResponse = Record | string; - -/** - * Creates a new instance of BackendClient with the provided options. - * - * @example - * - * ```typescript - const serverClient = createBackendClient({ - environment: "development", - projectId: "", - credentials: { - clientId: "", - clientSecret: "", - }, - }) - * ``` - * - * @param opts - The options for creating the server client. - * @returns A new instance of ServerClient. - */ -export function createBackendClient(opts: BackendClientOpts) { - return new BackendClient(opts); -} - -/** - * A client for interacting with the Pipedream Connect API on the server-side. - */ -export class BackendClient extends BaseClient { - private oauthClient: { - client: oauth.Client - clientAuth: oauth.ClientAuth - as: oauth.AuthorizationServer - } | undefined; - private oauthAccessToken?: { - token: string - expiresAt: number - }; - protected override projectId: string = ""; - private staticAccessToken?: string; - private scope?: string[]; - - /** - * Constructs a new ServerClient instance. - * - * @param opts - The options for configuring the server client. - * @param oauthClient - An optional OAuth client to use for authentication in tests - */ - constructor(opts: BackendClientOpts) { - super(opts); - - this.ensureValidEnvironment(opts.environment); - this.projectId = opts.projectId; - this.scope = opts.scope; - if ("accessToken" in opts.credentials) { - this.staticAccessToken = opts.credentials.accessToken; - } else { - this.oauthClient = this.newOauthClient(opts.credentials, this.apiHost); - } - } - - private ensureValidEnvironment(environment?: string) { - if (!environment || ![ - "development", - "production", - ].includes(environment)) { - throw new Error( - "Project environment is required. Supported environments are development and production.", - ); - } - } - - private newOauthClient( - { - clientId, clientSecret, - }: OAuthCredentials, - tokenHost: string, - ) { - if (!clientId || !clientSecret) { - throw new Error("OAuth client ID and secret are required"); - } - const client: oauth.Client = { - client_id: clientId, - } - const clientAuth = oauth.ClientSecretPost(clientSecret) - const as: oauth.AuthorizationServer = { - issuer: tokenHost, - token_endpoint: `https://${tokenHost}/v1/oauth/token`, - } - return { - client, - clientAuth, - as, - } - } - - /** - * Returns the raw access token string or a promise resolving to it. - * This can be used when you need the token directly without Authorization header formatting. - * - * @returns A string or promise resolving to the access token. - */ - public rawAccessToken(): string | Promise { - if (this.staticAccessToken) { - return this.staticAccessToken; - } - return this.ensureValidOauthAccessToken(); - } - - protected authHeaders(): string | Promise { - if (this.staticAccessToken) { - return `Bearer ${this.staticAccessToken}`; - } - return this.oauthAuthorizationHeader(); - } - - private async ensureValidOauthAccessToken(): Promise { - if (!this.oauthClient) { - throw new Error("OAuth client not configured") - } - const { - client, - clientAuth, - as, - } = this.oauthClient - - let attempts = 0; - const maxAttempts = 2; - - while (!this.oauthAccessToken || this.oauthAccessToken.expiresAt - Date.now() < 1000) { - if (attempts > maxAttempts) { - throw new Error("ran out of attempts trying to retrieve oauth access token"); - } - if (attempts > 0) { - // Wait for a short duration before retrying to avoid rapid retries - await new Promise((resolve) => setTimeout(resolve, 100)); - } - - const parameters = new URLSearchParams(); - if (this.scope && this.scope.length > 0) { - parameters.set("scope", this.scope.join(" ")); - } - parameters.set("project_id", this.projectId); - parameters.set("environment", this.environment); - try { - const response = await oauth.clientCredentialsGrantRequest(as, client, clientAuth, parameters); - const oauthTokenResponse = await oauth.processClientCredentialsResponse(as, client, response); - this.oauthAccessToken = { - token: oauthTokenResponse.access_token, - expiresAt: Date.now() + (oauthTokenResponse.expires_in || 0) * 1000, - }; - } catch { - // pass - } - - attempts++; - } - - return this.oauthAccessToken.token; - } - - private async oauthAuthorizationHeader(): Promise { - const accessToken = await this.ensureValidOauthAccessToken(); - - return `Bearer ${accessToken}`; - } - - /** - * Creates a new Pipedream Connect token. See - * https://pipedream.com/docs/connect/quickstart#connect-to-the-pipedream-api-from-your-server-and-create-a-token - * - * @param opts - The options for creating the connect token. - * @returns A promise resolving to the connect token response. - * - * @example - * - * ```typescript - * const tokenResponse = await client.connectTokenCreate({ - * external_user_id: "external-user-id", }); - * console.log(tokenResponse.token); - * ``` - */ - public createConnectToken( - opts: ConnectTokenCreateOpts, - ): Promise { - const body = { - ...opts, - external_id: opts.external_user_id, - }; - return this.makeConnectRequest("/tokens", { - method: "POST", - body, - }); - } - - /** - * Retrieves a specific account by ID. - * - * @param accountId - The ID of the account to retrieve. - * @param params - Additional options for the request. - * @returns A promise resolving to the account. - * - * @example - * ```typescript - * const account = await client.getAccountById("account-id"); - * console.log(account); - * ``` - * - * @example - * ```typescript - * const account = await client.getAccountById("account-id", { - * include_credentials: true, - * }); - * console.log(account); - * ``` - */ - public getAccountById( - accountId: string, - params: GetAccountByIdOpts = {}, - ): Promise { - return this.makeConnectRequest(`/accounts/${accountId}`, { - method: "GET", - params, - }); - } - - /** - * Deletes a specific account by ID. - * - * @param accountId - The ID of the account to delete. - * @returns A promise resolving when the account is deleted. - * - * @example - * ```typescript - * await client.deleteAccount("account-id"); - * console.log("Account deleted"); - * ``` - */ - public deleteAccount(accountId: string): Promise { - return this.makeConnectRequest(`/accounts/${accountId}`, { - method: "DELETE", - }); - } - - /** - * Deletes all accounts associated with a specific app. - * - * @param appId - The ID of the app. - * @returns A promise resolving when all accounts are deleted. - * - * @example - * ```typescript - * await client.deleteAccountsByApp("app-id"); - * console.log("All accounts deleted"); - * ``` - */ - public deleteAccountsByApp(appId: string): Promise { - return this.makeConnectRequest(`/accounts/app/${appId}`, { - method: "DELETE", - }); - } - - /** - * Deletes all accounts associated with a specific external ID. - * - * @param externalId - The external ID associated with the accounts. - * @returns A promise resolving when all accounts are deleted. - * - * @example - * ```typescript - * await client.deleteExternalUser("external-id"); - * console.log("All accounts deleted"); - * ``` - */ - public deleteExternalUser(externalId: string): Promise { - return this.makeConnectRequest(`/users/${externalId}`, { - method: "DELETE", - }); - } - - /** - * Retrieves the project's information, such as the list of apps linked to it. - * - * @returns A promise resolving to the project info response. - * - * @example - * ```typescript - * const projectInfo = await client.getProjectInfo(); - * console.log(projectInfo); - * ``` - */ - public getProjectInfo(): Promise { - return this.makeConnectRequest("/projects/info", { - method: "GET", - }); - } - - /** - * Makes a proxy request to the target app API with the specified query parameters and options. - * - * @returns A promise resolving to the response from the downstream service - */ - public makeProxyRequest(proxyOptions: ProxyApiOpts, targetRequest: ProxyTargetApiRequest): Promise { - const url64 = btoa(targetRequest.url).replace(/\+/g, "-") - .replace(/\//g, "_") - .replace(/=+$/, ""); - - const headers = targetRequest.options.headers || {}; - - const newHeaders = Object.keys(headers).reduce<{ [key: string]: string }>((acc, key) => { - acc[`x-pd-proxy-${key}`] = headers[key]; - return acc; - }, {}); - - const newOpts: RequestOptions = { - method: targetRequest.options.method, - headers: newHeaders, - params: proxyOptions.searchParams, - } - - if (targetRequest.options.body) { - newOpts.body = targetRequest.options.body - } - - return this.makeConnectRequest(`/proxy/${url64}`, newOpts); - } -} diff --git a/packages/sdk/src/shared/component.ts b/packages/sdk/src/shared/component.ts deleted file mode 100644 index 08aecefbc770f..0000000000000 --- a/packages/sdk/src/shared/component.ts +++ /dev/null @@ -1,279 +0,0 @@ -// eslint-disable @typescript-eslint/no-explicit-any -type BaseConfigurableProp = { - /** - * When building `configuredProps`, make sure to use this field as the key when - * setting the prop value. - */ - name: string; - type: string; - - // XXX don't actually apply to all, fix - - /** - * Value to use as an input label. In cases where `type` is "app", should load - * the app via `getApp`, etc. and show `app.name` instead. - */ - label?: string; - - description?: string; - optional?: boolean; - disabled?: boolean; - - /** - * If true, should not expose this prop to the user. - */ - hidden?: boolean; - - /** - * If true, call `configureComponent` for this prop to load remote options. - * It is safe, and preferred, given a returned list of - * { label: string; value: any } objects to set the prop - * value to { __lv: { label: string; value: any } }. This way, on load, you - * can access label for the value without necessarily reloading these options. - */ - remoteOptions?: boolean; - - /** - * If true, calls to `configureComponent` for this prop support receiving a - * `query` parameter to filter remote options. - */ - useQuery?: boolean; - - /** - * If true, after setting a value for this prop, a call to `reloadComponentProps` is - * required as the component has dynamic configurable props dependent on this - * one. - */ - reloadProps?: boolean; - - /** - * If true, you must save the configured prop value as a "label-value" object - * which should look like: { __lv: { label: string; value: any } } - * because the execution needs to access the label. - */ - withLabel?: boolean; -}; - -// XXX fix duplicating mapping to value type here and with PropValue - -type LabelValueOption = { - label: string; - value: T; -}; - -type Defaultable = { - default?: T; - options?: SingleT[] | Array>; -} - -export type ConfigurablePropAlert = BaseConfigurableProp & { - type: "alert"; - alertType?: "info" | "neutral" | "warning" | "error"; // TODO check the types - content: string; -}; - -export type ConfigurablePropAny = BaseConfigurableProp & { - type: "any"; -} & Defaultable; // eslint-disable-line @typescript-eslint/no-explicit-any - -export type ConfigurablePropApp = BaseConfigurableProp & { - type: "app"; - app: string; -}; - -export type ConfigurablePropBoolean = BaseConfigurableProp & { - type: "boolean"; -} & Defaultable; - -export type ConfigurablePropInteger = BaseConfigurableProp & { - type: "integer"; - min?: number; - max?: number; -} & Defaultable; - -export type ConfigurablePropObject = BaseConfigurableProp & { - type: "object"; -} & Defaultable; - -export type ConfigurablePropString = BaseConfigurableProp & { - type: "string"; - secret?: boolean; -} & Defaultable; - -export type ConfigurablePropStringArray = BaseConfigurableProp & { - type: "string[]"; - secret?: boolean; // TODO is this supported -} & Defaultable; - -export type TimerInterval = { - intervalSeconds: number; -} - -export type TimerCron = { - cron: string; -} - -export type ConfigurablePropTimer = BaseConfigurableProp & { - type: "$.interface.timer"; - static?: TimerInterval | TimerCron; -} & Defaultable; - -export type ConfigurablePropApphook = BaseConfigurableProp & { - type: "$.interface.apphook"; - appProp: string; - eventNames?: Array; - remote?: boolean; - static?: Array; -} - -export type ConfigurablePropIntegerArray = BaseConfigurableProp & { - type: "integer[]"; - min?: number; - max?: number; -} & Defaultable - -export type ConfigurablePropHttp = BaseConfigurableProp & { - type: "$.interface.http"; - customResponse?: boolean; -} - -export type ConfigurablePropDb = BaseConfigurableProp & { - type: "$.service.db"; -} - -export type ConfigurablePropSql = BaseConfigurableProp & { - type: "sql"; - auth?: { - app: string; - }; -} & Defaultable; - -export type ConfigurablePropAirtableBaseId = BaseConfigurableProp & { - type: "$.airtable.baseId"; - appProp: string; -} - -export type ConfigurablePropAirtableTableId = BaseConfigurableProp & { - type: "$.airtable.tableId"; - baseIdProp: string; -} - -export type ConfigurablePropAirtableViewId = BaseConfigurableProp & { - type: "$.airtable.viewId"; - tableIdProp: string; -} - -export type ConfigurablePropAirtableFieldId = BaseConfigurableProp & { - type: "$.airtable.fieldId"; - tableIdProp: string; -} - -export type ConfigurablePropDiscordChannel = BaseConfigurableProp & { - type: "$.discord.channel"; - appProp: string; -} - -export type ConfigurablePropDiscordChannelArray = BaseConfigurableProp & { - type: "$.discord.channel[]"; - appProp: string; -} - -export type ConfigurableProp = - | ConfigurablePropAirtableBaseId - | ConfigurablePropAirtableFieldId - | ConfigurablePropAirtableTableId - | ConfigurablePropAirtableViewId - | ConfigurablePropAlert - | ConfigurablePropAny - | ConfigurablePropApp - | ConfigurablePropApphook - | ConfigurablePropBoolean - | ConfigurablePropDb - | ConfigurablePropDiscordChannel - | ConfigurablePropDiscordChannelArray - | ConfigurablePropHttp - | ConfigurablePropInteger - | ConfigurablePropIntegerArray - | ConfigurablePropObject - | ConfigurablePropSql - | ConfigurablePropString - | ConfigurablePropStringArray - | ConfigurablePropTimer - -export type ConfigurableProps = Readonly; - -export type PropValue = T extends "alert" - ? never - : T extends "any" - ? any // eslint-disable-line @typescript-eslint/no-explicit-any - : T extends "app" - ? { authProvisionId: string; } - : T extends "boolean" - ? boolean - : T extends "integer" - ? number - : T extends "object" - ? object - : T extends "string" - ? string - : T extends "string[]" - ? string[] // XXX support arrays differently? - : T extends "sql" - ? { app: string; query: string; params: unknown[]; } - : never; - -export type ConfiguredProps = { - [K in T[number] as K["name"]]?: PropValue -}; - -// as returned by API (configurable_props_json from `afterSave`) -export type V1Component = { // eslint-disable-line @typescript-eslint/no-explicit-any - name: string; - key: string; - version: string; - configurable_props: T; - description?: string; - component_type?: string; - stash?: "optional" | "required"; -}; - -export type V1DeployedComponent = { // eslint-disable-line @typescript-eslint/no-explicit-any - id: string; - owner_id: string; - component_id: string; - configurable_props: T; - configured_props: ConfiguredProps; - active: boolean; - created_at: number; - updated_at: number; - name: string; - name_slug: string; - callback_observations?: unknown; - - /** - * The URL to the HTTP interface of this component, if it has one. - */ - endpoint_url?: string; -}; - -export type V1EmittedEvent = { - /** - * The event's payload. - */ - e: Record; // eslint-disable-line @typescript-eslint/no-explicit-any - - /** - * The event's type (set to "emit" currently). - */ - k: string; - - /** - * The event's timestamp in epoch milliseconds. - */ - ts: number; - - /** - * The event's unique ID. - */ - id: string; -} diff --git a/packages/sdk/src/shared/index.ts b/packages/sdk/src/shared/index.ts deleted file mode 100644 index 7486d34b1ed72..0000000000000 --- a/packages/sdk/src/shared/index.ts +++ /dev/null @@ -1,2041 +0,0 @@ -// This code is meant to be shared between the browser and server. -import type { - ConfigurableProps, - ConfiguredProps, - V1Component, - V1DeployedComponent, - V1EmittedEvent, -} from "./component.js"; -export * from "./component.js"; -import { version as sdkVersion } from "../version.js"; - -type RequireAtLeastOne = - Pick> - & { - [K in Keys]-?: Required> & Partial>> - }[Keys] - -// Using `RequireAtLeastOne` here prevents the renaming of the attribute to -// break existing SDK users, by keeping the old attribute name, while ensuring -// that at least one of the two attributes is present. -type ExternalUserId = RequireAtLeastOne<{ - /** - * Your end user ID, for whom you're configuring the component. - */ - externalUserId: string; - - /** - * @deprecated Use `externalUserId` instead. - */ - userId: string; -}, "externalUserId" | "userId">; - -type RequestInit = globalThis.RequestInit; - -/** - * Options for creating a server-side client. - * This is used to configure the BackendClient instance. - */ -export type ClientOpts = { - /** - * The environment in which the server client is running (e.g., "production", - * "development"). - */ - environment?: string; - - /** - * The API host URL. Used by Pipedream employees. Defaults to - * "api.pipedream.com" if not provided. - */ - apiHost?: string; - - /** - * Base domain for workflows. Used for custom domains: - * https://pipedream.com/docs/workflows/domains - */ - workflowDomain?: string; -}; - -/** - * Basic ID information of a Pipedream app. - */ -export type AppInfo = { - /** - * ID of the app. Only applies for OAuth apps. - */ - id?: string; - - /** - * The name slug of the target app (see - * https://pipedream.com/docs/connect/quickstart#find-your-apps-name-slug) - */ - name_slug: string; -}; - -/** - * The types of authentication that Pipedream apps support. - */ -export enum AppAuthType { - OAuth = "oauth", - Keys = "keys", - None = "none", -} - -/** - * Response object for a Pipedream app's metadata - */ -export type App = AppInfo & { - /** - * The human-readable name of the app. - */ - name: string; - - /** - * A short description of the app. - */ - description: string; - - /** - * The authentication type used by the app. - */ - auth_type: AppAuthType; - - /** - * The URL to the app's logo. - */ - img_src: string; - - /** - * A JSON string representing the custom fields for the app. - */ - custom_fields_json: string; - - /** - * Categories associated with the app. - */ - categories: string[]; - - /** - * A rough directional ordering of app popularity, subject to changes by Pipedream. - */ - featured_weight: number -}; - -/** - * @deprecated Use `App` instead. - */ -export type AppResponse = App; - -/** - * App category data returned from the API. - */ -export type AppCategory = { - /** - * The unique ID of the category. - */ - id: string; - - /** - * The name of the category. - */ - name: string; - - /** - * A description of the category. - */ - description: string; -}; - -/** - * The response received when retrieving app categories. - */ -export type GetAppCategoriesResponse = AppCategory[]; - -/** - * A configuration option for a component's prop. - */ -export type PropOption = { - label: string; - value: string; -}; - -type ConfigureComponentContext = Record - -/** - * The response received after configuring a component's prop. - */ -export type ConfigureComponentResponse = { - /** - * The options for the prop that's being configured. This field is applicable - * when the values don't nicely map to a descriptive string. Useful when the - * values for each option are meaningless numeric IDs, unless mapped to a - * human-readable string. - * - * @example a branch with ID `21208123` and name `my-repo/foo` in a Gitlab - * repo - * ```json - * { - * "label": "my-repo/foo", - * "value": 21208123 - * } - * ``` - */ - options: PropOption[]; - - /** - * The options for the prop that's being configured. This field is applicable - * when the values themselves are already human-readable strings. - */ - stringOptions: string[]; - - /** - * A list of errors that occurred during the configuration process. - */ - errors: string[]; - - /** - * The context object resolved in the options execution (useful for pagination, etc.). - * See {@link ConfigureComponentOpts.prevContext}. - */ - context?: ConfigureComponentContext -}; - -/** - * Attributes to use for pagination in API requests. - */ -export type RelationOpts = { - /** - * The retrieve records starting from a certain cursor. - */ - after?: string; - - /** - * To retrieve records up until a certain cursor. - */ - before?: string; - - /** - * The maximum number of records to retrieve. - */ - limit?: number; -}; - -/** - * Pagination attributes for API responses. - */ -export type ResponsePageInfo = { - /** - * The total number of records available. - */ - total_count: number; - - /** - * The number of records returned in the current response. - */ - count: number; - - /** - * The cursor to retrieve the next page of records. - */ - start_cursor: string; - - /** - * The cursor of the last page of records. - */ - end_cursor: string; -}; - -/** - * The response attributes for paginated API responses. - */ -export type PaginationResponse = { - /** - * The pagination information for the response. - */ - page_info: ResponsePageInfo; -} - -/** - * @deprecated Use `ConfigureComponentResponse` instead. - */ -export type ComponentConfigureResponse = ConfigureComponentResponse; - -/** - * Parameters for the retrieval of apps from the Connect API - */ -export type GetAppsOpts = RelationOpts & { - /** - * A search query to filter the apps. - */ - q?: string; - /** - * Filter by whether apps have actions in the component registry. - */ - hasActions?: boolean; - /** - * Filter by whether apps have components in the component registry. - */ - hasComponents?: boolean; - /** - * Filter by whether apps have triggers in the component registry. - */ - hasTriggers?: boolean; - /** - * Filter apps by category IDs (format: appcat_[a-zA-Z0-9]+). - */ - categoryIds?: string[]; - /** - * The key to sort the apps by. - * - * @default "name_slug" - */ - sortKey?: "name" | "featured_weight" | "name_slug"; - /** - * The direction to sort the apps. - * - * @default "asc" - */ - sortDirection?: "asc" | "desc"; -}; - -/** - * Parameters for the retrieval of accounts from the Connect API - */ -export type GetAccountOpts = RelationOpts & { - /** - * The ID or name slug of the app, in case you want to only retrieve the - * accounts for a specific app. - */ - app?: string; - - /** - * The ID of the app (if it's an OAuth app), in case you want to only retrieve - * the accounts for a specific app. - */ - oauth_app_id?: string; - - /** - * Whether to retrieve the account's credentials or not. - */ - include_credentials?: boolean; - - /** - * The external user ID associated with the account. - */ - external_user_id?: string; -}; - -/** - * End user account data, returned from the API. - */ -export type Account = { - /** - * The unique ID of the account. - */ - id: string; - - /** - * The name of the account. - */ - name: string; - - /** - * The external ID associated with the account. - */ - external_id: string; - - /** - * Indicates if the account is healthy. Pipedream will periodically retry - * token refresh and test requests for unhealthy accounts. - */ - healthy: boolean; - - /** - * Indicates if the account is no longer active. - */ - dead: boolean; - - /** - * The app associated with the account. - */ - app: AppResponse; - - /** - * The date and time the account was created, an ISO 8601 formatted string. - */ - created_at: string; - - /** - * The date and time the account was last updated, an ISO 8601 formatted - * string. - */ - updated_at: string; - - /** - * The credentials associated with the account, if the `include_credentials` - * parameter was set to true in the request. - */ - credentials?: Record; -}; - -/** - * The request options for reloading a component's props when dealing with - * dynamic props. - */ -export type ReloadComponentPropsOpts = ExternalUserId & { - /** - * The ID of the component you're configuring. This is the key that uniquely - * identifies the component. - */ - componentId: string | ComponentId; - - /** - * The props that have already been configured for the component. This is a - * JSON-serializable object with the prop names as keys and the configured - * values as values. - */ - configuredProps: ConfiguredProps; - - /** - * The ID of the last prop reload (or none when reloading the props for the - * first time). - */ - dynamicPropsId?: string; -}; - -export type ReloadComponentPropsResponse = { - // XXX observations - - /** - * A list of errors that occurred during the prop reloading process. - */ - errors: string[] - - /** - * Dynamic props object containing the dynamic props ID and the dynamic - * configurable props for the component. - */ - dynamicProps: { - id: string - configurableProps: ConfigurableProps - } -} - -/** - * @deprecated Use `ReloadComponentPropsOpts` instead. - */ -export type ComponentReloadPropsOpts = ReloadComponentPropsOpts; - -/** - * The request options for configuring a component's prop. - */ -export type ConfigureComponentOpts = ExternalUserId & { - /** - * The ID of the component you're configuring. This is the key that uniquely - * identifies the component. - */ - componentId: string | ComponentId; - - /** - * The name of the prop you're configuring. - */ - propName: string; - - /** - * The props that have already been configured for the component. This is a - * JSON-serializable object with the prop names as keys and the configured - * values as values. - */ - configuredProps: ConfiguredProps; - - /** - * The ID of the last prop reconfiguration (if any). - */ - dynamicPropsId?: string; - - /** - * A string with the user input if the prop has the useQuery property set to - * true. Use with APIs that return items based on a query or search parameter. - */ - query?: string; - - /** - * A 0 indexed page number. Use with APIs that accept a - * numeric page number for pagination. - */ - page?: number; - - /** - * The context object from the previous options execution (useful for pagination, etc.). - * See {@link ConfigureComponentResponse.context}. - */ - prevContext?: ConfigureComponentContext; -}; - -/** - * @deprecated Use `ConfigureComponentOpts` instead. - */ -export type ComponentConfigureOpts = ConfigureComponentOpts; - -/** - * The request options for retrieving a list of components. - */ -export type GetComponentsOpts = RelationOpts & { - /** - * A search query to filter the components. - */ - q?: string; - - /** - * The ID or name slug of the app to filter the components. - */ - app?: string; - - /** - * The type of component to filter (either "trigger" or "action"). - */ - componentType?: ComponentType; -}; - -/** - * @deprecated Use `GetComponentsOpts` instead. - */ -export type GetComponentOpts = GetComponentsOpts; - -/** - * An object that identifies a single, unique component in Pipedream. - */ -export type ComponentId = { - /** - * The key that uniquely identifies the component. - * - * @example "gitlab-list-commits" - * @example "slack-send-message" - */ - key: string; -}; - -/** - * Components can be either triggers or actions. - */ -export type ComponentType = "trigger" | "action"; - -/** - * Response received after creating a connect token. - */ -export type ConnectTokenResponse = { - /** - * The generated token. - */ - token: string; - - /** - * The expiration time of the token in ISO 8601 format. - */ - expires_at: string; - - /** - * The Connect Link URL - */ - connect_link_url: string; -}; - -/** - * The response received when retrieving a list of accounts. - */ -export type GetAccountsResponse = PaginationResponse & { - data: Account[]; -}; - -/** - * @deprecated Use `GetAccountsResponse` instead. - */ -export type AccountsRequestResponse = GetAccountsResponse; - -/** - * The response received when retrieving a list of apps. - */ -export type GetAppsResponse = PaginationResponse & { - data: App[]; -}; - -/** - * @deprecated Use `GetAppsResponse` instead. - */ -export type AppsRequestResponse = GetAppsResponse; - -/** - * The response received when retrieving a specific app. - */ -export type GetAppResponse = { data: App; }; - -/** - * @deprecated Use `GetAppResponse` instead. - */ -export type AppRequestResponse = GetAppResponse; - -/** - * The response received when retrieving a list of components. - */ -export type GetComponentsResponse = PaginationResponse & { - data: V1Component[]; -}; - -/** - * @deprecated Use `GetComponentsResponse` instead. - */ -export type ComponentsRequestResponse = GetComponentsResponse; - -/** - * The response received when retrieving a specific component. - */ -export type GetComponentResponse = { data: V1Component; }; - -/** - * @deprecated Use `GetComponentResponse` instead. - */ -export type ComponentRequestResponse = GetComponentResponse; - -/** - * The request options for running an action. - */ -export type RunActionOpts = ExternalUserId & { - /** - * The ID of the action you're running. This is the key that uniquely - * identifies the action. - */ - actionId: string | ComponentId; - - /** - * The props that have already been configured for the action. This is a - * JSON-serializable object with the prop names as keys and the configured - * values as values. - */ - configuredProps: ConfiguredProps; - - /** - * The ID of the last prop reconfiguration (if any). - */ - dynamicPropsId?: string; - - /** - * The ID of the File Stash to sync the action's /tmp directory with. This - * allows you to persist files across action runs for up to 1 day. If set to - * `true` or "", a unique stash ID will be generated for you and returned in - * the response. If not set, the action will not sync its /tmp directory with - * a File Stash. - */ - stashId?: string | boolean; -}; - -/** - * The response received after running an action. See - * https://pipedream.com/docs/components/api#returning-data-from-steps for more - * details. - */ -export type RunActionResponse = { - /** - * The key-value pairs resulting from calls to `$.export` - */ - exports: unknown; - - /** - * Any logs produced during the execution of the action - */ - os: unknown[]; - - /** - * The value returned by the action - */ - ret: unknown; - - /** - * The ID of the File Stash that was used to sync the action's /tmp directory - */ - stashId?: string; -}; - -/** - * The request options for deploying a trigger. - */ -export type DeployTriggerOpts = ExternalUserId & { - /** - * The ID of the trigger you're deploying. This is the key that uniquely - * identifies the trigger. - */ - triggerId: string | ComponentId; - - /** - * The props that have already been configured for the trigger. This is a - * JSON-serializable object with the prop names as keys and the configured - * values as values. - */ - configuredProps: ConfiguredProps; - - /** - * The ID of the last prop reconfiguration (if any). - */ - dynamicPropsId?: string; - - /** - * The ID of the workflow that the trigger will use to send the events it - * generates. - */ - workflowId?: string; - - /** - * The webhook URL that the trigger will use to send the events it generates. - */ - webhookUrl?: string; -}; - -/** - * The response received after deploying a trigger. - */ -export type DeployTriggerResponse = { - /** - * The contents of the deployed trigger. - */ - data: V1DeployedComponent; -} - -/** - * The request options for deleting a deployed trigger owned by a particular - * user. - */ -export type DeleteTriggerOpts = { - /** - * The ID of the trigger you're deleting (`dc_xxxxxxx` for example ). - */ - id: string; - - /** - * The end user ID, for whom you deployed the trigger. - */ - externalUserId: string; - - /** - * When explicitly set, the API will ignore any errors that occur during the - * deactivation hook of the trigger, effectively forcing the deletion of the - * trigger. - */ - ignoreHookErrors?: boolean; -}; - -/** - * The request options for retrieving a deployed trigger owned by a particular - * user. - */ -export type GetTriggerOpts = { - /** - * The ID of the trigger you're retrieving. - */ - id: string; - - /** - * Your end user ID, for whom you deployed the trigger. - */ - externalUserId: string; -}; - -/** - * The response received after retrieving a deployed trigger. - */ -export type GetTriggerResponse = { - /** - * The contents of the deployed trigger. - */ - data: V1DeployedComponent; -}; - -/** - * The request options for retrieving the events emitted by a deployed trigger. - */ -export type GetTriggerEventsOpts = GetTriggerOpts & { - /** - * The number of events to retrieve (defaults to 20 if not provided). - */ - limit?: number; -}; - -/** - * The response from retrieving the events emitted by a deployed trigger. - */ -export type GetTriggerEventsResponse = { - /** - * The list of events emitted by the trigger. - */ - data: V1EmittedEvent[]; -}; - -/** - * The request options for retrieving the workflows that listen to events - * emitted by a specific trigger. - */ -export type GetTriggerWorkflowsOpts = GetTriggerOpts; - -/** - * The response from retrieving the workflows that listen to events emitted by a - * specific trigger. - */ -export type GetTriggerWorkflowsResponse = { - /** - * The list of workflow IDs that listen to events emitted by the trigger. - */ - workflow_ids: string[]; -}; - -/** - * The request options for updating the workflows that listen to events emitted - * by a specific trigger. - */ -export type UpdateTriggerWorkflowsOpts = GetTriggerOpts & { - /** - * The workflow IDs that should to events emitted by the trigger. - */ - workflowIds: string[]; -} - -/** - * The request options for retrieving the webhooks that listen to events - * emitted by a specific trigger. - */ -export type GetTriggerWebhooksOpts = GetTriggerOpts; - -/** - * The response from retrieving the webhooks that listen to events emitted by a - * specific trigger. - */ -export type GetTriggerWebhooksResponse = { - /** - * The list of webhook URLs that listen to events emitted by the trigger. - */ - webhook_urls: string[]; -}; - -/** - * The request options for updating the webhooks that listen to events emitted - * by a specific trigger. - */ -export type UpdateTriggerWebhooksOpts = GetTriggerOpts & { - /** - * The webhook URLs that should to events emitted by the trigger. - */ - webhookUrls: string[]; -} - -/** - * The request options for retrieving a list of deployed triggers for a - * particular user. - */ -export type GetTriggersOpts = RelationOpts & { - /** - * Your end user ID, for whom you deployed the trigger. - */ - externalUserId: string; -}; - -/** - * The response received after retrieving a list of deployed triggers. - */ -export type GetTriggersResponse = PaginationResponse & { - /** - * The list of deployed triggers. - */ - data: V1DeployedComponent[]; -}; - -/** - * The request options for updating a trigger. - */ -export type UpdateTriggerOpts = { - /** - * The ID of the trigger you're updating. - */ - id: string; - - /** - * Your end user ID, for whom you deployed the trigger. - */ - externalUserId: string; - - /** - * The state to which the trigger should be updated. - */ - active?: boolean; - - /** - * The props that have already been configured for the trigger. This is a - * JSON-serializable object with the prop names as keys and the configured - * values as values. - */ - configuredProps?: ConfiguredProps; - - /** - * The new name of the trigger. - */ - name?: string; -}; - -/** - * Different ways in which customers can authorize requests to HTTP endpoints - */ -export enum HTTPAuthType { - None = "none", - StaticBearer = "static_bearer_token", - OAuth = "oauth", -} - -/** - * Error response returned by the API in case of an error. - */ -export type ErrorResponse = { - /** - * The error message returned by the API. - */ - error: string; -}; - -/** - * A generic API response that can either be a success or an error. - */ -export type ConnectAPIResponse = T | ErrorResponse; - -/** - * Options for making a request to the Pipedream API. - */ -export interface RequestOptions extends Omit { - /** - * Query parameters to include in the request URL. - */ - params?: Record; - - /** - * Headers to include in the request. - */ - headers?: Record; - - /** - * The URL to make the request to. - */ - baseURL?: string; - - /** - * The body of the request. - */ - body?: Record | string | FormData | URLSearchParams | null; -} - -export interface AsyncRequestOptions extends RequestOptions { - body: { async_handle: string; } & Required; -} - -const SENSITIVE_KEYS = [ - "token", - "password", - "secret", - "apiKey", - "authorization", - "auth", - "key", - "access_token", -]; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function sanitize(value: any, seen = new WeakSet()): any { - if (value === null || value === undefined) return value; - - if (typeof value === "object") { - if (seen.has(value)) return "[CIRCULAR]"; - seen.add(value); - - if (Array.isArray(value)) { - return value.map((v) => sanitize(v, seen)); - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const sanitizedObj: Record = {}; - for (const [ - k, - v, - ] of Object.entries(value)) { - const isSensitiveKey = SENSITIVE_KEYS.some((sensitiveKey) => - k.toLowerCase().includes(sensitiveKey.toLowerCase())); - sanitizedObj[k] = isSensitiveKey - ? "[REDACTED]" - : sanitize(v, seen); - } - return sanitizedObj; - } - - return value; // numbers, booleans, functions, etc. -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function DEBUG(...args: any[]) { - if ( - typeof process !== "undefined" && - typeof process.env !== "undefined" && - process.env.PD_SDK_DEBUG === "true" - ) { - const safeArgs = args.map((arg) => sanitize(arg)); - console.log("[PD_SDK_DEBUG]", ...safeArgs); - } -} - -/** - * A client for interacting with the Pipedream Connect API on the server-side. - */ -export abstract class BaseClient { - version = sdkVersion; - protected apiHost: string; - protected readonly baseApiUrl: string; - protected environment: string; - protected projectId?: string; - protected readonly workflowDomain: string; - - /** - * Constructs a new BackendClient instance. - * - * @param opts - The options for configuring the server client. - */ - constructor(opts: ClientOpts) { - this.environment = opts.environment ?? "production"; - - const { - apiHost = "api.pipedream.com", - workflowDomain = "m.pipedream.net", - } = opts; - this.apiHost = apiHost; - this.baseApiUrl = `https://${apiHost}/v1`; - this.workflowDomain = workflowDomain; - } - - /** - * Retrieves the current environment the client is configured to use. - * @returns {string} The current environment. - */ - public getEnvironment(): string { - return this.environment; - } - - /** - * Makes an HTTP request - * - * @template T - The expected response type. - * @param path - The API endpoint path. - * @param opts - The options for the request. - * @returns A promise resolving to the API response. - * @throws Will throw an error if the response status is not OK. - */ - public async makeRequest( - path: string, - opts: RequestOptions = {}, - ): Promise { - const { - params, - headers: customHeaders, - body, - method = "GET", - baseURL = this.baseApiUrl, - ...fetchOpts - } = opts; - - const url = new URL(`${baseURL}${path}`); - - if (params) { - for (const [ - key, - value, - ] of Object.entries(params)) { - if (value !== undefined && value !== null) { - url.searchParams.append(key, String(value)); - } - } - } - - const headers: Record = { - ...customHeaders, - "X-PD-SDK-Version": sdkVersion, - "X-PD-Environment": this.environment, - }; - - let processedBody: string | URLSearchParams | FormData | null = null; - - if (body) { - if ( - body instanceof FormData || - body instanceof URLSearchParams || - typeof body === "string" - ) { - // For FormData, URLSearchParams, or strings, pass the body as-is - processedBody = body; - } else { - // For objects, assume it's JSON and serialize it - processedBody = JSON.stringify(body); - // Set the Content-Type header to application/json if not already set - headers["Content-Type"] = headers["Content-Type"] || "application/json"; - } - } - - const requestOptions: RequestInit = { - method, - headers, - ...fetchOpts, - }; - - if ( - [ - "POST", - "PUT", - "PATCH", - ].includes(method.toUpperCase()) && - processedBody - ) { - requestOptions.body = processedBody; - } - - const response: Response = await fetch(url.toString(), requestOptions); - - const rawBody = await response.text(); - - DEBUG("status: ", response.status) - DEBUG("url: ", url.toString()) - DEBUG("requestOptions: ", requestOptions) - DEBUG("rawBody: ", rawBody) - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}, body: ${rawBody}`); - } - - const contentType = response.headers.get("Content-Type"); - if (contentType && contentType.includes("application/json")) { - try { - const json = JSON.parse(rawBody); - return json as T; - } catch (err) { - DEBUG("Couldn't parse json, falling back to raw", err) - } - } - - return rawBody as unknown as T; - } - - protected abstract authHeaders(): string | Promise; - - /** - * Makes a request to the Pipedream API with appropriate authorization. - * - * @template T - The expected response type. - * @param path - The API endpoint path. - * @param opts - The options for the request. - * @returns A promise resolving to the API response. - * @throws Will throw an error if the response status is not OK. - */ - public async makeAuthorizedRequest( - path: string, - opts: RequestOptions = {}, - ): Promise { - const headers: Record = { - "Content-Type": "application/json", - ...opts.headers, - "Authorization": await this.authHeaders(), - }; - - return this.makeRequest(path, { - ...opts, - headers, - }); - } - - /** - * Makes a request to the Connect API using Connect authorization. - * - * @template T - The expected response type. - * @param path - The API endpoint path. - * @param opts - The options for the request. - * @returns A promise resolving to the API response. - */ - protected makeConnectRequest( - path: string, - opts: RequestOptions = {}, - ): Promise { - let fullPath = "/connect"; - if (this.projectId) { - fullPath += `/${this.projectId}`; - } - fullPath += path; - return this.makeAuthorizedRequest(fullPath, opts); - } - - /** - * Retrieves the list of accounts associated with the project. - * - * @param params - The query parameters for retrieving accounts. - * @returns A promise resolving to a list of accounts. - * - * @example - * ```typescript - * const accounts = await client.getAccounts({ include_credentials: true }); - * console.log(accounts); - * ``` - */ - public getAccounts(params: GetAccountOpts = {}) { - return this.makeConnectRequest("/accounts", { - method: "GET", - params, - }); - } - - /** - * Retrieves the list of apps available in Pipedream. - * - * @param opts - The options for retrieving apps. - * @returns A promise resolving to a list of apps. - * - * @example - * ```typescript - * const apps = await client.getApps({ q: "slack" }); - * console.log(apps); - * ``` - */ - public getApps(opts?: GetAppsOpts) { - const params: Record = {}; - if (opts?.q) { - params.q = opts.q; - } - if (opts?.hasActions != null) { - params.has_actions = opts.hasActions - ? "1" - : "0"; - } - if (opts?.hasComponents != null) { - params.has_components = opts.hasComponents - ? "1" - : "0"; - } - if (opts?.hasTriggers != null) { - params.has_triggers = opts.hasTriggers - ? "1" - : "0"; - } - if (opts?.categoryIds && opts.categoryIds.length > 0) { - params.category_ids = opts.categoryIds.join(","); - } - if (opts?.sortKey) { - params.sort_key = opts.sortKey; - } - if (opts?.sortDirection) { - params.sort_direction = opts.sortDirection; - } - - this.addRelationOpts(params, opts); - return this.makeAuthorizedRequest( - "/apps", - { - method: "GET", - params, - }, - ); - } - - /** - * @deprecated Use `getApps` instead. - */ - public apps(opts?: GetAppsOpts) { - return this.getApps(opts); - } - - /** - * Retrieves the metadata for a specific app. - * - * @param idOrNameSlug - The ID or name slug of the app. - * @returns A promise resolving to the app metadata. - * - * @example - * ```typescript - * const app = await client.getApp("slack"); - * console.log(app); - * ``` - */ - public getApp(idOrNameSlug: string) { - const url = `/apps/${idOrNameSlug}`; - return this.makeAuthorizedRequest(url, { - method: "GET", - }); - } - - /** - * @deprecated Use `getApp` instead. - */ - public app(idOrNameSlug: string) { - return this.getApp(idOrNameSlug); - } - - /** - * Retrieves the list of app categories available in Pipedream. - * - * @returns A promise resolving to a list of app categories. - * - * @example - * ```typescript - * const categories = await client.getAppCategories(); - * console.log(categories); - * ``` - */ - public getAppCategories() { - return this.makeAuthorizedRequest("/connect/app_categories", { - method: "GET", - }); - } - - /** - * Retrieves the list of components available in Pipedream. - * - * @param opts - The options for retrieving components. - * @returns A promise resolving to a list of components. - * - * @example - * ```typescript - * const components = await client.getComponents({ q: "slack" }); - * console.log(components); - * ``` - */ - public getComponents(opts?: GetComponentsOpts) { - const params: Record = {}; - if (opts?.app) { - params.app = opts.app; - } - if (opts?.q) { - params.q = opts.q; - } - this.addRelationOpts(params, opts, 20); - // XXX can just use /components and ?type instead when supported - let path = "/components"; - if (opts?.componentType === "trigger") { - path = "/triggers"; - } else if (opts?.componentType === "action") { - path = "/actions"; - } - // XXX Is V1Component the correct type for triggers and actions? - return this.makeConnectRequest(path, { - method: "GET", - params, - }); - } - - /** - * @deprecated Use `getComponents` instead. - */ - public components(opts?: GetComponentOpts) { - return this.getComponents(opts); - } - - /** - * Retrieves the metadata for a specific component. - * - * @param id - The identifier of the component. - * @returns A promise resolving to the component metadata. - * - * @example - * ```typescript - * const component = await client.getComponent("slack-send-message"); - * console.log(component); - * ``` - */ - public getComponent(id: ComponentId) { - const { key } = id; - const path = `/components/${key}`; - return this.makeConnectRequest(path, { - method: "GET", - }); - } - - /** - * @deprecated Use `getComponent` instead. - */ - public component({ key }: { key: string; }) { - return this.getComponent({ - key, - }); - } - - /** - * Configure the next component's prop, based on the current component's - * configuration. - * - * @param opts - The options for configuring the component. - * @returns A promise resolving to the response from the configuration. - * - * @example - * ```typescript - * const { options } = await client.configureComponent({ - * externalUserId: "jverce", - * componentId: { - * key: "slack-send-message", - * }, - * propName: "channel", - * configuredProps: { - * slack: { - * authProvisionId: "apn_z8hD1b4", - * }, - * }, - * }); - * console.log(options); - */ - public configureComponent(opts: ConfigureComponentOpts) { - const { - userId, - externalUserId = userId, - componentId, - } = opts; - - const id = typeof componentId === "object" - ? componentId.key - : componentId; - - const body = { - external_user_id: externalUserId, - id, - prop_name: opts.propName, - configured_props: opts.configuredProps, - dynamic_props_id: opts.dynamicPropsId, - page: opts.page, - prev_context: opts.prevContext, - query: opts.query, - }; - return this.makeConnectRequest("/components/configure", { - method: "POST", - body, - }); - } - - /** - * @deprecated Use `configureComponent` instead. - */ - public componentConfigure(opts: ComponentConfigureOpts) { - return this.configureComponent(opts); - } - - /** - * Reload the component prop's based on the current component's configuration. - * This applies to dynamic props (see the docs for more info: - * https://pipedream.com/docs/components/api#dynamic-props). - * - * @param opts - The options for reloading the component's props. - * @returns A promise resolving to the response from the reload. - * - * @example - * ```typescript - * const { dynamicProps } = await client.reloadComponentProps({ - * externalUserId: "jverce", - * componentId: { - * key: "slack-send-message", - * }, - * configuredProps: { - * slack: { - * authProvisionId: "apn_z8hD1b4", - * }, - * }, - * }); - * - * const { configurableProps, id: dynamicPropsId } = dynamicProps; - * // Use `dynamicPropsId` to configure the next prop - * // Use `configurableProps` to display the new set of props to the user - */ - public reloadComponentProps(opts: ReloadComponentPropsOpts) { - const { - userId, - externalUserId = userId, - componentId, - } = opts; - - const id = typeof componentId === "object" - ? componentId.key - : componentId; - - // RpcActionReloadPropsInput - const body = { - external_user_id: externalUserId, - id, - configured_props: opts.configuredProps, - dynamic_props_id: opts.dynamicPropsId, - }; - - return this.makeConnectRequest( - "/components/props", { - // TODO trigger - method: "POST", - body, - }, - ); - } - - /** - * @deprecated Use `reloadComponentProps` instead. - */ - public componentReloadProps(opts: ComponentReloadPropsOpts) { - return this.reloadComponentProps(opts); - } - - /** - * Invoke an action component for a Pipedream Connect user in a project - * - * @param opts - The options for running the action. - * @returns A promise resolving to the response from the action's execution. - * - * @example - * ```typescript - * const response = await client.runAction({ - * externalUserId: "jverce", - * actionId: { - * key: "gitlab-list-commits", - * }, - * configuredProps: { - * gitlab: { - * authProvisionId: "apn_z8hD1b4" - * }, - * projectId: 21208123, - * refName: "10-0-stable-ee", - * }, - * }); - * console.log(response); - * ``` - */ - public runAction(opts: RunActionOpts) { - const { - userId, - externalUserId = userId, - actionId, - } = opts; - - const id = typeof actionId === "object" - ? actionId.key - : actionId; - - const body = { - external_user_id: externalUserId, - id, - configured_props: opts.configuredProps, - dynamic_props_id: opts.dynamicPropsId, - stash_id: opts.stashId, - }; - return this.makeConnectRequest("/actions/run", { - method: "POST", - body, - }); - } - - /** - * @deprecated Use `runAction` instead. - */ - public actionRun(opts: RunActionOpts) { - return this.runAction(opts); - } - - /** - * Deploy a trigger component for a Pipedream Connect user in a project - * - * @param opts - The options for deploying the trigger. - * @returns A promise resolving to the response from the trigger's deployment. - * - * @example - * ```typescript - * const response = await client.deployTrigger({ - * externalUserId: "jverce", - * triggerId: { - * key: "gitlab-new-issue", - * }, - * configuredProps: { - * gitlab: { - * authProvisionId: "apn_z8hD1b4", - * }, - * projectId: 21208123, - * }, - * webhookUrl: "https://dest.mydomain.com", - * }); - * console.log(response); - */ - public deployTrigger(opts: DeployTriggerOpts) { - const { - userId, - externalUserId = userId, - triggerId, - } = opts; - - const id = typeof triggerId === "object" - ? triggerId.key - : triggerId; - - const body = { - external_user_id: externalUserId, - id, - configured_props: opts.configuredProps, - dynamic_props_id: opts.dynamicPropsId, - workflow_id: opts.workflowId, - webhook_url: opts.webhookUrl, - }; - return this.makeConnectRequest("/triggers/deploy", { - method: "POST", - body, - }); - } - - /** - * @deprecated Use `deployTrigger` instead. - */ - public triggerDeploy(opts: DeployTriggerOpts) { - return this.deployTrigger(opts); - } - - /** - * Deletes a specific trigger. - * - * @param opts - The options for deleting the trigger. - * @returns No content - */ - public deleteTrigger(opts: DeleteTriggerOpts) { - const { - id, - externalUserId, - ignoreHookErrors = null, - } = opts; - - return this.makeConnectRequest(`/deployed-triggers/${id}`, { - method: "DELETE", - params: { - external_user_id: externalUserId, - ignore_hook_errors: ignoreHookErrors, - }, - }); - } - - /** - * Retrieves the metadata for a specific trigger. - * - * @param opts - The options for retrieving the trigger. - * @returns A promise resolving to the trigger metadata. - */ - public getTrigger(opts: GetTriggerOpts) { - const { - id, - externalUserId, - } = opts; - - return this.makeConnectRequest(`/deployed-triggers/${id}`, { - method: "GET", - params: { - external_user_id: externalUserId, - }, - }); - } - - /** - * Retrieves the metadata for all deployed triggers - * - * @param opts - The options for retrieving the triggers. - * @returns A promise resolving to a list of the trigger metadata. - */ - public getTriggers(opts: GetTriggersOpts) { - const { externalUserId } = opts; - - return this.makeConnectRequest("/deployed-triggers", { - method: "GET", - params: { - external_user_id: externalUserId, - }, - }); - } - - /** - * Updates a specific trigger. - * - * @param opts - The options for updating the trigger. - * @returns A promise resolving to the trigger metadata. - */ - public updateTrigger(opts: UpdateTriggerOpts) { - const { - id, - externalUserId, - active = null, - configuredProps = null, - name = null, - } = opts; - - return this.makeConnectRequest(`/deployed-triggers/${id}`, { - method: "PUT", - params: { - external_user_id: externalUserId, - }, - body: { - active, - configured_props: configuredProps, - name, - }, - }); - } - - /** - * Retrieves the last events emitted by a specific trigger. - * - * @param opts - The options for retrieving the trigger events. - * @returns A promise resolving to a list of emitted events. - */ - public getTriggerEvents(opts: GetTriggerEventsOpts) { - const { - id, - externalUserId, - limit = null, - } = opts; - - return this.makeConnectRequest( - `/deployed-triggers/${id}/events`, { - method: "GET", - params: { - external_user_id: externalUserId, - n: limit, - }, - }, - ); - } - - /** - * Retrieves the list of workflows to which the trigger emits events. - * - * @param opts - The options for retrieving the listening workflows. - * @returns A promise resolving to a list of workflows. - */ - public getTriggerWorkflows(opts: GetTriggerWorkflowsOpts) { - const { - id, - externalUserId, - } = opts; - - return this.makeConnectRequest( - `/deployed-triggers/${id}/pipelines`, { - method: "GET", - params: { - external_user_id: externalUserId, - }, - }, - ); - } - - /** - * Updates the list of workflows to which the trigger will emit events. - * - * @param opts - The options for updating the listening workflows. - * @throws If `workflowIds` is not an array. - * @returns A promise resolving to a list of workflows. - */ - public updateTriggerWorkflows(opts: UpdateTriggerWorkflowsOpts) { - const { - id, - externalUserId, - workflowIds, - } = opts; - - if (!Array.isArray(workflowIds)) { - throw new Error("workflowIds must be an array"); - } - - return this.makeConnectRequest( - `/deployed-triggers/${id}/pipelines`, { - method: "PUT", - params: { - external_user_id: externalUserId, - }, - body: { - workflow_ids: workflowIds, - }, - }, - ); - } - - /** - * Retrieves the list of webhooks to which the trigger emits events. - * - * @param opts - The options for retrieving the listening webhooks. - * @returns A promise resolving to a list of webhooks. - */ - public getTriggerWebhooks(opts: GetTriggerWebhooksOpts) { - const { - id, - externalUserId, - } = opts; - - return this.makeConnectRequest( - `/deployed-triggers/${id}/webhooks`, { - method: "GET", - params: { - external_user_id: externalUserId, - }, - }, - ); - } - - /** - * Updates the list of webhooks to which the trigger will emit events. - * - * @param opts - The options for updating the listening webhooks. - * @throws If `webhookUrls` is not an array. - * @returns A promise resolving to a list of webhooks. - */ - public updateTriggerWebhooks(opts: UpdateTriggerWebhooksOpts) { - const { - id, - externalUserId, - webhookUrls, - } = opts; - - if (!Array.isArray(webhookUrls)) { - throw new Error("webhookUrls must be an array"); - } - - return this.makeConnectRequest( - `/deployed-triggers/${id}/webhooks`, { - method: "PUT", - params: { - external_user_id: externalUserId, - }, - body: { - webhook_urls: webhookUrls, - }, - }, - ); - } - - /** - * Builds a full workflow URL based on the input. - * - * @param input - Either a full URL (with or without protocol) or just an - * endpoint ID. - * @returns The fully constructed URL. - * @throws If the input is a malformed URL, throws an error with a clear - * message. - * - * @example - * ```typescript - * // Full URL input - * this.buildWorkflowUrl("https://en123.m.pipedream.net"); - * // Returns: "https://en123.m.pipedream.net" - * ``` - * - * @example - * ```typescript - * // Partial URL (without protocol) - * this.buildWorkflowUrl("en123.m.pipedream.net"); - * // Returns: "https://en123.m.pipedream.net" - * ``` - * - * @example - * ```typescript - * // ID only input - * this.buildWorkflowUrl("en123"); - * // Returns: "https://en123.yourdomain.com" (where `yourdomain.com` is set in `workflowDomain`) - * ``` - */ - private buildWorkflowUrl(input: string): string { - const sanitizedInput = input - .trim() - .replace(/[^\w-./:]/g, "") - .toLowerCase(); - if (!sanitizedInput) { - throw new Error("URL or endpoint ID is required"); - } - - let url: string; - const isUrl = - sanitizedInput.includes(".") || sanitizedInput.startsWith("http"); - - if (isUrl) { - // Try to parse the input as a URL - let parsedUrl: URL; - try { - const urlString = sanitizedInput.startsWith("http") - ? sanitizedInput - : `https://${sanitizedInput}`; - parsedUrl = new URL(urlString); - } catch { - throw new Error(` - The provided URL is malformed: "${sanitizedInput}". - Please provide a valid URL. - `); - } - - // Validate the hostname to prevent potential DNS rebinding attacks - if (!parsedUrl.hostname.endsWith(this.workflowDomain)) { - throw new Error( - `Invalid workflow domain. URL must end with ${this.workflowDomain}`, - ); - } - - url = parsedUrl.href; - } else { - // If the input is an ID, construct the full URL using the base domain - if (!/^e(n|o)[a-z0-9-]+$/i.test(sanitizedInput)) { - throw new Error(` - Invalid endpoint ID format. - Must contain only letters, numbers, and hyphens, and start with either "en" or "eo". - `); - } - - url = `https://${sanitizedInput}.${this.workflowDomain}`; - } - - return url; - } - - /** - * Invokes a workflow using the URL of its HTTP interface(s), by sending an - * - * @param urlOrEndpoint - The URL of the workflow's HTTP interface, or the ID of the endpoint - * @param opts - The options for the request. - * @param opts.body - The body of the request. It must be a JSON-serializable - * value (e.g. an object, null, a string, etc.). - * @param opts.headers - The headers to include in the request. Note that the - * Authorization header will always be set with an OAuth access token - * retrieved by the client. - * @param authType - The type of authorization to use for the request. - * @returns A promise resolving to the response from the workflow. - * - * @example - * ```typescript - * const response: JSON = await client.invokeWorkflow( - * "https://en-your-endpoint.m.pipedream.net", - * { - * body: { - * foo: 123, - * bar: "abc", - * baz: null, - * }, - * headers: { - * "Accept": "application/json", - * }, - * }, - * "oauth", - * ); - * console.log(response); - * ``` - */ - public async invokeWorkflow( - urlOrEndpoint: string, - opts: RequestOptions = {}, - authType: HTTPAuthType = HTTPAuthType.None, - ): Promise { - const { - body, headers = {}, - } = opts; - - const url = this.buildWorkflowUrl(urlOrEndpoint); - - let authHeader: string | undefined; - switch (authType) { - case HTTPAuthType.StaticBearer: - // It's expected that users will pass their own Authorization header in - // the static bearer case - authHeader = headers["Authorization"]; - break; - case HTTPAuthType.OAuth: - authHeader = await this.authHeaders(); // TODO How to handle this client side? We should pass the auth even if it's not OAuth - break; - default: - break; - } - - return this.makeRequest("", { - ...opts, - baseURL: url, - method: opts.method || "POST", // Default to POST if not specified - headers: authHeader - ? { - ...headers, - Authorization: authHeader, - } - : headers, - body, - }); - } - - /** - * Invokes a workflow for a Pipedream Connect user in a project - * - * @param url - The URL of the workflow's HTTP interface. - * @param externalUserId — Your end user ID, for whom you're invoking the - * workflow. - * @param opts - The options for the request. - * @param opts.body - The body of the request. It must be a JSON-serializable - * value (e.g. an object, null, a string, etc.). - * @param opts.headers - The headers to include in the request. Note that the - * Authorization header will always be set with an OAuth access token - * retrieved by the client. - * @returns A promise resolving to the response from the workflow. - * - * @example - * ```typescript - * const response = await client.invokeWorkflowForExternalUser( - * "https://your-workflow-url.m.pipedream.net", - * "your-external-user-id", - * { - * body: { - * foo: 123, - * bar: "abc", - * baz: null, - * }, - * headers: { - * "Accept": "application/json", - * }, - * }, - * ); - * console.log(response); - * ``` - */ - public async invokeWorkflowForExternalUser( - url: string, - externalUserId: string, - opts: RequestOptions = {}, - ): Promise { - if (!externalUserId?.trim()) { - throw new Error("External user ID is required"); - } - - if (!url.trim()) { - throw new Error("Workflow URL is required"); - } - - if (!(await this.authHeaders())) { - throw new Error( - // TODO Test that this works with token auth - "OAuth or token is required for invoking workflows for external users. Please pass credentials for a valid OAuth client", - ); - } - - const { headers = {} } = opts; - return this.invokeWorkflow( - url, - { - ...opts, - headers: { - ...headers, - "X-PD-External-User-ID": externalUserId, - }, - }, - HTTPAuthType.OAuth, - ); // OAuth auth is required for invoking workflows for external users - } - - private addRelationOpts(params: Record, opts?: RelationOpts, defaultLimit?: number) { - if (opts?.limit != null) { - params.limit = "" + opts.limit; - } - if (defaultLimit != null && !params.limit) { - params.limit = "" + defaultLimit; - } - if (opts?.after) { - params.after = opts.after; - } - if (opts?.before) { - params.before = opts.before; - } - } -} diff --git a/packages/sdk/src/shared/shims.d.ts b/packages/sdk/src/shared/shims.d.ts deleted file mode 100644 index 3f8248deb8c20..0000000000000 --- a/packages/sdk/src/shared/shims.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const process: { - env?: { - [key: string]: string | undefined; - }; -} | undefined; diff --git a/packages/sdk/src/version.ts b/packages/sdk/src/version.ts deleted file mode 100644 index 6cdfb0c994f91..0000000000000 --- a/packages/sdk/src/version.ts +++ /dev/null @@ -1,2 +0,0 @@ -// DO NOT EDIT, SET AT BUILD TIME -export const version = "0.0.0" diff --git a/packages/sdk/tsconfig.browser.json b/packages/sdk/tsconfig.browser.json deleted file mode 100644 index 45ee1b87ce23d..0000000000000 --- a/packages/sdk/tsconfig.browser.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "module": "ESNext", - "target": "es2017", - "lib": ["ES5", "DOM", "es2017"], - "declaration": true, - "outDir": "dist/browser", - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "skipLibCheck": true, - "types": [], - "allowJs": true - }, - "include": [ - "src/shared/shims.d.ts", - "src/browser/**/*" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/packages/sdk/tsconfig.node.json b/packages/sdk/tsconfig.node.json deleted file mode 100644 index d2ebdb24b22ff..0000000000000 --- a/packages/sdk/tsconfig.node.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "module": "NodeNext", - "target": "es2017", - "lib": [ - "es2017" - ], - "declaration": true, - "outDir": "dist/server", - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "allowSyntheticDefaultImports": true, - "skipLibCheck": true, - "sourceMap": true, - "moduleResolution": "NodeNext", - "noImplicitAny": true, - "types": [ - "node", - "jest" - ] - }, - "include": [ - "src/server/**/*" - ], - "exclude": [ - "**/*.test.ts", - "node_modules" - ] -} diff --git a/packages/sdk/tsup.browser.config.js b/packages/sdk/tsup.browser.config.js deleted file mode 100644 index aa97fb28e86fb..0000000000000 --- a/packages/sdk/tsup.browser.config.js +++ /dev/null @@ -1,15 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: { - browser: "./src/browser/index.ts", - }, - format: [ - "cjs", - "esm", - ], - minify: true, - sourcemap: true, - dts: true, - tsconfig: "./tsconfig.browser.json", -}); diff --git a/packages/sdk/tsup.server.cjs.config.js b/packages/sdk/tsup.server.cjs.config.js deleted file mode 100644 index d553f3f495e0e..0000000000000 --- a/packages/sdk/tsup.server.cjs.config.js +++ /dev/null @@ -1,16 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: { - server: "./src/server/index.ts", - cli: "./src/server/cli.ts", - }, - format: "cjs", - noExternal: [ - "oauth4webapi", - ], - minify: true, - sourcemap: true, - dts: true, - tsconfig: "./tsconfig.node.json", -}); diff --git a/packages/sdk/tsup.server.esm.config.js b/packages/sdk/tsup.server.esm.config.js deleted file mode 100644 index 7223f1d293597..0000000000000 --- a/packages/sdk/tsup.server.esm.config.js +++ /dev/null @@ -1,13 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: { - server: "./src/server/index.ts", - cli: "./src/server/cli.ts", - }, - format: "esm", - minify: true, - sourcemap: true, - dts: true, - tsconfig: "./tsconfig.node.json", -}); From 54f3f4f0b7a47e79b3c50ccc15648f08e405d8ab Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Fri, 21 Nov 2025 14:13:19 -0300 Subject: [PATCH 5/6] Removing gitignore --- packages/sdk/.gitignore | 3 - pnpm-lock.yaml | 337 +++++----------------------------------- 2 files changed, 41 insertions(+), 299 deletions(-) delete mode 100644 packages/sdk/.gitignore diff --git a/packages/sdk/.gitignore b/packages/sdk/.gitignore deleted file mode 100644 index b12c26f6f2e29..0000000000000 --- a/packages/sdk/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -dist -node_modules -*.env* diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fe83b377b8c9..f78a1326aa6d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17314,7 +17314,7 @@ importers: dependencies: '@pipedream/sdk': specifier: workspace:^ - version: link:../sdk + version: link:../../components/sdk openai: specifier: ^4.77.0 version: 4.104.0(ws@8.18.3)(zod@3.25.76) @@ -17393,52 +17393,6 @@ importers: specifier: ^5.0.4 version: 5.6.3 - packages/sdk: - dependencies: - '@rails/actioncable': - specifier: ^8.0.0 - version: 8.1.100 - commander: - specifier: ^12.1.0 - version: 12.1.0 - oauth4webapi: - specifier: ^3.1.4 - version: 3.8.2 - ws: - specifier: ^8.17.1 - version: 8.18.3 - devDependencies: - '@types/jest': - specifier: ^29.5.13 - version: 29.5.14 - '@types/node': - specifier: ^20.17.6 - version: 20.19.25 - '@types/rails__actioncable': - specifier: ^6.1.11 - version: 6.1.11 - '@types/ws': - specifier: ^8.5.13 - version: 8.18.1 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) - lodash.isequal: - specifier: ^4.5.0 - version: 4.5.0 - nodemon: - specifier: ^3.1.7 - version: 3.1.11 - ts-jest: - specifier: ^29.2.5 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3) - tsup: - specifier: ^8.3.6 - version: 8.5.0(@microsoft/api-extractor@7.55.0(@types/node@20.19.25))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.6.3)(yaml@2.8.1) - typescript: - specifier: ^5.6 - version: 5.6.3 - packages/snowflake-sdk: dependencies: snowflake-sdk: @@ -17474,7 +17428,7 @@ importers: version: 3.1.0 jest: specifier: ^29.1.2 - version: 29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + version: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) type-fest: specifier: ^4.15.0 version: 4.41.0 @@ -22590,9 +22544,6 @@ packages: '@types/jest@27.5.2': resolution: {integrity: sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==} - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} - '@types/jsesc@2.5.1': resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} @@ -22689,9 +22640,6 @@ packages: '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - '@types/rails__actioncable@6.1.11': - resolution: {integrity: sha512-L6A3Rg6sGsv2cqalOgdOmyFvL1Pw69Mg0WuG6NtY9chzabhtkiSFY5fczo72mqRGezrMvl0Jy80v+N719CW+Tg==} - '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -26834,9 +26782,6 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -29012,11 +28957,6 @@ packages: resolution: {integrity: sha512-Us/Se1WtT0ylXgNFfyFSx4LElllVLJXQjWi2Xz17xWw7amDKO2MLtFnVp1WACy7GkVGs+oBlRopVNUzlrGSw1w==} engines: {node: '>=6.0.0'} - nodemon@3.1.11: - resolution: {integrity: sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==} - engines: {node: '>=10'} - hasBin: true - nopt@8.1.0: resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} engines: {node: ^18.17.0 || >=20.5.0} @@ -30061,9 +30001,6 @@ packages: psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - pump@1.0.3: resolution: {integrity: sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==} @@ -30952,10 +30889,6 @@ packages: simple-lru-cache@0.0.2: resolution: {integrity: sha512-uEv/AFO0ADI7d99OHDmh1QfYzQk/izT1vCmu/riQfh7qjBVUUgRT87E5s5h7CxWCA/+YoZerykpEthzVrW3LIw==} - simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} - simple-xml2json@1.2.3: resolution: {integrity: sha512-R2qDtYMXCaaXq300+TKTtzJvryJ2BFmbP2VANnS6H7XzUgVbi9an7VnCVLvXMdEqyzAW6G4whZix7fOuUo54oQ==} @@ -31444,17 +31377,17 @@ packages: superagent@3.8.1: resolution: {integrity: sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==} engines: {node: '>= 4.0'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@4.1.0: resolution: {integrity: sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==} engines: {node: '>= 6.0'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@5.3.1: resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} engines: {node: '>= 7.0.0'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net supports-color@10.2.2: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} @@ -31699,10 +31632,6 @@ packages: tomlify-j0.4@3.0.0: resolution: {integrity: sha512-2Ulkc8T7mXJ2l0W476YC/A209PR38Nw8PuaCNtk9uI3t1zzFdGQeWYGQvmj2PZkVvRC/Yoi4xQKMRnWc/N29tQ==} - touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} - hasBin: true - tough-cookie@2.5.0: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} engines: {node: '>=0.8'} @@ -32086,9 +32015,6 @@ packages: uncrypto@0.1.3: resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - underscore@1.12.1: resolution: {integrity: sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==} @@ -36926,7 +36852,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -36940,7 +36866,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -36961,7 +36887,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -36975,7 +36901,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -37257,15 +37183,6 @@ snapshots: transitivePeerDependencies: - debug - '@microsoft/api-extractor-model@7.32.0(@types/node@20.19.25)': - dependencies: - '@microsoft/tsdoc': 0.16.0 - '@microsoft/tsdoc-config': 0.18.0 - '@rushstack/node-core-library': 5.18.0(@types/node@20.19.25) - transitivePeerDependencies: - - '@types/node' - optional: true - '@microsoft/api-extractor-model@7.32.0(@types/node@22.19.1)': dependencies: '@microsoft/tsdoc': 0.16.0 @@ -37274,26 +37191,6 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.55.0(@types/node@20.19.25)': - dependencies: - '@microsoft/api-extractor-model': 7.32.0(@types/node@20.19.25) - '@microsoft/tsdoc': 0.16.0 - '@microsoft/tsdoc-config': 0.18.0 - '@rushstack/node-core-library': 5.18.0(@types/node@20.19.25) - '@rushstack/rig-package': 0.6.0 - '@rushstack/terminal': 0.19.3(@types/node@20.19.25) - '@rushstack/ts-command-line': 5.1.3(@types/node@20.19.25) - diff: 8.0.2 - lodash: 4.17.21 - minimatch: 10.0.3 - resolve: 1.22.11 - semver: 7.5.4 - source-map: 0.6.1 - typescript: 5.8.2 - transitivePeerDependencies: - - '@types/node' - optional: true - '@microsoft/api-extractor@7.55.0(@types/node@22.19.1)': dependencies: '@microsoft/api-extractor-model': 7.32.0(@types/node@22.19.1) @@ -39891,20 +39788,6 @@ snapshots: '@rushstack/eslint-patch@1.15.0': {} - '@rushstack/node-core-library@5.18.0(@types/node@20.19.25)': - dependencies: - ajv: 8.13.0 - ajv-draft-04: 1.0.0(ajv@8.13.0) - ajv-formats: 3.0.1(ajv@8.13.0) - fs-extra: 11.3.2 - import-lazy: 4.0.0 - jju: 1.4.0 - resolve: 1.22.11 - semver: 7.5.4 - optionalDependencies: - '@types/node': 20.19.25 - optional: true - '@rushstack/node-core-library@5.18.0(@types/node@22.19.1)': dependencies: ajv: 8.13.0 @@ -39918,11 +39801,6 @@ snapshots: optionalDependencies: '@types/node': 22.19.1 - '@rushstack/problem-matcher@0.1.1(@types/node@20.19.25)': - optionalDependencies: - '@types/node': 20.19.25 - optional: true - '@rushstack/problem-matcher@0.1.1(@types/node@22.19.1)': optionalDependencies: '@types/node': 22.19.1 @@ -39932,15 +39810,6 @@ snapshots: resolve: 1.22.11 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.19.3(@types/node@20.19.25)': - dependencies: - '@rushstack/node-core-library': 5.18.0(@types/node@20.19.25) - '@rushstack/problem-matcher': 0.1.1(@types/node@20.19.25) - supports-color: 8.1.1 - optionalDependencies: - '@types/node': 20.19.25 - optional: true - '@rushstack/terminal@0.19.3(@types/node@22.19.1)': dependencies: '@rushstack/node-core-library': 5.18.0(@types/node@22.19.1) @@ -39949,16 +39818,6 @@ snapshots: optionalDependencies: '@types/node': 22.19.1 - '@rushstack/ts-command-line@5.1.3(@types/node@20.19.25)': - dependencies: - '@rushstack/terminal': 0.19.3(@types/node@20.19.25) - '@types/argparse': 1.0.38 - argparse: 1.0.10 - string-argv: 0.3.2 - transitivePeerDependencies: - - '@types/node' - optional: true - '@rushstack/ts-command-line@5.1.3(@types/node@22.19.1)': dependencies: '@rushstack/terminal': 0.19.3(@types/node@22.19.1) @@ -40970,11 +40829,6 @@ snapshots: jest-matcher-utils: 27.5.1 pretty-format: 27.5.1 - '@types/jest@29.5.14': - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - '@types/jsesc@2.5.1': {} '@types/json-schema@7.0.15': {} @@ -41070,8 +40924,6 @@ snapshots: '@types/qs@6.14.0': {} - '@types/rails__actioncable@6.1.11': {} - '@types/range-parser@1.2.7': {} '@types/react-transition-group@4.4.12(@types/react@18.3.26)': @@ -42430,7 +42282,8 @@ snapshots: bignumber.js@9.3.1: {} - binary-extensions@2.3.0: {} + binary-extensions@2.3.0: + optional: true binascii@0.0.2: {} @@ -42829,6 +42682,7 @@ snapshots: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 + optional: true chokidar@4.0.3: dependencies: @@ -43370,13 +43224,13 @@ snapshots: safe-buffer: 5.2.1 sha.js: 2.4.12 - create-jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + create-jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -43385,13 +43239,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)): + create-jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -43615,12 +43469,6 @@ snapshots: optionalDependencies: supports-color: 10.2.2 - debug@4.4.3(supports-color@5.5.0): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 5.5.0 - debug@4.4.3(supports-color@9.4.0): dependencies: ms: 2.1.3 @@ -46614,8 +46462,6 @@ snapshots: ieee754@1.2.1: {} - ignore-by-default@1.0.1: {} - ignore@5.3.2: {} ignore@7.0.5: {} @@ -46860,6 +46706,7 @@ snapshots: is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 + optional: true is-boolean-object@1.2.2: dependencies: @@ -47249,16 +47096,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + jest-cli@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + create-jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -47268,16 +47115,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)): + jest-cli@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + create-jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + jest-config: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -47287,7 +47134,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): dependencies: '@babel/core': 7.28.5 '@jest/test-sequencer': 29.7.0 @@ -47313,12 +47160,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.25 - ts-node: 10.9.2(@types/node@20.19.25)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@20.19.25)(typescript@3.9.10) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)): + jest-config@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: '@babel/core': 7.28.5 '@jest/test-sequencer': 29.7.0 @@ -47344,38 +47191,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.25 - ts-node: 10.9.2(@types/node@22.19.1)(typescript@3.9.10) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)): - dependencies: - '@babel/core': 7.28.5 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.5) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0(babel-plugin-macros@3.1.0) - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.19.1 - ts-node: 10.9.2(@types/node@22.19.1)(typescript@3.9.10) + ts-node: 10.9.2(@types/node@20.19.25)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -47611,24 +47427,24 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): + jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) + jest-cli: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)): + jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.19.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10)) + jest-cli: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -49494,19 +49310,6 @@ snapshots: nodemailer@7.0.10: {} - nodemon@3.1.11: - dependencies: - chokidar: 3.6.0 - debug: 4.4.3(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 7.7.3 - simple-update-notifier: 2.0.0 - supports-color: 5.5.0 - touch: 3.1.1 - undefsafe: 2.0.5 - nopt@8.1.0: dependencies: abbrev: 3.0.1 @@ -50671,8 +50474,6 @@ snapshots: dependencies: punycode: 2.3.1 - pstree.remy@1.1.8: {} - pump@1.0.3: dependencies: end-of-stream: 1.4.5 @@ -51149,6 +50950,7 @@ snapshots: readdirp@3.6.0: dependencies: picomatch: 2.3.1 + optional: true readdirp@4.1.2: {} @@ -52146,10 +51948,6 @@ snapshots: simple-lru-cache@0.0.2: {} - simple-update-notifier@2.0.0: - dependencies: - semver: 7.7.3 - simple-xml2json@1.2.3: {} sisteransi@1.0.5: {} @@ -53094,8 +52892,6 @@ snapshots: tomlify-j0.4@3.0.0: {} - touch@3.1.1: {} - tough-cookie@2.5.0: dependencies: psl: 1.15.0 @@ -53168,26 +52964,6 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3): - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.3 - type-fest: 4.41.0 - typescript: 5.6.3 - yargs-parser: 21.1.1 - optionalDependencies: - '@babel/core': 7.28.5 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.5) - jest-util: 29.7.0 - ts-jest@29.4.5(@babel/core@8.0.0-beta.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@8.0.0-beta.3))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.25)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3)))(typescript@5.6.3): dependencies: bs-logger: 0.2.6 @@ -53208,7 +52984,7 @@ snapshots: babel-jest: 29.7.0(@babel/core@8.0.0-beta.3) jest-util: 29.7.0 - ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3): + ts-node@10.9.2(@types/node@20.19.25)(typescript@3.9.10): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -53222,26 +52998,26 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.6.3 + typescript: 3.9.10 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optional: true - ts-node@10.9.2(@types/node@22.19.1)(typescript@3.9.10): + ts-node@10.9.2(@types/node@20.19.25)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.19.1 + '@types/node': 20.19.25 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 3.9.10 + typescript: 5.6.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optional: true @@ -53353,35 +53129,6 @@ snapshots: tsutils: 2.29.0(typescript@5.9.3) typescript: 5.9.3 - tsup@8.5.0(@microsoft/api-extractor@7.55.0(@types/node@20.19.25))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.6.3)(yaml@2.8.1): - dependencies: - bundle-require: 5.1.0(esbuild@0.25.12) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.3(supports-color@9.4.0) - esbuild: 0.25.12 - fix-dts-default-cjs-exports: 1.0.1 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(yaml@2.8.1) - resolve-from: 5.0.0 - rollup: 4.53.2 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tree-kill: 1.2.2 - optionalDependencies: - '@microsoft/api-extractor': 7.55.0(@types/node@20.19.25) - postcss: 8.5.6 - typescript: 5.6.3 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - tsup@8.5.0(@microsoft/api-extractor@7.55.0(@types/node@22.19.1))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.6.3)(yaml@2.8.1): dependencies: bundle-require: 5.1.0(esbuild@0.25.12) @@ -53631,8 +53378,6 @@ snapshots: uncrypto@0.1.3: {} - undefsafe@2.0.5: {} - underscore@1.12.1: {} underscore@1.13.7: {} From 92eecdbe401643e259f0b8a4212f3e54b697edeb Mon Sep 17 00:00:00 2001 From: GTFalcao Date: Fri, 21 Nov 2025 14:16:08 -0300 Subject: [PATCH 6/6] Removing SDK github actions --- .../pipedream-sdk-markdown-lint.yaml | 24 ---------- .github/workflows/pipedream-sdk-test.yaml | 47 ------------------- 2 files changed, 71 deletions(-) delete mode 100644 .github/workflows/pipedream-sdk-markdown-lint.yaml delete mode 100644 .github/workflows/pipedream-sdk-test.yaml diff --git a/.github/workflows/pipedream-sdk-markdown-lint.yaml b/.github/workflows/pipedream-sdk-markdown-lint.yaml deleted file mode 100644 index 8332eee516a6b..0000000000000 --- a/.github/workflows/pipedream-sdk-markdown-lint.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: Lint SDK Markdown Files - -on: - pull_request: - types: [opened, edited, synchronize] - paths: - - 'packages/sdk/**/*.md' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Lint markdown files - uses: DavidAnson/markdownlint-cli2-action@v17 - with: - globs: 'packages/sdk/**/*.md' diff --git a/.github/workflows/pipedream-sdk-test.yaml b/.github/workflows/pipedream-sdk-test.yaml deleted file mode 100644 index a9bdf279681fc..0000000000000 --- a/.github/workflows/pipedream-sdk-test.yaml +++ /dev/null @@ -1,47 +0,0 @@ -name: Run SDK Tests - -on: - pull_request: - types: [opened, edited, synchronize] - paths: - - 'packages/sdk/**' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4.0.0 - with: - version: 9.14.2 - - name: Get pnpm store directory - id: pnpm-cache - run: | - echo "::set-output name=pnpm_cache_dir::$(pnpm store path)" - - uses: actions/cache@v4 - name: Setup pnpm cache - with: - path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '22' - - - name: Install dependencies - run: pnpm install - working-directory: packages/sdk - - - name: Run tests - run: pnpm test - working-directory: packages/sdk