Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.15.0",
"@next/eslint-plugin-next": "^14.2.5",
"@pipedream/types": "0.1.4",
"@tsconfig/node14": "^1.0.1",
"@types/jest": "^27.4.1",
Expand All @@ -59,7 +60,6 @@
"husky": "^7.0.4",
"jest": "^29.7.0",
"lint-staged": "^12.3.4",
"@next/eslint-plugin-next": "^14.2.5",
"pnpm": "9.14.2",
"putout": ">=36",
"renamer": "^4.0.0",
Expand Down
8 changes: 8 additions & 0 deletions packages/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

# Changelog

## [1.5.1] - 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.0] - 2025-04-08

### Added
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@pipedream/sdk",
"type": "module",
"version": "1.5.0",
"version": "1.5.1",
"description": "Pipedream SDK",
"main": "./dist/server.js",
"module": "./dist/server.js",
Expand Down
71 changes: 64 additions & 7 deletions packages/sdk/src/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,59 @@ export interface AsyncRequestOptions extends RequestOptions {
body: { async_handle: string; } & Required<RequestOptions["body"]>;
}

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<string, any> = {};
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.
*/
Expand Down Expand Up @@ -961,20 +1014,24 @@ export abstract class BaseClient {

const response: Response = await fetch(url.toString(), requestOptions);

const rawBody = await response.text();

if (!response.ok) {
const errorBody = await response.text();
throw new Error(
`HTTP error! status: ${response.status}, body: ${errorBody}`,
);
throw new Error(`HTTP error! status: ${response.status}, body: ${rawBody}`);
}

// Attempt to parse JSON, fall back to raw text if it fails
DEBUG(response.status, url.toString(), requestOptions, rawBody)
const contentType = response.headers.get("Content-Type");
if (contentType && contentType.includes("application/json")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have used optional chaining I guess.

return (await response.json()) as T;
try {
const json = JSON.parse(rawBody);
return json as T;
} catch (err) {
DEBUG("Couldn't parse json, falling back to raw", err)
}
}

return (await response.text()) as unknown as T;
return rawBody as unknown as T;
}

protected abstract authHeaders(): string | Promise<string>;
Expand Down
5 changes: 5 additions & 0 deletions packages/sdk/src/shared/shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare const process: {
env?: {
[key: string]: string | undefined;
};
} | undefined;
1 change: 1 addition & 0 deletions packages/sdk/tsconfig.browser.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"allowJs": true
},
"include": [
"src/shared/shims.d.ts",
"src/browser/**/*"
],
"exclude": [
Expand Down
Loading
Loading