@nmtjs/ws-transport 0.8.0 → 0.9.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/dist/http.js +148 -0
- package/dist/http.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/injectables.js +8 -1
- package/dist/injectables.js.map +1 -1
- package/dist/server.js +232 -47
- package/dist/server.js.map +1 -1
- package/dist/transport.js +2 -0
- package/dist/transport.js.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.js +53 -9
- package/dist/utils.js.map +1 -1
- package/package.json +7 -7
- package/src/http.ts +150 -0
- package/src/injectables.ts +6 -1
- package/src/server.ts +308 -68
- package/src/transport.ts +2 -2
- package/src/types.ts +7 -9
- package/src/utils.ts +63 -13
package/dist/http.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { createMetadataKey } from "@nmtjs/core";
|
|
2
|
+
import { ErrorCode } from "@nmtjs/protocol/common";
|
|
3
|
+
export let HttpCode = /* @__PURE__ */ function(HttpCode) {
|
|
4
|
+
HttpCode[HttpCode["Continue"] = 100] = "Continue";
|
|
5
|
+
HttpCode[HttpCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
|
|
6
|
+
HttpCode[HttpCode["Processing"] = 102] = "Processing";
|
|
7
|
+
HttpCode[HttpCode["EarlyHints"] = 103] = "EarlyHints";
|
|
8
|
+
HttpCode[HttpCode["OK"] = 200] = "OK";
|
|
9
|
+
HttpCode[HttpCode["Created"] = 201] = "Created";
|
|
10
|
+
HttpCode[HttpCode["Accepted"] = 202] = "Accepted";
|
|
11
|
+
HttpCode[HttpCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
|
|
12
|
+
HttpCode[HttpCode["NoContent"] = 204] = "NoContent";
|
|
13
|
+
HttpCode[HttpCode["ResetContent"] = 205] = "ResetContent";
|
|
14
|
+
HttpCode[HttpCode["PartialContent"] = 206] = "PartialContent";
|
|
15
|
+
HttpCode[HttpCode["MultiStatus"] = 207] = "MultiStatus";
|
|
16
|
+
HttpCode[HttpCode["AlreadyReported"] = 208] = "AlreadyReported";
|
|
17
|
+
HttpCode[HttpCode["IMUsed"] = 226] = "IMUsed";
|
|
18
|
+
HttpCode[HttpCode["MultipleChoices"] = 300] = "MultipleChoices";
|
|
19
|
+
HttpCode[HttpCode["MovedPermanently"] = 301] = "MovedPermanently";
|
|
20
|
+
HttpCode[HttpCode["Found"] = 302] = "Found";
|
|
21
|
+
HttpCode[HttpCode["SeeOther"] = 303] = "SeeOther";
|
|
22
|
+
HttpCode[HttpCode["NotModified"] = 304] = "NotModified";
|
|
23
|
+
HttpCode[HttpCode["UseProxy"] = 305] = "UseProxy";
|
|
24
|
+
HttpCode[HttpCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
|
|
25
|
+
HttpCode[HttpCode["PermanentRedirect"] = 308] = "PermanentRedirect";
|
|
26
|
+
HttpCode[HttpCode["BadRequest"] = 400] = "BadRequest";
|
|
27
|
+
HttpCode[HttpCode["Unauthorized"] = 401] = "Unauthorized";
|
|
28
|
+
HttpCode[HttpCode["PaymentRequired"] = 402] = "PaymentRequired";
|
|
29
|
+
HttpCode[HttpCode["Forbidden"] = 403] = "Forbidden";
|
|
30
|
+
HttpCode[HttpCode["NotFound"] = 404] = "NotFound";
|
|
31
|
+
HttpCode[HttpCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
|
|
32
|
+
HttpCode[HttpCode["NotAcceptable"] = 406] = "NotAcceptable";
|
|
33
|
+
HttpCode[HttpCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
|
|
34
|
+
HttpCode[HttpCode["RequestTimeout"] = 408] = "RequestTimeout";
|
|
35
|
+
HttpCode[HttpCode["Conflict"] = 409] = "Conflict";
|
|
36
|
+
HttpCode[HttpCode["Gone"] = 410] = "Gone";
|
|
37
|
+
HttpCode[HttpCode["LengthRequired"] = 411] = "LengthRequired";
|
|
38
|
+
HttpCode[HttpCode["PreconditionFailed"] = 412] = "PreconditionFailed";
|
|
39
|
+
HttpCode[HttpCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
|
|
40
|
+
HttpCode[HttpCode["URITooLong"] = 414] = "URITooLong";
|
|
41
|
+
HttpCode[HttpCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
|
|
42
|
+
HttpCode[HttpCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
|
|
43
|
+
HttpCode[HttpCode["ExpectationFailed"] = 417] = "ExpectationFailed";
|
|
44
|
+
HttpCode[HttpCode["ImATeapot"] = 418] = "ImATeapot";
|
|
45
|
+
HttpCode[HttpCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
|
|
46
|
+
HttpCode[HttpCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
|
|
47
|
+
HttpCode[HttpCode["Locked"] = 423] = "Locked";
|
|
48
|
+
HttpCode[HttpCode["FailedDependency"] = 424] = "FailedDependency";
|
|
49
|
+
HttpCode[HttpCode["TooEarly"] = 425] = "TooEarly";
|
|
50
|
+
HttpCode[HttpCode["UpgradeRequired"] = 426] = "UpgradeRequired";
|
|
51
|
+
HttpCode[HttpCode["PreconditionRequired"] = 428] = "PreconditionRequired";
|
|
52
|
+
HttpCode[HttpCode["TooManyRequests"] = 429] = "TooManyRequests";
|
|
53
|
+
HttpCode[HttpCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
|
|
54
|
+
HttpCode[HttpCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
|
|
55
|
+
HttpCode[HttpCode["InternalServerError"] = 500] = "InternalServerError";
|
|
56
|
+
HttpCode[HttpCode["NotImplemented"] = 501] = "NotImplemented";
|
|
57
|
+
HttpCode[HttpCode["BadGateway"] = 502] = "BadGateway";
|
|
58
|
+
HttpCode[HttpCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
|
59
|
+
HttpCode[HttpCode["GatewayTimeout"] = 504] = "GatewayTimeout";
|
|
60
|
+
HttpCode[HttpCode["HTTPVersionNotSupported"] = 505] = "HTTPVersionNotSupported";
|
|
61
|
+
HttpCode[HttpCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
|
|
62
|
+
HttpCode[HttpCode["InsufficientStorage"] = 507] = "InsufficientStorage";
|
|
63
|
+
HttpCode[HttpCode["LoopDetected"] = 508] = "LoopDetected";
|
|
64
|
+
HttpCode[HttpCode["NotExtended"] = 510] = "NotExtended";
|
|
65
|
+
HttpCode[HttpCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
|
|
66
|
+
return HttpCode;
|
|
67
|
+
}({});
|
|
68
|
+
export const HttpStatusText = {
|
|
69
|
+
[HttpCode.Continue]: "Continue",
|
|
70
|
+
[HttpCode.SwitchingProtocols]: "Switching Protocols",
|
|
71
|
+
[HttpCode.Processing]: "Processing",
|
|
72
|
+
[HttpCode.EarlyHints]: "Early Hints",
|
|
73
|
+
[HttpCode.OK]: "OK",
|
|
74
|
+
[HttpCode.Created]: "Created",
|
|
75
|
+
[HttpCode.Accepted]: "Accepted",
|
|
76
|
+
[HttpCode.NonAuthoritativeInformation]: "Non-Authoritative Information",
|
|
77
|
+
[HttpCode.NoContent]: "No Content",
|
|
78
|
+
[HttpCode.ResetContent]: "Reset Content",
|
|
79
|
+
[HttpCode.PartialContent]: "Partial Content",
|
|
80
|
+
[HttpCode.MultiStatus]: "Multi-Status",
|
|
81
|
+
[HttpCode.AlreadyReported]: "Already Reported",
|
|
82
|
+
[HttpCode.IMUsed]: "IM Used",
|
|
83
|
+
[HttpCode.MultipleChoices]: "Multiple Choices",
|
|
84
|
+
[HttpCode.MovedPermanently]: "Moved Permanently",
|
|
85
|
+
[HttpCode.Found]: "Found",
|
|
86
|
+
[HttpCode.SeeOther]: "See Other",
|
|
87
|
+
[HttpCode.NotModified]: "Not Modified",
|
|
88
|
+
[HttpCode.UseProxy]: "Use Proxy",
|
|
89
|
+
[HttpCode.TemporaryRedirect]: "Temporary Redirect",
|
|
90
|
+
[HttpCode.PermanentRedirect]: "Permanent Redirect",
|
|
91
|
+
[HttpCode.BadRequest]: "Bad Request",
|
|
92
|
+
[HttpCode.Unauthorized]: "Unauthorized",
|
|
93
|
+
[HttpCode.PaymentRequired]: "Payment Required",
|
|
94
|
+
[HttpCode.Forbidden]: "Forbidden",
|
|
95
|
+
[HttpCode.NotFound]: "Not Found",
|
|
96
|
+
[HttpCode.MethodNotAllowed]: "Method Not Allowed",
|
|
97
|
+
[HttpCode.NotAcceptable]: "Not Acceptable",
|
|
98
|
+
[HttpCode.ProxyAuthenticationRequired]: "Proxy Authentication Required",
|
|
99
|
+
[HttpCode.RequestTimeout]: "Request Timeout",
|
|
100
|
+
[HttpCode.Conflict]: "Conflict",
|
|
101
|
+
[HttpCode.Gone]: "Gone",
|
|
102
|
+
[HttpCode.LengthRequired]: "Length Required",
|
|
103
|
+
[HttpCode.PreconditionFailed]: "Precondition Failed",
|
|
104
|
+
[HttpCode.PayloadTooLarge]: "Payload Too Large",
|
|
105
|
+
[HttpCode.URITooLong]: "URI Too Long",
|
|
106
|
+
[HttpCode.UnsupportedMediaType]: "Unsupported Media Type",
|
|
107
|
+
[HttpCode.RangeNotSatisfiable]: "Range Not Satisfiable",
|
|
108
|
+
[HttpCode.ExpectationFailed]: "Expectation Failed",
|
|
109
|
+
[HttpCode.ImATeapot]: "I'm a Teapot",
|
|
110
|
+
[HttpCode.MisdirectedRequest]: "Misdirected Request",
|
|
111
|
+
[HttpCode.UnprocessableEntity]: "Unprocessable Entity",
|
|
112
|
+
[HttpCode.Locked]: "Locked",
|
|
113
|
+
[HttpCode.FailedDependency]: "Failed Dependency",
|
|
114
|
+
[HttpCode.TooEarly]: "Too Early",
|
|
115
|
+
[HttpCode.UpgradeRequired]: "Upgrade Required",
|
|
116
|
+
[HttpCode.PreconditionRequired]: "Precondition Required",
|
|
117
|
+
[HttpCode.TooManyRequests]: "Too Many Requests",
|
|
118
|
+
[HttpCode.RequestHeaderFieldsTooLarge]: "Request Header Fields Too Large",
|
|
119
|
+
[HttpCode.UnavailableForLegalReasons]: "Unavailable For Legal Reasons",
|
|
120
|
+
[HttpCode.InternalServerError]: "Internal Server Error",
|
|
121
|
+
[HttpCode.NotImplemented]: "Not Implemented",
|
|
122
|
+
[HttpCode.BadGateway]: "Bad Gateway",
|
|
123
|
+
[HttpCode.ServiceUnavailable]: "Service Unavailable",
|
|
124
|
+
[HttpCode.GatewayTimeout]: "Gateway Timeout",
|
|
125
|
+
[HttpCode.HTTPVersionNotSupported]: "HTTP Version Not Supported",
|
|
126
|
+
[HttpCode.VariantAlsoNegotiates]: "Variant Also Negotiates",
|
|
127
|
+
[HttpCode.InsufficientStorage]: "Insufficient Storage",
|
|
128
|
+
[HttpCode.LoopDetected]: "Loop Detected",
|
|
129
|
+
[HttpCode.NotExtended]: "Not Extended",
|
|
130
|
+
[HttpCode.NetworkAuthenticationRequired]: "Network Authentication Required"
|
|
131
|
+
};
|
|
132
|
+
export const HttpCodeMap = {
|
|
133
|
+
[ErrorCode.ValidationError]: HttpCode.BadRequest,
|
|
134
|
+
[ErrorCode.BadRequest]: HttpCode.BadRequest,
|
|
135
|
+
[ErrorCode.NotFound]: HttpCode.NotFound,
|
|
136
|
+
[ErrorCode.Forbidden]: HttpCode.Forbidden,
|
|
137
|
+
[ErrorCode.Unauthorized]: HttpCode.Unauthorized,
|
|
138
|
+
[ErrorCode.InternalServerError]: HttpCode.InternalServerError,
|
|
139
|
+
[ErrorCode.NotAcceptable]: HttpCode.NotAcceptable,
|
|
140
|
+
[ErrorCode.RequestTimeout]: HttpCode.RequestTimeout,
|
|
141
|
+
[ErrorCode.GatewayTimeout]: HttpCode.GatewayTimeout,
|
|
142
|
+
[ErrorCode.ServiceUnavailable]: HttpCode.ServiceUnavailable,
|
|
143
|
+
[ErrorCode.ClientRequestError]: HttpCode.BadRequest,
|
|
144
|
+
[ErrorCode.ConnectionError]: HttpCode.NotAcceptable
|
|
145
|
+
};
|
|
146
|
+
export const AllowedHttpMethod = createMetadataKey("http:method");
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"AAAA,SAAS,yBAAyB,aAAa;AAC/C,SAAS,iBAAiB,wBAAwB;AAElD,OAAO,IAAK,8CAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACD;AAED,OAAO,MAAMA,iBAA2C;EACrD,SAAS,WAAW;EACpB,SAAS,qBAAqB;EAC9B,SAAS,aAAa;EACtB,SAAS,aAAa;EACtB,SAAS,KAAK;EACd,SAAS,UAAU;EACnB,SAAS,WAAW;EACpB,SAAS,8BAA8B;EACvC,SAAS,YAAY;EACrB,SAAS,eAAe;EACxB,SAAS,iBAAiB;EAC1B,SAAS,cAAc;EACvB,SAAS,kBAAkB;EAC3B,SAAS,SAAS;EAClB,SAAS,kBAAkB;EAC3B,SAAS,mBAAmB;EAC5B,SAAS,QAAQ;EACjB,SAAS,WAAW;EACpB,SAAS,cAAc;EACvB,SAAS,WAAW;EACpB,SAAS,oBAAoB;EAC7B,SAAS,oBAAoB;EAC7B,SAAS,aAAa;EACtB,SAAS,eAAe;EACxB,SAAS,kBAAkB;EAC3B,SAAS,YAAY;EACrB,SAAS,WAAW;EACpB,SAAS,mBAAmB;EAC5B,SAAS,gBAAgB;EACzB,SAAS,8BAA8B;EACvC,SAAS,iBAAiB;EAC1B,SAAS,WAAW;EACpB,SAAS,OAAO;EAChB,SAAS,iBAAiB;EAC1B,SAAS,qBAAqB;EAC9B,SAAS,kBAAkB;EAC3B,SAAS,aAAa;EACtB,SAAS,uBAAuB;EAChC,SAAS,sBAAsB;EAC/B,SAAS,oBAAoB;EAC7B,SAAS,YAAY;EACrB,SAAS,qBAAqB;EAC9B,SAAS,sBAAsB;EAC/B,SAAS,SAAS;EAClB,SAAS,mBAAmB;EAC5B,SAAS,WAAW;EACpB,SAAS,kBAAkB;EAC3B,SAAS,uBAAuB;EAChC,SAAS,kBAAkB;EAC3B,SAAS,8BAA8B;EACvC,SAAS,6BAA6B;EACtC,SAAS,sBAAsB;EAC/B,SAAS,iBAAiB;EAC1B,SAAS,aAAa;EACtB,SAAS,qBAAqB;EAC9B,SAAS,iBAAiB;EAC1B,SAAS,0BAA0B;EACnC,SAAS,wBAAwB;EACjC,SAAS,sBAAsB;EAC/B,SAAS,eAAe;EACxB,SAAS,cAAc;EACvB,SAAS,gCAAgC;AAC3C;AAED,OAAO,MAAM,cAAc;EACxB,UAAU,kBAAkB,SAAS;EACrC,UAAU,aAAa,SAAS;EAChC,UAAU,WAAW,SAAS;EAC9B,UAAU,YAAY,SAAS;EAC/B,UAAU,eAAe,SAAS;EAClC,UAAU,sBAAsB,SAAS;EACzC,UAAU,gBAAgB,SAAS;EACnC,UAAU,iBAAiB,SAAS;EACpC,UAAU,iBAAiB,SAAS;EACpC,UAAU,qBAAqB,SAAS;EACxC,UAAU,qBAAqB,SAAS;EACxC,UAAU,kBAAkB,SAAS;AACvC;AAED,OAAO,MAAM,oBACX,kBAAyC,cAAc","names":["HttpStatusText: Record<HttpCode, string>"],"sources":["../src/http.ts"],"sourcesContent":["import { createMetadataKey } from '@nmtjs/core'\nimport { ErrorCode } from '@nmtjs/protocol/common'\n\nexport enum HttpCode {\n Continue = 100,\n SwitchingProtocols = 101,\n Processing = 102,\n EarlyHints = 103,\n OK = 200,\n Created = 201,\n Accepted = 202,\n NonAuthoritativeInformation = 203,\n NoContent = 204,\n ResetContent = 205,\n PartialContent = 206,\n MultiStatus = 207,\n AlreadyReported = 208,\n IMUsed = 226,\n MultipleChoices = 300,\n MovedPermanently = 301,\n Found = 302,\n SeeOther = 303,\n NotModified = 304,\n UseProxy = 305,\n TemporaryRedirect = 307,\n PermanentRedirect = 308,\n BadRequest = 400,\n Unauthorized = 401,\n PaymentRequired = 402,\n Forbidden = 403,\n NotFound = 404,\n MethodNotAllowed = 405,\n NotAcceptable = 406,\n ProxyAuthenticationRequired = 407,\n RequestTimeout = 408,\n Conflict = 409,\n Gone = 410,\n LengthRequired = 411,\n PreconditionFailed = 412,\n PayloadTooLarge = 413,\n URITooLong = 414,\n UnsupportedMediaType = 415,\n RangeNotSatisfiable = 416,\n ExpectationFailed = 417,\n ImATeapot = 418,\n MisdirectedRequest = 421,\n UnprocessableEntity = 422,\n Locked = 423,\n FailedDependency = 424,\n TooEarly = 425,\n UpgradeRequired = 426,\n PreconditionRequired = 428,\n TooManyRequests = 429,\n RequestHeaderFieldsTooLarge = 431,\n UnavailableForLegalReasons = 451,\n InternalServerError = 500,\n NotImplemented = 501,\n BadGateway = 502,\n ServiceUnavailable = 503,\n GatewayTimeout = 504,\n HTTPVersionNotSupported = 505,\n VariantAlsoNegotiates = 506,\n InsufficientStorage = 507,\n LoopDetected = 508,\n NotExtended = 510,\n NetworkAuthenticationRequired = 511,\n}\n\nexport const HttpStatusText: Record<HttpCode, string> = {\n [HttpCode.Continue]: 'Continue',\n [HttpCode.SwitchingProtocols]: 'Switching Protocols',\n [HttpCode.Processing]: 'Processing',\n [HttpCode.EarlyHints]: 'Early Hints',\n [HttpCode.OK]: 'OK',\n [HttpCode.Created]: 'Created',\n [HttpCode.Accepted]: 'Accepted',\n [HttpCode.NonAuthoritativeInformation]: 'Non-Authoritative Information',\n [HttpCode.NoContent]: 'No Content',\n [HttpCode.ResetContent]: 'Reset Content',\n [HttpCode.PartialContent]: 'Partial Content',\n [HttpCode.MultiStatus]: 'Multi-Status',\n [HttpCode.AlreadyReported]: 'Already Reported',\n [HttpCode.IMUsed]: 'IM Used',\n [HttpCode.MultipleChoices]: 'Multiple Choices',\n [HttpCode.MovedPermanently]: 'Moved Permanently',\n [HttpCode.Found]: 'Found',\n [HttpCode.SeeOther]: 'See Other',\n [HttpCode.NotModified]: 'Not Modified',\n [HttpCode.UseProxy]: 'Use Proxy',\n [HttpCode.TemporaryRedirect]: 'Temporary Redirect',\n [HttpCode.PermanentRedirect]: 'Permanent Redirect',\n [HttpCode.BadRequest]: 'Bad Request',\n [HttpCode.Unauthorized]: 'Unauthorized',\n [HttpCode.PaymentRequired]: 'Payment Required',\n [HttpCode.Forbidden]: 'Forbidden',\n [HttpCode.NotFound]: 'Not Found',\n [HttpCode.MethodNotAllowed]: 'Method Not Allowed',\n [HttpCode.NotAcceptable]: 'Not Acceptable',\n [HttpCode.ProxyAuthenticationRequired]: 'Proxy Authentication Required',\n [HttpCode.RequestTimeout]: 'Request Timeout',\n [HttpCode.Conflict]: 'Conflict',\n [HttpCode.Gone]: 'Gone',\n [HttpCode.LengthRequired]: 'Length Required',\n [HttpCode.PreconditionFailed]: 'Precondition Failed',\n [HttpCode.PayloadTooLarge]: 'Payload Too Large',\n [HttpCode.URITooLong]: 'URI Too Long',\n [HttpCode.UnsupportedMediaType]: 'Unsupported Media Type',\n [HttpCode.RangeNotSatisfiable]: 'Range Not Satisfiable',\n [HttpCode.ExpectationFailed]: 'Expectation Failed',\n [HttpCode.ImATeapot]: \"I'm a Teapot\",\n [HttpCode.MisdirectedRequest]: 'Misdirected Request',\n [HttpCode.UnprocessableEntity]: 'Unprocessable Entity',\n [HttpCode.Locked]: 'Locked',\n [HttpCode.FailedDependency]: 'Failed Dependency',\n [HttpCode.TooEarly]: 'Too Early',\n [HttpCode.UpgradeRequired]: 'Upgrade Required',\n [HttpCode.PreconditionRequired]: 'Precondition Required',\n [HttpCode.TooManyRequests]: 'Too Many Requests',\n [HttpCode.RequestHeaderFieldsTooLarge]: 'Request Header Fields Too Large',\n [HttpCode.UnavailableForLegalReasons]: 'Unavailable For Legal Reasons',\n [HttpCode.InternalServerError]: 'Internal Server Error',\n [HttpCode.NotImplemented]: 'Not Implemented',\n [HttpCode.BadGateway]: 'Bad Gateway',\n [HttpCode.ServiceUnavailable]: 'Service Unavailable',\n [HttpCode.GatewayTimeout]: 'Gateway Timeout',\n [HttpCode.HTTPVersionNotSupported]: 'HTTP Version Not Supported',\n [HttpCode.VariantAlsoNegotiates]: 'Variant Also Negotiates',\n [HttpCode.InsufficientStorage]: 'Insufficient Storage',\n [HttpCode.LoopDetected]: 'Loop Detected',\n [HttpCode.NotExtended]: 'Not Extended',\n [HttpCode.NetworkAuthenticationRequired]: 'Network Authentication Required',\n}\n\nexport const HttpCodeMap = {\n [ErrorCode.ValidationError]: HttpCode.BadRequest,\n [ErrorCode.BadRequest]: HttpCode.BadRequest,\n [ErrorCode.NotFound]: HttpCode.NotFound,\n [ErrorCode.Forbidden]: HttpCode.Forbidden,\n [ErrorCode.Unauthorized]: HttpCode.Unauthorized,\n [ErrorCode.InternalServerError]: HttpCode.InternalServerError,\n [ErrorCode.NotAcceptable]: HttpCode.NotAcceptable,\n [ErrorCode.RequestTimeout]: HttpCode.RequestTimeout,\n [ErrorCode.GatewayTimeout]: HttpCode.GatewayTimeout,\n [ErrorCode.ServiceUnavailable]: HttpCode.ServiceUnavailable,\n [ErrorCode.ClientRequestError]: HttpCode.BadRequest,\n [ErrorCode.ConnectionError]: HttpCode.NotAcceptable,\n}\n\nexport const AllowedHttpMethod =\n createMetadataKey<Array<'get' | 'post'>>('http:method')\n"],"version":3,"file":"http.js"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc","names":[],"sources":["src/index.ts"],"sourcesContent":["export * from './injectables.ts'\nexport * from './server.ts'\nexport * from './transport.ts'\nexport * from './types.ts'\nexport * from './utils.ts'\n"],"version":3}
|
|
1
|
+
{"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc","names":[],"sources":["../src/index.ts"],"sourcesContent":["export * from './injectables.ts'\nexport * from './server.ts'\nexport * from './transport.ts'\nexport * from './types.ts'\nexport * from './utils.ts'\n"],"version":3,"file":"index.js"}
|
package/dist/injectables.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { createLazyInjectable, Scope } from "@nmtjs/core";
|
|
1
2
|
import { ProtocolInjectables } from "@nmtjs/protocol/server";
|
|
2
3
|
const connectionData = ProtocolInjectables.connectionData;
|
|
3
|
-
|
|
4
|
+
const httpResponseHeaders = createLazyInjectable(Scope.Call);
|
|
5
|
+
export const WsTransportInjectables = {
|
|
6
|
+
connectionData,
|
|
7
|
+
httpResponseHeaders
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=injectables.js.map
|
package/dist/injectables.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"
|
|
1
|
+
{"mappings":"AAAA,SAAS,sBAA2C,aAAa,aAAa;AAC9E,SAAS,2BAA2B,wBAAwB;AAG5D,MAAM,iBAAiB,oBAAoB;AAK3C,MAAM,sBAAsB,qBAC1B,MAAM,KACP;AAED,OAAO,MAAM,yBAAyB;CACpC;CACA;AACD","names":[],"sources":["../src/injectables.ts"],"sourcesContent":["import { createLazyInjectable, type LazyInjectable, Scope } from '@nmtjs/core'\nimport { ProtocolInjectables } from '@nmtjs/protocol/server'\nimport type { WsUserData } from './types.ts'\n\nconst connectionData = ProtocolInjectables.connectionData as LazyInjectable<\n WsUserData['request'],\n Scope.Connection\n>\n\nconst httpResponseHeaders = createLazyInjectable<Headers, Scope.Call>(\n Scope.Call,\n)\n\nexport const WsTransportInjectables = {\n connectionData,\n httpResponseHeaders,\n} as const\n"],"version":3,"file":"injectables.js"}
|
package/dist/server.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { App, SSLApp, us_socket_local_port } from "uWebSockets.js";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { once } from "node:events";
|
|
4
|
+
import { Duplex, Readable } from "node:stream";
|
|
5
|
+
import { Scope } from "@nmtjs/core";
|
|
6
|
+
import { ClientMessageType, decodeNumber, ErrorCode, ProtocolBlob } from "@nmtjs/protocol/common";
|
|
7
|
+
import { Connection, getFormat, isIterableResult, isSubscriptionResult, ProtocolClientStream, ProtocolError, ProtocolInjectables, UnsupportedContentTypeError, UnsupportedFormatError } from "@nmtjs/protocol/server";
|
|
8
|
+
import { AllowedHttpMethod, HttpCode, HttpCodeMap, HttpStatusText } from "./http.js";
|
|
6
9
|
import { WsTransportInjectables } from "./injectables.js";
|
|
7
|
-
import { getRequestData, send } from "./utils.js";
|
|
10
|
+
import { getRequestBody, getRequestData, readableToArrayBuffer, send, setHeaders } from "./utils.js";
|
|
11
|
+
const DEFAULT_ALLOWED_METHODS = ["post"];
|
|
8
12
|
export class WsTransportServer {
|
|
9
13
|
server;
|
|
10
14
|
clients = new Map();
|
|
@@ -23,54 +27,55 @@ export class WsTransportServer {
|
|
|
23
27
|
}).ws("/api", {
|
|
24
28
|
sendPingsAutomatically: true,
|
|
25
29
|
maxPayloadLength: this.options.maxPayloadLength,
|
|
26
|
-
upgrade: (res, req,
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
query: requestData.query,
|
|
34
|
-
headers: requestData.headers,
|
|
35
|
-
proxiedRemoteAddress: Buffer.from(res.getProxiedRemoteAddressAsText()).toString(),
|
|
36
|
-
remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString(),
|
|
37
|
-
contentType,
|
|
38
|
-
acceptType
|
|
39
|
-
},
|
|
40
|
-
opening: createPromise(),
|
|
41
|
-
backpressure: null,
|
|
42
|
-
context: {}
|
|
43
|
-
};
|
|
44
|
-
res.upgrade(data, req.getHeader("sec-websocket-key"), req.getHeader("sec-websocket-protocol"), req.getHeader("sec-websocket-extensions"), context);
|
|
45
|
-
},
|
|
46
|
-
open: async (ws) => {
|
|
47
|
-
const { id, context, request, opening } = ws.getUserData();
|
|
48
|
-
this.clients.set(id, ws);
|
|
49
|
-
this.logger.debug("Connection %s opened", id);
|
|
30
|
+
upgrade: async (res, req, socketContext) => {
|
|
31
|
+
const ac = new AbortController();
|
|
32
|
+
res.onAborted(ac.abort.bind(ac));
|
|
33
|
+
const requestData = getRequestData(req, res);
|
|
34
|
+
const contentType = requestData.query.get("content-type") || requestData.headers.get("content-type");
|
|
35
|
+
const acceptType = requestData.query.get("accept") || requestData.headers.get("accept");
|
|
36
|
+
const connectionId = randomUUID();
|
|
50
37
|
try {
|
|
51
|
-
const { context
|
|
52
|
-
id,
|
|
53
|
-
data: {}
|
|
38
|
+
const { context } = await this.protocol.addConnection(this, {
|
|
39
|
+
id: connectionId,
|
|
40
|
+
data: { type: "ws" }
|
|
54
41
|
}, {
|
|
55
|
-
acceptType
|
|
56
|
-
contentType
|
|
42
|
+
acceptType,
|
|
43
|
+
contentType
|
|
57
44
|
});
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
context.container.provide(WsTransportInjectables.connectionData, requestData);
|
|
46
|
+
if (!ac.signal.aborted) {
|
|
47
|
+
res.cork(() => {
|
|
48
|
+
res.upgrade({
|
|
49
|
+
id: connectionId,
|
|
50
|
+
request: requestData,
|
|
51
|
+
contentType,
|
|
52
|
+
acceptType,
|
|
53
|
+
backpressure: null,
|
|
54
|
+
context
|
|
55
|
+
}, req.getHeader("sec-websocket-key"), req.getHeader("sec-websocket-protocol"), req.getHeader("sec-websocket-extensions"), socketContext);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
62
58
|
} catch (error) {
|
|
63
|
-
|
|
59
|
+
this.logger.debug(new Error("Failed to upgrade connection", { cause: error }));
|
|
60
|
+
if (!ac.signal.aborted) {
|
|
61
|
+
res.cork(() => {
|
|
62
|
+
res.writeStatus("500 Internal Server Error");
|
|
63
|
+
res.endWithoutBody();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
67
|
},
|
|
68
|
+
open: (ws) => {
|
|
69
|
+
const { id } = ws.getUserData();
|
|
70
|
+
this.logger.debug("Connection %s opened", id);
|
|
71
|
+
this.clients.set(id, ws);
|
|
72
|
+
},
|
|
66
73
|
message: async (ws, buffer) => {
|
|
67
|
-
const { opening } = ws.getUserData();
|
|
68
74
|
const messageType = decodeNumber(buffer, "Uint8");
|
|
69
75
|
if (messageType in this === false) {
|
|
70
76
|
ws.end(1011, "Unknown message type");
|
|
71
77
|
} else {
|
|
72
78
|
try {
|
|
73
|
-
await opening.promise;
|
|
74
79
|
await this[messageType](ws, buffer.slice(Uint8Array.BYTES_PER_ELEMENT));
|
|
75
80
|
} catch (error) {
|
|
76
81
|
this.logError(error, "Error while processing message");
|
|
@@ -86,9 +91,9 @@ export class WsTransportServer {
|
|
|
86
91
|
const { id } = ws.getUserData();
|
|
87
92
|
this.logger.debug("Connection %s closed with code %s: %s", id, code, Buffer.from(message).toString());
|
|
88
93
|
this.clients.delete(id);
|
|
89
|
-
await this.protocol.
|
|
94
|
+
await this.protocol.removeConnection(id);
|
|
90
95
|
}
|
|
91
|
-
});
|
|
96
|
+
}).get("/api/:namespace/:procedure", this.httpHandler.bind(this)).post("/api/:namespace/:procedure", this.httpHandler.bind(this));
|
|
92
97
|
}
|
|
93
98
|
send(connection, messageType, buffer) {
|
|
94
99
|
const ws = this.clients.get(connection.id);
|
|
@@ -121,6 +126,174 @@ export class WsTransportServer {
|
|
|
121
126
|
async stop() {
|
|
122
127
|
this.server.close();
|
|
123
128
|
}
|
|
129
|
+
async httpHandler(res, req) {
|
|
130
|
+
this.applyCors(res, req);
|
|
131
|
+
const ac = new AbortController();
|
|
132
|
+
res.onAborted(ac.abort.bind(ac));
|
|
133
|
+
const method = req.getMethod();
|
|
134
|
+
const namespace = req.getParameter("namespace");
|
|
135
|
+
const procedure = req.getParameter("procedure");
|
|
136
|
+
const requestData = getRequestData(req, res);
|
|
137
|
+
if (!namespace || !procedure) {
|
|
138
|
+
const status = HttpCode.NotFound;
|
|
139
|
+
const text = HttpStatusText[status];
|
|
140
|
+
return void res.cork(() => {
|
|
141
|
+
if (ac.signal.aborted) return;
|
|
142
|
+
res.writeStatus(`${status} ${text}`);
|
|
143
|
+
res.endWithoutBody();
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const isBlob = requestData.headers.get("x-neemata-blob") === "true";
|
|
147
|
+
const contentType = requestData.headers.get("content-type");
|
|
148
|
+
const acceptType = requestData.headers.get("accept");
|
|
149
|
+
const connectionId = randomUUID();
|
|
150
|
+
const connection = new Connection({
|
|
151
|
+
id: connectionId,
|
|
152
|
+
data: { type: "http" }
|
|
153
|
+
});
|
|
154
|
+
const responseHeaders = new Headers();
|
|
155
|
+
const container = this.context.container.fork(Scope.Call);
|
|
156
|
+
container.provide(ProtocolInjectables.connection, connection);
|
|
157
|
+
container.provide(WsTransportInjectables.connectionData, requestData);
|
|
158
|
+
container.provide(WsTransportInjectables.httpResponseHeaders, responseHeaders);
|
|
159
|
+
const body = method === "post" ? getRequestBody(res) : undefined;
|
|
160
|
+
const metadata = (metadata) => {
|
|
161
|
+
const allowHttpMethod = metadata.get(AllowedHttpMethod) ?? DEFAULT_ALLOWED_METHODS;
|
|
162
|
+
if (!allowHttpMethod.includes(method)) {
|
|
163
|
+
throw new ProtocolError(ErrorCode.NotFound);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
let format;
|
|
167
|
+
try {
|
|
168
|
+
format = getFormat(this.context.format, {
|
|
169
|
+
acceptType,
|
|
170
|
+
contentType: isBlob ? "*/*" : contentType
|
|
171
|
+
});
|
|
172
|
+
let payload = undefined;
|
|
173
|
+
if (body) {
|
|
174
|
+
if (isBlob) {
|
|
175
|
+
const type = contentType || "application/octet-stream";
|
|
176
|
+
const contentLength = requestData.headers.get("content-length");
|
|
177
|
+
const size = contentLength ? Number.parseInt(contentLength) : undefined;
|
|
178
|
+
const stream = new ProtocolClientStream(-1, {
|
|
179
|
+
size,
|
|
180
|
+
type
|
|
181
|
+
});
|
|
182
|
+
body.pipe(stream);
|
|
183
|
+
payload = stream;
|
|
184
|
+
} else {
|
|
185
|
+
const buffer = await readableToArrayBuffer(body);
|
|
186
|
+
if (buffer.byteLength > 0) {
|
|
187
|
+
payload = format.decoder.decode(buffer);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const result = await this.protocol.call({
|
|
192
|
+
connection,
|
|
193
|
+
namespace,
|
|
194
|
+
procedure,
|
|
195
|
+
payload,
|
|
196
|
+
metadata,
|
|
197
|
+
container,
|
|
198
|
+
signal: ac.signal
|
|
199
|
+
});
|
|
200
|
+
if (isIterableResult(result) || isSubscriptionResult(result)) {
|
|
201
|
+
res.cork(() => {
|
|
202
|
+
if (ac.signal.aborted) return;
|
|
203
|
+
const status = HttpCode.NotImplemented;
|
|
204
|
+
const text = HttpStatusText[status];
|
|
205
|
+
res.writeStatus(`${status} ${text}`);
|
|
206
|
+
res.end();
|
|
207
|
+
});
|
|
208
|
+
} else {
|
|
209
|
+
const { output } = result;
|
|
210
|
+
if (output instanceof ProtocolBlob) {
|
|
211
|
+
const { source, metadata } = output;
|
|
212
|
+
const { type } = metadata;
|
|
213
|
+
let stream;
|
|
214
|
+
if (source instanceof ReadableStream) {
|
|
215
|
+
stream = Readable.fromWeb(source);
|
|
216
|
+
} else if (source instanceof Readable || source instanceof Duplex) {
|
|
217
|
+
stream = Readable.from(source);
|
|
218
|
+
} else {
|
|
219
|
+
throw new Error("Invalid stream source");
|
|
220
|
+
}
|
|
221
|
+
res.cork(() => {
|
|
222
|
+
if (ac.signal.aborted) return;
|
|
223
|
+
responseHeaders.set("X-Neemata-Blob", "true");
|
|
224
|
+
responseHeaders.set("Content-Type", type);
|
|
225
|
+
if (metadata.size) res.writeHeader("Content-Length", metadata.size.toString());
|
|
226
|
+
setHeaders(res, responseHeaders);
|
|
227
|
+
});
|
|
228
|
+
ac.signal.addEventListener("abort", () => stream.destroy(), { once: true });
|
|
229
|
+
stream.on("data", (chunk) => {
|
|
230
|
+
console.log({ chunk });
|
|
231
|
+
if (ac.signal.aborted) return;
|
|
232
|
+
const buf = Buffer.from(chunk);
|
|
233
|
+
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
234
|
+
const ok = res.write(ab);
|
|
235
|
+
if (!ok) {
|
|
236
|
+
stream.pause();
|
|
237
|
+
res.onWritable(() => {
|
|
238
|
+
stream.resume();
|
|
239
|
+
return true;
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
await once(stream, "end");
|
|
244
|
+
if (stream.readableAborted) {
|
|
245
|
+
res.end(undefined, true);
|
|
246
|
+
} else {
|
|
247
|
+
res.end();
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
res.cork(() => {
|
|
251
|
+
if (ac.signal.aborted) return;
|
|
252
|
+
const status = HttpCode.OK;
|
|
253
|
+
const text = HttpStatusText[status];
|
|
254
|
+
const buffer = format.encoder.encode(output);
|
|
255
|
+
res.writeStatus(`${status} ${text}`);
|
|
256
|
+
responseHeaders.set("Content-Type", format.encoder.contentType);
|
|
257
|
+
setHeaders(res, responseHeaders);
|
|
258
|
+
res.end(buffer);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} catch (error) {
|
|
263
|
+
if (ac.signal.aborted) return;
|
|
264
|
+
if (error instanceof UnsupportedFormatError) {
|
|
265
|
+
res.cork(() => {
|
|
266
|
+
if (ac.signal.aborted) return;
|
|
267
|
+
const status = error instanceof UnsupportedContentTypeError ? HttpCode.UnsupportedMediaType : HttpCode.NotAcceptable;
|
|
268
|
+
const text = HttpStatusText[status];
|
|
269
|
+
res.writeStatus(`${status} ${text}`);
|
|
270
|
+
res.end();
|
|
271
|
+
});
|
|
272
|
+
} else if (error instanceof ProtocolError) {
|
|
273
|
+
res.cork(() => {
|
|
274
|
+
if (ac.signal.aborted) return;
|
|
275
|
+
const status = error.code in HttpCodeMap ? HttpCodeMap[error.code] : HttpCode.InternalServerError;
|
|
276
|
+
const text = HttpStatusText[status];
|
|
277
|
+
res.writeStatus(`${status} ${text}`);
|
|
278
|
+
res.end(format.encoder.encode(error));
|
|
279
|
+
});
|
|
280
|
+
} else {
|
|
281
|
+
this.logError(error, "Unknown error while processing request");
|
|
282
|
+
res.cork(() => {
|
|
283
|
+
if (ac.signal.aborted) return;
|
|
284
|
+
const status = HttpCode.InternalServerError;
|
|
285
|
+
const text = HttpStatusText[status];
|
|
286
|
+
const payload = format.encoder.encode(new ProtocolError(ErrorCode.InternalServerError, "Internal Server Error"));
|
|
287
|
+
res.writeStatus(`${status} ${text}`);
|
|
288
|
+
res.end(payload);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
} finally {
|
|
292
|
+
container.dispose().catch((error) => {
|
|
293
|
+
this.logError(error, "Error while disposing call container");
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
124
297
|
get protocol() {
|
|
125
298
|
return this.context.protocol;
|
|
126
299
|
}
|
|
@@ -131,8 +304,18 @@ export class WsTransportServer {
|
|
|
131
304
|
this.logger.error(new Error(message, { cause }));
|
|
132
305
|
}
|
|
133
306
|
applyCors(res, req) {
|
|
307
|
+
if (this.options.cors === false) return;
|
|
134
308
|
const origin = req.getHeader("origin");
|
|
135
309
|
if (!origin) return;
|
|
310
|
+
let allowed = false;
|
|
311
|
+
if (this.options.cors === undefined || this.options.cors === true) {
|
|
312
|
+
allowed = true;
|
|
313
|
+
} else if (Array.isArray(this.options.cors)) {
|
|
314
|
+
allowed = this.options.cors.includes(origin);
|
|
315
|
+
} else {
|
|
316
|
+
allowed = this.options.cors(origin);
|
|
317
|
+
}
|
|
318
|
+
if (!allowed) return;
|
|
136
319
|
res.writeHeader("Access-Control-Allow-Origin", origin);
|
|
137
320
|
res.writeHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
138
321
|
res.writeHeader("Access-Control-Allow-Methods", "GET, POST");
|
|
@@ -153,26 +336,28 @@ export class WsTransportServer {
|
|
|
153
336
|
[ClientMessageType.ClientStreamPush](ws, buffer) {
|
|
154
337
|
const { id } = ws.getUserData();
|
|
155
338
|
const streamId = decodeNumber(buffer, "Uint32");
|
|
156
|
-
this.protocol.
|
|
339
|
+
this.protocol.pushClientStream(id, streamId, buffer.slice(Uint32Array.BYTES_PER_ELEMENT));
|
|
157
340
|
}
|
|
158
341
|
[ClientMessageType.ClientStreamEnd](ws, buffer) {
|
|
159
342
|
const { id } = ws.getUserData();
|
|
160
343
|
const streamId = decodeNumber(buffer, "Uint32");
|
|
161
|
-
this.protocol.
|
|
344
|
+
this.protocol.endClientStream(id, streamId);
|
|
162
345
|
}
|
|
163
346
|
[ClientMessageType.ClientStreamAbort](ws, buffer) {
|
|
164
347
|
const { id } = ws.getUserData();
|
|
165
348
|
const streamId = decodeNumber(buffer, "Uint32");
|
|
166
|
-
this.protocol.
|
|
349
|
+
this.protocol.abortClientStream(id, streamId);
|
|
167
350
|
}
|
|
168
351
|
[ClientMessageType.ServerStreamPull](ws, buffer) {
|
|
169
352
|
const { id } = ws.getUserData();
|
|
170
353
|
const streamId = decodeNumber(buffer, "Uint32");
|
|
171
|
-
this.protocol.
|
|
354
|
+
this.protocol.pullServerStream(id, streamId);
|
|
172
355
|
}
|
|
173
356
|
[ClientMessageType.ServerStreamAbort](ws, buffer) {
|
|
174
357
|
const { id } = ws.getUserData();
|
|
175
358
|
const streamId = decodeNumber(buffer, "Uint32");
|
|
176
|
-
this.protocol.
|
|
359
|
+
this.protocol.abortServerStream(id, streamId);
|
|
177
360
|
}
|
|
178
361
|
}
|
|
362
|
+
|
|
363
|
+
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","names":["context: TransportPluginContext","options: WsTransportOptions","data: WsUserData","ws: WsTransportSocket","error: any","connection: Connection<WsConnectionData>","messageType: ServerMessageType","buffer: ArrayBuffer","cause: Error","res: HttpResponse","req: HttpRequest"],"sources":["src/server.ts"],"sourcesContent":["import {\n App,\n type HttpRequest,\n type HttpResponse,\n SSLApp,\n type TemplatedApp,\n us_socket_local_port,\n} from 'uWebSockets.js'\nimport { randomUUID } from 'node:crypto'\nimport { createPromise } from '@nmtjs/common'\nimport {\n ClientMessageType,\n decodeNumber,\n type ServerMessageType,\n} from '@nmtjs/protocol/common'\nimport {\n type Connection,\n ProtocolInjectables,\n type Transport,\n type TransportPluginContext,\n} from '@nmtjs/protocol/server'\nimport { WsTransportInjectables } from './injectables.ts'\nimport type {\n WsTransportOptions,\n WsTransportSocket,\n WsUserData,\n} from './types.ts'\nimport { getRequestData, send } from './utils.ts'\n\nexport type WsConnectionData = {}\n\nexport class WsTransportServer implements Transport<WsConnectionData> {\n protected server!: TemplatedApp\n protected clients: Map<string, WsTransportSocket> = new Map()\n\n constructor(\n protected readonly context: TransportPluginContext,\n protected readonly options: WsTransportOptions,\n ) {\n this.server = this.options.tls ? SSLApp(options.tls!) : App()\n\n this.server\n .options('/*', (res, req) => {\n this.applyCors(res, req)\n res.writeStatus('200 OK')\n res.endWithoutBody()\n })\n .get('/healthy', (res, req) => {\n this.applyCors(res, req)\n res.writeHeader('Content-Type', 'text/plain')\n res.end('OK')\n })\n .ws<WsUserData>('/api', {\n sendPingsAutomatically: true,\n maxPayloadLength: this.options.maxPayloadLength,\n upgrade: (res, req, context) => {\n const requestData = getRequestData(req)\n\n const contentType =\n requestData.headers.get('content-type') ||\n requestData.query.get('content-type')\n\n const acceptType =\n requestData.headers.get('accept') || requestData.query.get('accept')\n\n const data: WsUserData = {\n id: randomUUID(),\n request: {\n query: requestData.query,\n headers: requestData.headers,\n proxiedRemoteAddress: Buffer.from(\n res.getProxiedRemoteAddressAsText(),\n ).toString(),\n remoteAddress: Buffer.from(\n res.getRemoteAddressAsText(),\n ).toString(),\n contentType,\n acceptType,\n },\n opening: createPromise(),\n backpressure: null,\n context: {} as any,\n }\n\n res.upgrade(\n data,\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context,\n )\n },\n open: async (ws: WsTransportSocket) => {\n const { id, context, request, opening } = ws.getUserData()\n this.clients.set(id, ws)\n this.logger.debug('Connection %s opened', id)\n try {\n const { context: _context, connection } =\n await this.context.protocol.connections.add(\n this,\n { id, data: {} },\n {\n acceptType: request.acceptType,\n contentType: request.contentType,\n },\n )\n Object.assign(context, _context)\n context.container.provide(\n ProtocolInjectables.connection,\n connection,\n )\n context.container.provide(\n WsTransportInjectables.connectionData,\n request,\n )\n opening.resolve()\n } catch (error) {\n opening.reject(error)\n }\n },\n message: async (ws: WsTransportSocket, buffer) => {\n const { opening } = ws.getUserData()\n const messageType = decodeNumber(buffer, 'Uint8')\n if (messageType in this === false) {\n ws.end(1011, 'Unknown message type')\n } else {\n try {\n await opening.promise\n await this[messageType](\n ws,\n buffer.slice(Uint8Array.BYTES_PER_ELEMENT),\n )\n } catch (error: any) {\n this.logError(error, 'Error while processing message')\n }\n }\n },\n drain: (ws: WsTransportSocket) => {\n const data = ws.getUserData()\n data.backpressure?.resolve()\n data.backpressure = null\n },\n close: async (ws: WsTransportSocket, code, message) => {\n const { id } = ws.getUserData()\n\n this.logger.debug(\n 'Connection %s closed with code %s: %s',\n id,\n code,\n Buffer.from(message).toString(),\n )\n this.clients.delete(id)\n await this.protocol.connections.remove(id)\n },\n })\n }\n\n send(\n connection: Connection<WsConnectionData>,\n messageType: ServerMessageType,\n buffer: ArrayBuffer,\n ) {\n const ws = this.clients.get(connection.id)\n if (ws) send(ws, messageType, buffer)\n }\n\n async start() {\n return new Promise<void>((resolve, reject) => {\n const { hostname = '127.0.0.1', port = 0, unix } = this.options\n if (unix) {\n this.server.listen_unix((socket) => {\n if (socket) {\n this.logger.info('Server started on unix://%s', unix)\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n }, unix)\n } else {\n this.server.listen(hostname, port, (socket) => {\n if (socket) {\n this.logger.info(\n 'WebSocket Server started on %s:%s',\n hostname,\n us_socket_local_port(socket),\n )\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n })\n }\n })\n }\n\n async stop() {\n this.server.close()\n }\n\n protected get protocol() {\n return this.context.protocol\n }\n\n protected get logger() {\n return this.context.logger\n }\n\n protected async logError(\n cause: Error,\n message = 'Unknown error while processing request',\n ) {\n this.logger.error(new Error(message, { cause }))\n }\n\n protected applyCors(res: HttpResponse, req: HttpRequest) {\n // TODO: this should be configurable\n const origin = req.getHeader('origin')\n if (!origin) return\n res.writeHeader('Access-Control-Allow-Origin', origin)\n res.writeHeader('Access-Control-Allow-Headers', 'Content-Type')\n res.writeHeader('Access-Control-Allow-Methods', 'GET, POST')\n res.writeHeader('Access-Control-Allow-Credentials', 'true')\n }\n\n protected [ClientMessageType.Rpc](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcStreamAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.ClientStreamPush](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.clientStreams.push(\n id,\n streamId,\n buffer.slice(Uint32Array.BYTES_PER_ELEMENT),\n )\n }\n\n protected [ClientMessageType.ClientStreamEnd](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.clientStreams.end(id, streamId)\n }\n\n protected [ClientMessageType.ClientStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.clientStreams.abort(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamPull](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.serverStreams.pull(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.serverStreams.abort(id, streamId)\n }\n}\n"],"version":3}
|
|
1
|
+
{"mappings":"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","names":["context: TransportPluginContext","options: WsTransportOptions","ws: WsTransportSocket","error: any","connection: Connection<WsConnectionData>","messageType: ServerMessageType","buffer: ArrayBuffer","res: HttpResponse","req: HttpRequest","metadata: ProtocolApiCallOptions['metadata']","format: ReturnType<typeof getFormat>","payload: any","stream: Readable","cause: any"],"sources":["../src/server.ts"],"sourcesContent":["import {\n App,\n type HttpRequest,\n type HttpResponse,\n SSLApp,\n type TemplatedApp,\n us_socket_local_port,\n} from 'uWebSockets.js'\nimport { randomUUID } from 'node:crypto'\nimport { once } from 'node:events'\nimport { Duplex, Readable } from 'node:stream'\nimport { Scope } from '@nmtjs/core'\nimport {\n ClientMessageType,\n decodeNumber,\n ErrorCode,\n ProtocolBlob,\n type ServerMessageType,\n} from '@nmtjs/protocol/common'\nimport {\n Connection,\n getFormat,\n isIterableResult,\n isSubscriptionResult,\n type ProtocolApiCallOptions,\n ProtocolClientStream,\n ProtocolError,\n ProtocolInjectables,\n type Transport,\n type TransportPluginContext,\n UnsupportedContentTypeError,\n UnsupportedFormatError,\n} from '@nmtjs/protocol/server'\nimport {\n AllowedHttpMethod,\n HttpCode,\n HttpCodeMap,\n HttpStatusText,\n} from './http.ts'\nimport { WsTransportInjectables } from './injectables.ts'\nimport type {\n WsConnectionData,\n WsTransportOptions,\n WsTransportSocket,\n WsUserData,\n} from './types.ts'\nimport {\n getRequestBody,\n getRequestData,\n readableToArrayBuffer,\n send,\n setHeaders,\n} from './utils.ts'\n\nconst DEFAULT_ALLOWED_METHODS = ['post'] as ('get' | 'post')[]\n\nexport class WsTransportServer implements Transport<WsConnectionData> {\n protected server!: TemplatedApp\n protected clients: Map<string, WsTransportSocket> = new Map()\n\n constructor(\n protected readonly context: TransportPluginContext,\n protected readonly options: WsTransportOptions,\n ) {\n this.server = this.options.tls ? SSLApp(options.tls!) : App()\n this.server\n .options('/*', (res, req) => {\n this.applyCors(res, req)\n res.writeStatus('200 OK')\n res.endWithoutBody()\n })\n .get('/healthy', (res, req) => {\n this.applyCors(res, req)\n res.writeHeader('Content-Type', 'text/plain')\n res.end('OK')\n })\n .ws<WsUserData>('/api', {\n sendPingsAutomatically: true,\n maxPayloadLength: this.options.maxPayloadLength,\n upgrade: async (res, req, socketContext) => {\n const ac = new AbortController()\n\n res.onAborted(ac.abort.bind(ac))\n\n const requestData = getRequestData(req, res)\n const contentType =\n requestData.query.get('content-type') ||\n requestData.headers.get('content-type')\n const acceptType =\n requestData.query.get('accept') || requestData.headers.get('accept')\n\n const connectionId = randomUUID()\n\n try {\n const { context } = await this.protocol.addConnection(\n this,\n { id: connectionId, data: { type: 'ws' } },\n { acceptType, contentType },\n )\n context.container.provide(\n WsTransportInjectables.connectionData,\n requestData,\n )\n if (!ac.signal.aborted) {\n res.cork(() => {\n res.upgrade(\n {\n id: connectionId,\n request: requestData,\n contentType,\n acceptType,\n backpressure: null,\n context,\n } as WsUserData,\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n socketContext,\n )\n })\n }\n } catch (error) {\n this.logger.debug(\n new Error('Failed to upgrade connection', { cause: error }),\n )\n if (!ac.signal.aborted) {\n res.cork(() => {\n res.writeStatus('500 Internal Server Error')\n res.endWithoutBody()\n })\n }\n }\n },\n open: (ws: WsTransportSocket) => {\n const { id } = ws.getUserData()\n this.logger.debug('Connection %s opened', id)\n this.clients.set(id, ws)\n },\n message: async (ws: WsTransportSocket, buffer) => {\n const messageType = decodeNumber(buffer, 'Uint8')\n if (messageType in this === false) {\n ws.end(1011, 'Unknown message type')\n } else {\n try {\n await this[messageType](\n ws,\n buffer.slice(Uint8Array.BYTES_PER_ELEMENT),\n )\n } catch (error: any) {\n this.logError(error, 'Error while processing message')\n }\n }\n },\n drain: (ws: WsTransportSocket) => {\n const data = ws.getUserData()\n data.backpressure?.resolve()\n data.backpressure = null\n },\n close: async (ws: WsTransportSocket, code, message) => {\n const { id } = ws.getUserData()\n\n this.logger.debug(\n 'Connection %s closed with code %s: %s',\n id,\n code,\n Buffer.from(message).toString(),\n )\n this.clients.delete(id)\n await this.protocol.removeConnection(id)\n },\n })\n .get('/api/:namespace/:procedure', this.httpHandler.bind(this))\n .post('/api/:namespace/:procedure', this.httpHandler.bind(this))\n }\n\n send(\n connection: Connection<WsConnectionData>,\n messageType: ServerMessageType,\n buffer: ArrayBuffer,\n ) {\n const ws = this.clients.get(connection.id)\n if (ws) send(ws, messageType, buffer)\n }\n\n async start() {\n return new Promise<void>((resolve, reject) => {\n const { hostname = '127.0.0.1', port = 0, unix } = this.options\n if (unix) {\n this.server.listen_unix((socket) => {\n if (socket) {\n this.logger.info('Server started on unix://%s', unix)\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n }, unix)\n } else {\n this.server.listen(hostname, port, (socket) => {\n if (socket) {\n this.logger.info(\n 'WebSocket Server started on %s:%s',\n hostname,\n us_socket_local_port(socket),\n )\n resolve()\n } else {\n reject(new Error('Failed to start WebSockets server'))\n }\n })\n }\n })\n }\n\n async stop() {\n this.server.close()\n }\n\n // TODO: decompose this mess\n protected async httpHandler(res: HttpResponse, req: HttpRequest) {\n this.applyCors(res, req)\n\n const ac = new AbortController()\n\n res.onAborted(ac.abort.bind(ac))\n\n const method = req.getMethod() as 'get' | 'post'\n const namespace = req.getParameter('namespace')\n const procedure = req.getParameter('procedure')\n const requestData = getRequestData(req, res)\n\n if (!namespace || !procedure) {\n const status = HttpCode.NotFound\n const text = HttpStatusText[status]\n return void res.cork(() => {\n if (ac.signal.aborted) return\n res.writeStatus(`${status} ${text}`)\n res.endWithoutBody()\n })\n }\n\n const isBlob = requestData.headers.get('x-neemata-blob') === 'true'\n\n const contentType = requestData.headers.get('content-type')\n const acceptType = requestData.headers.get('accept')\n const connectionId = randomUUID()\n const connection = new Connection<WsConnectionData>({\n id: connectionId,\n data: { type: 'http' },\n })\n const responseHeaders = new Headers()\n const container = this.context.container.fork(Scope.Call)\n container.provide(ProtocolInjectables.connection, connection)\n container.provide(WsTransportInjectables.connectionData, requestData)\n container.provide(\n WsTransportInjectables.httpResponseHeaders,\n responseHeaders,\n )\n\n const body = method === 'post' ? getRequestBody(res) : undefined\n\n const metadata: ProtocolApiCallOptions['metadata'] = (metadata) => {\n const allowHttpMethod =\n metadata.get(AllowedHttpMethod) ?? DEFAULT_ALLOWED_METHODS\n if (!allowHttpMethod.includes(method)) {\n throw new ProtocolError(ErrorCode.NotFound)\n }\n }\n let format: ReturnType<typeof getFormat>\n try {\n format = getFormat(this.context.format, {\n acceptType,\n contentType: isBlob ? '*/*' : contentType,\n })\n\n let payload: any = undefined\n\n if (body) {\n if (isBlob) {\n const type = contentType || 'application/octet-stream'\n const contentLength = requestData.headers.get('content-length')\n const size = contentLength\n ? Number.parseInt(contentLength)\n : undefined\n const stream = new ProtocolClientStream(-1, { size, type })\n body.pipe(stream)\n payload = stream\n } else {\n const buffer = await readableToArrayBuffer(body)\n if (buffer.byteLength > 0) {\n payload = format.decoder.decode(buffer)\n }\n }\n }\n\n const result = await this.protocol.call({\n connection,\n namespace,\n procedure,\n payload,\n metadata,\n container,\n signal: ac.signal,\n })\n\n if (isIterableResult(result) || isSubscriptionResult(result)) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.NotImplemented\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end()\n })\n } else {\n const { output } = result\n\n if (output instanceof ProtocolBlob) {\n const { source, metadata } = output\n const { type } = metadata\n\n let stream: Readable\n\n if (source instanceof ReadableStream) {\n stream = Readable.fromWeb(source as any)\n } else if (source instanceof Readable || source instanceof Duplex) {\n stream = Readable.from(source)\n } else {\n throw new Error('Invalid stream source')\n }\n\n res.cork(() => {\n if (ac.signal.aborted) return\n responseHeaders.set('X-Neemata-Blob', 'true')\n responseHeaders.set('Content-Type', type)\n if (metadata.size)\n res.writeHeader('Content-Length', metadata.size.toString())\n setHeaders(res, responseHeaders)\n })\n\n ac.signal.addEventListener('abort', () => stream.destroy(), {\n once: true,\n })\n\n stream.on('data', (chunk) => {\n console.log({ chunk })\n if (ac.signal.aborted) return\n const buf = Buffer.from(chunk)\n const ab = buf.buffer.slice(\n buf.byteOffset,\n buf.byteOffset + buf.byteLength,\n )\n const ok = res.write(ab)\n if (!ok) {\n stream.pause()\n res.onWritable(() => {\n stream.resume()\n return true\n })\n }\n })\n await once(stream, 'end')\n if (stream.readableAborted) {\n res.end(undefined, true)\n } else {\n res.end()\n }\n } else {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.OK\n const text = HttpStatusText[status]\n const buffer = format.encoder.encode(output)\n res.writeStatus(`${status} ${text}`)\n responseHeaders.set('Content-Type', format.encoder.contentType)\n setHeaders(res, responseHeaders)\n res.end(buffer)\n })\n }\n }\n } catch (error) {\n if (ac.signal.aborted) return\n if (error instanceof UnsupportedFormatError) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status =\n error instanceof UnsupportedContentTypeError\n ? HttpCode.UnsupportedMediaType\n : HttpCode.NotAcceptable\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end()\n })\n } else if (error instanceof ProtocolError) {\n res.cork(() => {\n if (ac.signal.aborted) return\n const status =\n error.code in HttpCodeMap\n ? HttpCodeMap[error.code]\n : HttpCode.InternalServerError\n const text = HttpStatusText[status]\n res.writeStatus(`${status} ${text}`)\n res.end(format!.encoder.encode(error))\n })\n } else {\n this.logError(error, 'Unknown error while processing request')\n res.cork(() => {\n if (ac.signal.aborted) return\n const status = HttpCode.InternalServerError\n const text = HttpStatusText[status]\n const payload = format!.encoder.encode(\n new ProtocolError(\n ErrorCode.InternalServerError,\n 'Internal Server Error',\n ),\n )\n res.writeStatus(`${status} ${text}`)\n res.end(payload)\n })\n }\n } finally {\n container.dispose().catch((error) => {\n this.logError(error, 'Error while disposing call container')\n })\n }\n }\n\n protected get protocol() {\n return this.context.protocol\n }\n\n protected get logger() {\n return this.context.logger\n }\n\n protected async logError(\n cause: any,\n message = 'Unknown error while processing request',\n ) {\n this.logger.error(new Error(message, { cause }))\n }\n\n protected applyCors(res: HttpResponse, req: HttpRequest) {\n if (this.options.cors === false) return\n\n const origin = req.getHeader('origin')\n if (!origin) return\n\n let allowed = false\n\n if (this.options.cors === undefined || this.options.cors === true) {\n allowed = true\n } else if (Array.isArray(this.options.cors)) {\n allowed = this.options.cors.includes(origin)\n } else {\n allowed = this.options.cors(origin)\n }\n\n if (!allowed) return\n\n res.writeHeader('Access-Control-Allow-Origin', origin)\n res.writeHeader('Access-Control-Allow-Headers', 'Content-Type')\n res.writeHeader('Access-Control-Allow-Methods', 'GET, POST')\n res.writeHeader('Access-Control-Allow-Credentials', 'true')\n }\n\n protected [ClientMessageType.Rpc](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.RpcStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n this.protocol.rpcStreamAbortRaw(id, buffer)\n }\n\n protected [ClientMessageType.ClientStreamPush](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.pushClientStream(\n id,\n streamId,\n buffer.slice(Uint32Array.BYTES_PER_ELEMENT),\n )\n }\n\n protected [ClientMessageType.ClientStreamEnd](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.endClientStream(id, streamId)\n }\n\n protected [ClientMessageType.ClientStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.abortClientStream(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamPull](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.pullServerStream(id, streamId)\n }\n\n protected [ClientMessageType.ServerStreamAbort](\n ws: WsTransportSocket,\n buffer: ArrayBuffer,\n ) {\n const { id } = ws.getUserData()\n const streamId = decodeNumber(buffer, 'Uint32')\n this.protocol.abortServerStream(id, streamId)\n }\n}\n"],"version":3,"file":"server.js"}
|