express.exe 0.0.1769201820754

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/lib/request.js ADDED
@@ -0,0 +1,557 @@
1
+ /*!
2
+ * express
3
+ * Copyright(c) 2009-2013 TJ Holowaychuk
4
+ * Copyright(c) 2013 Roman Shtylman
5
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
6
+ * MIT Licensed
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /**
12
+ * Module dependencies.
13
+ * @private
14
+ */
15
+
16
+ var accepts = require('accepts');
17
+ var isIP = require('node:net').isIP;
18
+ var typeis = require('type-is');
19
+ var http = require('node:http');
20
+ var fresh = require('fresh');
21
+ var parseRange = require('range-parser');
22
+ var parse = require('parseurl');
23
+ var proxyaddr = require('proxy-addr');
24
+
25
+ /**
26
+ * Request prototype.
27
+ * @public
28
+ */
29
+
30
+ var req = Object.create(http.IncomingMessage.prototype)
31
+
32
+ /**
33
+ * Module exports.
34
+ * @public
35
+ */
36
+
37
+ module.exports = req
38
+
39
+ /**
40
+ * Return request header.
41
+ *
42
+ * The `Referrer` header field is special-cased,
43
+ * both `Referrer` and `Referer` are interchangeable.
44
+ *
45
+ * Examples:
46
+ *
47
+ * req.get('Content-Type');
48
+ * // => "text/plain"
49
+ *
50
+ * req.get('content-type');
51
+ * // => "text/plain"
52
+ *
53
+ * req.get('Something');
54
+ * // => undefined
55
+ *
56
+ * Aliased as `req.header()`.
57
+ *
58
+ * @param {String} name
59
+ * @return {String}
60
+ * @public
61
+ */
62
+
63
+ req.get =
64
+ req.header = function header(name) {
65
+ if (!name) {
66
+ throw new TypeError('name argument is required to req.get');
67
+ }
68
+
69
+ if (typeof name !== 'string') {
70
+ throw new TypeError('name must be a string to req.get');
71
+ }
72
+
73
+ var lc = name.toLowerCase();
74
+
75
+ switch (lc) {
76
+ case 'referer':
77
+ case 'referrer':
78
+ return this.headers.referrer
79
+ || this.headers.referer;
80
+ default:
81
+ return this.headers[lc];
82
+ }
83
+ };
84
+
85
+ /**
86
+ * To do: update docs.
87
+ *
88
+ * Check if the given `type(s)` is acceptable, returning
89
+ * the best match when true, otherwise `undefined`, in which
90
+ * case you should respond with 406 "Not Acceptable".
91
+ *
92
+ * The `type` value may be a single MIME type string
93
+ * such as "application/json", an extension name
94
+ * such as "json", a comma-delimited list such as "json, html, text/plain",
95
+ * an argument list such as `"json", "html", "text/plain"`,
96
+ * or an array `["json", "html", "text/plain"]`. When a list
97
+ * or array is given, the _best_ match, if any is returned.
98
+ *
99
+ * Examples:
100
+ *
101
+ * // Accept: text/html
102
+ * req.accepts('html');
103
+ * // => "html"
104
+ *
105
+ * // Accept: text/*, application/json
106
+ * req.accepts('html');
107
+ * // => "html"
108
+ * req.accepts('text/html');
109
+ * // => "text/html"
110
+ * req.accepts('json, text');
111
+ * // => "json"
112
+ * req.accepts('application/json');
113
+ * // => "application/json"
114
+ *
115
+ * // Accept: text/*, application/json
116
+ * req.accepts('image/png');
117
+ * req.accepts('png');
118
+ * // => undefined
119
+ *
120
+ * // Accept: text/*;q=.5, application/json
121
+ * req.accepts(['html', 'json']);
122
+ * req.accepts('html', 'json');
123
+ * req.accepts('html, json');
124
+ * // => "json"
125
+ *
126
+ * @param {String|Array} type(s)
127
+ * @return {String|Array|Boolean}
128
+ * @public
129
+ */
130
+
131
+ req.accepts = function(){
132
+ var accept = accepts(this);
133
+ return accept.types.apply(accept, arguments);
134
+ };
135
+
136
+ /**
137
+ * Check if the given `encoding`s are accepted.
138
+ *
139
+ * @param {String} ...encoding
140
+ * @return {String|Array}
141
+ * @public
142
+ */
143
+
144
+ req.acceptsEncodings = function(){
145
+ var accept = accepts(this);
146
+ return accept.encodings.apply(accept, arguments);
147
+ };
148
+
149
+ /**
150
+ * Check if the given `charset`s are acceptable,
151
+ * otherwise you should respond with 406 "Not Acceptable".
152
+ *
153
+ * @param {String} ...charset
154
+ * @return {String|Array}
155
+ * @public
156
+ */
157
+
158
+ req.acceptsCharsets = function(){
159
+ var accept = accepts(this);
160
+ return accept.charsets.apply(accept, arguments);
161
+ };
162
+
163
+ /**
164
+ * Check if the given `lang`s are acceptable,
165
+ * otherwise you should respond with 406 "Not Acceptable".
166
+ *
167
+ * @param {String} ...lang
168
+ * @return {String|Array}
169
+ * @public
170
+ */
171
+
172
+ req.acceptsLanguages = function(...languages) {
173
+ return accepts(this).languages(...languages);
174
+ };
175
+
176
+ /**
177
+ * Parse Range header field, capping to the given `size`.
178
+ *
179
+ * Unspecified ranges such as "0-" require knowledge of your resource length. In
180
+ * the case of a byte range this is of course the total number of bytes. If the
181
+ * Range header field is not given `undefined` is returned, `-1` when unsatisfiable,
182
+ * and `-2` when syntactically invalid.
183
+ *
184
+ * When ranges are returned, the array has a "type" property which is the type of
185
+ * range that is required (most commonly, "bytes"). Each array element is an object
186
+ * with a "start" and "end" property for the portion of the range.
187
+ *
188
+ * The "combine" option can be set to `true` and overlapping & adjacent ranges
189
+ * will be combined into a single range.
190
+ *
191
+ * NOTE: remember that ranges are inclusive, so for example "Range: users=0-3"
192
+ * should respond with 4 users when available, not 3.
193
+ *
194
+ * @param {number} size
195
+ * @param {object} [options]
196
+ * @param {boolean} [options.combine=false]
197
+ * @return {number|array}
198
+ * @public
199
+ */
200
+
201
+ req.range = function range(size, options) {
202
+ var range = this.get('Range');
203
+ if (!range) return;
204
+ return parseRange(size, range, options);
205
+ };
206
+
207
+ /**
208
+ * Parse the query string of `req.url`.
209
+ *
210
+ * This uses the "query parser" setting to parse the raw
211
+ * string into an object.
212
+ *
213
+ * @return {String}
214
+ * @api public
215
+ */
216
+
217
+ defineGetter(req, '_query', function _query(){
218
+ var queryparse = this.app.get('query parser fn');
219
+
220
+ if (!queryparse) {
221
+ // parsing is disabled
222
+ return Object.create(null);
223
+ }
224
+
225
+ var querystring = parse(this).query;
226
+
227
+ return queryparse(querystring);
228
+ });
229
+
230
+ /**
231
+ * Check if the incoming request contains the "Content-Type"
232
+ * header field, and it contains the given mime `type`.
233
+ *
234
+ * Examples:
235
+ *
236
+ * // With Content-Type: text/html; charset=utf-8
237
+ * req.is('html');
238
+ * req.is('text/html');
239
+ * req.is('text/*');
240
+ * // => true
241
+ *
242
+ * // When Content-Type is application/json
243
+ * req.is('json');
244
+ * req.is('application/json');
245
+ * req.is('application/*');
246
+ * // => true
247
+ *
248
+ * req.is('html');
249
+ * // => false
250
+ *
251
+ * @param {String|Array} types...
252
+ * @return {String|false|null}
253
+ * @public
254
+ */
255
+
256
+ req.is = function is(types) {
257
+ var arr = types;
258
+
259
+ // support flattened arguments
260
+ if (!Array.isArray(types)) {
261
+ arr = new Array(arguments.length);
262
+ for (var i = 0; i < arr.length; i++) {
263
+ arr[i] = arguments[i];
264
+ }
265
+ }
266
+
267
+ return typeis(this, arr);
268
+ };
269
+
270
+ /**
271
+ * Return the protocol string "http" or "https"
272
+ * when requested with TLS. When the "trust proxy"
273
+ * setting trusts the socket address, the
274
+ * "X-Forwarded-Proto" header field will be trusted
275
+ * and used if present.
276
+ *
277
+ * If you're running behind a reverse proxy that
278
+ * supplies https for you this may be enabled.
279
+ *
280
+ * @return {String}
281
+ * @public
282
+ */
283
+
284
+ defineGetter(req, 'protocol', function protocol(){
285
+ if (this.app.config ["http:secure"]) return "https";
286
+ var proto = this.socket.encrypted
287
+ ? 'https'
288
+ : 'http';
289
+ var trust = this.app.get('trust proxy fn');
290
+
291
+ if (!trust(this.socket.remoteAddress, 0)) {
292
+ return proto;
293
+ }
294
+
295
+ // Note: X-Forwarded-Proto is normally only ever a
296
+ // single value, but this is to be safe.
297
+ var header = this.get('X-Forwarded-Proto') || proto
298
+ var index = header.indexOf(',')
299
+
300
+ return index !== -1
301
+ ? header.substring(0, index).trim()
302
+ : header.trim()
303
+ });
304
+
305
+ /**
306
+ * Short-hand for:
307
+ *
308
+ * req.protocol === 'https'
309
+ *
310
+ * @return {Boolean}
311
+ * @public
312
+ */
313
+
314
+ defineGetter(req, 'secure', function secure(){
315
+ return this.protocol === 'https';
316
+ });
317
+
318
+ /**
319
+ * Return the remote address from the trusted proxy.
320
+ *
321
+ * The is the remote address on the socket unless
322
+ * "trust proxy" is set.
323
+ *
324
+ * @return {String}
325
+ * @public
326
+ */
327
+
328
+ defineGetter(req, 'ip', function ip(){
329
+ var trust = this.app.get('trust proxy fn');
330
+ return proxyaddr(this, trust);
331
+ });
332
+
333
+ /**
334
+ * When "trust proxy" is set, trusted proxy addresses + client.
335
+ *
336
+ * For example if the value were "client, proxy1, proxy2"
337
+ * you would receive the array `["client", "proxy1", "proxy2"]`
338
+ * where "proxy2" is the furthest down-stream and "proxy1" and
339
+ * "proxy2" were trusted.
340
+ *
341
+ * @return {Array}
342
+ * @public
343
+ */
344
+
345
+ defineGetter(req, 'ips', function ips() {
346
+ var trust = this.app.get('trust proxy fn');
347
+ var addrs = proxyaddr.all(this, trust);
348
+
349
+ // reverse the order (to farthest -> closest)
350
+ // and remove socket address
351
+ addrs.reverse().pop()
352
+
353
+ return addrs
354
+ });
355
+
356
+ /**
357
+ * Return subdomains as an array.
358
+ *
359
+ * Subdomains are the dot-separated parts of the host before the main domain of
360
+ * the app. By default, the domain of the app is assumed to be the last two
361
+ * parts of the host. This can be changed by setting "subdomain offset".
362
+ *
363
+ * For example, if the domain is "tobi.ferrets.example.com":
364
+ * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
365
+ * If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
366
+ *
367
+ * @return {Array}
368
+ * @public
369
+ */
370
+
371
+ defineGetter(req, 'subdomains', function subdomains() {
372
+ var hostname = this.hostname;
373
+
374
+ if (!hostname) return [];
375
+
376
+ var offset = this.app.get('subdomain offset');
377
+ var subdomains = !isIP(hostname)
378
+ ? hostname.split('.').reverse()
379
+ : [hostname];
380
+
381
+ return subdomains.slice(offset);
382
+ });
383
+
384
+ /**
385
+ * Short-hand for `url.parse(req.url).pathname`.
386
+ *
387
+ * @return {String}
388
+ * @public
389
+ */
390
+
391
+ defineGetter(req, 'path', function path() {
392
+ return parse(this).pathname;
393
+ });
394
+
395
+ /**
396
+ * Parse the "Host" header field to a host.
397
+ *
398
+ * When the "trust proxy" setting trusts the socket
399
+ * address, the "X-Forwarded-Host" header field will
400
+ * be trusted.
401
+ *
402
+ * @return {String}
403
+ * @public
404
+ */
405
+
406
+ defineGetter(req, 'host', function host(){
407
+ var trust = this.app.get('trust proxy fn');
408
+ var val = this.get('X-Forwarded-Host');
409
+
410
+ if (!val || !trust(this.socket.remoteAddress, 0)) {
411
+ val = this.get('Host');
412
+ } else if (val.indexOf(',') !== -1) {
413
+ // Note: X-Forwarded-Host is normally only ever a
414
+ // single value, but this is to be safe.
415
+ val = val.substring(0, val.indexOf(',')).trimRight()
416
+ }
417
+
418
+ return val || undefined;
419
+ });
420
+
421
+ /**
422
+ * Parse the "Host" header field to a hostname.
423
+ *
424
+ * When the "trust proxy" setting trusts the socket
425
+ * address, the "X-Forwarded-Host" header field will
426
+ * be trusted.
427
+ *
428
+ * @return {String}
429
+ * @api public
430
+ */
431
+
432
+ defineGetter(req, 'hostname', function hostname(){
433
+ var host = this.host;
434
+
435
+ if (!host) return;
436
+
437
+ // IPv6 literal support
438
+ var offset = host[0] === '['
439
+ ? host.indexOf(']') + 1
440
+ : 0;
441
+ var index = host.indexOf(':', offset);
442
+
443
+ return index !== -1
444
+ ? host.substring(0, index)
445
+ : host;
446
+ });
447
+
448
+ /**
449
+ * Check if the request is fresh, aka
450
+ * Last-Modified or the ETag
451
+ * still match.
452
+ *
453
+ * @return {Boolean}
454
+ * @public
455
+ */
456
+
457
+ defineGetter(req, 'fresh', function(){
458
+ var method = this.method;
459
+ var res = this.res
460
+ var status = res.statusCode
461
+
462
+ // GET or HEAD for weak freshness validation only
463
+ if ('GET' !== method && 'HEAD' !== method) return false;
464
+
465
+ // 2xx or 304 as per rfc2616 14.26
466
+ if ((status >= 200 && status < 300) || 304 === status) {
467
+ return fresh(this.headers, {
468
+ 'etag': res.get('ETag'),
469
+ 'last-modified': res.get('Last-Modified')
470
+ })
471
+ }
472
+
473
+ return false;
474
+ });
475
+
476
+ /**
477
+ * Check if the request is stale, aka
478
+ * "Last-Modified" and / or the "ETag" for the
479
+ * resource has changed.
480
+ *
481
+ * @return {Boolean}
482
+ * @public
483
+ */
484
+
485
+ defineGetter(req, 'stale', function stale(){
486
+ return !this.fresh;
487
+ });
488
+
489
+ /**
490
+ * Check if the request was an _XMLHttpRequest_.
491
+ *
492
+ * @return {Boolean}
493
+ * @public
494
+ */
495
+
496
+ defineGetter(req, 'xhr', function xhr(){
497
+ var val = this.get('X-Requested-With') || '';
498
+ return val.toLowerCase() === 'xmlhttprequest';
499
+ });
500
+
501
+ /**
502
+ * Helper function for creating a getter on an object.
503
+ *
504
+ * @param {Object} obj
505
+ * @param {String} name
506
+ * @param {Function} getter
507
+ * @private
508
+ */
509
+ function defineGetter(obj, name, getter) {
510
+ Object.defineProperty(obj, name, {
511
+ configurable: true,
512
+ enumerable: true,
513
+ get: getter
514
+ });
515
+ }
516
+
517
+ req.setup = function setup () {
518
+ if ("url") {
519
+ this.base_url = `${this.protocol}://${this.host}`;
520
+ this.parse_url = URL.parse (this.canonical = `${this.base_url}${this.url}`);
521
+ this.domain = this.parse_url.domain;
522
+ this.query = function query (query) { return this.request.parse_url.queries [query] || ""; }.bind ({request: this});
523
+ this.param = function param (param) { return this.request.params [param] || ""; }.bind ({request: this});
524
+ }
525
+ return this;
526
+ }
527
+
528
+ defineGetter (req, "visitor", function visitor () {
529
+ if ("visitor") {
530
+ var ip_address = this.headers ["x-real-ip"] || "127.0.0.1";
531
+ var country_code = this.headers ["x-vercel-ip-country"] || "";
532
+ var country_name = "";
533
+ var country_region = this.headers ["x-vercel-ip-country-region"] || "";
534
+ var country_city_code = "";
535
+ var country_city_name = this.headers ["x-vercel-ip-city"] || "";
536
+ var country_timezone = this.headers ["x-vercel-ip-timezone"] || "";
537
+ var coordinate_latitude = this.headers ["x-vercel-ip-latitude"] || "";
538
+ var coordinate_longitude = this.headers ["x-vercel-ip-longitude"] || "";
539
+ return {
540
+ ip: {address: ip_address},
541
+ country: {code: country_code, name: country_name, region: country_region, city: {name: country_city_name}, timezone: country_timezone, coordinate: {latitude: coordinate_latitude, longitude: coordinate_longitude}},
542
+ browser: this.header ("user-agent"),
543
+ }
544
+ }
545
+ });
546
+
547
+ req.prepare = async function prepare () {
548
+ this.date = new Date.io ();
549
+ this.instance = function () {}
550
+ this.theme = function () {}
551
+ if ("db") {
552
+ if (this.app.config.db.driver === "appwrite") this.db = new Function.appwrite.db ({id: this.app.config.db.id, host: this.app.config.db.host, project: this.app.config.db.project, collection: this.app.config.db.collection}, this.app.config.db.json);
553
+ this.instance.list = (await this.db.select ("instance").find ().query ()).data;
554
+ this.theme.list = (await this.db.select ("theme").find ().query ()).data;
555
+ }
556
+ return this;
557
+ }