@vsaas/remoting 10.0.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.
Files changed (109) hide show
  1. package/LICENSE.md +202 -0
  2. package/README.md +78 -0
  3. package/dist/_virtual/_rolldown/runtime.js +32 -0
  4. package/dist/ext/meta.d.ts +1 -0
  5. package/dist/ext/meta.js +39 -0
  6. package/dist/ext/meta.js.map +1 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +20 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/lib/context-base.d.ts +1 -0
  11. package/dist/lib/context-base.js +30 -0
  12. package/dist/lib/context-base.js.map +1 -0
  13. package/dist/lib/deprecate.d.ts +1 -0
  14. package/dist/lib/deprecate.js +34 -0
  15. package/dist/lib/deprecate.js.map +1 -0
  16. package/dist/lib/escape-regexp.d.ts +1 -0
  17. package/dist/lib/escape-regexp.js +12 -0
  18. package/dist/lib/escape-regexp.js.map +1 -0
  19. package/dist/lib/exports-helper.d.ts +1 -0
  20. package/dist/lib/exports-helper.js +101 -0
  21. package/dist/lib/exports-helper.js.map +1 -0
  22. package/dist/lib/http-context.d.ts +1 -0
  23. package/dist/lib/http-context.js +484 -0
  24. package/dist/lib/http-context.js.map +1 -0
  25. package/dist/lib/http-invocation.d.ts +1 -0
  26. package/dist/lib/http-invocation.js +254 -0
  27. package/dist/lib/http-invocation.js.map +1 -0
  28. package/dist/lib/jsonrpc-adapter.d.ts +1 -0
  29. package/dist/lib/jsonrpc-adapter.js +187 -0
  30. package/dist/lib/jsonrpc-adapter.js.map +1 -0
  31. package/dist/lib/looks-like-json.d.ts +1 -0
  32. package/dist/lib/looks-like-json.js +22 -0
  33. package/dist/lib/looks-like-json.js.map +1 -0
  34. package/dist/lib/messages.d.ts +1 -0
  35. package/dist/lib/messages.js +24 -0
  36. package/dist/lib/messages.js.map +1 -0
  37. package/dist/lib/number-checks.d.ts +1 -0
  38. package/dist/lib/number-checks.js +18 -0
  39. package/dist/lib/number-checks.js.map +1 -0
  40. package/dist/lib/phases/merge-phase-name-lists.d.ts +5 -0
  41. package/dist/lib/phases/merge-phase-name-lists.d.ts.map +1 -0
  42. package/dist/lib/phases/merge-phase-name-lists.js +39 -0
  43. package/dist/lib/phases/merge-phase-name-lists.js.map +1 -0
  44. package/dist/lib/phases/phase-list.d.ts +27 -0
  45. package/dist/lib/phases/phase-list.d.ts.map +1 -0
  46. package/dist/lib/phases/phase-list.js +154 -0
  47. package/dist/lib/phases/phase-list.js.map +1 -0
  48. package/dist/lib/phases/phase.d.ts +24 -0
  49. package/dist/lib/phases/phase.d.ts.map +1 -0
  50. package/dist/lib/phases/phase.js +144 -0
  51. package/dist/lib/phases/phase.js.map +1 -0
  52. package/dist/lib/remote-objects.d.ts +1 -0
  53. package/dist/lib/remote-objects.js +642 -0
  54. package/dist/lib/remote-objects.js.map +1 -0
  55. package/dist/lib/rest-adapter-browser.d.ts +1 -0
  56. package/dist/lib/rest-adapter-browser.js +302 -0
  57. package/dist/lib/rest-adapter-browser.js.map +1 -0
  58. package/dist/lib/rest-adapter.d.ts +1 -0
  59. package/dist/lib/rest-adapter.js +519 -0
  60. package/dist/lib/rest-adapter.js.map +1 -0
  61. package/dist/lib/server-sent-events.d.ts +1 -0
  62. package/dist/lib/server-sent-events.js +61 -0
  63. package/dist/lib/server-sent-events.js.map +1 -0
  64. package/dist/lib/shared-class.d.ts +1 -0
  65. package/dist/lib/shared-class.js +207 -0
  66. package/dist/lib/shared-class.js.map +1 -0
  67. package/dist/lib/shared-method.d.ts +1 -0
  68. package/dist/lib/shared-method.js +469 -0
  69. package/dist/lib/shared-method.js.map +1 -0
  70. package/dist/lib/socket-io-adapter.d.ts +1 -0
  71. package/dist/lib/socket-io-adapter.js +93 -0
  72. package/dist/lib/socket-io-adapter.js.map +1 -0
  73. package/dist/lib/socket-io-context.d.ts +1 -0
  74. package/dist/lib/socket-io-context.js +94 -0
  75. package/dist/lib/socket-io-context.js.map +1 -0
  76. package/dist/lib/type-registry.d.ts +1 -0
  77. package/dist/lib/type-registry.js +99 -0
  78. package/dist/lib/type-registry.js.map +1 -0
  79. package/dist/lib/types/any.d.ts +1 -0
  80. package/dist/lib/types/any.js +44 -0
  81. package/dist/lib/types/any.js.map +1 -0
  82. package/dist/lib/types/array.d.ts +1 -0
  83. package/dist/lib/types/array.js +99 -0
  84. package/dist/lib/types/array.js.map +1 -0
  85. package/dist/lib/types/boolean.d.ts +1 -0
  86. package/dist/lib/types/boolean.js +37 -0
  87. package/dist/lib/types/boolean.js.map +1 -0
  88. package/dist/lib/types/date.d.ts +1 -0
  89. package/dist/lib/types/date.js +37 -0
  90. package/dist/lib/types/date.js.map +1 -0
  91. package/dist/lib/types/geopoint.d.ts +1 -0
  92. package/dist/lib/types/geopoint.js +68 -0
  93. package/dist/lib/types/geopoint.js.map +1 -0
  94. package/dist/lib/types/integer.d.ts +1 -0
  95. package/dist/lib/types/integer.js +36 -0
  96. package/dist/lib/types/integer.js.map +1 -0
  97. package/dist/lib/types/number.d.ts +1 -0
  98. package/dist/lib/types/number.js +30 -0
  99. package/dist/lib/types/number.js.map +1 -0
  100. package/dist/lib/types/object.d.ts +1 -0
  101. package/dist/lib/types/object.js +57 -0
  102. package/dist/lib/types/object.js.map +1 -0
  103. package/dist/lib/types/string.d.ts +1 -0
  104. package/dist/lib/types/string.js +29 -0
  105. package/dist/lib/types/string.js.map +1 -0
  106. package/dist/phases.d.ts +4 -0
  107. package/dist/phases.js +35 -0
  108. package/dist/phases.js.map +1 -0
  109. package/package.json +96 -0
@@ -0,0 +1,484 @@
1
+ "use strict";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
3
+ const require_lib_messages = require("./messages.js");
4
+ const require_lib_context_base = require("./context-base.js");
5
+ const require_lib_shared_method = require("./shared-method.js");
6
+ const require_lib_server_sent_events = require("./server-sent-events.js");
7
+ //#region src/lib/http-context.ts
8
+ var require_http_context = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
9
+ const g = require_lib_messages;
10
+ /*!
11
+ * Expose `HttpContext`.
12
+ */
13
+ module.exports = HttpContext;
14
+ /*!
15
+ * Module dependencies.
16
+ */
17
+ const debug = require("debug")("strong-remoting:http-context");
18
+ const inherits = require("util").inherits;
19
+ const assert = require("assert");
20
+ const ContextBase = require_lib_context_base;
21
+ const js2xmlparser = require("js2xmlparser");
22
+ const SharedMethod = require_lib_shared_method;
23
+ const DEFAULT_SUPPORTED_TYPES = [
24
+ "application/json",
25
+ "application/javascript",
26
+ "application/xml",
27
+ "text/javascript",
28
+ "text/xml",
29
+ "json",
30
+ "xml",
31
+ "*/*"
32
+ ];
33
+ const DEFAULT_SUPPORTED_TYPES_WITHOUT_XML = DEFAULT_SUPPORTED_TYPES.filter(function(type) {
34
+ return !/\bxml\b/i.test(type);
35
+ });
36
+ /*!
37
+ * This comment is here as a workaround for a strong-docs bug.
38
+ * The above array value leads to spurious doc output.
39
+ */
40
+ const MuxDemux = require("mux-demux");
41
+ const SSEClient = require_lib_server_sent_events;
42
+ /**
43
+ * Create a new `HttpContext` with the given `options`.
44
+ * Invoking a remote method via HTTP creates `HttpContext` object.
45
+ *
46
+ * @param {Object} req Express Request object.
47
+ * @param {Object} res Express Response object.
48
+ * @param {Function} method A [SharedMethod](#sharedmethod)
49
+ * @options {Object} options See below.
50
+ * @property {Boolean} xml Set to `true` to enable XML-based types. Default is false.
51
+ * @class
52
+ */
53
+ function HttpContext(req, res, method, options, typeRegistry) {
54
+ ContextBase.call(this, method, typeRegistry);
55
+ const configuredSupportedTypes = options && options.supportedTypes;
56
+ this.req = req;
57
+ this.res = res;
58
+ this.method = method;
59
+ this.options = options || {};
60
+ this.args = this.buildArgs(method);
61
+ this.methodString = method.stringName;
62
+ this.supportedTypes = configuredSupportedTypes || (!this.options.xml ? DEFAULT_SUPPORTED_TYPES_WITHOUT_XML : DEFAULT_SUPPORTED_TYPES);
63
+ if (Array.isArray(this.supportedTypes)) this.supportedTypes = this.supportedTypes.slice();
64
+ this.result = {};
65
+ const streamsDesc = method.streams;
66
+ const methodReturnsStream = !!(streamsDesc && streamsDesc.returns);
67
+ req.remotingContext = this;
68
+ if (methodReturnsStream) this.createStream();
69
+ }
70
+ inherits(HttpContext, ContextBase);
71
+ HttpContext.prototype.createStream = function() {
72
+ const streamsDesc = this.method.streams;
73
+ const returnStreamDesc = streamsDesc && streamsDesc.returns;
74
+ const mdm = this.muxDemuxStream = new MuxDemux();
75
+ this.io = {};
76
+ const res = this.res;
77
+ debug("create stream");
78
+ if (returnStreamDesc.json && returnStreamDesc.type === "ReadableStream") {
79
+ if (!this.shouldReturnEventStream()) {
80
+ res.setHeader("Content-Type", returnStreamDesc.contentType || "application/json; boundary=NL");
81
+ res.setHeader("Transfer-Encoding", "chunked");
82
+ this.io.out = mdm.createWriteStream();
83
+ mdm.pipe(res);
84
+ res.on("close", function() {
85
+ mdm.destroy();
86
+ });
87
+ }
88
+ }
89
+ };
90
+ /**
91
+ * Build args object from the http context's `req` and `res`.
92
+ */
93
+ HttpContext.prototype.buildArgs = function(method) {
94
+ const args = {};
95
+ const ctx = this;
96
+ const accepts = method.accepts;
97
+ const isJsonRequest = /^application\/json\b/.test(getRequestHeader(ctx.req, "content-type") || "");
98
+ for (let i = 0, n = accepts.length; i < n; i++) {
99
+ const o = accepts[i];
100
+ const httpFormat = o.http;
101
+ const name = o.name || o.arg;
102
+ let val;
103
+ const typeConverter = ctx.typeRegistry.getConverter(o.type);
104
+ const conversionOptions = SharedMethod.getConversionOptionsForArg(o);
105
+ let doSloppyCoerce = !isJsonRequest;
106
+ if (httpFormat) switch (typeof httpFormat) {
107
+ case "function":
108
+ val = httpFormat(ctx);
109
+ doSloppyCoerce = false;
110
+ break;
111
+ case "object":
112
+ switch (httpFormat.source) {
113
+ case "body":
114
+ val = ctx.req.body;
115
+ break;
116
+ case "form":
117
+ case "formData":
118
+ val = ctx.req.body && ctx.req.body[name];
119
+ break;
120
+ case "query":
121
+ val = ctx.req.query[name];
122
+ doSloppyCoerce = true;
123
+ break;
124
+ case "path":
125
+ val = ctx.req.params[name];
126
+ doSloppyCoerce = true;
127
+ break;
128
+ case "header":
129
+ val = getRequestHeader(ctx.req, name);
130
+ doSloppyCoerce = true;
131
+ break;
132
+ case "req":
133
+ val = ctx.req;
134
+ break;
135
+ case "res":
136
+ val = ctx.res;
137
+ break;
138
+ case "context":
139
+ val = ctx;
140
+ break;
141
+ }
142
+ break;
143
+ }
144
+ else {
145
+ val = ctx.getArgByName(name, o);
146
+ doSloppyCoerce = !(isJsonRequest && ctx.req.body && val === ctx.req.body[name]);
147
+ }
148
+ const result = doSloppyCoerce ? typeConverter.fromSloppyValue(ctx, val, conversionOptions) : typeConverter.fromTypedValue(ctx, val, conversionOptions);
149
+ debug("arg %j: %s converted %j to %j", name, doSloppyCoerce ? "sloppy" : "typed", val, result);
150
+ if (!(typeof result === "object" && ("error" in result || "value" in result))) throw new assert.AssertionError({ message: "Type conversion result should have \"error\" or \"value\" property. Got " + JSON.stringify(result) + " instead." });
151
+ if (result.error) throw result.error;
152
+ args[o.arg] = result.value;
153
+ }
154
+ return args;
155
+ };
156
+ /**
157
+ * Get an arg by name using the given options.
158
+ *
159
+ * @param {String} name
160
+ * @param {Object} options **optional**
161
+ */
162
+ HttpContext.prototype.getArgByName = function(name, options) {
163
+ const req = this.req;
164
+ return req.params[name] !== void 0 ? req.params[name] : (req.body && req.body[name]) !== void 0 ? req.body[name] : req.query[name] !== void 0 ? req.query[name] : getRequestHeader(req, name);
165
+ };
166
+ function buildArgs(ctx, method, fn) {
167
+ try {
168
+ return ctx.buildArgs(method);
169
+ } catch (err) {
170
+ process.nextTick(function() {
171
+ fn(err);
172
+ });
173
+ return;
174
+ }
175
+ }
176
+ /**
177
+ * Invoke the given shared method using the provided scope against the current context.
178
+ */
179
+ HttpContext.prototype.invoke = function(scope, method, fn, isCtor) {
180
+ let args = this.args;
181
+ if (isCtor) {
182
+ args = this.ctorArgs = buildArgs(this, method, fn);
183
+ if (args === void 0) return;
184
+ }
185
+ const http = method.http;
186
+ const pipe = http && http.pipe;
187
+ const pipeDest = pipe && pipe.dest;
188
+ const pipeSrc = pipe && pipe.source;
189
+ const ctx = this;
190
+ const defaultErrorStatus = http && http.errorStatus;
191
+ const res = this.res;
192
+ if (pipeDest) switch (pipeDest) {
193
+ case "res":
194
+ setResponseHeader(this.res, "Content-Type", "application/json");
195
+ setResponseHeader(this.res, "Transfer-Encoding", "chunked");
196
+ method.invoke(scope, args, this.options, ctx, fn).pipe(this.res);
197
+ break;
198
+ default:
199
+ fn(new Error(g.f("unsupported pipe destination")));
200
+ break;
201
+ }
202
+ else if (pipeSrc) switch (pipeDest) {
203
+ case "req":
204
+ this.req.pipe(method.invoke(scope, args, this.options, ctx, fn));
205
+ break;
206
+ default:
207
+ fn(new Error(g.f("unsupported pipe source")));
208
+ break;
209
+ }
210
+ else method.invoke(scope, args, this.options, ctx, function(err, result) {
211
+ if (err) {
212
+ if (defaultErrorStatus && (res.statusCode === void 0 || res.statusCode === 200)) setResponseStatus(res, err.status || err.statusCode || defaultErrorStatus);
213
+ return fn(err);
214
+ }
215
+ fn(null, result);
216
+ });
217
+ };
218
+ HttpContext.prototype.setReturnArgByName = function(name, value) {
219
+ const ARG_WAS_HANDLED = true;
220
+ const returnDesc = this.method.getReturnArgDescByName(name);
221
+ this.result;
222
+ const res = this.res;
223
+ if (!returnDesc) {
224
+ debug("warning: cannot set return value for arg (%s) without description!", name);
225
+ return;
226
+ }
227
+ if (returnDesc.root) {
228
+ this.resultType = typeof returnDesc.type === "string" ? returnDesc.type.toLowerCase() : returnDesc.type;
229
+ return;
230
+ }
231
+ if (returnDesc.http) switch (returnDesc.http.target) {
232
+ case "status":
233
+ setResponseStatus(res, value);
234
+ return ARG_WAS_HANDLED;
235
+ case "header":
236
+ setResponseHeader(res, returnDesc.http.header || name, value);
237
+ return ARG_WAS_HANDLED;
238
+ }
239
+ };
240
+ function toJSON(input) {
241
+ if (!input) return input;
242
+ if (typeof input.toJSON === "function") return input.toJSON();
243
+ else if (Array.isArray(input)) return input.map(toJSON);
244
+ else return input;
245
+ }
246
+ function toXML(input, options) {
247
+ let xml;
248
+ const xmlOptions = Object.assign({ declaration: true }, options);
249
+ if (input && typeof input.toXML === "function") xml = input.toXML();
250
+ else {
251
+ if (typeof input == "object") input = toJSON(input);
252
+ if (Array.isArray(input)) input = { result: input };
253
+ xml = js2xmlparser.parse(xmlOptions.wrapperElement || "response", input, {
254
+ declaration: {
255
+ include: xmlOptions.declaration,
256
+ encoding: "UTF-8"
257
+ },
258
+ format: {
259
+ doubleQuotes: true,
260
+ indent: " "
261
+ },
262
+ convertMap: { "[object Date]": function(date) {
263
+ return date.toISOString();
264
+ } }
265
+ });
266
+ }
267
+ return xml;
268
+ }
269
+ HttpContext.prototype.shouldReturnEventStream = function() {
270
+ const req = this.req;
271
+ const format = (req.query || {})._format;
272
+ const acceptable = requestAccepts(req, "text/event-stream");
273
+ const returnEventStream = format === "event-stream" || acceptable;
274
+ if (returnEventStream) this.res.setHeader("Content-Encoding", "x-no-compression");
275
+ return returnEventStream;
276
+ };
277
+ HttpContext.prototype.respondWithEventStream = function(stream) {
278
+ const client = new SSEClient(this.req, this.res);
279
+ client.initialize();
280
+ stream.on("data", function(chunk) {
281
+ client.send("data", JSON.stringify(chunk));
282
+ });
283
+ stream.on("error", function(err) {
284
+ const outErr = { message: err.message };
285
+ for (const key in err) outErr[key] = err[key];
286
+ client.send("error", JSON.stringify(outErr));
287
+ });
288
+ stream.on("end", function() {
289
+ client.send({
290
+ event: "end",
291
+ data: "null"
292
+ });
293
+ });
294
+ if (stream.destroy) client.once("close", function() {
295
+ stream.destroy();
296
+ });
297
+ };
298
+ /**
299
+ * Utility functions to send response body
300
+ */
301
+ function sendBodyJson(res, data) {
302
+ if (typeof res.json === "function") {
303
+ res.json(data);
304
+ return;
305
+ }
306
+ if (!getResponseHeader(res, "Content-Type")) setResponseHeader(res, "Content-Type", "application/json; charset=utf-8");
307
+ sendResponseBody(res, JSON.stringify(data));
308
+ }
309
+ function sendBodyJsonp(res, data) {
310
+ if (typeof res.jsonp === "function") {
311
+ res.jsonp(data);
312
+ return;
313
+ }
314
+ sendBodyJson(res, data);
315
+ }
316
+ function sendBodyXml(res, data, method) {
317
+ if (data === null) {
318
+ setResponseHeader(res, "Content-Length", "7");
319
+ sendResponseBody(res, "<null/>");
320
+ } else if (data) try {
321
+ sendResponseBody(res, toXML(data, method.returns[0].xml || {}));
322
+ } catch (e) {
323
+ setResponseStatus(res, 500);
324
+ sendResponseBody(res, e + "\n" + data);
325
+ }
326
+ }
327
+ function sendBodyDefault(res) {
328
+ setResponseStatus(res, 406);
329
+ sendResponseBody(res, "Not Acceptable");
330
+ }
331
+ /**
332
+ * Deciding on the operation of response, function is called inside this.done()
333
+ */
334
+ HttpContext.prototype.resolveReponseOperation = function(accepts) {
335
+ const result = {
336
+ sendBody: sendBodyJson,
337
+ contentType: "application/json"
338
+ };
339
+ switch (accepts) {
340
+ case "*/*":
341
+ case "application/json":
342
+ case "json": break;
343
+ case "application/vnd.api+json":
344
+ result.contentType = "application/vnd.api+json";
345
+ break;
346
+ case "application/javascript":
347
+ case "text/javascript":
348
+ result.sendBody = sendBodyJsonp;
349
+ break;
350
+ case "application/xml":
351
+ case "text/xml":
352
+ case "xml":
353
+ if (accepts == "application/xml") result.contentType = "application/xml";
354
+ else result.contentType = "text/xml";
355
+ result.sendBody = sendBodyXml;
356
+ break;
357
+ default:
358
+ result.sendBody = sendBodyDefault;
359
+ result.contentType = "text/plain";
360
+ break;
361
+ }
362
+ return result;
363
+ };
364
+ /**
365
+ * Finish the request and send the correct response.
366
+ */
367
+ HttpContext.prototype.done = function(cb) {
368
+ const ctx = this;
369
+ const method = this.method;
370
+ const streamsDesc = method.streams;
371
+ const returnStreamDesc = streamsDesc && streamsDesc.returns;
372
+ const methodReturnsStream = !!returnStreamDesc;
373
+ const res = this.res;
374
+ const out = this.io && this.io.out;
375
+ this.error;
376
+ const result = this.result;
377
+ if (methodReturnsStream) {
378
+ if (returnStreamDesc.json) {
379
+ debug("handling json stream");
380
+ const stream = result[returnStreamDesc.arg];
381
+ if (returnStreamDesc.type === "ReadableStream") {
382
+ if (ctx.shouldReturnEventStream()) {
383
+ debug("respondWithEventStream");
384
+ ctx.respondWithEventStream(stream);
385
+ return;
386
+ }
387
+ debug("piping to mdm stream");
388
+ stream.pipe(out);
389
+ stream.on("error", function(err) {
390
+ const outErr = { message: err.message };
391
+ for (const key in err) outErr[key] = err[key];
392
+ out.error(outErr);
393
+ out.end();
394
+ });
395
+ out.on("close", function() {
396
+ stream.destroy();
397
+ });
398
+ } else cb(new Error(g.f("unsupported stream type: %s", returnStreamDesc.type)));
399
+ } else cb(new Error(g.f("Unsupported stream descriptor, only descriptors with property \"{{json:true}}\" are supported")));
400
+ return;
401
+ }
402
+ const data = this.result;
403
+ let accepts = requestAccepts(this.req, this.supportedTypes);
404
+ const defaultStatus = this.method.http.status;
405
+ if (defaultStatus) setResponseStatus(res, defaultStatus);
406
+ const format = this.req.query && this.req.query._format;
407
+ if (format) if (typeof format !== "string") accepts = "invalid";
408
+ else accepts = format.toLowerCase();
409
+ const dataExists = typeof data !== "undefined";
410
+ const operationResults = this.resolveReponseOperation(accepts);
411
+ if ((res.statusCode < 300 || res.statusCode > 399) && !getResponseHeader(res, "Content-Type")) setResponseHeader(res, "Content-Type", operationResults.contentType);
412
+ if (dataExists) if (this.resultType !== "file") {
413
+ operationResults.sendBody(res, data, method);
414
+ res.end();
415
+ } else if (Buffer.isBuffer(data) || typeof data === "string") res.end(data);
416
+ else if (data.pipe) data.pipe(res);
417
+ else {
418
+ const valueType = SharedMethod.getType(data);
419
+ const msg = g.f("Cannot create a file response from %s ", valueType);
420
+ return cb(new Error(msg));
421
+ }
422
+ else {
423
+ if (res.statusCode === void 0 || res.statusCode === 200) res.statusCode = 204;
424
+ res.end();
425
+ }
426
+ cb();
427
+ };
428
+ function getRequestHeader(req, name) {
429
+ if (typeof req.get === "function") return req.get(name);
430
+ return req.headers && req.headers[name.toLowerCase()];
431
+ }
432
+ function requestAccepts(req, types) {
433
+ if (typeof req.accepts === "function") return req.accepts(types);
434
+ const acceptHeader = getRequestHeader(req, "accept") || "*/*";
435
+ const acceptedTypes = String(acceptHeader).split(",").map((part) => part.split(";")[0].trim().toLowerCase());
436
+ const requestedTypes = Array.isArray(types) ? types : [types];
437
+ for (const requestedType of requestedTypes) {
438
+ const normalizedType = String(requestedType).toLowerCase();
439
+ if (acceptedTypes.includes("*/*") || acceptedTypes.includes(normalizedType) || normalizedType === "json" && acceptedTypes.some((type) => /\bjson\b/.test(type)) || normalizedType === "xml" && acceptedTypes.some((type) => /\bxml\b/.test(type))) return requestedType;
440
+ }
441
+ return false;
442
+ }
443
+ function getResponseHeader(res, name) {
444
+ if (typeof res.get === "function") return res.get(name);
445
+ if (typeof res.getHeader === "function") return res.getHeader(name);
446
+ }
447
+ function setResponseStatus(res, statusCode) {
448
+ if (typeof res.status === "function") {
449
+ res.status(statusCode);
450
+ return;
451
+ }
452
+ res.statusCode = statusCode;
453
+ }
454
+ function setResponseHeader(res, name, value) {
455
+ if (typeof res.header === "function") {
456
+ res.header(name, value);
457
+ return;
458
+ }
459
+ if (typeof res.set === "function") {
460
+ res.set(name, value);
461
+ return;
462
+ }
463
+ if (typeof res.setHeader === "function") res.setHeader(name, value);
464
+ }
465
+ function sendResponseBody(res, body) {
466
+ if (typeof res.send === "function") {
467
+ res.send(body);
468
+ return;
469
+ }
470
+ if (body === void 0) {
471
+ res.end();
472
+ return;
473
+ }
474
+ if (Buffer.isBuffer(body) || typeof body === "string") {
475
+ res.end(body);
476
+ return;
477
+ }
478
+ res.end(String(body));
479
+ }
480
+ }));
481
+ //#endregion
482
+ module.exports = require_http_context();
483
+
484
+ //# sourceMappingURL=http-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-context.js","names":[],"sources":["../../src/lib/http-context.ts"],"sourcesContent":["// Copyright IBM Corp. 2013,2018. All Rights Reserved.\n// Node module: strong-remoting\n// This file is licensed under the Artistic License 2.0.\n// License text available at https://opensource.org/licenses/Artistic-2.0\n\n// @ts-nocheck\n'use strict';\n\nconst g = require('./messages');\n/*!\n * Expose `HttpContext`.\n */\nmodule.exports = HttpContext;\n\n/*!\n * Module dependencies.\n */\nconst debug = require('debug')('strong-remoting:http-context');\nconst util = require('util');\nconst inherits = util.inherits;\nconst assert = require('assert');\nconst ContextBase = require('./context-base');\nconst js2xmlparser = require('js2xmlparser');\nconst SharedMethod = require('./shared-method');\n\nconst DEFAULT_SUPPORTED_TYPES = [\n 'application/json',\n 'application/javascript',\n 'application/xml',\n 'text/javascript',\n 'text/xml',\n 'json',\n 'xml',\n '*/*',\n];\nconst DEFAULT_SUPPORTED_TYPES_WITHOUT_XML = DEFAULT_SUPPORTED_TYPES.filter(function (type) {\n return !/\\bxml\\b/i.test(type);\n});\n\n/*!\n * This comment is here as a workaround for a strong-docs bug.\n * The above array value leads to spurious doc output.\n */\n\nconst MuxDemux = require('mux-demux');\nconst SSEClient = require('./server-sent-events');\n\n/**\n * Create a new `HttpContext` with the given `options`.\n * Invoking a remote method via HTTP creates `HttpContext` object.\n *\n * @param {Object} req Express Request object.\n * @param {Object} res Express Response object.\n * @param {Function} method A [SharedMethod](#sharedmethod)\n * @options {Object} options See below.\n * @property {Boolean} xml Set to `true` to enable XML-based types. Default is false.\n * @class\n */\n\nfunction HttpContext(req, res, method, options, typeRegistry) {\n ContextBase.call(this, method, typeRegistry);\n\n const configuredSupportedTypes = options && options.supportedTypes;\n\n this.req = req;\n this.res = res;\n this.method = method;\n this.options = options || {};\n this.args = this.buildArgs(method);\n this.methodString = method.stringName;\n this.supportedTypes =\n configuredSupportedTypes || (!this.options.xml ? DEFAULT_SUPPORTED_TYPES_WITHOUT_XML : DEFAULT_SUPPORTED_TYPES);\n if (Array.isArray(this.supportedTypes)) {\n this.supportedTypes = this.supportedTypes.slice();\n }\n this.result = {};\n\n const streamsDesc = method.streams;\n const returnStreamDesc = streamsDesc && streamsDesc.returns;\n const methodReturnsStream = !!returnStreamDesc;\n\n req.remotingContext = this;\n\n // streaming support\n if (methodReturnsStream) {\n this.createStream();\n }\n}\n\ninherits(HttpContext, ContextBase);\n\nHttpContext.prototype.createStream = function () {\n const streamsDesc = this.method.streams;\n const returnStreamDesc = streamsDesc && streamsDesc.returns;\n const mdm = (this.muxDemuxStream = new MuxDemux());\n const io = (this.io = {});\n const res = this.res;\n\n debug('create stream');\n\n if (returnStreamDesc.json && returnStreamDesc.type === 'ReadableStream') {\n if (!this.shouldReturnEventStream()) {\n res.setHeader(\n 'Content-Type',\n returnStreamDesc.contentType || 'application/json; boundary=NL',\n );\n res.setHeader('Transfer-Encoding', 'chunked');\n\n this.io.out = mdm.createWriteStream();\n // since the method returns a ReadableStream\n // setup an output to pipe the ReadableStream to\n mdm.pipe(res);\n res.on('close', function () {\n mdm.destroy();\n });\n }\n }\n};\n\n/**\n * Build args object from the http context's `req` and `res`.\n */\n\nHttpContext.prototype.buildArgs = function (method) {\n const args = {};\n const ctx = this;\n const accepts = method.accepts;\n\n const isJsonRequest = /^application\\/json\\b/.test(\n getRequestHeader(ctx.req, 'content-type') || '',\n );\n\n // build arguments from req and method options\n for (let i = 0, n = accepts.length; i < n; i++) {\n const o = accepts[i];\n const httpFormat = o.http;\n const name = o.name || o.arg;\n let val;\n\n const typeConverter = ctx.typeRegistry.getConverter(o.type);\n const conversionOptions = SharedMethod.getConversionOptionsForArg(o);\n\n // Turn off sloppy coercion for values coming from JSON payloads.\n // This is because JSON, unlike other methods, properly retains types\n // like Numbers, Booleans, and null/undefined.\n let doSloppyCoerce = !isJsonRequest;\n\n // This is an http method keyword, which requires special parsing.\n if (httpFormat) {\n switch (typeof httpFormat) {\n case 'function':\n // the options have defined a formatter\n val = httpFormat(ctx);\n // it's up to the custom provider to perform any coercion as needed\n doSloppyCoerce = false;\n break;\n case 'object':\n switch (httpFormat.source) {\n case 'body':\n val = ctx.req.body;\n break;\n case 'form':\n case 'formData':\n // From the form (body)\n val = ctx.req.body && ctx.req.body[name];\n break;\n case 'query':\n // From the query string\n val = ctx.req.query[name];\n doSloppyCoerce = true;\n break;\n case 'path':\n // From the url path\n val = ctx.req.params[name];\n doSloppyCoerce = true;\n break;\n case 'header':\n val = getRequestHeader(ctx.req, name);\n doSloppyCoerce = true;\n break;\n case 'req':\n // Direct access to http req\n val = ctx.req;\n break;\n case 'res':\n // Direct access to http res\n val = ctx.res;\n break;\n case 'context':\n // Direct access to http context\n val = ctx;\n break;\n }\n break;\n }\n } else {\n val = ctx.getArgByName(name, o);\n doSloppyCoerce = !(isJsonRequest && ctx.req.body && val === ctx.req.body[name]);\n }\n\n // Most of the time, the data comes through 'sloppy' methods like HTTP headers or a qs\n // which don't preserve types.\n //\n // Use some sloppy typing semantics to try to guess what the user meant to send.\n const result = doSloppyCoerce\n ? typeConverter.fromSloppyValue(ctx, val, conversionOptions)\n : typeConverter.fromTypedValue(ctx, val, conversionOptions);\n\n debug('arg %j: %s converted %j to %j', name, doSloppyCoerce ? 'sloppy' : 'typed', val, result);\n\n const isValidResult = typeof result === 'object' && ('error' in result || 'value' in result);\n if (!isValidResult) {\n throw new assert.AssertionError({\n message:\n 'Type conversion result should have \"error\" or \"value\" property. ' +\n 'Got ' +\n JSON.stringify(result) +\n ' instead.',\n });\n }\n\n if (result.error) {\n throw result.error;\n }\n\n // Set the argument value.\n args[o.arg] = result.value;\n }\n\n return args;\n};\n\n/**\n * Get an arg by name using the given options.\n *\n * @param {String} name\n * @param {Object} options **optional**\n */\n\nHttpContext.prototype.getArgByName = function (name, options) {\n const req = this.req;\n\n // search these in order by name\n const arg =\n req.params[name] !== undefined\n ? req.params[name] // params\n : (req.body && req.body[name]) !== undefined\n ? req.body[name] // body\n : req.query[name] !== undefined\n ? req.query[name] // query\n : getRequestHeader(req, name); // header\n\n return arg;\n};\n\nfunction buildArgs(ctx, method, fn) {\n try {\n return ctx.buildArgs(method);\n } catch (err) {\n // JSON.parse() might throw\n process.nextTick(function () {\n fn(err);\n });\n return undefined;\n }\n}\n\n/**\n * Invoke the given shared method using the provided scope against the current context.\n */\n\nHttpContext.prototype.invoke = function (scope, method, fn, isCtor) {\n let args = this.args;\n if (isCtor) {\n args = this.ctorArgs = buildArgs(this, method, fn);\n if (args === undefined) {\n return;\n }\n }\n const http = method.http;\n const pipe = http && http.pipe;\n const pipeDest = pipe && pipe.dest;\n const pipeSrc = pipe && pipe.source;\n const ctx = this;\n const defaultErrorStatus = http && http.errorStatus;\n const res = this.res;\n\n if (pipeDest) {\n // only support response for now\n switch (pipeDest) {\n case 'res':\n // Probably not correct...but passes my test.\n setResponseHeader(this.res, 'Content-Type', 'application/json');\n setResponseHeader(this.res, 'Transfer-Encoding', 'chunked');\n\n const stream = method.invoke(scope, args, this.options, ctx, fn);\n stream.pipe(this.res);\n break;\n default:\n fn(new Error(g.f('unsupported pipe destination')));\n break;\n }\n } else if (pipeSrc) {\n // only support request for now\n switch (pipeDest) {\n case 'req':\n this.req.pipe(method.invoke(scope, args, this.options, ctx, fn));\n break;\n default:\n fn(new Error(g.f('unsupported pipe source')));\n break;\n }\n } else {\n // simple invoke\n method.invoke(scope, args, this.options, ctx, function (err, result) {\n if (err) {\n if (defaultErrorStatus && (res.statusCode === undefined || res.statusCode === 200)) {\n setResponseStatus(res, err.status || err.statusCode || defaultErrorStatus);\n }\n return fn(err);\n }\n fn(null, result);\n });\n }\n};\n\nHttpContext.prototype.setReturnArgByName = function (name, value) {\n const ARG_WAS_HANDLED = true;\n const returnDesc = this.method.getReturnArgDescByName(name);\n const result = this.result;\n const res = this.res;\n\n if (!returnDesc) {\n debug('warning: cannot set return value for arg' + ' (%s) without description!', name);\n return;\n }\n\n if (returnDesc.root) {\n // TODO(bajtos) call SharedMethod's convertToBasicRemotingType here?\n this.resultType =\n typeof returnDesc.type === 'string' ? returnDesc.type.toLowerCase() : returnDesc.type;\n return;\n }\n\n if (returnDesc.http) {\n switch (returnDesc.http.target) {\n case 'status':\n setResponseStatus(res, value);\n return ARG_WAS_HANDLED;\n case 'header':\n setResponseHeader(res, returnDesc.http.header || name, value);\n return ARG_WAS_HANDLED;\n }\n }\n};\n\nfunction toJSON(input) {\n if (!input) {\n return input;\n }\n if (typeof input.toJSON === 'function') {\n return input.toJSON();\n } else if (Array.isArray(input)) {\n return input.map(toJSON);\n } else {\n return input;\n }\n}\n\nfunction toXML(input, options) {\n let xml;\n const xmlDefaultOptions = { declaration: true };\n const xmlOptions = Object.assign(xmlDefaultOptions, options);\n if (input && typeof input.toXML === 'function') {\n xml = input.toXML();\n } else {\n if (typeof input == 'object') {\n // Trigger toJSON() conversions\n input = toJSON(input);\n }\n if (Array.isArray(input)) {\n input = { result: input };\n }\n xml = js2xmlparser.parse(xmlOptions.wrapperElement || 'response', input, {\n declaration: {\n include: xmlOptions.declaration,\n encoding: 'UTF-8',\n },\n format: {\n doubleQuotes: true,\n indent: ' ',\n },\n convertMap: {\n '[object Date]': function (date) {\n return date.toISOString();\n },\n },\n });\n }\n return xml;\n}\n\nHttpContext.prototype.shouldReturnEventStream = function () {\n const req = this.req;\n const query = req.query || {};\n const format = query._format;\n\n const acceptable = requestAccepts(req, 'text/event-stream');\n const returnEventStream = format === 'event-stream' || acceptable;\n if (returnEventStream) {\n this.res.setHeader('Content-Encoding', 'x-no-compression');\n }\n return returnEventStream;\n};\n\nHttpContext.prototype.respondWithEventStream = function (stream) {\n const client = new SSEClient(this.req, this.res);\n\n client.initialize();\n\n stream.on('data', function (chunk) {\n client.send('data', JSON.stringify(chunk));\n });\n\n stream.on('error', function (err) {\n const outErr = { message: err.message };\n for (const key in err) {\n outErr[key] = err[key];\n }\n client.send('error', JSON.stringify(outErr));\n });\n\n stream.on('end', function () {\n client.send({ event: 'end', data: 'null' });\n });\n\n if (stream.destroy) {\n // ReadableStream#destroy() was added in Node.js 8.0.0\n // In earlier versions, some kinds of streams are already\n // providing this method, which allows us to correctly cancel them.\n // For streams that do not provide this method, there\n // is no other reliable way for closing them prematurely.\n client.once('close', function () {\n stream.destroy();\n });\n }\n};\n\n/**\n * Utility functions to send response body\n */\nfunction sendBodyJson(res, data) {\n if (typeof res.json === 'function') {\n res.json(data);\n return;\n }\n\n if (!getResponseHeader(res, 'Content-Type')) {\n setResponseHeader(res, 'Content-Type', 'application/json; charset=utf-8');\n }\n\n sendResponseBody(res, JSON.stringify(data));\n}\n\nfunction sendBodyJsonp(res, data) {\n if (typeof res.jsonp === 'function') {\n res.jsonp(data);\n return;\n }\n\n sendBodyJson(res, data);\n}\n\nfunction sendBodyXml(res, data, method) {\n if (data === null) {\n setResponseHeader(res, 'Content-Length', '7');\n sendResponseBody(res, '<null/>');\n } else if (data) {\n try {\n const xmlOptions = method.returns[0].xml || {};\n const xml = toXML(data, xmlOptions);\n sendResponseBody(res, xml);\n } catch (e) {\n setResponseStatus(res, 500);\n sendResponseBody(res, e + '\\n' + data);\n }\n }\n}\n\nfunction sendBodyDefault(res) {\n setResponseStatus(res, 406);\n sendResponseBody(res, 'Not Acceptable');\n}\n\n/**\n * Deciding on the operation of response, function is called inside this.done()\n */\n\nHttpContext.prototype.resolveReponseOperation = function (accepts) {\n const result = {\n // default\n sendBody: sendBodyJson,\n contentType: 'application/json',\n };\n switch (accepts) {\n case '*/*':\n case 'application/json':\n case 'json':\n break;\n case 'application/vnd.api+json':\n result.contentType = 'application/vnd.api+json';\n break;\n case 'application/javascript':\n case 'text/javascript':\n result.sendBody = sendBodyJsonp;\n break;\n case 'application/xml':\n case 'text/xml':\n case 'xml':\n if (accepts == 'application/xml') {\n result.contentType = 'application/xml';\n } else {\n result.contentType = 'text/xml';\n }\n result.sendBody = sendBodyXml;\n break;\n default:\n result.sendBody = sendBodyDefault;\n result.contentType = 'text/plain';\n break;\n }\n return result;\n};\n\n/**\n * Finish the request and send the correct response.\n */\n\nHttpContext.prototype.done = function (cb) {\n const ctx = this;\n const method = this.method;\n const streamsDesc = method.streams;\n const returnStreamDesc = streamsDesc && streamsDesc.returns;\n const methodReturnsStream = !!returnStreamDesc;\n const res = this.res;\n const out = this.io && this.io.out;\n const err = this.error;\n const result = this.result;\n\n if (methodReturnsStream) {\n if (returnStreamDesc.json) {\n debug('handling json stream');\n\n const stream = result[returnStreamDesc.arg];\n\n if (returnStreamDesc.type === 'ReadableStream') {\n if (ctx.shouldReturnEventStream()) {\n debug('respondWithEventStream');\n ctx.respondWithEventStream(stream);\n return;\n }\n\n debug('piping to mdm stream');\n stream.pipe(out);\n stream.on('error', function (err) {\n const outErr = { message: err.message };\n for (const key in err) {\n outErr[key] = err[key];\n }\n\n // this is the reason we are using mux-demux\n out.error(outErr);\n\n out.end();\n });\n out.on('close', function () {\n stream.destroy();\n });\n // TODO(ritch) support multi-part streams\n } else {\n cb(new Error(g.f('unsupported stream type: %s', returnStreamDesc.type)));\n }\n } else {\n cb(\n new Error(\n g.f(\n 'Unsupported stream descriptor, only descriptors ' +\n 'with property \"{{json:true}}\" are supported',\n ),\n ),\n );\n }\n return;\n }\n\n // send the result back as\n // the requested content type\n const data = this.result;\n let accepts = requestAccepts(this.req, this.supportedTypes);\n const defaultStatus = this.method.http.status;\n\n if (defaultStatus) {\n setResponseStatus(res, defaultStatus);\n }\n\n const format = this.req.query && this.req.query._format;\n if (format) {\n if (typeof format !== 'string') {\n accepts = 'invalid'; // this will 406\n } else {\n accepts = format.toLowerCase();\n }\n }\n const dataExists = typeof data !== 'undefined';\n const operationResults = this.resolveReponseOperation(accepts);\n if ((res.statusCode < 300 || res.statusCode > 399) && !getResponseHeader(res, 'Content-Type')) {\n setResponseHeader(res, 'Content-Type', operationResults.contentType);\n }\n if (dataExists) {\n if (this.resultType !== 'file') {\n operationResults.sendBody(res, data, method);\n res.end();\n } else if (Buffer.isBuffer(data) || typeof data === 'string') {\n res.end(data);\n } else if (data.pipe) {\n data.pipe(res);\n } else {\n const valueType = SharedMethod.getType(data);\n const msg = g.f('Cannot create a file response from %s ', valueType);\n return cb(new Error(msg));\n }\n } else {\n if (res.statusCode === undefined || res.statusCode === 200) {\n res.statusCode = 204;\n }\n res.end();\n }\n\n cb();\n};\n\nfunction getRequestHeader(req, name) {\n if (typeof req.get === 'function') {\n return req.get(name);\n }\n\n return req.headers && req.headers[name.toLowerCase()];\n}\n\nfunction requestAccepts(req, types) {\n if (typeof req.accepts === 'function') {\n return req.accepts(types);\n }\n\n const acceptHeader = getRequestHeader(req, 'accept') || '*/*';\n const acceptedTypes = String(acceptHeader)\n .split(',')\n .map((part) => part.split(';')[0].trim().toLowerCase());\n\n const requestedTypes = Array.isArray(types) ? types : [types];\n for (const requestedType of requestedTypes) {\n const normalizedType = String(requestedType).toLowerCase();\n if (\n acceptedTypes.includes('*/*') ||\n acceptedTypes.includes(normalizedType) ||\n (normalizedType === 'json' && acceptedTypes.some((type) => /\\bjson\\b/.test(type))) ||\n (normalizedType === 'xml' && acceptedTypes.some((type) => /\\bxml\\b/.test(type)))\n ) {\n return requestedType;\n }\n }\n\n return false;\n}\n\nfunction getResponseHeader(res, name) {\n if (typeof res.get === 'function') {\n return res.get(name);\n }\n\n if (typeof res.getHeader === 'function') {\n return res.getHeader(name);\n }\n\n return undefined;\n}\n\nfunction setResponseStatus(res, statusCode) {\n if (typeof res.status === 'function') {\n res.status(statusCode);\n return;\n }\n\n res.statusCode = statusCode;\n}\n\nfunction setResponseHeader(res, name, value) {\n if (typeof res.header === 'function') {\n res.header(name, value);\n return;\n }\n\n if (typeof res.set === 'function') {\n res.set(name, value);\n return;\n }\n\n if (typeof res.setHeader === 'function') {\n res.setHeader(name, value);\n }\n}\n\nfunction sendResponseBody(res, body) {\n if (typeof res.send === 'function') {\n res.send(body);\n return;\n }\n\n if (body === undefined) {\n res.end();\n return;\n }\n\n if (Buffer.isBuffer(body) || typeof body === 'string') {\n res.end(body);\n return;\n }\n\n res.end(String(body));\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { };