@innet/server 2.0.0-alpha.8 → 2.0.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -317,7 +317,9 @@ This section contains elements of utils.
317
317
 
318
318
  [\<swagger>](#swagger)
319
319
  [\<dev>](#dev)
320
+ [\<prod>](#prod)
320
321
  [\<dts>](#dts)
322
+ [\<protection>](#protection)
321
323
 
322
324
  ---
323
325
 
@@ -374,6 +376,25 @@ export default (
374
376
  )
375
377
  ```
376
378
 
379
+ ### \<prod>
380
+
381
+ [← back](#utils)
382
+
383
+ Everything inside <prod> will work when `NODE_ENV` equals `production`.
384
+
385
+ *src/app.tsx*
386
+ ```typescript jsx
387
+ export default (
388
+ <server>
389
+ <api>
390
+ <prod>
391
+ <swagger />
392
+ </prod>
393
+ </api>
394
+ </server>
395
+ )
396
+ ```
397
+
377
398
  ### \<dts>
378
399
 
379
400
  [← back](#utils)
@@ -419,6 +440,149 @@ export function DeleteTodo () {
419
440
  }
420
441
  ```
421
442
 
443
+ ### \<protection>
444
+
445
+ [← back](#utils)
446
+
447
+ This element adds protection page.
448
+ You can use it when you want to protect your application.
449
+ This element MUST be placed in `<api>` element.
450
+
451
+ #### html
452
+
453
+ `<protection>` has a required prop of `html`.
454
+ This is a `string` of HTML a user will see if they have no protection.
455
+
456
+ *src/app.tsx*
457
+ ```typescript jsx
458
+ import html from './protection.html'
459
+
460
+ export default (
461
+ <server>
462
+ <api>
463
+ <protection
464
+ html={html}
465
+ />
466
+ </api>
467
+ </server>
468
+ )
469
+ ```
470
+
471
+ #### value
472
+
473
+ This prop is a secret string of protection value.
474
+ User must provide a protection query param equals the `value`.
475
+
476
+ By default, the value is `undefined` and protection does not work.
477
+ You can use `PROTECTION` env to set default protection `value`.
478
+
479
+ *src/app.tsx*
480
+ ```typescript jsx
481
+ import html from './protection.html'
482
+
483
+ export default (
484
+ <server>
485
+ <api>
486
+ <protection
487
+ value='secret'
488
+ html={html}
489
+ />
490
+ </api>
491
+ </server>
492
+ )
493
+ ```
494
+
495
+ #### maxAge
496
+
497
+ This prop sets how much time protection is qualified.
498
+
499
+ By default, the prop equals a year.
500
+ You can use `PROTECTION_MAX_AGE` env to set default `maxAge`.
501
+
502
+ *src/app.tsx*
503
+ ```typescript jsx
504
+ import html from './protection.html'
505
+
506
+ export default (
507
+ <server>
508
+ <api>
509
+ <protection
510
+ maxAge={24 * 60 * 60}
511
+ html={html}
512
+ />
513
+ </api>
514
+ </server>
515
+ )
516
+ ```
517
+
518
+ #### excludeIp
519
+
520
+ This prop sets a list of IP addresses (split by `,`) to ignore the protection.
521
+
522
+ You can use `PROTECTED_IP` env to set default `excludeIp`.
523
+
524
+ *src/app.tsx*
525
+ ```typescript jsx
526
+ import html from './protection.html'
527
+
528
+ export default (
529
+ <server>
530
+ <api>
531
+ <protection
532
+ excludeIp='0.0.0.0,127.0.0.0'
533
+ html={html}
534
+ />
535
+ </api>
536
+ </server>
537
+ )
538
+ ```
539
+
540
+ #### cookieKey
541
+
542
+ This prop sets a cookie field name used to store protection of a user.
543
+
544
+ By default, it equals `protection`.
545
+ You can use `PROTECTION_COOKIE_KEY` env to set default `cookieKey`.
546
+
547
+ *src/app.tsx*
548
+ ```typescript jsx
549
+ import html from './protection.html'
550
+
551
+ export default (
552
+ <server>
553
+ <api>
554
+ <protection
555
+ cookieKey='secret'
556
+ html={html}
557
+ />
558
+ </api>
559
+ </server>
560
+ )
561
+ ```
562
+
563
+ #### searchKey
564
+
565
+ This prop sets a search query field name used to check protection.
566
+
567
+ By default, it equals `protection`.
568
+ You can use `PROTECTION_SEARCH_KEY` env to set default `searchKey`.
569
+
570
+ *src/app.tsx*
571
+ ```typescript jsx
572
+ import html from './protection.html'
573
+
574
+ export default (
575
+ <server>
576
+ <api>
577
+ <protection
578
+ searchKey='secret'
579
+ html={html}
580
+ />
581
+ </api>
582
+ </server>
583
+ )
584
+ ```
585
+
422
586
  ## API Info
423
587
 
424
588
  The API information elements are here.
@@ -1,6 +1,6 @@
1
1
  import { context, type ContextProps, slot, type SlotProps, slots, type SlotsProps } from '@innet/jsx';
2
2
  import { arraySync, async } from '@innet/utils';
3
- import { type ApiProps, type ArrayProps, type BinaryProps, type BodyProps, type BooleanProps, cms, type CmsProps, type ContactProps, type CookieProps, type DateProps, type DevProps, type DtsProps, type EndpointProps, type ErrorProps, type FallbackProps, type FieldProps, file, type FileProps, type HeaderProps, type HostProps, type IntegerProps, type LicenseProps, type NullProps, type NumberProps, type ObjectProps, type ParamProps, type ProdProps, type ProxyProps, type RedirectProps, type RequestProps, type ResponseProps, type ServerProps, type StringProps, type SuccessProps, type SwaggerProps, type TagProps, type TupleProps, type UuidProps, type VariableProps } from '../plugins';
3
+ import { type ApiProps, type ArrayProps, type BinaryProps, type BodyProps, type BooleanProps, cms, type CmsProps, type ContactProps, type CookieProps, type DateProps, type DevProps, type DtsProps, type EndpointProps, type ErrorProps, type FallbackProps, type FieldProps, file, type FileProps, type HeaderProps, type HostProps, type IntegerProps, type LicenseProps, type NullProps, type NumberProps, type ObjectProps, type ParamProps, type ProdProps, protection, type ProtectionProps, type ProxyProps, type RedirectProps, type RequestProps, type ResponseProps, type ServerProps, type StringProps, type SuccessProps, type SwaggerProps, type TagProps, type TupleProps, type UuidProps, type VariableProps } from '../plugins';
4
4
  export declare const arrayPlugins: (typeof arraySync)[];
5
5
  export declare const JSXPlugins: {
6
6
  api: import("innet").HandlerPlugin;
@@ -29,6 +29,7 @@ export declare const JSXPlugins: {
29
29
  object: import("innet").HandlerPlugin;
30
30
  param: import("innet").HandlerPlugin;
31
31
  prod: import("innet").HandlerPlugin;
32
+ protection: typeof protection;
32
33
  proxy: import("innet").HandlerPlugin;
33
34
  redirect: import("innet").HandlerPlugin;
34
35
  request: import("innet").HandlerPlugin;
@@ -77,6 +78,7 @@ declare global {
77
78
  object: ObjectProps;
78
79
  param: ParamProps;
79
80
  prod: ProdProps;
81
+ protection: ProtectionProps;
80
82
  proxy: ProxyProps;
81
83
  redirect: RedirectProps;
82
84
  request: RequestProps;
@@ -27,6 +27,7 @@ import { number } from '../plugins/schema/number/number.es6.js';
27
27
  import { object } from '../plugins/schema/object/object.es6.js';
28
28
  import { param } from '../plugins/main/param/param.es6.js';
29
29
  import { prod } from '../plugins/utils/prod/prod.es6.js';
30
+ import { protection } from '../plugins/utils/protection/protection.es6.js';
30
31
  import { proxy } from '../plugins/request/proxy/proxy.es6.js';
31
32
  import { redirect } from '../plugins/request/redirect/redirect.es6.js';
32
33
  import { request } from '../plugins/main/request/request.es6.js';
@@ -71,6 +72,7 @@ const JSXPlugins = {
71
72
  object,
72
73
  param,
73
74
  prod,
75
+ protection,
74
76
  proxy,
75
77
  redirect,
76
78
  request,
@@ -31,6 +31,7 @@ var number = require('../plugins/schema/number/number.js');
31
31
  var object = require('../plugins/schema/object/object.js');
32
32
  var param = require('../plugins/main/param/param.js');
33
33
  var prod = require('../plugins/utils/prod/prod.js');
34
+ var protection = require('../plugins/utils/protection/protection.js');
34
35
  var proxy = require('../plugins/request/proxy/proxy.js');
35
36
  var redirect = require('../plugins/request/redirect/redirect.js');
36
37
  var request = require('../plugins/main/request/request.js');
@@ -75,6 +76,7 @@ const JSXPlugins = {
75
76
  object: object.object,
76
77
  param: param.param,
77
78
  prod: prod.prod,
79
+ protection: protection.protection,
78
80
  proxy: proxy.proxy,
79
81
  redirect: redirect.redirect,
80
82
  request: request.request,
@@ -1,15 +1,9 @@
1
- import { getClientIp } from 'request-ip';
2
- import '../useRequest/index.es6.js';
3
- import '../useThrow/index.es6.js';
4
- import { useRequest } from '../useRequest/useRequest.es6.js';
5
- import { useThrow } from '../useThrow/useThrow.es6.js';
1
+ import '../useAction/index.es6.js';
2
+ import { useAction } from '../useAction/useAction.es6.js';
6
3
 
7
4
  function useClientIp() {
8
- const req = useRequest();
9
- if (!req) {
10
- useThrow('<{type}> MUST be in <request> or <fallback>');
11
- }
12
- return getClientIp(req);
5
+ const action = useAction();
6
+ return action.clientIp;
13
7
  }
14
8
 
15
9
  export { useClientIp };
@@ -2,18 +2,12 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var requestIp = require('request-ip');
6
- require('../useRequest/index.js');
7
- require('../useThrow/index.js');
8
- var useRequest = require('../useRequest/useRequest.js');
9
- var useThrow = require('../useThrow/useThrow.js');
5
+ require('../useAction/index.js');
6
+ var useAction = require('../useAction/useAction.js');
10
7
 
11
8
  function useClientIp() {
12
- const req = useRequest.useRequest();
13
- if (!req) {
14
- useThrow.useThrow('<{type}> MUST be in <request> or <fallback>');
15
- }
16
- return requestIp.getClientIp(req);
9
+ const action = useAction.useAction();
10
+ return action.clientIp;
17
11
  }
18
12
 
19
13
  exports.useClientIp = useClientIp;
package/index.es6.js CHANGED
@@ -41,6 +41,7 @@ export { swagger } from './plugins/utils/swagger/swagger.es6.js';
41
41
  export { dts } from './plugins/utils/dts/dts.es6.js';
42
42
  export { dev } from './plugins/utils/dev/dev.es6.js';
43
43
  export { prod } from './plugins/utils/prod/prod.es6.js';
44
+ export { protection } from './plugins/utils/protection/protection.es6.js';
44
45
  export { serverFn } from './plugins/handler/serverFn/serverFn.es6.js';
45
46
  export { EMPTY_SEARCH, parseSearch } from './utils/parseSearch/parseSearch.es6.js';
46
47
  export { stringifySearch } from './utils/stringifySearch/stringifySearch.es6.js';
package/index.js CHANGED
@@ -45,6 +45,7 @@ var swagger = require('./plugins/utils/swagger/swagger.js');
45
45
  var dts = require('./plugins/utils/dts/dts.js');
46
46
  var dev = require('./plugins/utils/dev/dev.js');
47
47
  var prod = require('./plugins/utils/prod/prod.js');
48
+ var protection = require('./plugins/utils/protection/protection.js');
48
49
  var serverFn = require('./plugins/handler/serverFn/serverFn.js');
49
50
  var parseSearch = require('./utils/parseSearch/parseSearch.js');
50
51
  var stringifySearch = require('./utils/stringifySearch/stringifySearch.js');
@@ -163,6 +164,7 @@ exports.swagger = swagger.swagger;
163
164
  exports.dts = dts.dts;
164
165
  exports.dev = dev.dev;
165
166
  exports.prod = prod.prod;
167
+ exports.protection = protection.protection;
166
168
  exports.serverFn = serverFn.serverFn;
167
169
  exports.EMPTY_SEARCH = parseSearch.EMPTY_SEARCH;
168
170
  exports.parseSearch = parseSearch.parseSearch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@innet/server",
3
- "version": "2.0.0-alpha.8",
3
+ "version": "2.0.0-alpha.9",
4
4
  "description": "Create server-side application with innet",
5
5
  "main": "index.js",
6
6
  "module": "index.es6.js",
@@ -34,7 +34,7 @@ const api = () => {
34
34
  var _b, _c, _d, _e, _f, _g;
35
35
  if (res.writableEnded)
36
36
  return;
37
- const action = new Action(req);
37
+ const action = new Action(req, res);
38
38
  const path = action.parsedUrl.path;
39
39
  const url = path.endsWith('/') ? path.slice(0, -1) : path;
40
40
  if (url === (prefix || '')) {
@@ -47,7 +47,7 @@ const api = () => {
47
47
  return;
48
48
  }
49
49
  for (const requestPlugin of requestPlugins) {
50
- if (requestPlugin(req, res))
50
+ if (requestPlugin(action))
51
51
  return;
52
52
  }
53
53
  const method = ((_c = (_b = req.method) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : 'get');
@@ -42,7 +42,7 @@ const api = () => {
42
42
  var _b, _c, _d, _e, _f, _g;
43
43
  if (res.writableEnded)
44
44
  return;
45
- const action = new Action.Action(req);
45
+ const action = new Action.Action(req, res);
46
46
  const path = action.parsedUrl.path;
47
47
  const url = path.endsWith('/') ? path.slice(0, -1) : path;
48
48
  if (url === (prefix || '')) {
@@ -55,7 +55,7 @@ const api = () => {
55
55
  return;
56
56
  }
57
57
  for (const requestPlugin of requestPlugins) {
58
- if (requestPlugin(req, res))
58
+ if (requestPlugin(action))
59
59
  return;
60
60
  }
61
61
  const method = ((_c = (_b = req.method) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : 'get');
@@ -1,28 +1,12 @@
1
1
  import { __rest } from 'tslib';
2
2
  import { useProps } from '@innet/jsx';
3
- import cookie$1 from 'cookie';
4
3
  import '../../../hooks/index.es6.js';
5
- import { useResponse } from '../../../hooks/useResponse/useResponse.es6.js';
6
- import { useThrow } from '../../../hooks/useThrow/useThrow.es6.js';
4
+ import { useAction } from '../../../hooks/useAction/useAction.es6.js';
7
5
 
8
6
  const cookie = () => {
9
- const res = useResponse();
10
- if (!res) {
11
- useThrow('<{type}> MUST be in <request> or <fallback>');
12
- }
7
+ const action = useAction();
13
8
  const _a = useProps(), { key, value } = _a, opt = __rest(_a, ["key", "value"]);
14
- let cookies = res.getHeader('Set-Cookie');
15
- if (typeof cookies === 'string') {
16
- cookies = [cookies];
17
- }
18
- const normValue = typeof value === 'string' ? cookie$1.serialize(key, value, opt) : `${key}=; max-age=0`;
19
- if (cookies) {
20
- cookies.push(normValue);
21
- }
22
- else {
23
- cookies = normValue;
24
- }
25
- res.setHeader('Set-Cookie', cookies);
9
+ action.setCookie(key, value, opt);
26
10
  };
27
11
 
28
12
  export { cookie };
@@ -4,33 +4,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var tslib = require('tslib');
6
6
  var jsx = require('@innet/jsx');
7
- var cookie$1 = require('cookie');
8
7
  require('../../../hooks/index.js');
9
- var useResponse = require('../../../hooks/useResponse/useResponse.js');
10
- var useThrow = require('../../../hooks/useThrow/useThrow.js');
11
-
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
-
14
- var cookie__default = /*#__PURE__*/_interopDefaultLegacy(cookie$1);
8
+ var useAction = require('../../../hooks/useAction/useAction.js');
15
9
 
16
10
  const cookie = () => {
17
- const res = useResponse.useResponse();
18
- if (!res) {
19
- useThrow.useThrow('<{type}> MUST be in <request> or <fallback>');
20
- }
11
+ const action = useAction.useAction();
21
12
  const _a = jsx.useProps(), { key, value } = _a, opt = tslib.__rest(_a, ["key", "value"]);
22
- let cookies = res.getHeader('Set-Cookie');
23
- if (typeof cookies === 'string') {
24
- cookies = [cookies];
25
- }
26
- const normValue = typeof value === 'string' ? cookie__default["default"].serialize(key, value, opt) : `${key}=; max-age=0`;
27
- if (cookies) {
28
- cookies.push(normValue);
29
- }
30
- else {
31
- cookies = normValue;
32
- }
33
- res.setHeader('Set-Cookie', cookies);
13
+ action.setCookie(key, value, opt);
34
14
  };
35
15
 
36
16
  exports.cookie = cookie;
@@ -2,3 +2,4 @@ export * from './swagger';
2
2
  export * from './dts';
3
3
  export * from './dev';
4
4
  export * from './prod';
5
+ export * from './protection';
@@ -2,3 +2,4 @@ import './swagger/index.es6.js';
2
2
  import './dts/index.es6.js';
3
3
  import './dev/index.es6.js';
4
4
  import './prod/index.es6.js';
5
+ import './protection/index.es6.js';
@@ -4,4 +4,5 @@ require('./swagger/index.js');
4
4
  require('./dts/index.js');
5
5
  require('./dev/index.js');
6
6
  require('./prod/index.js');
7
+ require('./protection/index.js');
7
8
 
@@ -0,0 +1 @@
1
+ export * from './protection';
@@ -0,0 +1 @@
1
+ export { protection } from './protection.es6.js';
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var protection = require('./protection.js');
6
+
7
+
8
+
9
+ exports.protection = protection.protection;
@@ -0,0 +1,9 @@
1
+ export interface ProtectionProps {
2
+ html: string;
3
+ value?: string;
4
+ maxAge?: number;
5
+ excludeIp?: string | string[];
6
+ cookieKey?: string;
7
+ searchKey?: string;
8
+ }
9
+ export declare function protection(): void;
@@ -0,0 +1,38 @@
1
+ import { useProps } from '@innet/jsx';
2
+ import '../../../hooks/index.es6.js';
3
+ import { useRequestPlugin } from '../../../hooks/useRequestPlugin/useRequestPlugin.es6.js';
4
+
5
+ function protection() {
6
+ const { html, maxAge = Number(process.env.PROTECTION_MAX_AGE) || 365 * 24 * 60 * 60, value = process.env.PROTECTION, excludeIp = process.env.PROTECTED_IP, cookieKey = process.env.PROTECTION_COOKIE_KEY || 'protection', searchKey = process.env.PROTECTION_SEARCH_KEY || 'protection', } = useProps();
7
+ if (!value)
8
+ return;
9
+ const excludeIps = Array.isArray(excludeIp) ? excludeIp : excludeIp === null || excludeIp === void 0 ? void 0 : excludeIp.split(',');
10
+ useRequestPlugin(action => {
11
+ if (!action.clientIp) {
12
+ action.res.write(html);
13
+ action.res.end();
14
+ return true;
15
+ }
16
+ if (excludeIps === null || excludeIps === void 0 ? void 0 : excludeIps.includes(action.clientIp))
17
+ return false;
18
+ const { [cookieKey]: cookieProtection } = action.cookies;
19
+ if (cookieProtection && cookieProtection === value)
20
+ return false;
21
+ const { [searchKey]: searchProtection } = action.search;
22
+ if (searchProtection && searchProtection === value) {
23
+ action.setCookie(cookieKey, value, {
24
+ maxAge,
25
+ httpOnly: true,
26
+ secure: true,
27
+ path: '/',
28
+ });
29
+ return false;
30
+ }
31
+ action.setCookie(cookieKey);
32
+ action.res.write(html);
33
+ action.res.end();
34
+ return true;
35
+ });
36
+ }
37
+
38
+ export { protection };
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsx = require('@innet/jsx');
6
+ require('../../../hooks/index.js');
7
+ var useRequestPlugin = require('../../../hooks/useRequestPlugin/useRequestPlugin.js');
8
+
9
+ function protection() {
10
+ const { html, maxAge = Number(process.env.PROTECTION_MAX_AGE) || 365 * 24 * 60 * 60, value = process.env.PROTECTION, excludeIp = process.env.PROTECTED_IP, cookieKey = process.env.PROTECTION_COOKIE_KEY || 'protection', searchKey = process.env.PROTECTION_SEARCH_KEY || 'protection', } = jsx.useProps();
11
+ if (!value)
12
+ return;
13
+ const excludeIps = Array.isArray(excludeIp) ? excludeIp : excludeIp === null || excludeIp === void 0 ? void 0 : excludeIp.split(',');
14
+ useRequestPlugin.useRequestPlugin(action => {
15
+ if (!action.clientIp) {
16
+ action.res.write(html);
17
+ action.res.end();
18
+ return true;
19
+ }
20
+ if (excludeIps === null || excludeIps === void 0 ? void 0 : excludeIps.includes(action.clientIp))
21
+ return false;
22
+ const { [cookieKey]: cookieProtection } = action.cookies;
23
+ if (cookieProtection && cookieProtection === value)
24
+ return false;
25
+ const { [searchKey]: searchProtection } = action.search;
26
+ if (searchProtection && searchProtection === value) {
27
+ action.setCookie(cookieKey, value, {
28
+ maxAge,
29
+ httpOnly: true,
30
+ secure: true,
31
+ path: '/',
32
+ });
33
+ return false;
34
+ }
35
+ action.setCookie(cookieKey);
36
+ action.res.write(html);
37
+ action.res.end();
38
+ return true;
39
+ });
40
+ }
41
+
42
+ exports.protection = protection;
@@ -8,14 +8,14 @@ const swagger = () => {
8
8
  const { path = '/swagger-ui' } = useProps() || {};
9
9
  const { docs, prefix } = useApi();
10
10
  let swaggerResponse;
11
- useRequestPlugin((req, res) => {
12
- if (req.url === prefix + path) {
11
+ useRequestPlugin(action => {
12
+ if (action.req.url === prefix + path) {
13
13
  if (!swaggerResponse) {
14
14
  swaggerResponse = html.replace('spec: {},', `spec: ${JSON.stringify(docs)},`);
15
15
  }
16
- res.statusCode = 200;
17
- res.write(swaggerResponse);
18
- res.end();
16
+ action.res.statusCode = 200;
17
+ action.res.write(swaggerResponse);
18
+ action.res.end();
19
19
  return true;
20
20
  }
21
21
  });
@@ -12,14 +12,14 @@ const swagger = () => {
12
12
  const { path = '/swagger-ui' } = jsx.useProps() || {};
13
13
  const { docs, prefix } = useApi.useApi();
14
14
  let swaggerResponse;
15
- useRequestPlugin.useRequestPlugin((req, res) => {
16
- if (req.url === prefix + path) {
15
+ useRequestPlugin.useRequestPlugin(action => {
16
+ if (action.req.url === prefix + path) {
17
17
  if (!swaggerResponse) {
18
18
  swaggerResponse = swagger$1["default"].replace('spec: {},', `spec: ${JSON.stringify(docs)},`);
19
19
  }
20
- res.statusCode = 200;
21
- res.write(swaggerResponse);
22
- res.end();
20
+ action.res.statusCode = 200;
21
+ action.res.write(swaggerResponse);
22
+ action.res.end();
23
23
  return true;
24
24
  }
25
25
  });
package/types.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- /// <reference types="node" />
2
- import type { IncomingMessage, ServerResponse } from 'http';
3
1
  import type { Handler } from 'innet';
4
2
  import type { OpenAPIV3_1 as API } from 'openapi-types';
5
3
  import type { ApiErrorValue } from './constants';
4
+ import { type Action } from './utils';
6
5
  import { type Rule, type RulesErrors } from './utils/rules';
7
6
  export type TagObject = API.TagObject;
8
7
  export type Document = API.Document;
@@ -73,4 +72,4 @@ export interface Fallback {
73
72
  children: any;
74
73
  handler: Handler;
75
74
  }
76
- export type RequestPlugin = (req: IncomingMessage, res: ServerResponse) => boolean | undefined;
75
+ export type RequestPlugin = (action: Action) => boolean | undefined;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
- import type http from 'http';
3
- import { type IncomingHttpHeaders } from 'http';
2
+ import { type CookieSerializeOptions } from 'cookie';
3
+ import { type IncomingHttpHeaders, type IncomingMessage, type ServerResponse } from 'http';
4
4
  import { type ParsedQs } from 'qs';
5
5
  import { type BodyType } from '../../types';
6
6
  export declare const URL_PARSER: RegExp;
@@ -10,8 +10,9 @@ export interface ParsedUrl {
10
10
  }
11
11
  export declare class Action {
12
12
  #private;
13
- private readonly req;
14
- constructor(req: http.IncomingMessage);
13
+ readonly req: IncomingMessage;
14
+ readonly res: ServerResponse;
15
+ constructor(req: IncomingMessage, res: ServerResponse);
15
16
  get parsedUrl(): ParsedUrl;
16
17
  get path(): string;
17
18
  get originSearch(): ParsedQs;
@@ -26,4 +27,6 @@ export declare class Action {
26
27
  get bodyType(): BodyType | undefined;
27
28
  body?: object;
28
29
  parseBody(): Promise<void>;
30
+ setCookie(name: string, value?: string, options?: CookieSerializeOptions): void;
31
+ get clientIp(): string | null;
29
32
  }
@@ -1,5 +1,6 @@
1
1
  import { __runInitializers, __classPrivateFieldGet, __classPrivateFieldSet, __awaiter, __esDecorate } from 'tslib';
2
- import cookie from 'cookie';
2
+ import cookieLib from 'cookie';
3
+ import { getClientIp } from 'request-ip';
3
4
  import '../decorators/index.es6.js';
4
5
  import '../parseBody/index.es6.js';
5
6
  import '../parseFormBody/index.es6.js';
@@ -19,9 +20,11 @@ let Action = (() => {
19
20
  let _get_originCookies_decorators;
20
21
  let _get_bodyType_decorators;
21
22
  let _parseBody_decorators;
23
+ let _get_clientIp_decorators;
22
24
  return _a = class Action {
23
- constructor(req) {
25
+ constructor(req, res) {
24
26
  this.req = (__runInitializers(this, _instanceExtraInitializers), req);
27
+ this.res = res;
25
28
  _Action_search.set(this, void 0);
26
29
  _Action_headers.set(this, {});
27
30
  _Action_cookie.set(this, {});
@@ -66,7 +69,7 @@ let Action = (() => {
66
69
  }
67
70
  get originCookies() {
68
71
  var _a;
69
- return cookie.parse((_a = this.req.headers.cookie) !== null && _a !== void 0 ? _a : '');
72
+ return cookieLib.parse((_a = this.req.headers.cookie) !== null && _a !== void 0 ? _a : '');
70
73
  }
71
74
  get cookies() {
72
75
  if (__classPrivateFieldGet(this, _Action_cookie, "f"))
@@ -103,6 +106,23 @@ let Action = (() => {
103
106
  }
104
107
  });
105
108
  }
109
+ setCookie(name, value, options) {
110
+ let cookies = this.res.getHeader('Set-Cookie');
111
+ if (typeof cookies === 'string') {
112
+ cookies = [cookies];
113
+ }
114
+ const normValue = typeof value === 'string' ? cookieLib.serialize(name, value, options) : `${name}=; max-age=0`;
115
+ if (cookies) {
116
+ cookies.push(normValue);
117
+ }
118
+ else {
119
+ cookies = normValue;
120
+ }
121
+ this.res.setHeader('Set-Cookie', cookies);
122
+ }
123
+ get clientIp() {
124
+ return getClientIp(this.req);
125
+ }
106
126
  },
107
127
  _Action_search = new WeakMap(),
108
128
  _Action_headers = new WeakMap(),
@@ -113,11 +133,13 @@ let Action = (() => {
113
133
  _get_originCookies_decorators = [once];
114
134
  _get_bodyType_decorators = [once];
115
135
  _parseBody_decorators = [once];
136
+ _get_clientIp_decorators = [once];
116
137
  __esDecorate(_a, null, _get_parsedUrl_decorators, { kind: "getter", name: "parsedUrl", static: false, private: false, access: { has: obj => "parsedUrl" in obj, get: obj => obj.parsedUrl } }, null, _instanceExtraInitializers);
117
138
  __esDecorate(_a, null, _get_originSearch_decorators, { kind: "getter", name: "originSearch", static: false, private: false, access: { has: obj => "originSearch" in obj, get: obj => obj.originSearch } }, null, _instanceExtraInitializers);
118
139
  __esDecorate(_a, null, _get_originCookies_decorators, { kind: "getter", name: "originCookies", static: false, private: false, access: { has: obj => "originCookies" in obj, get: obj => obj.originCookies } }, null, _instanceExtraInitializers);
119
140
  __esDecorate(_a, null, _get_bodyType_decorators, { kind: "getter", name: "bodyType", static: false, private: false, access: { has: obj => "bodyType" in obj, get: obj => obj.bodyType } }, null, _instanceExtraInitializers);
120
141
  __esDecorate(_a, null, _parseBody_decorators, { kind: "method", name: "parseBody", static: false, private: false, access: { has: obj => "parseBody" in obj, get: obj => obj.parseBody } }, null, _instanceExtraInitializers);
142
+ __esDecorate(_a, null, _get_clientIp_decorators, { kind: "getter", name: "clientIp", static: false, private: false, access: { has: obj => "clientIp" in obj, get: obj => obj.clientIp } }, null, _instanceExtraInitializers);
121
143
  })(),
122
144
  _a;
123
145
  })();
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var tslib = require('tslib');
6
- var cookie = require('cookie');
6
+ var cookieLib = require('cookie');
7
+ var requestIp = require('request-ip');
7
8
  require('../decorators/index.js');
8
9
  require('../parseBody/index.js');
9
10
  require('../parseFormBody/index.js');
@@ -16,7 +17,7 @@ var once = require('../decorators/once/once.js');
16
17
 
17
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
19
 
19
- var cookie__default = /*#__PURE__*/_interopDefaultLegacy(cookie);
20
+ var cookieLib__default = /*#__PURE__*/_interopDefaultLegacy(cookieLib);
20
21
 
21
22
  const URL_PARSER = /^(?<path>[^?]+)(\?(?<search>.*))?/;
22
23
  let Action = (() => {
@@ -27,9 +28,11 @@ let Action = (() => {
27
28
  let _get_originCookies_decorators;
28
29
  let _get_bodyType_decorators;
29
30
  let _parseBody_decorators;
31
+ let _get_clientIp_decorators;
30
32
  return _a = class Action {
31
- constructor(req) {
33
+ constructor(req, res) {
32
34
  this.req = (tslib.__runInitializers(this, _instanceExtraInitializers), req);
35
+ this.res = res;
33
36
  _Action_search.set(this, void 0);
34
37
  _Action_headers.set(this, {});
35
38
  _Action_cookie.set(this, {});
@@ -74,7 +77,7 @@ let Action = (() => {
74
77
  }
75
78
  get originCookies() {
76
79
  var _a;
77
- return cookie__default["default"].parse((_a = this.req.headers.cookie) !== null && _a !== void 0 ? _a : '');
80
+ return cookieLib__default["default"].parse((_a = this.req.headers.cookie) !== null && _a !== void 0 ? _a : '');
78
81
  }
79
82
  get cookies() {
80
83
  if (tslib.__classPrivateFieldGet(this, _Action_cookie, "f"))
@@ -111,6 +114,23 @@ let Action = (() => {
111
114
  }
112
115
  });
113
116
  }
117
+ setCookie(name, value, options) {
118
+ let cookies = this.res.getHeader('Set-Cookie');
119
+ if (typeof cookies === 'string') {
120
+ cookies = [cookies];
121
+ }
122
+ const normValue = typeof value === 'string' ? cookieLib__default["default"].serialize(name, value, options) : `${name}=; max-age=0`;
123
+ if (cookies) {
124
+ cookies.push(normValue);
125
+ }
126
+ else {
127
+ cookies = normValue;
128
+ }
129
+ this.res.setHeader('Set-Cookie', cookies);
130
+ }
131
+ get clientIp() {
132
+ return requestIp.getClientIp(this.req);
133
+ }
114
134
  },
115
135
  _Action_search = new WeakMap(),
116
136
  _Action_headers = new WeakMap(),
@@ -121,11 +141,13 @@ let Action = (() => {
121
141
  _get_originCookies_decorators = [once.once];
122
142
  _get_bodyType_decorators = [once.once];
123
143
  _parseBody_decorators = [once.once];
144
+ _get_clientIp_decorators = [once.once];
124
145
  tslib.__esDecorate(_a, null, _get_parsedUrl_decorators, { kind: "getter", name: "parsedUrl", static: false, private: false, access: { has: obj => "parsedUrl" in obj, get: obj => obj.parsedUrl } }, null, _instanceExtraInitializers);
125
146
  tslib.__esDecorate(_a, null, _get_originSearch_decorators, { kind: "getter", name: "originSearch", static: false, private: false, access: { has: obj => "originSearch" in obj, get: obj => obj.originSearch } }, null, _instanceExtraInitializers);
126
147
  tslib.__esDecorate(_a, null, _get_originCookies_decorators, { kind: "getter", name: "originCookies", static: false, private: false, access: { has: obj => "originCookies" in obj, get: obj => obj.originCookies } }, null, _instanceExtraInitializers);
127
148
  tslib.__esDecorate(_a, null, _get_bodyType_decorators, { kind: "getter", name: "bodyType", static: false, private: false, access: { has: obj => "bodyType" in obj, get: obj => obj.bodyType } }, null, _instanceExtraInitializers);
128
149
  tslib.__esDecorate(_a, null, _parseBody_decorators, { kind: "method", name: "parseBody", static: false, private: false, access: { has: obj => "parseBody" in obj, get: obj => obj.parseBody } }, null, _instanceExtraInitializers);
150
+ tslib.__esDecorate(_a, null, _get_clientIp_decorators, { kind: "getter", name: "clientIp", static: false, private: false, access: { has: obj => "clientIp" in obj, get: obj => obj.clientIp } }, null, _instanceExtraInitializers);
129
151
  })(),
130
152
  _a;
131
153
  })();