diff --git a/.github/workflows/pipedream-sdk-test.yaml b/.github/workflows/pipedream-sdk-test.yaml index 302684cf5dca7..a9bdf279681fc 100644 --- a/.github/workflows/pipedream-sdk-test.yaml +++ b/.github/workflows/pipedream-sdk-test.yaml @@ -36,7 +36,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: '18' + node-version: '22' - name: Install dependencies run: pnpm install diff --git a/eslint.config.mjs b/eslint.config.mjs index d2ce07b7e806d..770616aa74c3e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -2,6 +2,7 @@ import jsonc from "eslint-plugin-jsonc"; import putout from "eslint-plugin-putout"; import pipedream from "eslint-plugin-pipedream"; import typescriptEslint from "@typescript-eslint/eslint-plugin"; +import importPlugin from "eslint-plugin-import"; import jest from "eslint-plugin-jest"; import globals from "globals"; import parser from "jsonc-eslint-parser"; @@ -52,6 +53,7 @@ export default [ pipedream, "@typescript-eslint": typescriptEslint, jest, + "import": importPlugin, }, languageOptions: { @@ -313,4 +315,17 @@ export default [ "react/react-in-jsx-scope": "off", }, }, + { + files: [ + "packages/sdk/src/browser/**/*.ts", + "packages/sdk/src/shared/**/*.ts", + ], + + rules: { + "import/extensions": [ + "error", + "always", + ], + }, + }, ]; diff --git a/jest.config.js b/jest.config.js index bc158df836f75..a75bdfef5eb66 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,18 +4,22 @@ module.exports = { testEnvironment: "node", // See https://kulshekhar.github.io/ts-jest/docs/guides/esm-support extensionsToTreatAsEsm: [ + ".js", ".ts", ".mts", ], - globals: { - "ts-jest": { - useESM: true, - }, - }, moduleNameMapper: { - "^(\\.{1,2}/.*)\\.js$": "$1", + "^(.+)\\.js$": "$1", }, testPathIgnorePatterns: [ "types/.*.types.test..*$", ], + transform: { + "\\.[jt]s$": [ + "ts-jest", + { + "useESM": true, + }, + ], + }, }; diff --git a/package.json b/package.json index 163a91c4b7625..46784d0494096 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@typescript-eslint/parser": "^8", "eslint": "^8", "eslint-config-next": "^15", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-jest": "^28", "eslint-plugin-jsonc": "^1.6.0", "eslint-plugin-pipedream": "0.2.4", diff --git a/packages/sdk/CHANGELOG.md b/packages/sdk/CHANGELOG.md index 77c56b23d8c54..2f988260bb277 100644 --- a/packages/sdk/CHANGELOG.md +++ b/packages/sdk/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog +## [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 diff --git a/packages/sdk/examples/browser/Makefile b/packages/sdk/examples/browser/Makefile new file mode 100644 index 0000000000000..31dc6402c352d --- /dev/null +++ b/packages/sdk/examples/browser/Makefile @@ -0,0 +1,8 @@ +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 new file mode 100644 index 0000000000000..14ca5d69c402c --- /dev/null +++ b/packages/sdk/examples/browser/index.html @@ -0,0 +1,20 @@ + + + +

Load SDK in browser

+ + + + diff --git a/packages/sdk/examples/server/Makefile b/packages/sdk/examples/server/Makefile new file mode 100644 index 0000000000000..ff7b4a60c3538 --- /dev/null +++ b/packages/sdk/examples/server/Makefile @@ -0,0 +1,2 @@ +default: + @node index.mjs diff --git a/packages/sdk/examples/server/index.mjs b/packages/sdk/examples/server/index.mjs new file mode 100644 index 0000000000000..deb30ff419124 --- /dev/null +++ b/packages/sdk/examples/server/index.mjs @@ -0,0 +1,10 @@ +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 index e2a44e25601da..28030a603c6f1 100644 --- a/packages/sdk/jest.config.js +++ b/packages/sdk/jest.config.js @@ -15,10 +15,13 @@ module.exports = { "ts", "js", ], + moduleNameMapper: { + "^(.+)\\.js$": "$1", + }, 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` - "^.+\\.tsx?$": [ + "^.+\\.[jt]sx?$": [ "ts-jest", { tsconfig: "tsconfig.node.json", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 2f38f1897e035..bcb6c26fd4ca5 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/sdk", - "version": "1.0.8", + "version": "1.0.9", "description": "Pipedream SDK", "main": "dist/server/server/index.js", "module": "dist/server/server/index.js", @@ -35,8 +35,9 @@ "access": "public" }, "scripts": { - "prepublish": "rm -rf dist && pnpm run build", - "build": "pnpm run build:node && pnpm run build:browser", + "prepublish": "pnpm run build", + "prebuild": "node scripts/updateVersion.mjs", + "build": "rm -rf dist && pnpm run prebuild && pnpm run build:node && pnpm run build:browser", "build:node": "tsc -p tsconfig.node.json", "build:browser": "tsc -p tsconfig.browser.json", "test": "jest", diff --git a/packages/sdk/scripts/updateVersion.mjs b/packages/sdk/scripts/updateVersion.mjs new file mode 100644 index 0000000000000..4b6ed8894a5e3 --- /dev/null +++ b/packages/sdk/scripts/updateVersion.mjs @@ -0,0 +1,13 @@ +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/async.ts b/packages/sdk/src/browser/async.ts index a174d6aff5a31..0cff886578f93 100644 --- a/packages/sdk/src/browser/async.ts +++ b/packages/sdk/src/browser/async.ts @@ -1,5 +1,5 @@ -import { AsyncResponseManager } from "../shared/async"; -import type { AsyncResponseManagerOpts } from "../shared/async"; +import { AsyncResponseManager } from "../shared/async.js"; +import type { AsyncResponseManagerOpts } from "../shared/async.js"; export type BrowserAsyncResponseManagerOpts = { apiHost: string; diff --git a/packages/sdk/src/browser/index.ts b/packages/sdk/src/browser/index.ts index ac5c7d5617190..94d886e5cc929 100644 --- a/packages/sdk/src/browser/index.ts +++ b/packages/sdk/src/browser/index.ts @@ -4,14 +4,14 @@ // operations, like connecting accounts via Pipedream Connect. See the server/ // directory for the server client. -import { BrowserAsyncResponseManager } from "./async"; +import { BrowserAsyncResponseManager } from "./async.js"; import { AccountsRequestResponse, BaseClient, GetAccountOpts, type ConnectTokenResponse, -} from "../shared"; -export type * from "../shared"; +} from "../shared/index.js"; +export type * from "../shared/index.js"; /** * Options for creating a browser-side client. This is used to configure the diff --git a/packages/sdk/src/server/async.ts b/packages/sdk/src/server/async.ts index f15d7352048eb..560d1eef665f6 100644 --- a/packages/sdk/src/server/async.ts +++ b/packages/sdk/src/server/async.ts @@ -26,7 +26,7 @@ export class ServerAsyncResponseManager extends AsyncResponseManager { // eslint-disable-next-line @typescript-eslint/no-empty-function global.removeEventListener = () => {}; if (typeof adapters.WebSocket === "undefined") - adapters.WebSocket = WebSocket; + adapters.WebSocket = WebSocket as unknown as typeof adapters.WebSocket; } protected override async getOpts(): Promise { diff --git a/packages/sdk/src/shared/component.ts b/packages/sdk/src/shared/component.ts index f6fef25dab0ce..8f539bd381d06 100644 --- a/packages/sdk/src/shared/component.ts +++ b/packages/sdk/src/shared/component.ts @@ -94,3 +94,17 @@ export type V1Component = { // eslint-disable version: string; configurable_props: T; }; + +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; +}; diff --git a/packages/sdk/src/shared/index.ts b/packages/sdk/src/shared/index.ts index 2e88ced532388..d2c2191dea655 100644 --- a/packages/sdk/src/shared/index.ts +++ b/packages/sdk/src/shared/index.ts @@ -1,10 +1,15 @@ // This code is meant to be shared between the browser and server. -import { AsyncResponseManager } from "./async"; import type { - AsyncResponse, AsyncErrorResponse, -} from "./async"; -import type { V1Component } from "./component"; -export * from "./component"; + AsyncResponse, + AsyncErrorResponse, + AsyncResponseManager, +} from "./async.js"; +import type { + V1Component, + V1DeployedComponent, +} from "./component.js"; +export * from "./component.js"; +import { version as sdkVersion } from "../version.js"; type RequestInit = globalThis.RequestInit; @@ -290,6 +295,7 @@ export interface AsyncRequestOptions extends RequestOptions { * A client for interacting with the Pipedream Connect API on the server-side. */ export abstract class BaseClient { + version = sdkVersion; protected apiHost: string; protected abstract asyncResponseManager: AsyncResponseManager; protected readonly baseApiUrl: string; @@ -351,6 +357,7 @@ export abstract class BaseClient { const headers: Record = { ...customHeaders, + "X-PD-SDK-Version": sdkVersion, "X-PD-Environment": this.environment, }; @@ -572,7 +579,6 @@ export abstract class BaseClient { prop_name: opts.propName, configured_props: opts.configuredProps, dynamic_props_id: opts.dynamicPropsId, - environment: this.environment, }; return await this.makeConnectRequestAsync<{ options: { label: string; value: string; }[]; @@ -592,7 +598,6 @@ export abstract class BaseClient { id: opts.componentId, configured_props: opts.configuredProps, dynamic_props_id: opts.dynamicPropsId, - environment: this.environment, }; // eslint-disable-next-line @typescript-eslint/no-explicit-any return await this.makeConnectRequestAsync>("/components/props", { @@ -614,7 +619,6 @@ export abstract class BaseClient { id: opts.actionId, configured_props: opts.configuredProps, dynamic_props_id: opts.dynamicPropsId, - environment: this.environment, }; return await this.makeConnectRequestAsync<{ exports: unknown; @@ -626,6 +630,27 @@ export abstract class BaseClient { }); } + public async triggerDeploy(opts: { + userId: string; + triggerId: string; + configuredProps: Record; // eslint-disable-line @typescript-eslint/no-explicit-any + dynamicPropsId?: string; + webhookUrl?: string; + }) { + const body = { + async_handle: this.asyncResponseManager.createAsyncHandle(), + external_user_id: opts.userId, + id: opts.triggerId, + configured_props: opts.configuredProps, + dynamic_props_id: opts.dynamicPropsId, + webhook_url: opts.webhookUrl, + } + return await this.makeConnectRequestAsync("/triggers/deploy", { + method: "POST", + body, + }); + } + /** * Builds a full workflow URL based on the input. * diff --git a/packages/sdk/src/version.ts b/packages/sdk/src/version.ts new file mode 100644 index 0000000000000..6cdfb0c994f91 --- /dev/null +++ b/packages/sdk/src/version.ts @@ -0,0 +1,2 @@ +// 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 index 83828fc1f2d5f..ecb99678859d1 100644 --- a/packages/sdk/tsconfig.browser.json +++ b/packages/sdk/tsconfig.browser.json @@ -10,7 +10,8 @@ "forceConsistentCasingInFileNames": true, "moduleResolution": "node", "skipLibCheck": true, - "types": [] + "types": [], + "allowJs": true }, "include": [ "src/browser/**/*" diff --git a/packages/sdk/tsconfig.node.json b/packages/sdk/tsconfig.node.json index aac923e1f200d..cc120280d0d23 100644 --- a/packages/sdk/tsconfig.node.json +++ b/packages/sdk/tsconfig.node.json @@ -10,6 +10,7 @@ "strict": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, + "allowJs": true, "allowSyntheticDefaultImports": true, "skipLibCheck": true, "sourceMap": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 641f9a8ec00c3..2c4cac9fe597c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,6 +57,9 @@ importers: eslint-config-next: specifier: ^15 version: 15.0.3(eslint@8.57.1)(typescript@5.6.3) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-jest: specifier: ^28 version: 28.9.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(jest@29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0))(typescript@5.6.3) @@ -30514,7 +30517,7 @@ snapshots: agent-base@7.1.1: dependencies: - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -32987,7 +32990,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -33562,7 +33565,7 @@ snapshots: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) fs-extra: 11.2.0 transitivePeerDependencies: - supports-color @@ -34185,7 +34188,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -36817,7 +36820,7 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) get-uri: 6.0.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 @@ -37319,7 +37322,7 @@ snapshots: proxy-agent@6.3.1: dependencies: agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 lru-cache: 7.18.3 @@ -38631,7 +38634,7 @@ snapshots: socks-proxy-agent@8.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.7(supports-color@9.4.0) socks: 2.8.3 transitivePeerDependencies: - supports-color