@aws-sdk/middleware-sdk-transcribe-streaming 3.33.0 → 3.37.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/CHANGELOG.md +38 -0
- package/dist-cjs/configuration.js +21 -0
- package/dist-cjs/eventstream-handler.js +6 -0
- package/dist-cjs/index.js +10 -0
- package/dist-cjs/middleware-endpoint.js +36 -0
- package/dist-cjs/middleware-session-id.js +28 -0
- package/dist-cjs/plugin.js +12 -0
- package/dist-cjs/signer.js +28 -0
- package/dist-cjs/websocket-handler.js +109 -0
- package/dist-es/configuration.js +22 -0
- package/dist-es/eventstream-handler.js +3 -0
- package/{dist/types/index.d.ts → dist-es/index.js} +0 -0
- package/dist-es/middleware-endpoint.js +48 -0
- package/dist-es/middleware-session-id.js +46 -0
- package/dist-es/plugin.js +8 -0
- package/dist-es/signer.js +32 -0
- package/dist-es/websocket-handler.js +172 -0
- package/{dist/types → dist-types}/configuration.d.ts +0 -0
- package/{dist/types → dist-types}/eventstream-handler.d.ts +0 -0
- package/{src/index.ts → dist-types/index.d.ts} +0 -0
- package/{dist/types → dist-types}/middleware-endpoint.d.ts +0 -0
- package/{dist/types → dist-types}/middleware-session-id.d.ts +0 -0
- package/{dist/types → dist-types}/plugin.d.ts +0 -0
- package/{dist/types → dist-types}/signer.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/configuration.d.ts +2 -6
- package/{dist/types → dist-types}/ts3.4/eventstream-handler.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/index.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/middleware-endpoint.d.ts +1 -4
- package/dist-types/ts3.4/middleware-session-id.d.ts +6 -0
- package/{dist/types → dist-types}/ts3.4/plugin.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/signer.d.ts +0 -0
- package/{dist/types → dist-types}/ts3.4/websocket-handler.d.ts +2 -10
- package/{dist/types → dist-types}/websocket-handler.d.ts +0 -0
- package/package.json +18 -14
- package/dist/cjs/configuration.js +0 -22
- package/dist/cjs/eventstream-handler.js +0 -7
- package/dist/cjs/index.js +0 -11
- package/dist/cjs/middleware-endpoint.js +0 -53
- package/dist/cjs/middleware-session-id.js +0 -36
- package/dist/cjs/plugin.js +0 -13
- package/dist/cjs/signer.js +0 -35
- package/dist/cjs/websocket-handler.js +0 -136
- package/dist/es/configuration.js +0 -16
- package/dist/es/eventstream-handler.js +0 -4
- package/dist/es/index.js +0 -8
- package/dist/es/middleware-endpoint.js +0 -49
- package/dist/es/middleware-session-id.js +0 -31
- package/dist/es/plugin.js +0 -9
- package/dist/es/signer.js +0 -31
- package/dist/es/websocket-handler.js +0 -148
- package/dist/types/ts3.4/middleware-session-id.d.ts +0 -12
- package/src/configuration.ts +0 -40
- package/src/eventstream-handler.ts +0 -9
- package/src/middleware-endpoint.ts +0 -63
- package/src/middleware-session-id.ts +0 -50
- package/src/plugin.ts +0 -12
- package/src/signer.ts +0 -44
- package/src/websocket-handler.ts +0 -148
- package/tsconfig.cjs.json +0 -11
- package/tsconfig.es.json +0 -16
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { v4 } from "uuid";
|
|
3
|
-
/**
|
|
4
|
-
* Middleware that inject default sessionId for operations, and inject
|
|
5
|
-
* the parameters from request to the response metadata. This is
|
|
6
|
-
* necessary because the SDK cannot access any parameters other than
|
|
7
|
-
* the result stream. So it copies the parameters from input to the same
|
|
8
|
-
* parameters in the output.
|
|
9
|
-
*/
|
|
10
|
-
export const injectSessionIdMiddleware = (config) => (next) => (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
11
|
-
if (args.input.SessionId === undefined && isWebSocket(config)) {
|
|
12
|
-
args.input.SessionId = v4();
|
|
13
|
-
}
|
|
14
|
-
const requestParams = Object.assign({}, args.input);
|
|
15
|
-
const response = yield next(args);
|
|
16
|
-
const output = response.output;
|
|
17
|
-
for (const key of Object.keys(output)) {
|
|
18
|
-
if (output[key] === undefined && requestParams[key]) {
|
|
19
|
-
output[key] = requestParams[key];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return response;
|
|
23
|
-
});
|
|
24
|
-
const isWebSocket = (config) => { var _a; return ((_a = config.requestHandler.metadata) === null || _a === void 0 ? void 0 : _a.handlerProtocol) === "websocket"; };
|
|
25
|
-
export const injectSessionIdMiddlewareOptions = {
|
|
26
|
-
step: "initialize",
|
|
27
|
-
name: "injectSessionIdMiddleware",
|
|
28
|
-
tags: ["WEBSOCKET", "EVENT_STREAM"],
|
|
29
|
-
override: true,
|
|
30
|
-
};
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS1zZXNzaW9uLWlkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZGRsZXdhcmUtc2Vzc2lvbi1pZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBT0EsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQU8xQjs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FDcEMsQ0FBQyxNQUFvRCxFQUFrQyxFQUFFLENBQ3pGLENBQUMsSUFBaUQsRUFBRSxFQUFFLENBQ3RELENBQU8sSUFBNkMsRUFBRSxFQUFFO0lBQ3RELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEtBQUssU0FBUyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUM3RCxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxFQUFFLEVBQUUsQ0FBQztLQUM3QjtJQUNELE1BQU0sYUFBYSxxQkFDZCxJQUFJLENBQUMsS0FBSyxDQUNkLENBQUM7SUFDRixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQy9CLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUNyQyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ25ELE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDbEM7S0FDRjtJQUNELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQSxDQUFDO0FBRUosTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFvRCxFQUFFLEVBQUUsV0FDM0UsT0FBQSxDQUFBLE1BQUEsTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLDBDQUFFLGVBQWUsTUFBSyxXQUFXLENBQUEsRUFBQSxDQUFDO0FBRWxFLE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUE2QjtJQUN4RSxJQUFJLEVBQUUsWUFBWTtJQUNsQixJQUFJLEVBQUUsMkJBQTJCO0lBQ2pDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUM7SUFDbkMsUUFBUSxFQUFFLElBQUk7Q0FDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSW5pdGlhbGl6ZUhhbmRsZXIsXG4gIEluaXRpYWxpemVIYW5kbGVyQXJndW1lbnRzLFxuICBJbml0aWFsaXplSGFuZGxlck9wdGlvbnMsXG4gIEluaXRpYWxpemVNaWRkbGV3YXJlLFxuICBSZXF1ZXN0SGFuZGxlcixcbn0gZnJvbSBcIkBhd3Mtc2RrL3R5cGVzXCI7XG5pbXBvcnQgeyB2NCB9IGZyb20gXCJ1dWlkXCI7XG5cbnR5cGUgV2l0aFNlc3Npb24gPSB7XG4gIFNlc3Npb25JZD86IHN0cmluZztcbiAgW2tleTogc3RyaW5nXTogYW55O1xufTtcblxuLyoqXG4gKiBNaWRkbGV3YXJlIHRoYXQgaW5qZWN0IGRlZmF1bHQgc2Vzc2lvbklkIGZvciBvcGVyYXRpb25zLCBhbmQgaW5qZWN0XG4gKiB0aGUgcGFyYW1ldGVycyBmcm9tIHJlcXVlc3QgdG8gdGhlIHJlc3BvbnNlIG1ldGFkYXRhLiBUaGlzIGlzXG4gKiBuZWNlc3NhcnkgYmVjYXVzZSB0aGUgU0RLIGNhbm5vdCBhY2Nlc3MgYW55IHBhcmFtZXRlcnMgb3RoZXIgdGhhblxuICogdGhlIHJlc3VsdCBzdHJlYW0uIFNvIGl0IGNvcGllcyB0aGUgcGFyYW1ldGVycyBmcm9tIGlucHV0IHRvIHRoZSBzYW1lXG4gKiBwYXJhbWV0ZXJzIGluIHRoZSBvdXRwdXQuXG4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3RTZXNzaW9uSWRNaWRkbGV3YXJlID1cbiAgKGNvbmZpZzogeyByZXF1ZXN0SGFuZGxlcjogUmVxdWVzdEhhbmRsZXI8YW55LCBhbnk+IH0pOiBJbml0aWFsaXplTWlkZGxld2FyZTxhbnksIGFueT4gPT5cbiAgKG5leHQ6IEluaXRpYWxpemVIYW5kbGVyPFdpdGhTZXNzaW9uLCBXaXRoU2Vzc2lvbj4pID0+XG4gIGFzeW5jIChhcmdzOiBJbml0aWFsaXplSGFuZGxlckFyZ3VtZW50czxXaXRoU2Vzc2lvbj4pID0+IHtcbiAgICBpZiAoYXJncy5pbnB1dC5TZXNzaW9uSWQgPT09IHVuZGVmaW5lZCAmJiBpc1dlYlNvY2tldChjb25maWcpKSB7XG4gICAgICBhcmdzLmlucHV0LlNlc3Npb25JZCA9IHY0KCk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RQYXJhbXMgPSB7XG4gICAgICAuLi5hcmdzLmlucHV0LFxuICAgIH07XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBuZXh0KGFyZ3MpO1xuICAgIGNvbnN0IG91dHB1dCA9IHJlc3BvbnNlLm91dHB1dDtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhvdXRwdXQpKSB7XG4gICAgICBpZiAob3V0cHV0W2tleV0gPT09IHVuZGVmaW5lZCAmJiByZXF1ZXN0UGFyYW1zW2tleV0pIHtcbiAgICAgICAgb3V0cHV0W2tleV0gPSByZXF1ZXN0UGFyYW1zW2tleV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNwb25zZTtcbiAgfTtcblxuY29uc3QgaXNXZWJTb2NrZXQgPSAoY29uZmlnOiB7IHJlcXVlc3RIYW5kbGVyOiBSZXF1ZXN0SGFuZGxlcjxhbnksIGFueT4gfSkgPT5cbiAgY29uZmlnLnJlcXVlc3RIYW5kbGVyLm1ldGFkYXRhPy5oYW5kbGVyUHJvdG9jb2wgPT09IFwid2Vic29ja2V0XCI7XG5cbmV4cG9ydCBjb25zdCBpbmplY3RTZXNzaW9uSWRNaWRkbGV3YXJlT3B0aW9uczogSW5pdGlhbGl6ZUhhbmRsZXJPcHRpb25zID0ge1xuICBzdGVwOiBcImluaXRpYWxpemVcIixcbiAgbmFtZTogXCJpbmplY3RTZXNzaW9uSWRNaWRkbGV3YXJlXCIsXG4gIHRhZ3M6IFtcIldFQlNPQ0tFVFwiLCBcIkVWRU5UX1NUUkVBTVwiXSxcbiAgb3ZlcnJpZGU6IHRydWUsXG59O1xuIl19
|
package/dist/es/plugin.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { websocketURLMiddleware, websocketURLMiddlewareOptions } from "./middleware-endpoint";
|
|
2
|
-
import { injectSessionIdMiddleware, injectSessionIdMiddlewareOptions } from "./middleware-session-id";
|
|
3
|
-
export const getWebSocketPlugin = (config) => ({
|
|
4
|
-
applyToStack: (clientStack) => {
|
|
5
|
-
clientStack.addRelativeTo(websocketURLMiddleware(config), websocketURLMiddlewareOptions);
|
|
6
|
-
clientStack.add(injectSessionIdMiddleware(config), injectSessionIdMiddlewareOptions);
|
|
7
|
-
},
|
|
8
|
-
});
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RixPQUFPLEVBQUUseUJBQXlCLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV0RyxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLE1BQStCLEVBQXVCLEVBQUUsQ0FBQyxDQUFDO0lBQzNGLFlBQVksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFO1FBQzVCLFdBQVcsQ0FBQyxhQUFhLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztRQUN6RixXQUFXLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLE1BQU0sQ0FBQyxFQUFFLGdDQUFnQyxDQUFDLENBQUM7SUFDdkYsQ0FBQztDQUNGLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBsdWdnYWJsZSB9IGZyb20gXCJAYXdzLXNkay90eXBlc1wiO1xuXG5pbXBvcnQgeyBXZWJTb2NrZXRSZXNvbHZlZENvbmZpZyB9IGZyb20gXCIuL2NvbmZpZ3VyYXRpb25cIjtcbmltcG9ydCB7IHdlYnNvY2tldFVSTE1pZGRsZXdhcmUsIHdlYnNvY2tldFVSTE1pZGRsZXdhcmVPcHRpb25zIH0gZnJvbSBcIi4vbWlkZGxld2FyZS1lbmRwb2ludFwiO1xuaW1wb3J0IHsgaW5qZWN0U2Vzc2lvbklkTWlkZGxld2FyZSwgaW5qZWN0U2Vzc2lvbklkTWlkZGxld2FyZU9wdGlvbnMgfSBmcm9tIFwiLi9taWRkbGV3YXJlLXNlc3Npb24taWRcIjtcblxuZXhwb3J0IGNvbnN0IGdldFdlYlNvY2tldFBsdWdpbiA9IChjb25maWc6IFdlYlNvY2tldFJlc29sdmVkQ29uZmlnKTogUGx1Z2dhYmxlPGFueSwgYW55PiA9PiAoe1xuICBhcHBseVRvU3RhY2s6IChjbGllbnRTdGFjaykgPT4ge1xuICAgIGNsaWVudFN0YWNrLmFkZFJlbGF0aXZlVG8od2Vic29ja2V0VVJMTWlkZGxld2FyZShjb25maWcpLCB3ZWJzb2NrZXRVUkxNaWRkbGV3YXJlT3B0aW9ucyk7XG4gICAgY2xpZW50U3RhY2suYWRkKGluamVjdFNlc3Npb25JZE1pZGRsZXdhcmUoY29uZmlnKSwgaW5qZWN0U2Vzc2lvbklkTWlkZGxld2FyZU9wdGlvbnMpO1xuICB9LFxufSk7XG4iXX0=
|
package/dist/es/signer.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { HttpRequest } from "@aws-sdk/protocol-http";
|
|
3
|
-
export class SignatureV4 {
|
|
4
|
-
constructor(options) {
|
|
5
|
-
this.signer = options.signer;
|
|
6
|
-
}
|
|
7
|
-
presign(originalRequest, options = {}) {
|
|
8
|
-
return this.signer.presign(originalRequest, options);
|
|
9
|
-
}
|
|
10
|
-
sign(toSign, options) {
|
|
11
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
12
|
-
if (HttpRequest.isInstance(toSign)) {
|
|
13
|
-
// Presign the endpoint url with empty body, otherwise
|
|
14
|
-
// the payload hash would be UNSINGED-PAYLOAD
|
|
15
|
-
const signedRequest = yield this.signer.presign(Object.assign(Object.assign({}, toSign), { body: "" }), {
|
|
16
|
-
// presigned url must be expired within 5 mins.
|
|
17
|
-
expiresIn: 5 * 60,
|
|
18
|
-
// Not to sign headers. Transcribe-streaming WebSocket
|
|
19
|
-
// request omits headers except for required 'host' header. If we sign
|
|
20
|
-
// the other headers, the signature could be mismatch.
|
|
21
|
-
unsignableHeaders: new Set(Object.keys(toSign.headers).filter((header) => header !== "host")),
|
|
22
|
-
});
|
|
23
|
-
return Object.assign(Object.assign({}, signedRequest), { body: toSign.body });
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return this.signer.sign(toSign, options);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NpZ25lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBVXJELE1BQU0sT0FBTyxXQUFXO0lBRXRCLFlBQVksT0FBb0M7UUFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBQy9CLENBQUM7SUFFTSxPQUFPLENBQUMsZUFBNkIsRUFBRSxVQUFzQyxFQUFFO1FBQ3BGLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFWSxJQUFJLENBQUMsTUFBb0IsRUFBRSxPQUFpQzs7WUFDdkUsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNsQyxzREFBc0Q7Z0JBQ3RELDZDQUE2QztnQkFDN0MsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8saUNBQ3hDLE1BQU0sS0FBRSxJQUFJLEVBQUUsRUFBRSxLQUNyQjtvQkFDRSwrQ0FBK0M7b0JBQy9DLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRTtvQkFDakIsc0RBQXNEO29CQUN0RCxzRUFBc0U7b0JBQ3RFLHNEQUFzRDtvQkFDdEQsaUJBQWlCLEVBQUUsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUM7aUJBQzlGLENBQ0YsQ0FBQztnQkFDRix1Q0FDSyxhQUFhLEtBQ2hCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxJQUNqQjthQUNIO2lCQUFNO2dCQUNMLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQzFDO1FBQ0gsQ0FBQztLQUFBO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwUmVxdWVzdCB9IGZyb20gXCJAYXdzLXNkay9wcm90b2NvbC1odHRwXCI7XG5pbXBvcnQgeyBTaWduYXR1cmVWNCBhcyBCYXNlU2lnbmF0dXJlVjQgfSBmcm9tIFwiQGF3cy1zZGsvc2lnbmF0dXJlLXY0XCI7XG5pbXBvcnQge1xuICBIdHRwUmVxdWVzdCBhcyBJSHR0cFJlcXVlc3QsXG4gIFJlcXVlc3RQcmVzaWduZXIsXG4gIFJlcXVlc3RQcmVzaWduaW5nQXJndW1lbnRzLFxuICBSZXF1ZXN0U2lnbmVyLFxuICBSZXF1ZXN0U2lnbmluZ0FyZ3VtZW50cyxcbn0gZnJvbSBcIkBhd3Mtc2RrL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBTaWduYXR1cmVWNCBpbXBsZW1lbnRzIFJlcXVlc3RTaWduZXIsIFJlcXVlc3RQcmVzaWduZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IHNpZ25lcjogQmFzZVNpZ25hdHVyZVY0O1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiB7IHNpZ25lcjogQmFzZVNpZ25hdHVyZVY0IH0pIHtcbiAgICB0aGlzLnNpZ25lciA9IG9wdGlvbnMuc2lnbmVyO1xuICB9XG5cbiAgcHVibGljIHByZXNpZ24ob3JpZ2luYWxSZXF1ZXN0OiBJSHR0cFJlcXVlc3QsIG9wdGlvbnM6IFJlcXVlc3RQcmVzaWduaW5nQXJndW1lbnRzID0ge30pOiBQcm9taXNlPElIdHRwUmVxdWVzdD4ge1xuICAgIHJldHVybiB0aGlzLnNpZ25lci5wcmVzaWduKG9yaWdpbmFsUmVxdWVzdCwgb3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2lnbih0b1NpZ246IElIdHRwUmVxdWVzdCwgb3B0aW9ucz86IFJlcXVlc3RTaWduaW5nQXJndW1lbnRzKTogUHJvbWlzZTxJSHR0cFJlcXVlc3Q+IHtcbiAgICBpZiAoSHR0cFJlcXVlc3QuaXNJbnN0YW5jZSh0b1NpZ24pKSB7XG4gICAgICAvLyBQcmVzaWduIHRoZSBlbmRwb2ludCB1cmwgd2l0aCBlbXB0eSBib2R5LCBvdGhlcndpc2VcbiAgICAgIC8vIHRoZSBwYXlsb2FkIGhhc2ggd291bGQgYmUgVU5TSU5HRUQtUEFZTE9BRFxuICAgICAgY29uc3Qgc2lnbmVkUmVxdWVzdCA9IGF3YWl0IHRoaXMuc2lnbmVyLnByZXNpZ24oXG4gICAgICAgIHsgLi4udG9TaWduLCBib2R5OiBcIlwiIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBwcmVzaWduZWQgdXJsIG11c3QgYmUgZXhwaXJlZCB3aXRoaW4gNSBtaW5zLlxuICAgICAgICAgIGV4cGlyZXNJbjogNSAqIDYwLFxuICAgICAgICAgIC8vIE5vdCB0byBzaWduIGhlYWRlcnMuIFRyYW5zY3JpYmUtc3RyZWFtaW5nIFdlYlNvY2tldFxuICAgICAgICAgIC8vIHJlcXVlc3Qgb21pdHMgaGVhZGVycyBleGNlcHQgZm9yIHJlcXVpcmVkICdob3N0JyBoZWFkZXIuIElmIHdlIHNpZ25cbiAgICAgICAgICAvLyB0aGUgb3RoZXIgaGVhZGVycywgdGhlIHNpZ25hdHVyZSBjb3VsZCBiZSBtaXNtYXRjaC5cbiAgICAgICAgICB1bnNpZ25hYmxlSGVhZGVyczogbmV3IFNldChPYmplY3Qua2V5cyh0b1NpZ24uaGVhZGVycykuZmlsdGVyKChoZWFkZXIpID0+IGhlYWRlciAhPT0gXCJob3N0XCIpKSxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnNpZ25lZFJlcXVlc3QsXG4gICAgICAgIGJvZHk6IHRvU2lnbi5ib2R5LFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuc2lnbmVyLnNpZ24odG9TaWduLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { __asyncGenerator, __asyncValues, __await, __awaiter } from "tslib";
|
|
2
|
-
import { iterableToReadableStream, readableStreamtoIterable } from "@aws-sdk/eventstream-serde-browser";
|
|
3
|
-
import { HttpResponse } from "@aws-sdk/protocol-http";
|
|
4
|
-
import { formatUrl } from "@aws-sdk/util-format-url";
|
|
5
|
-
/**
|
|
6
|
-
* Base handler for websocket requests. By default, the request input and output
|
|
7
|
-
* body will be in a ReadableStream, because of interface consistency among middleware.
|
|
8
|
-
* If ReadableStream is not available, like in React-Native, the response body
|
|
9
|
-
* will be an async iterable.
|
|
10
|
-
*/
|
|
11
|
-
export class WebSocketHandler {
|
|
12
|
-
constructor({ connectionTimeout } = {}) {
|
|
13
|
-
this.metadata = {
|
|
14
|
-
handlerProtocol: "websocket",
|
|
15
|
-
};
|
|
16
|
-
this.connectionTimeout = connectionTimeout || 2000;
|
|
17
|
-
}
|
|
18
|
-
destroy() { }
|
|
19
|
-
handle(request) {
|
|
20
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
-
const url = formatUrl(request);
|
|
22
|
-
const socket = new WebSocket(url);
|
|
23
|
-
socket.binaryType = "arraybuffer";
|
|
24
|
-
yield waitForReady(socket, this.connectionTimeout);
|
|
25
|
-
const { body } = request;
|
|
26
|
-
const bodyStream = getIterator(body);
|
|
27
|
-
const asyncIterable = connect(socket, bodyStream);
|
|
28
|
-
const outputPayload = toReadableStream(asyncIterable);
|
|
29
|
-
return {
|
|
30
|
-
response: new HttpResponse({
|
|
31
|
-
statusCode: 200,
|
|
32
|
-
body: outputPayload,
|
|
33
|
-
}),
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const waitForReady = (socket, connectionTimeout) => new Promise((resolve, reject) => {
|
|
39
|
-
const timeout = setTimeout(() => {
|
|
40
|
-
reject({
|
|
41
|
-
$metadata: {
|
|
42
|
-
httpStatusCode: 500,
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
}, connectionTimeout);
|
|
46
|
-
socket.onopen = () => {
|
|
47
|
-
clearTimeout(timeout);
|
|
48
|
-
resolve();
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
const connect = (socket, data) => {
|
|
52
|
-
// To notify output stream any error thrown after response
|
|
53
|
-
// is returned while data keeps streaming.
|
|
54
|
-
let streamError = undefined;
|
|
55
|
-
const outputStream = {
|
|
56
|
-
[Symbol.asyncIterator]: () => ({
|
|
57
|
-
next: () => {
|
|
58
|
-
return new Promise((resolve, reject) => {
|
|
59
|
-
socket.onerror = (error) => {
|
|
60
|
-
socket.onclose = null;
|
|
61
|
-
socket.close();
|
|
62
|
-
reject(error);
|
|
63
|
-
};
|
|
64
|
-
socket.onclose = () => {
|
|
65
|
-
if (streamError) {
|
|
66
|
-
reject(streamError);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
resolve({
|
|
70
|
-
done: true,
|
|
71
|
-
value: undefined,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
socket.onmessage = (event) => {
|
|
76
|
-
resolve({
|
|
77
|
-
done: false,
|
|
78
|
-
value: new Uint8Array(event.data),
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
});
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
};
|
|
85
|
-
const send = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
-
var e_1, _a;
|
|
87
|
-
try {
|
|
88
|
-
try {
|
|
89
|
-
for (var data_1 = __asyncValues(data), data_1_1; data_1_1 = yield data_1.next(), !data_1_1.done;) {
|
|
90
|
-
const inputChunk = data_1_1.value;
|
|
91
|
-
socket.send(inputChunk);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
95
|
-
finally {
|
|
96
|
-
try {
|
|
97
|
-
if (data_1_1 && !data_1_1.done && (_a = data_1.return)) yield _a.call(data_1);
|
|
98
|
-
}
|
|
99
|
-
finally { if (e_1) throw e_1.error; }
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
// We don't throw the error here because the send()'s returned
|
|
104
|
-
// would already be settled by the time sending chunk throws error.
|
|
105
|
-
// Instead, the notify the output stream to throw if there's
|
|
106
|
-
// exceptions
|
|
107
|
-
streamError = err;
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
// WS status code: https://tools.ietf.org/html/rfc6455#section-7.4
|
|
111
|
-
socket.close(1000);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
send();
|
|
115
|
-
return outputStream;
|
|
116
|
-
};
|
|
117
|
-
/**
|
|
118
|
-
* Transfer payload data to an AsyncIterable.
|
|
119
|
-
* When the ReadableStream API is available in the runtime(e.g. browser), and
|
|
120
|
-
* the request body is ReadableStream, so we need to transfer it to AsyncIterable
|
|
121
|
-
* to make the stream consumable by WebSocket.
|
|
122
|
-
*/
|
|
123
|
-
const getIterator = (stream) => {
|
|
124
|
-
// Noop if stream is already an async iterable
|
|
125
|
-
if (stream[Symbol.asyncIterator])
|
|
126
|
-
return stream;
|
|
127
|
-
else if (isReadableStream(stream)) {
|
|
128
|
-
//If stream is a ReadableStream, transfer the ReadableStream to async iterable.
|
|
129
|
-
return readableStreamtoIterable(stream);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
//For other types, just wrap them with an async iterable.
|
|
133
|
-
return {
|
|
134
|
-
[Symbol.asyncIterator]: function () {
|
|
135
|
-
return __asyncGenerator(this, arguments, function* () {
|
|
136
|
-
yield yield __await(stream);
|
|
137
|
-
});
|
|
138
|
-
},
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
/**
|
|
143
|
-
* Convert async iterable to a ReadableStream when ReadableStream API
|
|
144
|
-
* is available(browsers). Otherwise, leave as it is(ReactNative).
|
|
145
|
-
*/
|
|
146
|
-
const toReadableStream = (asyncIterable) => typeof ReadableStream === "function" ? iterableToReadableStream(asyncIterable) : asyncIterable;
|
|
147
|
-
const isReadableStream = (payload) => typeof ReadableStream === "function" && payload instanceof ReadableStream;
|
|
148
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2Vic29ja2V0LWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3hHLE9BQU8sRUFBNEIsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFaEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBVXJEOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQUszQixZQUFZLEVBQUUsaUJBQWlCLEtBQThCLEVBQUU7UUFKL0MsYUFBUSxHQUEyQjtZQUNqRCxlQUFlLEVBQUUsV0FBVztTQUM3QixDQUFDO1FBR0EsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGlCQUFpQixJQUFJLElBQUksQ0FBQztJQUNyRCxDQUFDO0lBRUQsT0FBTyxLQUFVLENBQUM7SUFFWixNQUFNLENBQUMsT0FBb0I7O1lBQy9CLE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQixNQUFNLE1BQU0sR0FBYyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM3QyxNQUFNLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQztZQUNsQyxNQUFNLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbkQsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQztZQUN6QixNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNsRCxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN0RCxPQUFPO2dCQUNMLFFBQVEsRUFB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O0lBQ3RELDhDQUE4QztJQUM5QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDO1FBQUUsT0FBTyxNQUFNLENBQUM7U0FDM0MsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUNqQywrRUFBK0U7UUFDL0UsT0FBTyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUN6QztTQUFNO1FBQ0wseURBQXlEO1FBQ3pELE9BQU87WUFDTCxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRTs7b0JBQ3RCLG9CQUFNLE1BQU0sQ0FBQSxDQUFDO2dCQUNmLENBQUM7YUFBQTtTQUNGLENBQUM7S0FDSDtBQUNILENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBSSxhQUErQixFQUFFLEVBQUUsQ0FDOUQsT0FBTyxjQUFjLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO0FBRWpHLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxPQUFZLEVBQTZCLEVBQUUsQ0FDbkUsT0FBTyxjQUFjLEtBQUssVUFBVSxJQUFJLE9BQU8sWUFBWSxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpdGVyYWJsZVRvUmVhZGFibGVTdHJlYW0sIHJlYWRhYmxlU3RyZWFtdG9JdGVyYWJsZSB9IGZyb20gXCJAYXdzLXNkay9ldmVudHN0cmVhbS1zZXJkZS1icm93c2VyXCI7XG5pbXBvcnQgeyBIdHRwSGFuZGxlciwgSHR0cFJlcXVlc3QsIEh0dHBSZXNwb25zZSB9IGZyb20gXCJAYXdzLXNkay9wcm90b2NvbC1odHRwXCI7XG5pbXBvcnQgeyBSZXF1ZXN0SGFuZGxlck1ldGFkYXRhIH0gZnJvbSBcIkBhd3Mtc2RrL3R5cGVzXCI7XG5pbXBvcnQgeyBmb3JtYXRVcmwgfSBmcm9tIFwiQGF3cy1zZGsvdXRpbC1mb3JtYXQtdXJsXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViU29ja2V0SGFuZGxlck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG1heGltdW0gdGltZSBpbiBtaWxsaXNlY29uZHMgdGhhdCB0aGUgY29ubmVjdGlvbiBwaGFzZSBvZiBhIHJlcXVlc3RcbiAgICogbWF5IHRha2UgYmVmb3JlIHRoZSBjb25uZWN0aW9uIGF0dGVtcHQgaXMgYWJhbmRvbmVkLlxuICAgKi9cbiAgY29ubmVjdGlvblRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQmFzZSBoYW5kbGVyIGZvciB3ZWJzb2NrZXQgcmVxdWVzdHMuIEJ5IGRlZmF1bHQsIHRoZSByZXF1ZXN0IGlucHV0IGFuZCBvdXRwdXRcbiAqIGJvZHkgd2lsbCBiZSBpbiBhIFJlYWRhYmxlU3RyZWFtLCBiZWNhdXNlIG9mIGludGVyZmFjZSBjb25zaXN0ZW5jeSBhbW9uZyBtaWRkbGV3YXJlLlxuICogSWYgUmVhZGFibGVTdHJlYW0gaXMgbm90IGF2YWlsYWJsZSwgbGlrZSBpbiBSZWFjdC1OYXRpdmUsIHRoZSByZXNwb25zZSBib2R5XG4gKiB3aWxsIGJlIGFuIGFzeW5jIGl0ZXJhYmxlLlxuICovXG5leHBvcnQgY2xhc3MgV2ViU29ja2V0SGFuZGxlciBpbXBsZW1lbnRzIEh0dHBIYW5kbGVyIHtcbiAgcHVibGljIHJlYWRvbmx5IG1ldGFkYXRhOiBSZXF1ZXN0SGFuZGxlck1ldGFkYXRhID0ge1xuICAgIGhhbmRsZXJQcm90b2NvbDogXCJ3ZWJzb2NrZXRcIixcbiAgfTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0aW9uVGltZW91dDogbnVtYmVyO1xuICBjb25zdHJ1Y3Rvcih7IGNvbm5lY3Rpb25UaW1lb3V0IH06IFdlYlNvY2tldEhhbmRsZXJPcHRpb25zID0ge30pIHtcbiAgICB0aGlzLmNvbm5lY3Rpb25UaW1lb3V0ID0gY29ubmVjdGlvblRpbWVvdXQgfHwgMjAwMDtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7fVxuXG4gIGFzeW5jIGhhbmRsZShyZXF1ZXN0OiBIdHRwUmVxdWVzdCk6IFByb21pc2U8eyByZXNwb25zZTogSHR0cFJlc3BvbnNlIH0+IHtcbiAgICBjb25zdCB1cmwgPSBmb3JtYXRVcmwocmVxdWVzdCk7XG4gICAgY29uc3Qgc29ja2V0OiBXZWJTb2NrZXQgPSBuZXcgV2ViU29ja2V0KHVybCk7XG4gICAgc29ja2V0LmJpbmFyeVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG4gICAgYXdhaXQgd2FpdEZvclJlYWR5KHNvY2tldCwgdGhpcy5jb25uZWN0aW9uVGltZW91dCk7XG4gICAgY29uc3QgeyBib2R5IH0gPSByZXF1ZXN0O1xuICAgIGNvbnN0IGJvZHlTdHJlYW0gPSBnZXRJdGVyYXRvcihib2R5KTtcbiAgICBjb25zdCBhc3luY0l0ZXJhYmxlID0gY29ubmVjdChzb2NrZXQsIGJvZHlTdHJlYW0pO1xuICAgIGNvbnN0IG91dHB1dFBheWxvYWQgPSB0b1JlYWRhYmxlU3RyZWFtKGFzeW5jSXRlcmFibGUpO1xuICAgIHJldHVybiB7XG4gICAgICByZXNwb25zZTogbmV3IEh0dHBSZXNwb25zZSh7XG4gICAgICAgIHN0YXR1c0NvZGU6IDIwMCwgLy8gaW5kaWNhdGVzIGNvbm5lY3Rpb24gc3VjY2Vzc1xuICAgICAgICBib2R5OiBvdXRwdXRQYXlsb2FkLFxuICAgICAgfSksXG4gICAgfTtcbiAgfVxufVxuXG5jb25zdCB3YWl0Rm9yUmVhZHkgPSAoc29ja2V0OiBXZWJTb2NrZXQsIGNvbm5lY3Rpb25UaW1lb3V0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+ID0+XG4gIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICByZWplY3Qoe1xuICAgICAgICAkbWV0YWRhdGE6IHtcbiAgICAgICAgICBodHRwU3RhdHVzQ29kZTogNTAwLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSwgY29ubmVjdGlvblRpbWVvdXQpO1xuICAgIHNvY2tldC5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfTtcbiAgfSk7XG5cbmNvbnN0IGNvbm5lY3QgPSAoc29ja2V0OiBXZWJTb2NrZXQsIGRhdGE6IEFzeW5jSXRlcmFibGU8VWludDhBcnJheT4pOiBBc3luY0l0ZXJhYmxlPFVpbnQ4QXJyYXk+ID0+IHtcbiAgLy8gVG8gbm90aWZ5IG91dHB1dCBzdHJlYW0gYW55IGVycm9yIHRocm93biBhZnRlciByZXNwb25zZVxuICAvLyBpcyByZXR1cm5lZCB3aGlsZSBkYXRhIGtlZXBzIHN0cmVhbWluZy5cbiAgbGV0IHN0cmVhbUVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgY29uc3Qgb3V0cHV0U3RyZWFtOiBBc3luY0l0ZXJhYmxlPFVpbnQ4QXJyYXk+ID0ge1xuICAgIFtTeW1ib2wuYXN5bmNJdGVyYXRvcl06ICgpID0+ICh7XG4gICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgc29ja2V0Lm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIHNvY2tldC5vbmNsb3NlID0gbnVsbDtcbiAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpO1xuICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHNvY2tldC5vbmNsb3NlID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHN0cmVhbUVycm9yKSB7XG4gICAgICAgICAgICAgIHJlamVjdChzdHJlYW1FcnJvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICBkb25lOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgIGRvbmU6IGZhbHNlLFxuICAgICAgICAgICAgICB2YWx1ZTogbmV3IFVpbnQ4QXJyYXkoZXZlbnQuZGF0YSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgfSksXG4gIH07XG5cbiAgY29uc3Qgc2VuZCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgZm9yIGF3YWl0IChjb25zdCBpbnB1dENodW5rIG9mIGRhdGEpIHtcbiAgICAgICAgc29ja2V0LnNlbmQoaW5wdXRDaHVuayk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBXZSBkb24ndCB0aHJvdyB0aGUgZXJyb3IgaGVyZSBiZWNhdXNlIHRoZSBzZW5kKCkncyByZXR1cm5lZFxuICAgICAgLy8gd291bGQgYWxyZWFkeSBiZSBzZXR0bGVkIGJ5IHRoZSB0aW1lIHNlbmRpbmcgY2h1bmsgdGhyb3dzIGVycm9yLlxuICAgICAgLy8gSW5zdGVhZCwgdGhlIG5vdGlmeSB0aGUgb3V0cHV0IHN0cmVhbSB0byB0aHJvdyBpZiB0aGVyZSdzXG4gICAgICAvLyBleGNlcHRpb25zXG4gICAgICBzdHJlYW1FcnJvciA9IGVycjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gV1Mgc3RhdHVzIGNvZGU6IGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2NDU1I3NlY3Rpb24tNy40XG4gICAgICBzb2NrZXQuY2xvc2UoMTAwMCk7XG4gICAgfVxuICB9O1xuICBzZW5kKCk7XG4gIHJldHVybiBvdXRwdXRTdHJlYW07XG59O1xuXG4vKipcbiAqIFRyYW5zZmVyIHBheWxvYWQgZGF0YSB0byBhbiBBc3luY0l0ZXJhYmxlLlxuICogV2hlbiB0aGUgUmVhZGFibGVTdHJlYW0gQVBJIGlzIGF2YWlsYWJsZSBpbiB0aGUgcnVudGltZShlLmcuIGJyb3dzZXIpLCBhbmRcbiAqIHRoZSByZXF1ZXN0IGJvZHkgaXMgUmVhZGFibGVTdHJlYW0sIHNvIHdlIG5lZWQgdG8gdHJhbnNmZXIgaXQgdG8gQXN5bmNJdGVyYWJsZVxuICogdG8gbWFrZSB0aGUgc3RyZWFtIGNvbnN1bWFibGUgYnkgV2ViU29ja2V0LlxuICovXG5jb25zdCBnZXRJdGVyYXRvciA9IChzdHJlYW06IGFueSk6IEFzeW5jSXRlcmFibGU8YW55PiA9PiB7XG4gIC8vIE5vb3AgaWYgc3RyZWFtIGlzIGFscmVhZHkgYW4gYXN5bmMgaXRlcmFibGVcbiAgaWYgKHN0cmVhbVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0pIHJldHVybiBzdHJlYW07XG4gIGVsc2UgaWYgKGlzUmVhZGFibGVTdHJlYW0oc3RyZWFtKSkge1xuICAgIC8vSWYgc3RyZWFtIGlzIGEgUmVhZGFibGVTdHJlYW0sIHRyYW5zZmVyIHRoZSBSZWFkYWJsZVN0cmVhbSB0byBhc3luYyBpdGVyYWJsZS5cbiAgICByZXR1cm4gcmVhZGFibGVTdHJlYW10b0l0ZXJhYmxlKHN0cmVhbSk7XG4gIH0gZWxzZSB7XG4gICAgLy9Gb3Igb3RoZXIgdHlwZXMsIGp1c3Qgd3JhcCB0aGVtIHdpdGggYW4gYXN5bmMgaXRlcmFibGUuXG4gICAgcmV0dXJuIHtcbiAgICAgIFtTeW1ib2wuYXN5bmNJdGVyYXRvcl06IGFzeW5jIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIHlpZWxkIHN0cmVhbTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBDb252ZXJ0IGFzeW5jIGl0ZXJhYmxlIHRvIGEgUmVhZGFibGVTdHJlYW0gd2hlbiBSZWFkYWJsZVN0cmVhbSBBUElcbiAqIGlzIGF2YWlsYWJsZShicm93c2VycykuIE90aGVyd2lzZSwgbGVhdmUgYXMgaXQgaXMoUmVhY3ROYXRpdmUpLlxuICovXG5jb25zdCB0b1JlYWRhYmxlU3RyZWFtID0gPFQ+KGFzeW5jSXRlcmFibGU6IEFzeW5jSXRlcmFibGU8VD4pID0+XG4gIHR5cGVvZiBSZWFkYWJsZVN0cmVhbSA9PT0gXCJmdW5jdGlvblwiID8gaXRlcmFibGVUb1JlYWRhYmxlU3RyZWFtKGFzeW5jSXRlcmFibGUpIDogYXN5bmNJdGVyYWJsZTtcblxuY29uc3QgaXNSZWFkYWJsZVN0cmVhbSA9IChwYXlsb2FkOiBhbnkpOiBwYXlsb2FkIGlzIFJlYWRhYmxlU3RyZWFtID0+XG4gIHR5cGVvZiBSZWFkYWJsZVN0cmVhbSA9PT0gXCJmdW5jdGlvblwiICYmIHBheWxvYWQgaW5zdGFuY2VvZiBSZWFkYWJsZVN0cmVhbTtcbiJdfQ==
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { InitializeHandlerOptions, InitializeMiddleware, RequestHandler } from "@aws-sdk/types";
|
|
2
|
-
/**
|
|
3
|
-
* Middleware that inject default sessionId for operations, and inject
|
|
4
|
-
* the parameters from request to the response metadata. This is
|
|
5
|
-
* necessary because the SDK cannot access any parameters other than
|
|
6
|
-
* the result stream. So it copies the parameters from input to the same
|
|
7
|
-
* parameters in the output.
|
|
8
|
-
*/
|
|
9
|
-
export declare const injectSessionIdMiddleware: (config: {
|
|
10
|
-
requestHandler: RequestHandler<any, any>;
|
|
11
|
-
}) => InitializeMiddleware<any, any>;
|
|
12
|
-
export declare const injectSessionIdMiddlewareOptions: InitializeHandlerOptions;
|
package/src/configuration.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { SignatureV4 as BaseSignatureV4 } from "@aws-sdk/signature-v4";
|
|
2
|
-
import { Provider, RequestHandler, RequestSigner } from "@aws-sdk/types";
|
|
3
|
-
|
|
4
|
-
import { SignatureV4 } from "./signer";
|
|
5
|
-
|
|
6
|
-
export interface WebSocketInputConfig {}
|
|
7
|
-
|
|
8
|
-
interface PreviouslyResolved {
|
|
9
|
-
signer: Provider<RequestSigner>;
|
|
10
|
-
requestHandler: RequestHandler<any, any>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface WebSocketResolvedConfig {
|
|
14
|
-
/**
|
|
15
|
-
* Resolved value of input config {@link AwsAuthInputConfig.signer}
|
|
16
|
-
*/
|
|
17
|
-
signer: Provider<RequestSigner>;
|
|
18
|
-
/**
|
|
19
|
-
* The HTTP handler to use. Fetch in browser and Https in Nodejs.
|
|
20
|
-
*/
|
|
21
|
-
requestHandler: RequestHandler<any, any>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const resolveWebSocketConfig = <T>(
|
|
25
|
-
input: T & WebSocketInputConfig & PreviouslyResolved
|
|
26
|
-
): T & WebSocketResolvedConfig =>
|
|
27
|
-
input.requestHandler.metadata?.handlerProtocol !== "websocket"
|
|
28
|
-
? input
|
|
29
|
-
: {
|
|
30
|
-
...input,
|
|
31
|
-
signer: async () => {
|
|
32
|
-
const signerObj = await input.signer();
|
|
33
|
-
if (validateSigner(signerObj)) {
|
|
34
|
-
return new SignatureV4({ signer: signerObj });
|
|
35
|
-
}
|
|
36
|
-
throw new Error("Expected SignatureV4 signer, please check the client constructor.");
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const validateSigner = (signer: any): signer is BaseSignatureV4 => !!signer;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BuildHandler,
|
|
3
|
-
BuildHandlerArguments,
|
|
4
|
-
EventStreamPayloadHandler as IEventStreamPayloadHandler,
|
|
5
|
-
} from "@aws-sdk/types";
|
|
6
|
-
|
|
7
|
-
export const eventStreamPayloadHandler: IEventStreamPayloadHandler = {
|
|
8
|
-
handle: (next: BuildHandler<any, any>, args: BuildHandlerArguments<any>) => next(args),
|
|
9
|
-
};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { HttpRequest } from "@aws-sdk/protocol-http";
|
|
2
|
-
import {
|
|
3
|
-
BuildHandler,
|
|
4
|
-
BuildHandlerArguments,
|
|
5
|
-
BuildMiddleware,
|
|
6
|
-
RelativeMiddlewareOptions,
|
|
7
|
-
RequestHandler,
|
|
8
|
-
} from "@aws-sdk/types";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Middleware that generates WebSocket URL to TranscribeStreaming service
|
|
12
|
-
* Reference: https://docs.aws.amazon.com/transcribe/latest/dg/websocket.html
|
|
13
|
-
*/
|
|
14
|
-
export const websocketURLMiddleware =
|
|
15
|
-
(options: { requestHandler: RequestHandler<any, any> }): BuildMiddleware<any, any> =>
|
|
16
|
-
(next: BuildHandler<any, any>) =>
|
|
17
|
-
(args: BuildHandlerArguments<any>) => {
|
|
18
|
-
const { request } = args;
|
|
19
|
-
if (HttpRequest.isInstance(request) && options.requestHandler.metadata?.handlerProtocol === "websocket") {
|
|
20
|
-
// Update http/2 endpoint to WebSocket-specific endpoint.
|
|
21
|
-
request.protocol = "wss:";
|
|
22
|
-
// Append port to hostname because it needs to be signed together
|
|
23
|
-
request.hostname = `${request.hostname}:8443`;
|
|
24
|
-
request.path = `${request.path}-websocket`;
|
|
25
|
-
request.method = "GET";
|
|
26
|
-
|
|
27
|
-
// Move headers to query string. Because the signature is generated with
|
|
28
|
-
// headers moved to query, the endpoint url needs to tally with the signature.
|
|
29
|
-
const { headers } = request;
|
|
30
|
-
|
|
31
|
-
// 'Content-Type' and 'x-amz-content-sha256' headers are normally set for
|
|
32
|
-
// event stream, but WebSocket doesn't require it.
|
|
33
|
-
// See: 'eventStreamHeaderMiddleware' in @aws-sdk/middleware-eventstream
|
|
34
|
-
delete headers["Content-Type"];
|
|
35
|
-
delete headers["x-amz-content-sha256"];
|
|
36
|
-
|
|
37
|
-
// Serialized header like 'x-amzn-transcribe-sample-rate' should be 'sample-rate'
|
|
38
|
-
// in WebSocket URL.
|
|
39
|
-
for (const name of Object.keys(headers)) {
|
|
40
|
-
if (name.indexOf("x-amzn-transcribe-") === 0) {
|
|
41
|
-
const chunkedName = name.replace("x-amzn-transcribe-", "");
|
|
42
|
-
request.query[chunkedName] = headers[name];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// The service perfers Node.js style 'user-agent' over browser-style
|
|
47
|
-
// 'x-amz-user-agent'
|
|
48
|
-
if (headers["x-amz-user-agent"]) {
|
|
49
|
-
request.query["user-agent"] = headers["x-amz-user-agent"];
|
|
50
|
-
}
|
|
51
|
-
// Host header is required for signing
|
|
52
|
-
request.headers = { host: request.hostname };
|
|
53
|
-
}
|
|
54
|
-
return next(args);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export const websocketURLMiddlewareOptions: RelativeMiddlewareOptions = {
|
|
58
|
-
name: "websocketURLMiddleware",
|
|
59
|
-
tags: ["WEBSOCKET", "EVENT_STREAM"],
|
|
60
|
-
relation: "after",
|
|
61
|
-
toMiddleware: "eventStreamHeaderMiddleware",
|
|
62
|
-
override: true,
|
|
63
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InitializeHandler,
|
|
3
|
-
InitializeHandlerArguments,
|
|
4
|
-
InitializeHandlerOptions,
|
|
5
|
-
InitializeMiddleware,
|
|
6
|
-
RequestHandler,
|
|
7
|
-
} from "@aws-sdk/types";
|
|
8
|
-
import { v4 } from "uuid";
|
|
9
|
-
|
|
10
|
-
type WithSession = {
|
|
11
|
-
SessionId?: string;
|
|
12
|
-
[key: string]: any;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Middleware that inject default sessionId for operations, and inject
|
|
17
|
-
* the parameters from request to the response metadata. This is
|
|
18
|
-
* necessary because the SDK cannot access any parameters other than
|
|
19
|
-
* the result stream. So it copies the parameters from input to the same
|
|
20
|
-
* parameters in the output.
|
|
21
|
-
*/
|
|
22
|
-
export const injectSessionIdMiddleware =
|
|
23
|
-
(config: { requestHandler: RequestHandler<any, any> }): InitializeMiddleware<any, any> =>
|
|
24
|
-
(next: InitializeHandler<WithSession, WithSession>) =>
|
|
25
|
-
async (args: InitializeHandlerArguments<WithSession>) => {
|
|
26
|
-
if (args.input.SessionId === undefined && isWebSocket(config)) {
|
|
27
|
-
args.input.SessionId = v4();
|
|
28
|
-
}
|
|
29
|
-
const requestParams = {
|
|
30
|
-
...args.input,
|
|
31
|
-
};
|
|
32
|
-
const response = await next(args);
|
|
33
|
-
const output = response.output;
|
|
34
|
-
for (const key of Object.keys(output)) {
|
|
35
|
-
if (output[key] === undefined && requestParams[key]) {
|
|
36
|
-
output[key] = requestParams[key];
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return response;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const isWebSocket = (config: { requestHandler: RequestHandler<any, any> }) =>
|
|
43
|
-
config.requestHandler.metadata?.handlerProtocol === "websocket";
|
|
44
|
-
|
|
45
|
-
export const injectSessionIdMiddlewareOptions: InitializeHandlerOptions = {
|
|
46
|
-
step: "initialize",
|
|
47
|
-
name: "injectSessionIdMiddleware",
|
|
48
|
-
tags: ["WEBSOCKET", "EVENT_STREAM"],
|
|
49
|
-
override: true,
|
|
50
|
-
};
|
package/src/plugin.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Pluggable } from "@aws-sdk/types";
|
|
2
|
-
|
|
3
|
-
import { WebSocketResolvedConfig } from "./configuration";
|
|
4
|
-
import { websocketURLMiddleware, websocketURLMiddlewareOptions } from "./middleware-endpoint";
|
|
5
|
-
import { injectSessionIdMiddleware, injectSessionIdMiddlewareOptions } from "./middleware-session-id";
|
|
6
|
-
|
|
7
|
-
export const getWebSocketPlugin = (config: WebSocketResolvedConfig): Pluggable<any, any> => ({
|
|
8
|
-
applyToStack: (clientStack) => {
|
|
9
|
-
clientStack.addRelativeTo(websocketURLMiddleware(config), websocketURLMiddlewareOptions);
|
|
10
|
-
clientStack.add(injectSessionIdMiddleware(config), injectSessionIdMiddlewareOptions);
|
|
11
|
-
},
|
|
12
|
-
});
|
package/src/signer.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { HttpRequest } from "@aws-sdk/protocol-http";
|
|
2
|
-
import { SignatureV4 as BaseSignatureV4 } from "@aws-sdk/signature-v4";
|
|
3
|
-
import {
|
|
4
|
-
HttpRequest as IHttpRequest,
|
|
5
|
-
RequestPresigner,
|
|
6
|
-
RequestPresigningArguments,
|
|
7
|
-
RequestSigner,
|
|
8
|
-
RequestSigningArguments,
|
|
9
|
-
} from "@aws-sdk/types";
|
|
10
|
-
|
|
11
|
-
export class SignatureV4 implements RequestSigner, RequestPresigner {
|
|
12
|
-
private readonly signer: BaseSignatureV4;
|
|
13
|
-
constructor(options: { signer: BaseSignatureV4 }) {
|
|
14
|
-
this.signer = options.signer;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
public presign(originalRequest: IHttpRequest, options: RequestPresigningArguments = {}): Promise<IHttpRequest> {
|
|
18
|
-
return this.signer.presign(originalRequest, options);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async sign(toSign: IHttpRequest, options?: RequestSigningArguments): Promise<IHttpRequest> {
|
|
22
|
-
if (HttpRequest.isInstance(toSign)) {
|
|
23
|
-
// Presign the endpoint url with empty body, otherwise
|
|
24
|
-
// the payload hash would be UNSINGED-PAYLOAD
|
|
25
|
-
const signedRequest = await this.signer.presign(
|
|
26
|
-
{ ...toSign, body: "" },
|
|
27
|
-
{
|
|
28
|
-
// presigned url must be expired within 5 mins.
|
|
29
|
-
expiresIn: 5 * 60,
|
|
30
|
-
// Not to sign headers. Transcribe-streaming WebSocket
|
|
31
|
-
// request omits headers except for required 'host' header. If we sign
|
|
32
|
-
// the other headers, the signature could be mismatch.
|
|
33
|
-
unsignableHeaders: new Set(Object.keys(toSign.headers).filter((header) => header !== "host")),
|
|
34
|
-
}
|
|
35
|
-
);
|
|
36
|
-
return {
|
|
37
|
-
...signedRequest,
|
|
38
|
-
body: toSign.body,
|
|
39
|
-
};
|
|
40
|
-
} else {
|
|
41
|
-
return this.signer.sign(toSign, options);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
package/src/websocket-handler.ts
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { iterableToReadableStream, readableStreamtoIterable } from "@aws-sdk/eventstream-serde-browser";
|
|
2
|
-
import { HttpHandler, HttpRequest, HttpResponse } from "@aws-sdk/protocol-http";
|
|
3
|
-
import { RequestHandlerMetadata } from "@aws-sdk/types";
|
|
4
|
-
import { formatUrl } from "@aws-sdk/util-format-url";
|
|
5
|
-
|
|
6
|
-
export interface WebSocketHandlerOptions {
|
|
7
|
-
/**
|
|
8
|
-
* The maximum time in milliseconds that the connection phase of a request
|
|
9
|
-
* may take before the connection attempt is abandoned.
|
|
10
|
-
*/
|
|
11
|
-
connectionTimeout?: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Base handler for websocket requests. By default, the request input and output
|
|
16
|
-
* body will be in a ReadableStream, because of interface consistency among middleware.
|
|
17
|
-
* If ReadableStream is not available, like in React-Native, the response body
|
|
18
|
-
* will be an async iterable.
|
|
19
|
-
*/
|
|
20
|
-
export class WebSocketHandler implements HttpHandler {
|
|
21
|
-
public readonly metadata: RequestHandlerMetadata = {
|
|
22
|
-
handlerProtocol: "websocket",
|
|
23
|
-
};
|
|
24
|
-
private readonly connectionTimeout: number;
|
|
25
|
-
constructor({ connectionTimeout }: WebSocketHandlerOptions = {}) {
|
|
26
|
-
this.connectionTimeout = connectionTimeout || 2000;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
destroy(): void {}
|
|
30
|
-
|
|
31
|
-
async handle(request: HttpRequest): Promise<{ response: HttpResponse }> {
|
|
32
|
-
const url = formatUrl(request);
|
|
33
|
-
const socket: WebSocket = new WebSocket(url);
|
|
34
|
-
socket.binaryType = "arraybuffer";
|
|
35
|
-
await waitForReady(socket, this.connectionTimeout);
|
|
36
|
-
const { body } = request;
|
|
37
|
-
const bodyStream = getIterator(body);
|
|
38
|
-
const asyncIterable = connect(socket, bodyStream);
|
|
39
|
-
const outputPayload = toReadableStream(asyncIterable);
|
|
40
|
-
return {
|
|
41
|
-
response: new HttpResponse({
|
|
42
|
-
statusCode: 200, // indicates connection success
|
|
43
|
-
body: outputPayload,
|
|
44
|
-
}),
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const waitForReady = (socket: WebSocket, connectionTimeout: number): Promise<void> =>
|
|
50
|
-
new Promise((resolve, reject) => {
|
|
51
|
-
const timeout = setTimeout(() => {
|
|
52
|
-
reject({
|
|
53
|
-
$metadata: {
|
|
54
|
-
httpStatusCode: 500,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
}, connectionTimeout);
|
|
58
|
-
socket.onopen = () => {
|
|
59
|
-
clearTimeout(timeout);
|
|
60
|
-
resolve();
|
|
61
|
-
};
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const connect = (socket: WebSocket, data: AsyncIterable<Uint8Array>): AsyncIterable<Uint8Array> => {
|
|
65
|
-
// To notify output stream any error thrown after response
|
|
66
|
-
// is returned while data keeps streaming.
|
|
67
|
-
let streamError: Error | undefined = undefined;
|
|
68
|
-
const outputStream: AsyncIterable<Uint8Array> = {
|
|
69
|
-
[Symbol.asyncIterator]: () => ({
|
|
70
|
-
next: () => {
|
|
71
|
-
return new Promise((resolve, reject) => {
|
|
72
|
-
socket.onerror = (error) => {
|
|
73
|
-
socket.onclose = null;
|
|
74
|
-
socket.close();
|
|
75
|
-
reject(error);
|
|
76
|
-
};
|
|
77
|
-
socket.onclose = () => {
|
|
78
|
-
if (streamError) {
|
|
79
|
-
reject(streamError);
|
|
80
|
-
} else {
|
|
81
|
-
resolve({
|
|
82
|
-
done: true,
|
|
83
|
-
value: undefined,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
socket.onmessage = (event) => {
|
|
88
|
-
resolve({
|
|
89
|
-
done: false,
|
|
90
|
-
value: new Uint8Array(event.data),
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
});
|
|
94
|
-
},
|
|
95
|
-
}),
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const send = async (): Promise<void> => {
|
|
99
|
-
try {
|
|
100
|
-
for await (const inputChunk of data) {
|
|
101
|
-
socket.send(inputChunk);
|
|
102
|
-
}
|
|
103
|
-
} catch (err) {
|
|
104
|
-
// We don't throw the error here because the send()'s returned
|
|
105
|
-
// would already be settled by the time sending chunk throws error.
|
|
106
|
-
// Instead, the notify the output stream to throw if there's
|
|
107
|
-
// exceptions
|
|
108
|
-
streamError = err;
|
|
109
|
-
} finally {
|
|
110
|
-
// WS status code: https://tools.ietf.org/html/rfc6455#section-7.4
|
|
111
|
-
socket.close(1000);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
send();
|
|
115
|
-
return outputStream;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Transfer payload data to an AsyncIterable.
|
|
120
|
-
* When the ReadableStream API is available in the runtime(e.g. browser), and
|
|
121
|
-
* the request body is ReadableStream, so we need to transfer it to AsyncIterable
|
|
122
|
-
* to make the stream consumable by WebSocket.
|
|
123
|
-
*/
|
|
124
|
-
const getIterator = (stream: any): AsyncIterable<any> => {
|
|
125
|
-
// Noop if stream is already an async iterable
|
|
126
|
-
if (stream[Symbol.asyncIterator]) return stream;
|
|
127
|
-
else if (isReadableStream(stream)) {
|
|
128
|
-
//If stream is a ReadableStream, transfer the ReadableStream to async iterable.
|
|
129
|
-
return readableStreamtoIterable(stream);
|
|
130
|
-
} else {
|
|
131
|
-
//For other types, just wrap them with an async iterable.
|
|
132
|
-
return {
|
|
133
|
-
[Symbol.asyncIterator]: async function* () {
|
|
134
|
-
yield stream;
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Convert async iterable to a ReadableStream when ReadableStream API
|
|
142
|
-
* is available(browsers). Otherwise, leave as it is(ReactNative).
|
|
143
|
-
*/
|
|
144
|
-
const toReadableStream = <T>(asyncIterable: AsyncIterable<T>) =>
|
|
145
|
-
typeof ReadableStream === "function" ? iterableToReadableStream(asyncIterable) : asyncIterable;
|
|
146
|
-
|
|
147
|
-
const isReadableStream = (payload: any): payload is ReadableStream =>
|
|
148
|
-
typeof ReadableStream === "function" && payload instanceof ReadableStream;
|