UNPKG

2.84 kBJavaScriptView Raw
1/**
2 * @copyright Copyright (c) 2019 Maxim Khorin <maksimovichu@gmail.com>
3 */
4'use strict';
5
6const Base = require('../base/Component');
7
8module.exports = class Forwarder extends Base {
9
10 constructor (config) {
11 super({
12 items: {},
13 Url: require('./Url'),
14 ...config
15 });
16 this.clear();
17 }
18
19 init () {
20 this.createItems();
21 if (!this.isEmpty()) {
22 this.module.addHandler('use', this.forward.bind(this));
23 }
24 }
25
26 isEmpty () {
27 return this._urls.length === 0;
28 }
29
30 createItems () {
31 this._urls = [];
32 for (const source of Object.keys(this.items)) {
33 let data = this.items[source];
34 data = data instanceof Object ? data : {target: data};
35 data.source = source;
36 this._urls.push(ClassHelper.spawn(this.Url, data));
37 this.log('trace', `forward ${data.source} to ${data.target}`);
38 }
39 }
40
41 forward (req, res, next) {
42 const data = this.resolvePath(req.path, req.method);
43 if (!data) {
44 return next();
45 }
46 this.log('trace', `forward ${req.path} to ${data.path}`, data.params);
47 Object.assign(req.query, data.params);
48 req.url = data.path;
49 next();
50 }
51
52 resolve (url) {
53 let newUrl = this.get(url);
54 if (newUrl) {
55 return newUrl;
56 }
57 newUrl = this.createSourceUrl(UrlHelper.parse(url));
58 if (!newUrl && this.module.parent) {
59 newUrl = this.module.parent.resolveUrl(url);
60 }
61 this.set(url, newUrl);
62 return newUrl;
63 }
64
65 resolvePath (path, method) {
66 for (const url of this._urls) {
67 const data = url.resolve(path, method);
68 if (data) {
69 return data;
70 }
71 }
72 return null;
73 }
74
75 createSourceUrl (data) {
76 const index = data.segments.indexOf(this.module.getBaseName()) + 1;
77 data.path = index > 0
78 ? `/${data.segments.slice(index).join('/')}`
79 : `/${data.segments.join('/')}`;
80 for (let url of this._urls) {
81 url = url.createSourceUrl(data);
82 if (url) {
83 return index > 0 ? `/${data.segments.slice(0, index).join('/')}${url}` : url;
84 }
85 }
86 return null;
87 }
88
89 // CACHE
90
91 get (key) {
92 return Object.prototype.hasOwnProperty.call(this._cache, key) ? this._cache[key] : null;
93 }
94
95 set (key, value) {
96 this._cache[key] = value;
97 }
98
99 clear () {
100 this._cache = {};
101 }
102};
103
104const ClassHelper = require('../helper/ClassHelper');
105const UrlHelper = require('../helper/UrlHelper');
\No newline at end of file