@azure/web-pubsub 1.1.0-alpha.20221107.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/index.js +443 -294
- package/dist/index.js.map +1 -1
- package/dist-esm/src/generated/generatedClient.js +51 -3
- package/dist-esm/src/generated/generatedClient.js.map +1 -1
- package/dist-esm/src/generated/index.js +0 -1
- package/dist-esm/src/generated/index.js.map +1 -1
- package/dist-esm/src/generated/models/index.js +2 -0
- package/dist-esm/src/generated/models/index.js.map +1 -1
- package/dist-esm/src/generated/models/mappers.js +58 -44
- package/dist-esm/src/generated/models/mappers.js.map +1 -1
- package/dist-esm/src/generated/models/parameters.js +70 -31
- package/dist-esm/src/generated/models/parameters.js.map +1 -1
- package/dist-esm/src/generated/operations/healthApi.js.map +1 -1
- package/dist-esm/src/generated/operations/webPubSub.js +217 -185
- package/dist-esm/src/generated/operations/webPubSub.js.map +1 -1
- package/dist-esm/src/generated/operationsInterfaces/webPubSub.js.map +1 -1
- package/dist-esm/src/groupClient.js.map +1 -1
- package/dist-esm/src/hubClient.js +12 -2
- package/dist-esm/src/hubClient.js.map +1 -1
- package/dist-esm/src/index.js +1 -0
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/utils.js +44 -0
- package/dist-esm/src/utils.js.map +1 -1
- package/dist-esm/test/groups.spec.js +23 -0
- package/dist-esm/test/groups.spec.js.map +1 -1
- package/dist-esm/test/hubs.spec.js +59 -7
- package/dist-esm/test/hubs.spec.js.map +1 -1
- package/dist-esm/test/integration.spec.js +99 -7
- package/dist-esm/test/integration.spec.js.map +1 -1
- package/dist-esm/test/odata.spec.js +15 -0
- package/dist-esm/test/odata.spec.js.map +1 -0
- package/package.json +7 -6
- package/types/web-pubsub.d.ts +56 -3
@@ -1,7 +1,7 @@
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
2
2
|
// Licensed under the MIT license.
|
3
3
|
/* eslint-disable no-invalid-this */
|
4
|
-
import { WebPubSubServiceClient } from "../src/index";
|
4
|
+
import { WebPubSubServiceClient, odata } from "../src/index";
|
5
5
|
import { isLiveMode, assertEnvironmentVariable } from "@azure-tools/test-recorder";
|
6
6
|
import { assert } from "chai";
|
7
7
|
import ws from "ws";
|
@@ -26,12 +26,13 @@ class SimpleWebSocketFrame {
|
|
26
26
|
this.dataAsString = data.toString();
|
27
27
|
}
|
28
28
|
}
|
29
|
-
isEndSignal() {
|
29
|
+
isEndSignal(id = undefined) {
|
30
30
|
return (this.isBinary &&
|
31
31
|
this.data instanceof Buffer &&
|
32
32
|
this.data[0] === 5 &&
|
33
33
|
this.data[1] === 1 &&
|
34
|
-
this.data[2] === 1
|
34
|
+
this.data[2] === 1 &&
|
35
|
+
(id === undefined || this.data[3] === id));
|
35
36
|
}
|
36
37
|
toString() {
|
37
38
|
if (this.isEndSignal()) {
|
@@ -61,17 +62,19 @@ class PubSubWebSocketFrame {
|
|
61
62
|
return this.dataAsString;
|
62
63
|
}
|
63
64
|
}
|
64
|
-
function getEndSignal() {
|
65
|
+
function getEndSignal(id = undefined) {
|
65
66
|
// magic number 511
|
66
|
-
const payload = new Uint8Array(3);
|
67
|
+
const payload = new Uint8Array(id === undefined ? 3 : 4);
|
67
68
|
payload[0] = 5;
|
68
69
|
payload[1] = 1;
|
69
70
|
payload[2] = 1;
|
71
|
+
if (id !== undefined) {
|
72
|
+
payload[3] = id;
|
73
|
+
}
|
70
74
|
return payload;
|
71
75
|
}
|
72
76
|
describe("ServiceClient to manage the connected WebSocket connections", function () {
|
73
|
-
|
74
|
-
it.skip("Simple clients can receive expected messages with different content types", async function () {
|
77
|
+
it("Simple clients can receive expected messages with different content types", async function () {
|
75
78
|
if (!isLiveMode())
|
76
79
|
this.skip();
|
77
80
|
const hub = "SimpleClientCanReceiveMessage";
|
@@ -107,6 +110,53 @@ describe("ServiceClient to manage the connected WebSocket connections", function
|
|
107
110
|
assert.equal(messages[0].dataAsString, '{"message":"Hello world!"}');
|
108
111
|
assert.equal(messages[1].dataAsString, "Hi there!");
|
109
112
|
});
|
113
|
+
it("Simple clients can can join group and receive group messages", async function () {
|
114
|
+
if (!isLiveMode())
|
115
|
+
this.skip();
|
116
|
+
const hub = "SimpleClientCanReceiveGroupMessage";
|
117
|
+
const messages = [];
|
118
|
+
// Get token
|
119
|
+
const serviceClient = new WebPubSubServiceClient(assertEnvironmentVariable("WPS_CONNECTION_STRING"), hub);
|
120
|
+
const token = await serviceClient.getClientAccessToken({
|
121
|
+
groups: ["group1", "group2"],
|
122
|
+
});
|
123
|
+
const end1Signal = defer();
|
124
|
+
const end2Signal = defer();
|
125
|
+
// Start simple WebSocket connections
|
126
|
+
const client = new ws.WebSocket(token.url);
|
127
|
+
client.on("message", (data, isBinary) => {
|
128
|
+
const frame = new SimpleWebSocketFrame(data, isBinary);
|
129
|
+
console.log(frame.toString());
|
130
|
+
if (frame.isEndSignal(1)) {
|
131
|
+
end1Signal.resolve();
|
132
|
+
}
|
133
|
+
else if (frame.isEndSignal(2)) {
|
134
|
+
end2Signal.resolve();
|
135
|
+
}
|
136
|
+
else {
|
137
|
+
messages.push(frame);
|
138
|
+
}
|
139
|
+
});
|
140
|
+
client.on("open", async () => {
|
141
|
+
const group1Client = serviceClient.group("group1");
|
142
|
+
const group2Client = serviceClient.group("group2");
|
143
|
+
// send to all
|
144
|
+
// Send a JSON message
|
145
|
+
await group1Client.sendToAll({ message: "Hello world from group1!" });
|
146
|
+
await group2Client.sendToAll(getEndSignal(1));
|
147
|
+
// Send a plain text message
|
148
|
+
await group2Client.sendToAll("Hi there from group2!", { contentType: "text/plain" });
|
149
|
+
// Send the binary end signal message
|
150
|
+
await group2Client.sendToAll(getEndSignal(2));
|
151
|
+
});
|
152
|
+
await end1Signal.promise;
|
153
|
+
await end2Signal.promise;
|
154
|
+
client.close();
|
155
|
+
assert.equal(messages.length, 2);
|
156
|
+
// order from different groups is not guaranteed
|
157
|
+
assert.isTrue(messages.findIndex((s) => s.dataAsString === '{"message":"Hello world from group1!"}') > -1);
|
158
|
+
assert.isTrue(messages.findIndex((s) => s.dataAsString === "Hi there from group2!") > -1);
|
159
|
+
});
|
110
160
|
it("Subprotocol clients can receive expected messages with different content types", async function () {
|
111
161
|
if (!isLiveMode())
|
112
162
|
this.skip();
|
@@ -149,5 +199,47 @@ describe("ServiceClient to manage the connected WebSocket connections", function
|
|
149
199
|
assert.equal(messages[1].dataAsString, '{"type":"message","from":"server","dataType":"json","data":{"message":"Hello world!"}}');
|
150
200
|
assert.equal(messages[2].dataAsString, '{"type":"message","from":"server","dataType":"text","data":"Hi there!"}');
|
151
201
|
});
|
202
|
+
it("Clients can receive messages with filters", async function () {
|
203
|
+
if (!isLiveMode())
|
204
|
+
this.skip();
|
205
|
+
const hub = "ClientCanReceiveMessageWithFilters";
|
206
|
+
const messages = [];
|
207
|
+
// Get token
|
208
|
+
const serviceClient = new WebPubSubServiceClient(assertEnvironmentVariable("WPS_CONNECTION_STRING"), hub);
|
209
|
+
const token = await serviceClient.getClientAccessToken({ groups: ["groupA"] });
|
210
|
+
const endSignal = defer();
|
211
|
+
// Start simple WebSocket connections
|
212
|
+
const client = new ws.WebSocket(token.url);
|
213
|
+
client.on("message", (data, isBinary) => {
|
214
|
+
const frame = new SimpleWebSocketFrame(data, isBinary);
|
215
|
+
console.log(frame.toString());
|
216
|
+
if (frame.isEndSignal()) {
|
217
|
+
endSignal.resolve();
|
218
|
+
client.close();
|
219
|
+
}
|
220
|
+
else {
|
221
|
+
messages.push(frame);
|
222
|
+
}
|
223
|
+
});
|
224
|
+
client.on("open", async () => {
|
225
|
+
// Send a JSON message to anonymous connections
|
226
|
+
await serviceClient.sendToAll({ message: "Hello world!" }, { filter: "userId eq null" });
|
227
|
+
// Send a text message to connections in groupA but not in groupB
|
228
|
+
const groupA = "groupA";
|
229
|
+
const groupB = "groupB";
|
230
|
+
await serviceClient.sendToAll("Hello world!", {
|
231
|
+
contentType: "text/plain",
|
232
|
+
// use plain text "'groupA' in groups and not('groupB' in groups)"
|
233
|
+
// or use the odata helper method
|
234
|
+
filter: odata `${groupA} in groups and not(${groupB} in groups)`,
|
235
|
+
});
|
236
|
+
// Send the binary end signal message
|
237
|
+
await serviceClient.sendToAll(getEndSignal());
|
238
|
+
});
|
239
|
+
await endSignal.promise;
|
240
|
+
assert.equal(messages.length, 2);
|
241
|
+
assert.equal(messages[0].dataAsString, '{"message":"Hello world!"}');
|
242
|
+
assert.equal(messages[1].dataAsString, "Hello world!");
|
243
|
+
});
|
152
244
|
});
|
153
245
|
//# sourceMappingURL=integration.spec.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"integration.spec.js","sourceRoot":"","sources":["../../test/integration.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n/* eslint-disable no-invalid-this */\nimport { WebPubSubServiceClient } from \"../src/index\";\nimport { isLiveMode, assertEnvironmentVariable } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\nimport { assert } from \"chai\";\nimport ws from \"ws\";\n\nfunction defer<T>(): {\n promise: Promise<T>;\n resolve: (t: T) => void;\n reject: (err: Error) => void;\n} {\n let actualResolve: (t: T) => void;\n let actualReject: (err: Error) => void;\n\n const promise = new Promise<T>((resolve, reject) => {\n actualResolve = resolve;\n actualReject = reject;\n });\n\n return {\n promise,\n resolve: actualResolve!,\n reject: actualReject!,\n };\n}\n\nclass SimpleWebSocketFrame {\n public dataAsString: string | undefined;\n constructor(public data: Buffer | ArrayBuffer | Buffer[], public isBinary: boolean) {\n if (!isBinary) {\n this.dataAsString = data.toString();\n }\n }\n\n isEndSignal(): boolean {\n return (\n this.isBinary &&\n this.data instanceof Buffer &&\n this.data[0] === 5 &&\n this.data[1] === 1 &&\n this.data[2] === 1\n );\n }\n\n toString(): string | undefined {\n if (this.isEndSignal()) {\n return \"|EndSignal|\";\n }\n if (!this.isBinary) {\n return this.dataAsString;\n } else {\n return this.data.toString();\n }\n }\n}\n\nclass PubSubWebSocketFrame {\n public message: any;\n public dataAsString: string;\n constructor(data: Buffer | ArrayBuffer | Buffer[], isBinary: boolean) {\n assert.isFalse(isBinary);\n this.dataAsString = data.toString();\n this.message = JSON.parse(this.dataAsString);\n }\n\n isEndSignal(): boolean {\n return this.message.dataType === \"binary\" && this.message.data === \"BQEB\";\n }\n\n toString(): string | undefined {\n if (this.isEndSignal()) {\n return \"|EndSignal|\";\n }\n\n return this.dataAsString;\n }\n}\n\nfunction getEndSignal(): Uint8Array {\n // magic number 511\n const payload = new Uint8Array(3);\n payload[0] = 5;\n payload[1] = 1;\n payload[2] = 1;\n return payload;\n}\n\ndescribe(\"ServiceClient to manage the connected WebSocket connections\", function () {\n // Issue - https://github.com/Azure/azure-sdk-for-js/issues/20571 waiting for service fix\n it.skip(\"Simple clients can receive expected messages with different content types\", async function (this: Context) {\n if (!isLiveMode()) this.skip();\n const hub = \"SimpleClientCanReceiveMessage\";\n\n const messages: SimpleWebSocketFrame[] = [];\n\n // Get token\n const serviceClient = new WebPubSubServiceClient(\n assertEnvironmentVariable(\"WPS_CONNECTION_STRING\"),\n hub\n );\n const token = await serviceClient.getClientAccessToken();\n const endSignal = defer<void>();\n // Start simple WebSocket connections\n const client = new ws.WebSocket(token.url);\n client.on(\"message\", (data, isBinary) => {\n const frame = new SimpleWebSocketFrame(data, isBinary);\n console.log(frame.toString());\n if (frame.isEndSignal()) {\n endSignal.resolve();\n client.close();\n } else {\n messages.push(frame);\n }\n });\n client.on(\"open\", async () => {\n // send to all\n // Send a JSON message\n await serviceClient.sendToAll({ message: \"Hello world!\" });\n\n // Send a plain text message\n await serviceClient.sendToAll(\"Hi there!\", { contentType: \"text/plain\" });\n\n // Send the binary end signal message\n await serviceClient.sendToAll(getEndSignal());\n });\n\n await endSignal.promise;\n\n assert.equal(messages.length, 2);\n assert.equal(messages[0].dataAsString, '{\"message\":\"Hello world!\"}');\n assert.equal(messages[1].dataAsString, \"Hi there!\");\n });\n\n it(\"Subprotocol clients can receive expected messages with different content types\", async function (this: Context) {\n if (!isLiveMode()) this.skip();\n const hub = \"PubSubClientCanReceiveMessage\";\n const messages: PubSubWebSocketFrame[] = [];\n\n // Get token\n const serviceClient = new WebPubSubServiceClient(\n assertEnvironmentVariable(\"WPS_CONNECTION_STRING\"),\n hub\n );\n const token = await serviceClient.getClientAccessToken();\n const endSignal = defer<void>();\n const connectedSignal = defer<void>();\n // Start simple WebSocket connections\n const client = new ws.WebSocket(token.url, \"json.webpubsub.azure.v1\");\n client.on(\"message\", (data, isBinary) => {\n const frame = new PubSubWebSocketFrame(data, isBinary);\n console.log(frame.toString());\n if (frame.message.event === \"connected\") {\n connectedSignal.resolve();\n }\n if (frame.isEndSignal()) {\n endSignal.resolve();\n client.close();\n } else {\n messages.push(frame);\n }\n });\n client.on(\"open\", async () => {\n await connectedSignal.promise;\n\n // send to all\n // Send a JSON message\n await serviceClient.sendToAll({ message: \"Hello world!\" });\n\n // Send a plain text message\n await serviceClient.sendToAll(\"Hi there!\", { contentType: \"text/plain\" });\n\n // Send the binary end signal message\n await serviceClient.sendToAll(getEndSignal());\n });\n\n await endSignal.promise;\n\n assert.equal(messages.length, 3);\n assert.equal(messages[0].message.event, \"connected\");\n assert.equal(\n messages[1].dataAsString,\n '{\"type\":\"message\",\"from\":\"server\",\"dataType\":\"json\",\"data\":{\"message\":\"Hello world!\"}}'\n );\n assert.equal(\n messages[2].dataAsString,\n '{\"type\":\"message\",\"from\":\"server\",\"dataType\":\"text\",\"data\":\"Hi there!\"}'\n );\n });\n});\n"]}
|
1
|
+
{"version":3,"file":"integration.spec.js","sourceRoot":"","sources":["../../test/integration.spec.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n/* eslint-disable no-invalid-this */\nimport { WebPubSubServiceClient, odata } from \"../src/index\";\nimport { isLiveMode, assertEnvironmentVariable } from \"@azure-tools/test-recorder\";\nimport { Context } from \"mocha\";\nimport { assert } from \"chai\";\nimport ws from \"ws\";\n\nfunction defer<T>(): {\n promise: Promise<T>;\n resolve: (t: T) => void;\n reject: (err: Error) => void;\n} {\n let actualResolve: (t: T) => void;\n let actualReject: (err: Error) => void;\n\n const promise = new Promise<T>((resolve, reject) => {\n actualResolve = resolve;\n actualReject = reject;\n });\n\n return {\n promise,\n resolve: actualResolve!,\n reject: actualReject!,\n };\n}\n\nclass SimpleWebSocketFrame {\n public dataAsString: string | undefined;\n constructor(public data: Buffer | ArrayBuffer | Buffer[], public isBinary: boolean) {\n if (!isBinary) {\n this.dataAsString = data.toString();\n }\n }\n\n isEndSignal(id: number | undefined = undefined): boolean {\n return (\n this.isBinary &&\n this.data instanceof Buffer &&\n this.data[0] === 5 &&\n this.data[1] === 1 &&\n this.data[2] === 1 &&\n (id === undefined || this.data[3] === id)\n );\n }\n\n toString(): string | undefined {\n if (this.isEndSignal()) {\n return \"|EndSignal|\";\n }\n if (!this.isBinary) {\n return this.dataAsString;\n } else {\n return this.data.toString();\n }\n }\n}\n\nclass PubSubWebSocketFrame {\n public message: any;\n public dataAsString: string;\n constructor(data: Buffer | ArrayBuffer | Buffer[], isBinary: boolean) {\n assert.isFalse(isBinary);\n this.dataAsString = data.toString();\n this.message = JSON.parse(this.dataAsString);\n }\n\n isEndSignal(): boolean {\n return this.message.dataType === \"binary\" && this.message.data === \"BQEB\";\n }\n\n toString(): string | undefined {\n if (this.isEndSignal()) {\n return \"|EndSignal|\";\n }\n\n return this.dataAsString;\n }\n}\n\nfunction getEndSignal(id: number | undefined = undefined): Uint8Array {\n // magic number 511\n const payload = new Uint8Array(id === undefined ? 3 : 4);\n payload[0] = 5;\n payload[1] = 1;\n payload[2] = 1;\n if (id !== undefined) {\n payload[3] = id;\n }\n return payload;\n}\n\ndescribe(\"ServiceClient to manage the connected WebSocket connections\", function () {\n it(\"Simple clients can receive expected messages with different content types\", async function (this: Context) {\n if (!isLiveMode()) this.skip();\n const hub = \"SimpleClientCanReceiveMessage\";\n\n const messages: SimpleWebSocketFrame[] = [];\n\n // Get token\n const serviceClient = new WebPubSubServiceClient(\n assertEnvironmentVariable(\"WPS_CONNECTION_STRING\"),\n hub\n );\n const token = await serviceClient.getClientAccessToken();\n const endSignal = defer<void>();\n // Start simple WebSocket connections\n const client = new ws.WebSocket(token.url);\n client.on(\"message\", (data, isBinary) => {\n const frame = new SimpleWebSocketFrame(data, isBinary);\n console.log(frame.toString());\n if (frame.isEndSignal()) {\n endSignal.resolve();\n client.close();\n } else {\n messages.push(frame);\n }\n });\n client.on(\"open\", async () => {\n // send to all\n // Send a JSON message\n await serviceClient.sendToAll({ message: \"Hello world!\" });\n\n // Send a plain text message\n await serviceClient.sendToAll(\"Hi there!\", { contentType: \"text/plain\" });\n\n // Send the binary end signal message\n await serviceClient.sendToAll(getEndSignal());\n });\n\n await endSignal.promise;\n\n assert.equal(messages.length, 2);\n assert.equal(messages[0].dataAsString, '{\"message\":\"Hello world!\"}');\n assert.equal(messages[1].dataAsString, \"Hi there!\");\n });\n\n it(\"Simple clients can can join group and receive group messages\", async function (this: Context) {\n if (!isLiveMode()) this.skip();\n const hub = \"SimpleClientCanReceiveGroupMessage\";\n\n const messages: SimpleWebSocketFrame[] = [];\n\n // Get token\n const serviceClient = new WebPubSubServiceClient(\n assertEnvironmentVariable(\"WPS_CONNECTION_STRING\"),\n hub\n );\n const token = await serviceClient.getClientAccessToken({\n groups: [\"group1\", \"group2\"],\n });\n const end1Signal = defer<void>();\n const end2Signal = defer<void>();\n // Start simple WebSocket connections\n const client = new ws.WebSocket(token.url);\n client.on(\"message\", (data, isBinary) => {\n const frame = new SimpleWebSocketFrame(data, isBinary);\n console.log(frame.toString());\n if (frame.isEndSignal(1)) {\n end1Signal.resolve();\n } else if (frame.isEndSignal(2)) {\n end2Signal.resolve();\n } else {\n messages.push(frame);\n }\n });\n client.on(\"open\", async () => {\n const group1Client = serviceClient.group(\"group1\");\n const group2Client = serviceClient.group(\"group2\");\n // send to all\n // Send a JSON message\n await group1Client.sendToAll({ message: \"Hello world from group1!\" });\n await group2Client.sendToAll(getEndSignal(1));\n // Send a plain text message\n await group2Client.sendToAll(\"Hi there from group2!\", { contentType: \"text/plain\" });\n\n // Send the binary end signal message\n await group2Client.sendToAll(getEndSignal(2));\n });\n\n await end1Signal.promise;\n await end2Signal.promise;\n client.close();\n assert.equal(messages.length, 2);\n\n // order from different groups is not guaranteed\n assert.isTrue(\n messages.findIndex((s) => s.dataAsString === '{\"message\":\"Hello world from group1!\"}') > -1\n );\n assert.isTrue(messages.findIndex((s) => s.dataAsString === \"Hi there from group2!\") > -1);\n });\n\n it(\"Subprotocol clients can receive expected messages with different content types\", async function (this: Context) {\n if (!isLiveMode()) this.skip();\n const hub = \"PubSubClientCanReceiveMessage\";\n const messages: PubSubWebSocketFrame[] = [];\n\n // Get token\n const serviceClient = new WebPubSubServiceClient(\n assertEnvironmentVariable(\"WPS_CONNECTION_STRING\"),\n hub\n );\n const token = await serviceClient.getClientAccessToken();\n const endSignal = defer<void>();\n const connectedSignal = defer<void>();\n // Start simple WebSocket connections\n const client = new ws.WebSocket(token.url, \"json.webpubsub.azure.v1\");\n client.on(\"message\", (data, isBinary) => {\n const frame = new PubSubWebSocketFrame(data, isBinary);\n console.log(frame.toString());\n if (frame.message.event === \"connected\") {\n connectedSignal.resolve();\n }\n if (frame.isEndSignal()) {\n endSignal.resolve();\n client.close();\n } else {\n messages.push(frame);\n }\n });\n client.on(\"open\", async () => {\n await connectedSignal.promise;\n\n // send to all\n // Send a JSON message\n await serviceClient.sendToAll({ message: \"Hello world!\" });\n\n // Send a plain text message\n await serviceClient.sendToAll(\"Hi there!\", { contentType: \"text/plain\" });\n\n // Send the binary end signal message\n await serviceClient.sendToAll(getEndSignal());\n });\n\n await endSignal.promise;\n\n assert.equal(messages.length, 3);\n assert.equal(messages[0].message.event, \"connected\");\n assert.equal(\n messages[1].dataAsString,\n '{\"type\":\"message\",\"from\":\"server\",\"dataType\":\"json\",\"data\":{\"message\":\"Hello world!\"}}'\n );\n assert.equal(\n messages[2].dataAsString,\n '{\"type\":\"message\",\"from\":\"server\",\"dataType\":\"text\",\"data\":\"Hi there!\"}'\n );\n });\n\n it(\"Clients can receive messages with filters\", async function (this: Context) {\n if (!isLiveMode()) this.skip();\n const hub = \"ClientCanReceiveMessageWithFilters\";\n\n const messages: SimpleWebSocketFrame[] = [];\n\n // Get token\n const serviceClient = new WebPubSubServiceClient(\n assertEnvironmentVariable(\"WPS_CONNECTION_STRING\"),\n hub\n );\n const token = await serviceClient.getClientAccessToken({ groups: [\"groupA\"] });\n const endSignal = defer<void>();\n // Start simple WebSocket connections\n const client = new ws.WebSocket(token.url);\n client.on(\"message\", (data, isBinary) => {\n const frame = new SimpleWebSocketFrame(data, isBinary);\n console.log(frame.toString());\n if (frame.isEndSignal()) {\n endSignal.resolve();\n client.close();\n } else {\n messages.push(frame);\n }\n });\n client.on(\"open\", async () => {\n // Send a JSON message to anonymous connections\n await serviceClient.sendToAll({ message: \"Hello world!\" }, { filter: \"userId eq null\" });\n // Send a text message to connections in groupA but not in groupB\n const groupA = \"groupA\";\n const groupB = \"groupB\";\n await serviceClient.sendToAll(\"Hello world!\", {\n contentType: \"text/plain\",\n // use plain text \"'groupA' in groups and not('groupB' in groups)\"\n // or use the odata helper method\n filter: odata`${groupA} in groups and not(${groupB} in groups)`,\n });\n // Send the binary end signal message\n await serviceClient.sendToAll(getEndSignal());\n });\n\n await endSignal.promise;\n\n assert.equal(messages.length, 2);\n assert.equal(messages[0].dataAsString, '{\"message\":\"Hello world!\"}');\n assert.equal(messages[1].dataAsString, \"Hello world!\");\n });\n});\n"]}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
2
|
+
// Licensed under the MIT license.
|
3
|
+
/* eslint-disable no-invalid-this */
|
4
|
+
import { odata } from "../src/utils";
|
5
|
+
import { assert } from "chai";
|
6
|
+
describe("Can parse odata to string", function () {
|
7
|
+
it("can wrap different types as expected", async () => {
|
8
|
+
const userId = "vic's";
|
9
|
+
const anonymous = null;
|
10
|
+
const length = 3;
|
11
|
+
const filter = odata `userId eq ${anonymous} or userId eq ${userId} or length(userId) gt ${length}`;
|
12
|
+
assert.equal("userId eq null or userId eq 'vic''s' or length(userId) gt 3", filter);
|
13
|
+
});
|
14
|
+
});
|
15
|
+
//# sourceMappingURL=odata.spec.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"odata.spec.js","sourceRoot":"","sources":["../../test/odata.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,oCAAoC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,QAAQ,CAAC,2BAA2B,EAAE;IACpC,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,MAAM,GAAG,OAAO,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,CAAC;QACjB,MAAM,MAAM,GAAG,KAAK,CAAA,aAAa,SAAS,iBAAiB,MAAM,yBAAyB,MAAM,EAAE,CAAC;QACnG,MAAM,CAAC,KAAK,CAAC,6DAA6D,EAAE,MAAM,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n/* eslint-disable no-invalid-this */\nimport { odata } from \"../src/utils\";\nimport { assert } from \"chai\";\n\ndescribe(\"Can parse odata to string\", function () {\n it(\"can wrap different types as expected\", async () => {\n const userId = \"vic's\";\n const anonymous = null;\n const length = 3;\n const filter = odata`userId eq ${anonymous} or userId eq ${userId} or length(userId) gt ${length}`;\n assert.equal(\"userId eq null or userId eq 'vic''s' or length(userId) gt 3\", filter);\n });\n});\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@azure/web-pubsub",
|
3
|
-
"version": "1.1.0
|
3
|
+
"version": "1.1.0",
|
4
4
|
"description": "Azure client library for Azure Web PubSub",
|
5
5
|
"sdk-type": "client",
|
6
6
|
"main": "dist/index.js",
|
@@ -30,7 +30,8 @@
|
|
30
30
|
"test": "npm run build:test && npm run unit-test && npm run integration-test",
|
31
31
|
"unit-test:browser": "echo \"Browser is not supported.\" && exit 0",
|
32
32
|
"unit-test:node": "dev-tool run test:node-ts-input -- --timeout 1200000 --exclude 'test/**/browser/*.spec.ts' 'test/**/*.spec.ts'",
|
33
|
-
"unit-test": "npm run unit-test:node && npm run unit-test:browser"
|
33
|
+
"unit-test": "npm run unit-test:node && npm run unit-test:browser",
|
34
|
+
"generate:client": "autorest --typescript ./swagger/README.md"
|
34
35
|
},
|
35
36
|
"files": [
|
36
37
|
"dist/",
|
@@ -77,10 +78,10 @@
|
|
77
78
|
"jsonwebtoken": "^8.5.1"
|
78
79
|
},
|
79
80
|
"devDependencies": {
|
80
|
-
"@azure/dev-tool": "
|
81
|
-
"@azure/eslint-plugin-azure-sdk": "
|
82
|
-
"@azure/test-utils": "
|
83
|
-
"@azure-tools/test-credential": "
|
81
|
+
"@azure/dev-tool": "^1.0.0",
|
82
|
+
"@azure/eslint-plugin-azure-sdk": "^3.0.0",
|
83
|
+
"@azure/test-utils": "^1.0.0",
|
84
|
+
"@azure-tools/test-credential": "^1.0.0",
|
84
85
|
"@azure-tools/test-recorder": "^2.0.0",
|
85
86
|
"@microsoft/api-extractor": "^7.31.1",
|
86
87
|
"@types/chai": "^4.1.6",
|
package/types/web-pubsub.d.ts
CHANGED
@@ -47,6 +47,10 @@ export declare interface GenerateClientTokenOptions extends OperationOptions {
|
|
47
47
|
* Minutes until the token expires.
|
48
48
|
*/
|
49
49
|
expirationTimeInMinutes?: number;
|
50
|
+
/**
|
51
|
+
* The groups to join when the client connects
|
52
|
+
*/
|
53
|
+
groups?: string[];
|
50
54
|
}
|
51
55
|
|
52
56
|
/**
|
@@ -98,11 +102,10 @@ export declare interface GroupRemoveUserOptions extends OperationOptions {
|
|
98
102
|
/**
|
99
103
|
* Options for sending text messages to a group..
|
100
104
|
*/
|
101
|
-
export declare interface GroupSendTextToAllOptions extends
|
105
|
+
export declare interface GroupSendTextToAllOptions extends GroupSendToAllOptions {
|
102
106
|
/**
|
103
|
-
*
|
107
|
+
* The content will be sent to the clients in plain text.
|
104
108
|
*/
|
105
|
-
excludedConnections?: string[];
|
106
109
|
contentType: "text/plain";
|
107
110
|
}
|
108
111
|
|
@@ -114,6 +117,14 @@ export declare interface GroupSendToAllOptions extends OperationOptions {
|
|
114
117
|
* Connection ids to exclude from receiving this message.
|
115
118
|
*/
|
116
119
|
excludedConnections?: string[];
|
120
|
+
/**
|
121
|
+
* The filter syntax to filter out the connections to send the messages to following OData filter syntax.
|
122
|
+
* Examples:
|
123
|
+
* * Exclude connections from `user1` and `user2`: `userId ne 'user1' and userId ne 'user2'`
|
124
|
+
* * Exclude connections in `group1`: `not('group1' in groups)`
|
125
|
+
* Details about `filter` syntax please see [OData filter syntax for Azure Web PubSub](https://aka.ms/awps/filter-syntax).
|
126
|
+
*/
|
127
|
+
filter?: string;
|
117
128
|
}
|
118
129
|
|
119
130
|
/**
|
@@ -207,6 +218,9 @@ export declare interface HubRevokePermissionOptions extends OperationOptions {
|
|
207
218
|
* Options for sending text messages to hubs.
|
208
219
|
*/
|
209
220
|
export declare interface HubSendTextToAllOptions extends HubSendToAllOptions {
|
221
|
+
/**
|
222
|
+
* The content will be sent to the clients in plain text.
|
223
|
+
*/
|
210
224
|
contentType: "text/plain";
|
211
225
|
}
|
212
226
|
|
@@ -221,6 +235,9 @@ export declare interface HubSendTextToConnectionOptions extends HubSendToConnect
|
|
221
235
|
* Options for sending a text message to a user.
|
222
236
|
*/
|
223
237
|
export declare interface HubSendTextToUserOptions extends HubSendToUserOptions {
|
238
|
+
/**
|
239
|
+
* The content will be sent to the clients in plain text.
|
240
|
+
*/
|
224
241
|
contentType: "text/plain";
|
225
242
|
}
|
226
243
|
|
@@ -232,6 +249,14 @@ export declare interface HubSendToAllOptions extends OperationOptions {
|
|
232
249
|
* Connection ids to exclude from receiving this message.
|
233
250
|
*/
|
234
251
|
excludedConnections?: string[];
|
252
|
+
/**
|
253
|
+
* The filter syntax to filter out the connections to send the messages to following OData filter syntax.
|
254
|
+
* Examples:
|
255
|
+
* * Exclude connections from `user1` and `user2`: `userId ne 'user1' and userId ne 'user2'`
|
256
|
+
* * Exclude connections in `group1`: `not('group1' in groups)`
|
257
|
+
* Details about `filter` syntax please see [OData filter syntax for Azure Web PubSub](https://aka.ms/awps/filter-syntax).
|
258
|
+
*/
|
259
|
+
filter?: string;
|
235
260
|
}
|
236
261
|
|
237
262
|
/**
|
@@ -244,6 +269,14 @@ export declare interface HubSendToConnectionOptions extends OperationOptions {
|
|
244
269
|
* Options for sending a message to a user.
|
245
270
|
*/
|
246
271
|
export declare interface HubSendToUserOptions extends OperationOptions {
|
272
|
+
/**
|
273
|
+
* The filter syntax to filter out the connections to send the messages to following OData filter syntax.
|
274
|
+
* Examples:
|
275
|
+
* * Exclude connections in `group1`: `not('group1' in groups)`
|
276
|
+
* * Send to connections in `group1` or `group2`: `'group1' in groups or `group2` in groups`
|
277
|
+
* Details about `filter` syntax please see [OData filter syntax for Azure Web PubSub](https://aka.ms/awps/filter-syntax).
|
278
|
+
*/
|
279
|
+
filter?: string;
|
247
280
|
}
|
248
281
|
|
249
282
|
/**
|
@@ -251,6 +284,20 @@ export declare interface HubSendToUserOptions extends OperationOptions {
|
|
251
284
|
*/
|
252
285
|
export declare type JSONTypes = string | number | boolean | object;
|
253
286
|
|
287
|
+
/**
|
288
|
+
* Escapes an odata filter expression to avoid errors with quoting string literals.
|
289
|
+
* Example usage:
|
290
|
+
* ```ts
|
291
|
+
* const userId = "vic's";
|
292
|
+
* const anonymous = null;
|
293
|
+
* const length = 3
|
294
|
+
* const filter = odata`userId eq ${anonymous} or userId eq ${userId} or length(userId) > ${length}`;
|
295
|
+
* ```
|
296
|
+
* @param strings - Array of strings for the expression
|
297
|
+
* @param values - Array of values for the expression
|
298
|
+
*/
|
299
|
+
export declare function odata(strings: TemplateStringsArray, ...values: unknown[]): string;
|
300
|
+
|
254
301
|
export declare type Permission = "joinLeaveGroup" | "sendToGroup";
|
255
302
|
|
256
303
|
export declare interface WebPubSubGroup {
|
@@ -485,6 +532,12 @@ export declare class WebPubSubServiceClient {
|
|
485
532
|
* @param options - Additional options
|
486
533
|
*/
|
487
534
|
removeUserFromAllGroups(userId: string, options?: HubCloseConnectionOptions): Promise<void>;
|
535
|
+
/**
|
536
|
+
* Remove a specific connection from all groups they are joined to
|
537
|
+
* @param connectionId - The connection id to remove from all groups
|
538
|
+
* @param options - Additional options
|
539
|
+
*/
|
540
|
+
removeConnectionFromAllGroups(connectionId: string, options?: HubCloseConnectionOptions): Promise<void>;
|
488
541
|
/**
|
489
542
|
* Check if a particular group exists (i.e. has active connections).
|
490
543
|
*
|