Skip to content

Commit 4828583

Browse files
authored
Merge branch 'v4.x' into heenagupta/jsChangesForMySql
2 parents 98f13c0 + 9259cfc commit 4828583

16 files changed

+278
-11
lines changed

azure-pipelines/templates/build.yml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ jobs:
1616
displayName: 'Install Node.js'
1717
- script: npm ci
1818
displayName: 'npm ci'
19+
- script: npm audit --production
20+
displayName: 'Run vulnerability scan'
1921
- script: npm run updateVersion -- --buildNumber $(Build.BuildNumber)
2022
displayName: 'npm run updateVersion'
2123
condition: and(succeeded(), eq(${{ parameters.IsPrerelease }}, true))

package-lock.json

+9-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@azure/functions",
3-
"version": "4.6.0",
3+
"version": "4.6.1",
44
"description": "Microsoft Azure Functions NodeJS Framework",
55
"keywords": [
66
"azure",

src/app.ts

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
StorageQueueFunctionOptions,
2020
TimerFunctionOptions,
2121
WarmupFunctionOptions,
22+
WebPubSubFunctionOptions,
2223
} from '@azure/functions';
2324
import { FunctionCallback } from '@azure/functions-core';
2425
import { toCoreFunctionMetadata } from './converters/toCoreFunctionMetadata';
@@ -140,6 +141,10 @@ export function mySql(name: string, options: MySqlFunctionOptions): void {
140141
generic(name, convertToGenericOptions(options, trigger.mySql));
141142
}
142143

144+
export function webPubSub(name: string, options: WebPubSubFunctionOptions): void {
145+
generic(name, convertToGenericOptions(options, trigger.webPubSub));
146+
}
147+
143148
export function generic(name: string, options: GenericFunctionOptions): void {
144149
if (!hasSetModel) {
145150
setProgrammingModel();

src/constants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
export const version = '4.6.0';
4+
export const version = '4.6.1';
55

66
export const returnBindingKey = '$return';

src/http/httpProxy.ts

+55-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
import { serialize as serializeCookie } from 'cookie';
55
import { EventEmitter } from 'events';
66
import * as http from 'http';
7+
import * as net from 'net';
78
import { AzFuncSystemError, ensureErrorType } from '../errors';
89
import { nonNullProp } from '../utils/nonNull';
910
import { workerSystemLog } from '../utils/workerSystemLog';
1011
import { HttpResponse } from './HttpResponse';
1112

1213
const requests: Record<string, http.IncomingMessage> = {};
1314
const responses: Record<string, http.ServerResponse> = {};
15+
const minPort = 55000;
16+
const maxPort = 55025;
1417

1518
const invocRequestEmitter = new EventEmitter();
1619

@@ -105,8 +108,24 @@ export async function setupHttpProxy(): Promise<string> {
105108

106109
server.listen(() => {
107110
const address = server.address();
111+
// Valid address has been created
108112
if (address !== null && typeof address === 'object') {
109-
resolve(`http://localhost:${address.port}/`);
113+
if (address.port === 0) {
114+
// Auto-assigned port is 0, find and bind to an open port
115+
workerSystemLog('debug', `Port 0 assigned. Finding open port.`);
116+
findOpenPort((openPort: number) => {
117+
// Close the server and re-listen on the found open port
118+
server.close();
119+
server.listen(openPort, () => {
120+
workerSystemLog('debug', `Server is now listening on found open port: ${openPort}`);
121+
});
122+
resolve(`http://localhost:${openPort}/`);
123+
});
124+
} else {
125+
// Auto-assigned port is not 0
126+
workerSystemLog('debug', `Auto-assigned port is valid. Port: ${address.port}`);
127+
resolve(`http://localhost:${address.port}/`);
128+
}
110129
} else {
111130
reject(new AzFuncSystemError('Unexpected server address during http proxy setup'));
112131
}
@@ -117,3 +136,38 @@ export async function setupHttpProxy(): Promise<string> {
117136
});
118137
});
119138
}
139+
140+
// Function to find an open port starting from a specified port
141+
function findOpenPort(callback: (port: number) => void): void {
142+
const server = net.createServer();
143+
144+
function tryPort(port: number) {
145+
if (port > maxPort) {
146+
// If we've reached the maximum port, throw an error
147+
throw new AzFuncSystemError(
148+
`No available ports found between ${minPort} and ${maxPort}. To enable HTTP streaming, please open a port in this range.`
149+
);
150+
}
151+
152+
server.once('error', () => {
153+
// If the port is unavailable, increment and try the next one
154+
tryPort(port + 1);
155+
});
156+
157+
// If the port is available, return it
158+
server.once('listening', () => {
159+
const address = server.address();
160+
if (address !== null && typeof address === 'object') {
161+
port = address.port;
162+
server.close();
163+
callback(port);
164+
}
165+
});
166+
167+
// Try binding to the given port
168+
server.listen(port);
169+
}
170+
171+
// Start trying from the specified starting port
172+
tryPort(minPort);
173+
}

src/input.ts

+18
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import {
1414
StorageBlobInputOptions,
1515
TableInput,
1616
TableInputOptions,
17+
WebPubSubConnectionInput,
18+
WebPubSubConnectionInputOptions,
19+
WebPubSubContextInput,
20+
WebPubSubContextInputOptions,
1721
} from '@azure/functions';
1822
import { addBindingName } from './addBindingName';
1923

@@ -52,6 +56,20 @@ export function mySql(options: MySqlInputOptions): MySqlInput {
5256
});
5357
}
5458

59+
export function webPubSubConnection(options: WebPubSubConnectionInputOptions): WebPubSubConnectionInput {
60+
return addInputBindingName({
61+
...options,
62+
type: 'webPubSubConnection',
63+
});
64+
}
65+
66+
export function webPubSubContext(options: WebPubSubContextInputOptions): WebPubSubContextInput {
67+
return addInputBindingName({
68+
...options,
69+
type: 'webPubSubContext',
70+
});
71+
}
72+
5573
export function generic(options: GenericInputOptions): FunctionInput {
5674
return addInputBindingName(options);
5775
}

src/output.ts

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import {
2626
StorageQueueOutputOptions,
2727
TableOutput,
2828
TableOutputOptions,
29+
WebPubSubOutput,
30+
WebPubSubOutputOptions,
2931
} from '@azure/functions';
3032
import { addBindingName } from './addBindingName';
3133

@@ -106,6 +108,13 @@ export function mySql(options: MySqlOutputOptions): MySqlOutput {
106108
});
107109
}
108110

111+
export function webPubSub(options: WebPubSubOutputOptions): WebPubSubOutput {
112+
return addOutputBindingName({
113+
...options,
114+
type: 'webPubSub',
115+
});
116+
}
117+
109118
export function generic(options: GenericOutputOptions): FunctionOutput {
110119
return addOutputBindingName(options);
111120
}

src/trigger.ts

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import {
2828
TimerTriggerOptions,
2929
WarmupTrigger,
3030
WarmupTriggerOptions,
31+
WebPubSubTrigger,
32+
WebPubSubTriggerOptions,
3133
} from '@azure/functions';
3234
import { addBindingName } from './addBindingName';
3335

@@ -117,6 +119,13 @@ export function mySql(options: MySqlTriggerOptions): MySqlTrigger {
117119
});
118120
}
119121

122+
export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger {
123+
return addTriggerBindingName({
124+
...options,
125+
type: 'webPubSubTrigger',
126+
});
127+
}
128+
120129
export function generic(options: GenericTriggerOptions): FunctionTrigger {
121130
return addTriggerBindingName(options);
122131
}

types/InvocationContext.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ServiceBusQueueOutput, ServiceBusTopicOutput } from './serviceBus';
1111
import { SqlInput, SqlOutput } from './sql';
1212
import { StorageBlobInput, StorageBlobOutput, StorageQueueOutput } from './storage';
1313
import { TableInput, TableOutput } from './table';
14+
import { WebPubSubOutput } from './webpubsub';
1415

1516
/**
1617
* Contains metadata and helper methods specific to this invocation
@@ -230,6 +231,13 @@ export interface InvocationContextExtraOutputs {
230231
*/
231232
set(output: MySqlOutput, items: unknown): void;
232233

234+
/**
235+
* Set a secondary Web PubSub output for this invocation
236+
* @output the configuration object for this Web PubSub output
237+
* @message the output message(s) value
238+
*/
239+
set(output: WebPubSubOutput, messages: unknown): void;
240+
233241
/**
234242
* Set a secondary generic output for this invocation
235243
* @outputOrName the configuration object or name for this output

types/app.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { SqlFunctionOptions } from './sql';
1313
import { StorageBlobFunctionOptions, StorageQueueFunctionOptions } from './storage';
1414
import { TimerFunctionOptions } from './timer';
1515
import { WarmupFunctionOptions } from './warmup';
16+
import { WebPubSubFunctionOptions } from './webpubsub';
1617

1718
/**
1819
* Optional method to configure the behavior of your app.
@@ -188,4 +189,11 @@ export function mySql(name: string, options: MySqlFunctionOptions): void;
188189
*/
189190
export function generic(name: string, options: GenericFunctionOptions): void;
190191

192+
/**
193+
* Registers a WebPubSub function in your app that will be triggered by WebPubSub events
194+
* @param name The name of the function. The name must be unique within your app and will mostly be used for your own tracking purposes
195+
* @param options Configuration options describing the inputs, outputs, and handler for this function
196+
*/
197+
export function webPubSub(name: string, options: WebPubSubFunctionOptions): void;
198+
191199
export * as hook from './hooks/registerHook';

types/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export * from './table';
2727
export * from './timer';
2828
export * as trigger from './trigger';
2929
export * from './warmup';
30+
export * from './webpubsub';
3031

3132
/**
3233
* Void if no `return` output is registered

types/input.d.ts

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import { SqlInput, SqlInputOptions } from './sql';
88
import { StorageBlobInput, StorageBlobInputOptions } from './storage';
99
import { TableInput, TableInputOptions } from './table';
1010
import { MySqlInput, MySqlInputOptions } from './mySql';
11+
import {
12+
WebPubSubConnectionInput,
13+
WebPubSubConnectionInputOptions,
14+
WebPubSubContextInput,
15+
WebPubSubContextInputOptions,
16+
} from './webpubsub';
1117

1218
/**
1319
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-storage-blob-input?pivots=programming-language-javascript)
@@ -34,6 +40,16 @@ export function sql(options: SqlInputOptions): SqlInput;
3440
*/
3541
export function mySql(options: MySqlInputOptions): MySqlInput;
3642

43+
/**
44+
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-input?pivots=programming-language-javascript)
45+
*/
46+
export function webPubSubConnection(options: WebPubSubConnectionInputOptions): WebPubSubConnectionInput;
47+
48+
/**
49+
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-input?pivots=programming-language-javascript)
50+
*/
51+
export function webPubSubContext(options: WebPubSubContextInputOptions): WebPubSubContextInput;
52+
3753
/**
3854
* A generic option that can be used for any input type
3955
* Use this method if your desired input type does not already have its own method

types/output.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { SqlOutput, SqlOutputOptions } from './sql';
1717
import { StorageBlobOutput, StorageBlobOutputOptions, StorageQueueOutput, StorageQueueOutputOptions } from './storage';
1818
import { TableOutput, TableOutputOptions } from './table';
1919
import { MySqlOutput, MySqlOutputOptions } from './mySql';
20+
import { WebPubSubOutput, WebPubSubOutputOptions } from './webpubsub';
2021

2122
/**
2223
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-http-webhook-output?&pivots=programming-language-javascript)
@@ -73,6 +74,11 @@ export function sql(options: SqlOutputOptions): SqlOutput;
7374
*/
7475
export function mySql(options: MySqlOutputOptions): MySqlOutput;
7576

77+
/**
78+
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-output?pivots=programming-language-javascript)
79+
*/
80+
export function webPubSub(options: WebPubSubOutputOptions): WebPubSubOutput;
81+
7682
/**
7783
* A generic option that can be used for any output type
7884
* Use this method if your desired output type does not already have its own method

types/trigger.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
} from './storage';
2424
import { TimerTrigger, TimerTriggerOptions } from './timer';
2525
import { WarmupTrigger, WarmupTriggerOptions } from './warmup';
26+
import { WebPubSubTrigger, WebPubSubTriggerOptions } from './webpubsub';
2627

2728
/**
2829
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-http-webhook-trigger?&pivots=programming-language-javascript)
@@ -84,6 +85,11 @@ export function sql(options: SqlTriggerOptions): SqlTrigger;
8485
*/
8586
export function mySql(options: MySqlTriggerOptions): MySqlTrigger;
8687

88+
/**
89+
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-web-pubsub-trigger?pivots=programming-language-javascript)
90+
*/
91+
export function webPubSub(options: WebPubSubTriggerOptions): WebPubSubTrigger;
92+
8793
/**
8894
* A generic option that can be used for any trigger type
8995
* Use this method if your desired trigger type does not already have its own method

0 commit comments

Comments
 (0)