Skip to content

Commit 26353ae

Browse files
committed
feat: upgrade Twilio SDK to v5 and require as peer dependency
WHAT: - Upgraded the core `twilio` Node.js helper library to v5.5.2 across relevant packages (`runtime-handler`, `create-twilio-function` defaults, test dependencies). - Changed `@twilio-labs/serverless-runtime-types` and `@twilio-labs/twilio-run` to declare `twilio` as a `peerDependency` (^5.5.2) instead of a direct dependency. - Updated internal type definitions (`ClientOpts`) for compatibility with `[email protected]`. - Updated Twilio Console URL generation logic in `twilio-run`. - Updated default dependencies (`typescript`, `serverlessRuntimeTypes`) used by `create-twilio-function`. WHY: - Aligns the toolkit with the latest Twilio SDK features, improvements, and security updates available in v5. - Resolves potential version conflicts and type mismatches (e.g., TS2322/TS2352) by ensuring a single `twilio` instance is used, managed explicitly by the consuming project. This promotes a more stable and predictable dependency graph. BREAKING CHANGE: Consumers of `@twilio-labs/twilio-run` or projects directly importing types from `@twilio-labs/serverless-runtime-types` MUST now explicitly install `twilio` as a direct dependency in their own project. Add the `twilio` dependency: ```bash npm install twilio@^5.5.2 --save-dev yarn add twilio@^5.5.2 --dev ```
1 parent 14e4d32 commit 26353ae

File tree

15 files changed

+89
-33
lines changed

15 files changed

+89
-33
lines changed

Diff for: .changeset/heavy-moose-appear.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
'@twilio-labs/serverless-runtime-types': major
3+
'twilio-run': major
4+
'create-twilio-function': minor
5+
'@twilio/runtime-handler': minor
6+
---
7+
8+
feat: Upgrade Twilio SDK to v5 and use peer dependency
9+
10+
**WHAT:**
11+
- Upgraded the core `twilio` Node.js helper library to v5.5.2 across the toolkit.
12+
- Changed `@twilio-labs/serverless-runtime-types` and `@twilio-labs/twilio-run` to require `twilio` as a `peerDependency` instead of a direct dependency.
13+
- Updated type definitions (`ClientOpts`) for compatibility with `[email protected]`.
14+
- Updated default dependencies (`twilio`, `typescript`, `serverlessRuntimeTypes`) used by `@twilio-labs/create-twilio-function`.
15+
16+
**WHY:**
17+
- Aligns the toolkit with the latest Twilio SDK features, improvements, and security updates.
18+
- Resolves potential type conflicts (e.g., `TS2322`/`TS2352`) by ensuring a single `twilio` instance, managed by the user's project.
19+
20+
**HOW:**
21+
**BREAKING CHANGE:** Users of `@twilio-labs/twilio-run` or projects importing types from `@twilio-labs/serverless-runtime-types` **must** now add `twilio` as a direct dependency to their project:
22+
```bash
23+
npm install twilio@^5.5.2
24+
# or
25+
yarn add twilio@^5.5.2
26+
```
27+
After updating toolkit packages and adding `twilio`, perform a clean install (delete `node_modules` and lock file, then run `npm install` or `yarn install`).

Diff for: package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@changesets/cli": "^2.26.0",
2727
"@commitlint/cli": "^19.1.0",
2828
"@commitlint/config-conventional": "^19.1.0",
29-
"@twilio/test-dep": "npm:twilio@4.22.0",
29+
"@twilio/test-dep": "npm:twilio@5.2.2",
3030
"@types/jest": "^29.2.4",
3131
"all-contributors-cli": "^6.1.2",
3232
"commitizen": "^4.2.4",
@@ -45,6 +45,9 @@
4545
"typedoc": "^0.27.4",
4646
"typescript": "^5.3.3"
4747
},
48+
"peerDependencies": {
49+
"twilio": "^5.5.2"
50+
},
4851
"lint-staged": {
4952
"*.{js,jsx,ts,tsx}": [
5053
"prettier --write",

Diff for: packages/create-twilio-function/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
},
2525
"license": "MIT",
2626
"devDependencies": {
27-
"@twilio/runtime-handler": "^2.0.3",
27+
"@twilio/runtime-handler": "^2.1.0",
2828
"nock": "^11.3.4"
2929
},
3030
"dependencies": {
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
const pkgJson = require('../../package.json');
22

33
module.exports = {
4-
twilio: '5.0.3',
4+
twilio: '5.5.2',
55
twilioRuntimeHandler: pkgJson.devDependencies[
66
'@twilio/runtime-handler'
77
].replace(/[\^~]/, ''),
88
twilioRun: pkgJson.dependencies['twilio-run'],
99
node: '18',
10-
typescript: '^5.3.3',
11-
serverlessRuntimeTypes: '^4.0.0',
10+
typescript: '^5.8.0',
11+
serverlessRuntimeTypes: '^4.0.1',
1212
copyfiles: '^2.4.1',
1313
};

Diff for: packages/runtime-handler/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"nocache": "^2.1.0",
7171
"normalize.css": "^8.0.1",
7272
"serialize-error": "^7.0.1",
73-
"twilio": "4.23.0"
73+
"twilio": "5.5.2"
7474
},
7575
"gitHead": "6db273648ed19474f4125042556b10c051529912"
7676
}

Diff for: packages/serverless-runtime-types/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@
2222
npm install @twilio-labs/serverless-runtime-types
2323
```
2424

25+
**Peer Dependency Requirement:**
26+
27+
This package requires the core `twilio` Node.js library as a **peer dependency** (version `^5.5.2` or compatible). This is necessary to ensure type consistency and prevent version conflicts within your project.
28+
29+
**You MUST explicitly install both `@twilio-labs/serverless-runtime-types` and a compatible version of `twilio` in your project.**
30+
31+
```bash
32+
# Using npm
33+
npm install @twilio-labs/serverless-runtime-types twilio@^5.5.2 --save-dev
34+
```
35+
2536
## Example
2637

2738
### In JavaScript

Diff for: packages/serverless-runtime-types/package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
},
3030
"dependencies": {
3131
"@types/express": "^4.17.21",
32-
"@types/qs": "^6.9.4",
33-
"twilio": "^4.23.0"
32+
"@types/qs": "^6.9.4"
3433
},
34+
"peerDependencies": {
35+
"twilio": "^5.5.2"
36+
},
3537
"devDependencies": {
3638
"all-contributors-cli": "^6.7.0",
37-
"typescript": "^5.3.3"
39+
"typescript": "^5.8.0"
3840
},
3941
"publishConfig": {
4042
"access": "public"

Diff for: packages/serverless-runtime-types/types.d.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as twilio from 'twilio';
22
import { ServiceContext } from 'twilio/lib/rest/sync/v1/service';
33
import { SyncListListInstance } from 'twilio/lib/rest/sync/v1/service/syncList';
44
import { SyncMapListInstance } from 'twilio/lib/rest/sync/v1/service/syncMap';
5-
import { TwilioClientOptions } from 'twilio/lib/rest/Twilio';
5+
import { ClientOpts } from 'twilio';
66

77
export type EnvironmentVariables = {
88
[key: string]: string | undefined;
@@ -187,7 +187,7 @@ export interface TwilioResponse {
187187
removeCookie(key: string): TwilioResponse;
188188
}
189189

190-
export type RuntimeSyncClientOptions = TwilioClientOptions & {
190+
export type RuntimeSyncClientOptions = ClientOpts & {
191191
serviceName?: string;
192192
};
193193

@@ -360,7 +360,7 @@ export type Context<T = {}> = {
360360
* };
361361
* ```
362362
*/
363-
getTwilioClient(options?: TwilioClientOptions): twilio.Twilio;
363+
getTwilioClient(options?: ClientOpts): twilio.Twilio;
364364
/**
365365
* The domain name for the Service that contains this Function.
366366
*/
@@ -412,6 +412,7 @@ export type GlobalTwilio = Omit<typeof twilio, 'default'> & {
412412
export { ServiceContext } from 'twilio/lib/rest/sync/v1/service';
413413
export { SyncListListInstance } from 'twilio/lib/rest/sync/v1/service/syncList';
414414
export { SyncMapListInstance } from 'twilio/lib/rest/sync/v1/service/syncMap';
415-
export { TwilioClientOptions } from 'twilio/lib/rest/Twilio';
415+
export { ClientOpts as TwilioClientOptions } from 'twilio/lib/rest/Twilio';
416+
416417
export type TwilioClient = twilio.Twilio;
417418
export type TwilioPackage = typeof twilio;

Diff for: packages/twilio-run/package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@
7676
"serialize-error": "^7.0.1",
7777
"terminal-link": "^1.3.0",
7878
"title": "^3.4.1",
79-
"twilio": "^4.23.0",
8079
"type-fest": "^0.15.1",
8180
"window-size": "^1.1.1",
8281
"wrap-ansi": "^7.0.0",
8382
"yargs": "^17.2.1"
8483
},
84+
"peerDependencies": {
85+
"twilio": "^5.5.2"
86+
},
8587
"optionalDependencies": {
8688
"ngrok": "^3.3.0"
8789
},
@@ -113,7 +115,7 @@
113115
"nock": "^12.0.2",
114116
"supertest": "^3.1.0",
115117
"typescript": "^4.9.4",
116-
"@twilio/test-dep": "npm:twilio@4.22.0"
118+
"@twilio/test-dep": "npm:twilio@5.5.2"
117119
},
118120
"files": [
119121
"bin/",

Diff for: packages/twilio-run/src/commands/promote.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export async function handler(
9494
config.targetEnvironment || 'production'
9595
}`
9696
);
97-
printActivateResult(result, config.outputFormat);
97+
printActivateResult(result, config.outputFormat, config.region);
9898
} catch (err) {
9999
handleError(err, spinner);
100100
}

Diff for: packages/twilio-run/src/printers/activate.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export function printActivateConfig(
2525

2626
export function printActivateResult(
2727
result: ActivateResult,
28-
outputFormat: OutputFormat
28+
outputFormat: OutputFormat,
29+
region = 'us1'
2930
) {
3031
if (outputFormat === 'json') {
3132
writeJSONOutput(result);
@@ -36,7 +37,11 @@ export function printActivateResult(
3637

3738
const twilioConsoleLogsLink = terminalLink(
3839
'Open the Twilio Console',
39-
getTwilioConsoleDeploymentUrl(result.serviceSid, result.environmentSid),
40+
getTwilioConsoleDeploymentUrl(
41+
result.serviceSid,
42+
result.environmentSid,
43+
region
44+
),
4045
{
4146
fallback: (text: string, url: string) => chalk.dim(url),
4247
}

Diff for: packages/twilio-run/src/printers/deploy.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ function plainPrintDeployedResources(
6464
runtime: result.runtime,
6565
viewLiveLogs: getTwilioConsoleDeploymentUrl(
6666
result.serviceSid,
67-
result.environmentSid
67+
result.environmentSid,
68+
config.region
6869
),
6970
};
7071

@@ -132,7 +133,11 @@ function prettyPrintDeployedResources(
132133
) {
133134
const twilioConsoleLogsLink = terminalLink(
134135
'Open the Twilio Console',
135-
getTwilioConsoleDeploymentUrl(result.serviceSid, result.environmentSid),
136+
getTwilioConsoleDeploymentUrl(
137+
result.serviceSid,
138+
result.environmentSid,
139+
config.region
140+
),
136141
{
137142
fallback: (text: string, url: string) => chalk.dim(url),
138143
}
@@ -159,8 +164,7 @@ function prettyPrintDeployedResources(
159164
const functionMessage = result.functionResources
160165
.sort(sortByAccess)
161166
.map((fn) => {
162-
const accessPrefix =
163-
chalk`{bold [${fn.access}]} `;
167+
const accessPrefix = chalk`{bold [${fn.access}]} `;
164168
return chalk` ${accessPrefix}{dim https://${result.domain}}${fn.path}`;
165169
})
166170
.join('\n');
@@ -172,8 +176,7 @@ function prettyPrintDeployedResources(
172176
const assetMessage = result.assetResources
173177
.sort(sortByAccess)
174178
.map((asset) => {
175-
const accessPrefix =
176-
chalk`{bold [${asset.access}]} `;
179+
const accessPrefix = chalk`{bold [${asset.access}]} `;
177180
const accessUrl =
178181
asset.access === 'private'
179182
? chalk`{dim Runtime.getAssets()['}${asset.path}{dim ']}`
@@ -223,7 +226,8 @@ export function printJsonDeployedResources(
223226
runtime: result.runtime,
224227
viewLiveLogs: getTwilioConsoleDeploymentUrl(
225228
result.serviceSid,
226-
result.environmentSid
229+
result.environmentSid,
230+
config.region
227231
),
228232
functions: result.functionResources.sort(sortByAccess).map(formatResource),
229233
assets: result.assetResources.sort(sortByAccess).map(formatResource),

Diff for: packages/twilio-run/src/printers/utils.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ export const supportsEmoji =
1111

1212
export function getTwilioConsoleDeploymentUrl(
1313
serviceSid: string,
14-
environmentSid: string
14+
environmentSid: string,
15+
region = 'us1'
1516
) {
16-
return `https://www.twilio.com/console/functions/editor/${serviceSid}/environment/${environmentSid}`;
17+
return `https://console.twilio.com/${region}/develop/functions/editor/${serviceSid}/environment/${environmentSid}`;
1718
}
1819

1920
export function printObjectWithoutHeaders(obj: {}): string {
@@ -27,7 +28,7 @@ export function terminalLink(name: string, link: string): string {
2728
export function borderLeft(text: string, color: string): string {
2829
return text
2930
.split('\n')
30-
.map(str => `${chalk.keyword(color)('│')} ${str}`)
31+
.map((str) => `${chalk.keyword(color)('│')} ${str}`)
3132
.join('\n');
3233
}
3334

Diff for: packages/twilio-run/src/runtime/internal/runtime.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { getDebugFunction } from '../../utils/logger';
1616

1717
const debug = getDebugFunction('twilio-run:runtime');
1818

19-
const { getCachedResources } = require('./route-cache');
19+
import { getCachedResources } from './route-cache';
2020

2121
function getAssets(): AssetResourceMap {
2222
const { assets } = getCachedResources();
@@ -72,9 +72,9 @@ export function create({ env }: StartCliConfig): RuntimeInstance {
7272
.join(',')})`,
7373
});
7474
const client = twilio(env.ACCOUNT_SID, env.AUTH_TOKEN, options);
75-
const service = (client.sync.v1.services(
75+
const service = client.sync.v1.services(
7676
serviceName || 'default'
77-
) as unknown) as RuntimeSyncServiceContext;
77+
) as unknown as RuntimeSyncServiceContext;
7878

7979
service.maps = service.syncMaps;
8080
service.lists = service.syncLists;

Diff for: packages/twilio-run/src/runtime/route.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ServerlessEventObject,
55
ServerlessFunctionSignature,
66
} from '@twilio-labs/serverless-runtime-types/types';
7+
78
import { fork } from 'child_process';
89
import {
910
NextFunction,
@@ -23,7 +24,6 @@ import { cleanUpStackTrace } from '../utils/stack-trace/clean-up';
2324
import { Reply } from './internal/functionRunner';
2425
import { Response } from './internal/response';
2526
import * as Runtime from './internal/runtime';
26-
import * as PATH from 'path';
2727

2828
const RUNNER_PATH =
2929
process.env.NODE_ENV === 'test'
@@ -40,7 +40,7 @@ export function constructEvent<T extends ServerlessEventObject>(
4040
return { ...req.query, ...req.body };
4141
}
4242

43-
export function constructContext<T extends {} = {}>(
43+
export function constructContext(
4444
{ url, env }: StartCliConfig,
4545
functionPath: string
4646
): Context<{

0 commit comments

Comments
 (0)