Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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 components/bitget/bitget.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/explorium/explorium.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/hana/hana.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/indiefunnels/indiefunnels.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/joggai/joggai.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/mumble/mumble.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/sign_plus/sign_plus.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
2 changes: 1 addition & 1 deletion components/webscrape_ai/webscrape_ai.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export default {
console.log(Object.keys(this.$auth));
},
},
};
};
6 changes: 6 additions & 0 deletions packages/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

# Changelog

## [1.7.0] - 2025-07-03

### Added

- Added optional scope parameter to backendClient creation.

## [1.6.11] - 2025-07-02

### 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.6.11",
"version": "1.7.0",
"description": "Pipedream SDK",
"main": "./dist/server.js",
"module": "./dist/server.js",
Expand Down
96 changes: 75 additions & 21 deletions packages/sdk/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
* https://pipedream.com/docs/workflows/domains
*/
workflowDomain?: string;

/**
* OAuth scope to request when obtaining access tokens
*/
scope?: string[];
};

/**
Expand Down Expand Up @@ -197,6 +202,7 @@
};
protected override projectId: string = "";
private staticAccessToken?: string;
private scope?: string[];

/**
* Constructs a new ServerClient instance.
Expand All @@ -209,6 +215,7 @@

this.ensureValidEnvironment(opts.environment);
this.projectId = opts.projectId;
this.scope = opts.scope;
if ("accessToken" in opts.credentials) {
this.staticAccessToken = opts.credentials.accessToken;
} else {
Expand Down Expand Up @@ -264,6 +271,16 @@
return this.ensureValidOauthAccessToken();
}

/**s
* Returns true if the client is configured to use a static access token.
*
* @returns True if the client is configured to use a static access token.
*
*/
public isStaticAccessToken(): boolean {
return !!this.staticAccessToken;
}

protected authHeaders(): string | Promise<string> {
if (this.staticAccessToken) {
return `Bearer ${this.staticAccessToken}`;
Expand All @@ -281,31 +298,68 @@
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));
for (let attempts = 0; attempts <= maxAttempts; attempts++) {
Comment on lines 301 to +304
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Clarify the retry attempt count.

The variable is named maxAttempts = 2 but the loop condition attempts <= maxAttempts means it will actually attempt 3 times (0, 1, 2). This is confusing.

Either rename the variable or adjust the loop condition:

-    const maxAttempts = 2;
+    const maxAttempts = 3; // Total attempts including the initial one

Or:

-      for (let attempts = 0; attempts <= maxAttempts; attempts++) {
+      for (let attempts = 0; attempts < maxAttempts; attempts++) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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));
for (let attempts = 0; attempts <= maxAttempts; attempts++) {
const maxAttempts = 2;
while (!this.oauthAccessToken || this.oauthAccessToken.expiresAt - Date.now() < 1000) {
for (let attempts = 0; attempts < maxAttempts; attempts++) {
🤖 Prompt for AI Agents
In packages/sdk/src/server/index.ts around lines 301 to 304, the retry loop uses
maxAttempts = 2 but the loop condition attempts <= maxAttempts causes three
attempts (0, 1, 2), which is confusing. To fix this, either rename maxAttempts
to maxAttemptIndex or change the loop condition to attempts < maxAttempts so the
number of attempts matches the variable name and intent.

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);

Check failure on line 316 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Trailing spaces not allowed
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,
};
break; // Successfully got token, exit retry loop
} catch (e) {
// Extract error details from OAuth response
let errorMessage = "OAuth token request failed";
let wwwAuthenticate: string | undefined;
let statusCode: number | undefined;

Check failure on line 330 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Trailing spaces not allowed
if (e instanceof Error) {
errorMessage = e.message;
}

Check failure on line 334 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Trailing spaces not allowed
// Check if the error contains response information
if (e && typeof e === 'object' && 'response' in e) {

Check failure on line 336 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Strings must use doublequote

Check failure on line 336 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Strings must use doublequote
const errorResponse = (e as any).response;

Check failure on line 337 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Unexpected any. Specify a different type
if (errorResponse) {
statusCode = errorResponse.status;
wwwAuthenticate = errorResponse.headers?.get?.('www-authenticate') ||

Check failure on line 340 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Trailing spaces not allowed

Check failure on line 340 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Strings must use doublequote
errorResponse.headers?.['www-authenticate'];

Check failure on line 341 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Strings must use doublequote

Check failure on line 342 in packages/sdk/src/server/index.ts

View workflow job for this annotation

GitHub Actions / Lint Code Base

Trailing spaces not allowed
// Create more specific error message based on status code
if (statusCode === 401) {
errorMessage = `OAuth authentication failed (401 Unauthorized)${wwwAuthenticate ? `: ${wwwAuthenticate}` : ''}`;
} else if (statusCode === 400) {
errorMessage = "OAuth request invalid (400 Bad Request) - check client credentials";
} else if (statusCode) {
errorMessage = `OAuth request failed with status ${statusCode}`;
}
}
}

// If this is the last attempt, throw a detailed error
if (attempts >= maxAttempts) {
const error = new Error(errorMessage);
(error as any).statusCode = statusCode;
(error as any).wwwAuthenticate = wwwAuthenticate;
throw error;
}
}
}

const parameters = new URLSearchParams();
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;
Expand Down
8 changes: 8 additions & 0 deletions packages/sdk/src/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,14 @@ export type ErrorResponse = {
* The error message returned by the API.
*/
error: string;
/**
* The www-authenticate header value, if present in the error response.
*/
wwwAuthenticate?: string;
/**
* Additional error headers that may be relevant for error handling.
*/
headers?: Record<string, string>;
};

/**
Expand Down
3 changes: 1 addition & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading