Skip to content

Commit 8e728ed

Browse files
committed
Merge branch 'main' of https://github.com/Bandwidth/node-sdk into SWI-9204
2 parents d4f3ffe + 1bb5418 commit 8e728ed

20 files changed

+148
-25
lines changed

.github/workflows/deploy.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ jobs:
1313
BW_ACCOUNT_ID: ${{ secrets.BW_ACCOUNT_ID }}
1414
BW_USERNAME: ${{ secrets.BW_USERNAME }}
1515
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
16+
BW_CLIENT_ID: ${{ secrets.BW_CLIENT_ID }}
17+
BW_CLIENT_SECRET: ${{ secrets.BW_CLIENT_SECRET }}
1618
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
1719
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
1820
BW_VOICE_APPLICATION_ID: ${{ secrets.BW_VOICE_APPLICATION_ID }}
@@ -46,7 +48,7 @@ jobs:
4648
- name: Setup Node
4749
uses: actions/setup-node@v6
4850
with:
49-
node-version: 22
51+
node-version: 24
5052
registry-url: "https://registry.npmjs.org"
5153

5254
- name: Set OpenAPI Generator Version

.github/workflows/test-pr.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ env:
1313
BW_ACCOUNT_ID: ${{ secrets.BW_ACCOUNT_ID }}
1414
BW_USERNAME: ${{ secrets.BW_USERNAME }}
1515
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
16+
BW_CLIENT_ID: ${{ secrets.BW_CLIENT_ID }}
17+
BW_CLIENT_SECRET: ${{ secrets.BW_CLIENT_SECRET }}
1618
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
1719
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
1820
BW_VOICE_APPLICATION_ID: ${{ secrets.BW_VOICE_APPLICATION_ID }}
@@ -32,7 +34,7 @@ jobs:
3234
strategy:
3335
matrix:
3436
os: [windows-2022, windows-2025, ubuntu-22.04, ubuntu-24.04]
35-
node-version: [18, 20, 22, 24]
37+
node-version: [20, 22, 24]
3638
fail-fast: false
3739
steps:
3840
- name: Checkout

.github/workflows/test-smoke.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ concurrency:
1515
env:
1616
BW_USERNAME: ${{ secrets.BW_USERNAME }}
1717
BW_PASSWORD: ${{ secrets.BW_PASSWORD }}
18+
BW_CLIENT_ID: ${{ secrets.BW_CLIENT_ID }}
19+
BW_CLIENT_SECRET: ${{ secrets.BW_CLIENT_SECRET }}
1820
BW_USERNAME_FORBIDDEN: ${{ secrets.BW_USERNAME_FORBIDDEN }}
1921
BW_PASSWORD_FORBIDDEN: ${{ secrets.BW_PASSWORD_FORBIDDEN }}
2022
USER_NUMBER: ${{ secrets.USER_NUMBER }}
@@ -40,7 +42,7 @@ jobs:
4042
- name: Setup Node
4143
uses: actions/setup-node@v6
4244
with:
43-
node-version: 22
45+
node-version: 24
4446

4547
- name: Install Packages and Test
4648
run: |
@@ -67,7 +69,7 @@ jobs:
6769
- name: Setup Node
6870
uses: actions/setup-node@v6
6971
with:
70-
node-version: 22
72+
node-version: 24
7173

7274
- name: Install Packages and Test
7375
run: |

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ The following is a simple example of how to use this module:
8484
import { CallsApi, Configuration } from 'bandwidth-sdk';
8585

8686
const config = new Configuration({
87-
username: BW_USERNAME,
88-
password: BW_PASSWORD
87+
clientId: BW_CLIENT_ID,
88+
clientSecret: BW_CLIENT_SECRET
8989
});
9090
const callsApi = new CallsApi(config);
9191

common.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ export const setOAuthToObject = async function (object: any, name: string, scope
5858
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
5959
? await configuration.accessToken(name, scopes)
6060
: await configuration.accessToken;
61-
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
61+
if (localVarAccessTokenValue) {
62+
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
63+
}
6264
}
6365
}
6466

configuration.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* Do not edit the class manually.
1212
*/
1313

14+
import globalAxios from 'axios';
15+
1416
interface AWSv4Configuration {
1517
options?: {
1618
region?: string
@@ -27,6 +29,8 @@ export interface ConfigurationParameters {
2729
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
2830
username?: string;
2931
password?: string;
32+
clientId?: string;
33+
clientSecret?: string;
3034
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
3135
awsv4?: AWSv4Configuration;
3236
basePath?: string;
@@ -49,12 +53,28 @@ export class Configuration {
4953
* parameter for basic security
5054
*/
5155
password?: string;
56+
/**
57+
* parameter for client ID
58+
*/
59+
clientId?: string;
60+
/**
61+
* parameter for client secret
62+
*/
63+
clientSecret?: string;
5264
/**
5365
* parameter for oauth2 security
5466
* @param name security name
5567
* @param scopes oauth2 scope
5668
*/
5769
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
70+
/**
71+
* temporary access token storage
72+
*/
73+
tempAccessToken?: string;
74+
/**
75+
* when the temporary access token expires
76+
*/
77+
tempAccessTokenExpiration?: number;
5878
/**
5979
* parameter for aws4 signature security
6080
* @param {Object} AWS4Signature - AWS4 Signature security
@@ -91,7 +111,29 @@ export class Configuration {
91111
this.apiKey = param.apiKey;
92112
this.username = param.username;
93113
this.password = param.password;
94-
this.accessToken = param.accessToken;
114+
this.clientId = param.clientId;
115+
this.clientSecret = param.clientSecret;
116+
this.tempAccessToken;
117+
this.tempAccessTokenExpiration;
118+
this.accessToken = param.accessToken ?? (async (name, scopes) => {
119+
const now = Math.floor(Date.now() / 1000);
120+
if (this.tempAccessToken && (!this.tempAccessTokenExpiration || this.tempAccessTokenExpiration > now + 60)) {
121+
return this.tempAccessToken;
122+
} else if (this.clientId && this.clientSecret) {
123+
const tokenRequestArgs = {
124+
method: 'POST',
125+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
126+
auth: { username: this.clientId || '', password: this.clientSecret || '' },
127+
data: 'grant_type=client_credentials',
128+
url: 'https://api.bandwidth.com/api/v1/oauth2/token'
129+
};
130+
const response = await globalAxios.request(tokenRequestArgs);
131+
this.tempAccessToken = response.data.access_token;
132+
this.tempAccessTokenExpiration = now + response.data.expires_in;
133+
return this.tempAccessToken!;
134+
}
135+
return undefined;
136+
});
95137
this.awsv4 = param.awsv4;
96138
this.basePath = param.basePath;
97139
this.serverIndex = param.serverIndex;

custom_templates/README.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ The following is a simple example of how to use this module:
8484
import { CallsApi, Configuration } from '{{npmName}}';
8585

8686
const config = new Configuration({
87-
username: BW_USERNAME,
88-
password: BW_PASSWORD
87+
clientId: BW_CLIENT_ID,
88+
clientSecret: BW_CLIENT_SECRET
8989
});
9090
const callsApi = new CallsApi(config);
9191

custom_templates/common.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ export const setOAuthToObject = async function (object: any, name: string, scope
5454
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
5555
? await configuration.accessToken(name, scopes)
5656
: await configuration.accessToken;
57-
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
57+
if (localVarAccessTokenValue) {
58+
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
59+
}
5860
}
5961
}
6062

custom_templates/configuration.mustache

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* tslint:disable */
22
{{>licenseInfo}}
33

4+
import globalAxios from 'axios';
5+
46
interface AWSv4Configuration {
57
options?: {
68
region?: string
@@ -17,6 +19,8 @@ export interface ConfigurationParameters {
1719
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
1820
username?: string;
1921
password?: string;
22+
clientId?: string;
23+
clientSecret?: string;
2024
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
2125
awsv4?: AWSv4Configuration;
2226
basePath?: string;
@@ -39,12 +43,28 @@ export class Configuration {
3943
* parameter for basic security
4044
*/
4145
password?: string;
46+
/**
47+
* parameter for client ID
48+
*/
49+
clientId?: string;
50+
/**
51+
* parameter for client secret
52+
*/
53+
clientSecret?: string;
4254
/**
4355
* parameter for oauth2 security
4456
* @param name security name
4557
* @param scopes oauth2 scope
4658
*/
4759
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
60+
/**
61+
* temporary access token storage
62+
*/
63+
tempAccessToken?: string;
64+
/**
65+
* when the temporary access token expires
66+
*/
67+
tempAccessTokenExpiration?: number;
4868
/**
4969
* parameter for aws4 signature security
5070
* @param {Object} AWS4Signature - AWS4 Signature security
@@ -81,7 +101,29 @@ export class Configuration {
81101
this.apiKey = param.apiKey;
82102
this.username = param.username;
83103
this.password = param.password;
84-
this.accessToken = param.accessToken;
104+
this.clientId = param.clientId;
105+
this.clientSecret = param.clientSecret;
106+
this.tempAccessToken;
107+
this.tempAccessTokenExpiration;
108+
this.accessToken = param.accessToken ?? (async (name, scopes) => {
109+
const now = Math.floor(Date.now() / 1000);
110+
if (this.tempAccessToken && (!this.tempAccessTokenExpiration || this.tempAccessTokenExpiration > now + 60)) {
111+
return this.tempAccessToken;
112+
} else if (this.clientId && this.clientSecret) {
113+
const tokenRequestArgs = {
114+
method: 'POST',
115+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
116+
auth: { username: this.clientId || '', password: this.clientSecret || '' },
117+
data: 'grant_type=client_credentials',
118+
url: 'https://api.bandwidth.com/api/v1/oauth2/token'
119+
};
120+
const response = await globalAxios.request(tokenRequestArgs);
121+
this.tempAccessToken = response.data.access_token;
122+
this.tempAccessTokenExpiration = now + response.data.expires_in;
123+
return this.tempAccessToken!;
124+
}
125+
return undefined;
126+
});
85127
this.awsv4 = param.awsv4;
86128
this.basePath = param.basePath;
87129
this.serverIndex = param.serverIndex;

custom_templates/package.mustache

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,20 @@
2828
"test-smoke": "jest --coverage --detectOpenHandles --testPathPattern=tests/smoke",
2929
"test": "jest --coverage --detectOpenHandles"
3030
},
31+
"engines": {
32+
"node": ">=20.0.0"
33+
},
3134
"dependencies": {
3235
"axios": "^1.7.2",
33-
"xmlbuilder2": "^3.1.1"
36+
"xmlbuilder2": "^4.0.0"
3437
},
3538
"devDependencies": {
3639
"@types/jest": "^29.5.12",
3740
"@types/node": "^12.11.5",
3841
"jest": "^29.7.0",
3942
"jest-extended": "^4.0.2",
4043
"ts-jest": "^29.1.1",
41-
"typescript": "^5.0"
44+
"typescript": "^5.9.0"
4245
}{{#npmRepository}},{{/npmRepository}}
4346
{{#npmRepository}}
4447
"publishConfig": {

0 commit comments

Comments
 (0)