vaderjs 1.2.3 → 1.2.5
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/package.json +1 -1
- package/readme.md +17 -14
- package/vader.js +16 -11
- package/vaderRouter.js +189 -435
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -65,24 +65,27 @@ or
|
|
|
65
65
|
### Declarative Routing
|
|
66
66
|
|
|
67
67
|
```javascript
|
|
68
|
-
import
|
|
69
|
-
import {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
app.use('/') // use the route
|
|
73
|
-
|
|
74
|
-
app.get('/', async (req, res) => {
|
|
75
|
-
res.render('#app', await MyComponent.render())
|
|
76
|
-
})
|
|
68
|
+
import VaderRouter from "../dist/vader/vaderRouter.js";
|
|
69
|
+
import { Mycomponent} from "../src/pages/Home.js";
|
|
70
|
+
|
|
71
|
+
const app = new VaderRouter('/');
|
|
77
72
|
|
|
78
|
-
app.
|
|
79
|
-
res.
|
|
73
|
+
app.get("/", async (req, res)=>{
|
|
74
|
+
res.send('#root', await new Home().render())
|
|
80
75
|
})
|
|
81
|
-
app.get('/:
|
|
82
|
-
|
|
76
|
+
app.get('/docs/:page/*', async (req, res)=>{
|
|
77
|
+
// page and asterisk route use req.params for params and req.params[0] to get the asterisk
|
|
78
|
+
// you can get queries from the url using req.query!
|
|
83
79
|
})
|
|
80
|
+
const middleware = (req, res)=>{
|
|
81
|
+
req.time = Date.now()
|
|
82
|
+
}
|
|
83
|
+
app.use(middleware) // use middlewares
|
|
84
84
|
|
|
85
|
-
app.
|
|
85
|
+
app.listen(3000, ()=>{
|
|
86
|
+
console.log('listening on port 3000')
|
|
87
|
+
})
|
|
88
|
+
|
|
86
89
|
```
|
|
87
90
|
|
|
88
91
|
|
package/vader.js
CHANGED
|
@@ -17,13 +17,16 @@ function markdown(content) {
|
|
|
17
17
|
let link = line.match(/\[(.*?)\]\((.*?)\)/g);
|
|
18
18
|
let ul = line.match(/^\-\s/);
|
|
19
19
|
let ol = line.match(/^\d\.\s/);
|
|
20
|
+
let li = line.match(/^\s/);
|
|
20
21
|
let hr = line.match(/^\-\-\-\s/);
|
|
21
22
|
let blockquote = line.match(/^\>\s/);
|
|
22
23
|
let image = line.match(/\!\[(.*?)\]\((.*?)\)/g);
|
|
23
24
|
|
|
25
|
+
|
|
24
26
|
let codeBlock = line.match(/\`\`\`/g);
|
|
25
27
|
let codeBlockEnd = line.match(/\`\`\`/g);
|
|
26
28
|
|
|
29
|
+
|
|
27
30
|
if (heading) {
|
|
28
31
|
// @ts-ignore
|
|
29
32
|
let headingLevel = heading[0].match(/#/g).length;
|
|
@@ -81,11 +84,15 @@ function markdown(content) {
|
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
86
|
if(codeBlock){
|
|
84
|
-
line = line.replace(codeBlock[0], `<
|
|
87
|
+
line = line.replace(codeBlock[0], `<code>`);
|
|
88
|
+
|
|
85
89
|
}
|
|
86
90
|
if(codeBlockEnd){
|
|
87
|
-
line = line.replace(codeBlockEnd[0], `</code
|
|
91
|
+
line = line.replace(codeBlockEnd[0], `</code>`);
|
|
92
|
+
// remove spaces
|
|
93
|
+
line = line.replace(/^\s+/g, '');
|
|
88
94
|
}
|
|
95
|
+
|
|
89
96
|
|
|
90
97
|
|
|
91
98
|
result += `${line}\n`;
|
|
@@ -826,8 +833,9 @@ export class Component {
|
|
|
826
833
|
"You should wrap your html in a body tag, vader may not grab all html!"
|
|
827
834
|
);
|
|
828
835
|
}
|
|
829
|
-
|
|
830
|
-
|
|
836
|
+
|
|
837
|
+
const dom = new DOMParser().parseFromString(result, "text/html");
|
|
838
|
+
const elements = dom.documentElement.querySelectorAll("*");
|
|
831
839
|
|
|
832
840
|
elements.forEach((element) => {
|
|
833
841
|
switch (element.nodeName) {
|
|
@@ -861,11 +869,8 @@ export class Component {
|
|
|
861
869
|
let prevurl = element.getAttribute("src");
|
|
862
870
|
element.setAttribute("aria-hidden", "true");
|
|
863
871
|
element.setAttribute("hidden", "true");
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
window.location.pathname +
|
|
867
|
-
"/public/" +
|
|
868
|
-
element.getAttribute("src");
|
|
872
|
+
// if window.lcoation.pathname includes a html file remove it and only use the path
|
|
873
|
+
let url = window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '') + '/public/' + element.getAttribute("src");
|
|
869
874
|
let image = new Image();
|
|
870
875
|
image.src = url;
|
|
871
876
|
image.onerror = () => {
|
|
@@ -891,7 +896,7 @@ export class Component {
|
|
|
891
896
|
dom[element.getAttribute("ref")] = element;
|
|
892
897
|
}
|
|
893
898
|
if(element.nodeName === "MARKDOWN"){
|
|
894
|
-
element.innerHTML = markdown(element.innerHTML.trim())
|
|
899
|
+
element.innerHTML = markdown(element.innerHTML.replace(/\\n/g, '\n').trim())
|
|
895
900
|
}
|
|
896
901
|
|
|
897
902
|
if (element.hasAttribute("class")) {
|
|
@@ -1119,4 +1124,4 @@ export const include = async (path) => {
|
|
|
1119
1124
|
});
|
|
1120
1125
|
};
|
|
1121
1126
|
|
|
1122
|
-
export default Vader
|
|
1127
|
+
export default Vader
|
package/vaderRouter.js
CHANGED
|
@@ -1,477 +1,231 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
|
-
window.$URL_PARAMS = {};
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
window.$URL_QUERY = {};
|
|
5
1
|
|
|
6
2
|
/**
|
|
7
|
-
* @
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
3
|
+
* @class VaderRouter
|
|
4
|
+
* @description - creates an instance of Vader Express Router
|
|
5
|
+
*
|
|
6
|
+
* @param {String} path
|
|
7
|
+
* @param {Function} handler
|
|
8
|
+
* @param {object} req request object
|
|
9
|
+
* @param {object} res response object
|
|
10
|
+
* @returns {Object} Express
|
|
11
|
+
*
|
|
11
12
|
*/
|
|
12
|
-
class VaderRouter
|
|
13
|
+
class VaderRouter{
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {
|
|
15
|
+
* @constructor
|
|
16
|
+
* @param {*} basePath
|
|
17
|
+
*
|
|
16
18
|
*/
|
|
17
|
-
constructor(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* The current URL being navigated.
|
|
26
|
-
* @type {string}
|
|
27
|
-
*/
|
|
28
|
-
this.currentUrl = "";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Listener function for hash change events.
|
|
32
|
-
* @type {Function}
|
|
33
|
-
*/
|
|
34
|
-
//@ts-ignore
|
|
35
|
-
this.hashChangeListener = null;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Error handlers for different error types.
|
|
39
|
-
* @type {Object}
|
|
40
|
-
*/
|
|
41
|
-
this.errorHandlers = {};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Flag indicating if custom error handling is enabled.
|
|
45
|
-
* @type {boolean}
|
|
46
|
-
*/
|
|
47
|
-
//@ts-ignore
|
|
48
|
-
this.customerror = null;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Flag indicating if the router is currently handling a route.
|
|
52
|
-
* @type {boolean}
|
|
53
|
-
*/
|
|
54
|
-
this.hooked = false;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* The starting URL for the router.
|
|
58
|
-
* @type {string}
|
|
59
|
-
*/
|
|
60
|
-
this.starturl = starturl;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Array to store stored routes.
|
|
64
|
-
* @type {string[]}
|
|
65
|
-
*/
|
|
66
|
-
this.storedroutes = [];
|
|
19
|
+
constructor(basePath) {
|
|
20
|
+
this.routes = [];
|
|
21
|
+
this.middlewares = [];
|
|
22
|
+
this.errorMiddlewares = [];
|
|
23
|
+
this.listeners = [];
|
|
24
|
+
|
|
25
|
+
this.basePath = basePath;
|
|
67
26
|
}
|
|
68
27
|
|
|
69
28
|
/**
|
|
70
|
-
*
|
|
29
|
+
* @method get
|
|
30
|
+
* @param {String} path
|
|
31
|
+
* @param {Function} handler
|
|
32
|
+
* @description This method is used to register a get route
|
|
33
|
+
* @returns {void}
|
|
34
|
+
* @memberof Express
|
|
71
35
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
window.addEventListener("hashchange", () => {
|
|
79
|
-
this.handleRoute("POST");
|
|
36
|
+
get(path, handler) {
|
|
37
|
+
|
|
38
|
+
this.routes.push({
|
|
39
|
+
path,
|
|
40
|
+
handler,
|
|
41
|
+
method: 'get',
|
|
80
42
|
});
|
|
81
43
|
}
|
|
82
|
-
|
|
83
44
|
/**
|
|
84
|
-
* @
|
|
85
|
-
* @
|
|
86
|
-
* @param {
|
|
87
|
-
* @returns {void}
|
|
88
|
-
* @memberof VaderRouter
|
|
89
|
-
* @description Handles errors for the router.
|
|
90
|
-
* @example
|
|
91
|
-
* router.handleErrors('404', (err) => {
|
|
92
|
-
* // do something with err
|
|
93
|
-
* });
|
|
45
|
+
* @method use
|
|
46
|
+
* @description This method allows you to use middlewares
|
|
47
|
+
* @param {Function} middleware
|
|
94
48
|
*/
|
|
95
|
-
handleErrors(type, callback) {
|
|
96
|
-
this.errorHandlers[type] = callback;
|
|
97
|
-
this.customerror = true;
|
|
98
|
-
}
|
|
99
|
-
handleRoute(method) {
|
|
100
|
-
|
|
101
|
-
let route = window.location.hash.substring(1);
|
|
102
|
-
// @ts-ignore
|
|
103
|
-
window.$CURRENT_URL = route;
|
|
104
49
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
route = route.split("?")[0];
|
|
108
|
-
}
|
|
109
|
-
route = route.split("/")[0] + "/" + route.split("/")[1];
|
|
110
|
-
if (this.routes[route]) {
|
|
111
|
-
|
|
112
|
-
this.storedroutes.push(route);
|
|
113
|
-
const req = {
|
|
114
|
-
// @ts-ignore
|
|
115
|
-
params: $URL_PARAMS ? $URL_PARAMS : {},
|
|
116
|
-
// @ts-ignore
|
|
117
|
-
query: $URL_QUERY ? $URL_QUERY : {},
|
|
118
|
-
url: route,
|
|
119
|
-
method: method ? method : "GET",
|
|
120
|
-
};
|
|
121
|
-
const res = {
|
|
122
|
-
return: function (data) {
|
|
123
|
-
this.hooked = false;
|
|
124
|
-
},
|
|
125
|
-
render: function (selector, data) {
|
|
126
|
-
document.querySelector(selector).innerHTML = data;
|
|
127
|
-
},
|
|
128
|
-
};
|
|
129
|
-
if(typeof this.routes[route] === 'function'){
|
|
130
|
-
this.routes[route](req, res);
|
|
131
|
-
}
|
|
132
|
-
} else {
|
|
133
|
-
if (this.customerror) {
|
|
134
|
-
//@ts-ignore
|
|
135
|
-
this.handleError("404", route);
|
|
136
|
-
console.error("404: Route not found");
|
|
137
|
-
} else {
|
|
138
|
-
console.error("404: Route not found");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
50
|
+
use(/* path, */ middleware) {
|
|
51
|
+
this.middlewares.push(middleware);
|
|
143
52
|
}
|
|
53
|
+
|
|
144
54
|
/**
|
|
145
|
-
*
|
|
146
|
-
* @param {
|
|
147
|
-
* @param {
|
|
55
|
+
* @method listen
|
|
56
|
+
* @param {String} port - unique id for the listener
|
|
57
|
+
* @param {Function} callback - callback function
|
|
58
|
+
* @description This method is used to start listening to the routes
|
|
148
59
|
* @returns {void}
|
|
149
|
-
*
|
|
150
|
-
* @description used by start() to handle errors.
|
|
60
|
+
*
|
|
151
61
|
*/
|
|
152
62
|
|
|
153
|
-
|
|
154
|
-
if
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
63
|
+
listen(port, callback) {
|
|
64
|
+
if(!port){
|
|
65
|
+
port = Math.random().toString(36).substring(7);
|
|
66
|
+
}
|
|
67
|
+
this.listeners.push(port);
|
|
68
|
+
callback();
|
|
69
|
+
if (this.listeners.length === 1) {
|
|
70
|
+
this.handleRoute(window.location.hash);
|
|
71
|
+
}else{
|
|
72
|
+
this.listeners.pop();
|
|
73
|
+
}
|
|
74
|
+
if (callback) {
|
|
75
|
+
callback();
|
|
76
|
+
}
|
|
77
|
+
window.onhashchange = () => {
|
|
78
|
+
this.handleRoute(window.location.hash);
|
|
158
79
|
}
|
|
159
80
|
}
|
|
160
81
|
/**
|
|
161
|
-
* @
|
|
162
|
-
* @
|
|
163
|
-
* @param {
|
|
164
|
-
* @
|
|
165
|
-
* @
|
|
166
|
-
* @
|
|
82
|
+
* @method extractParams
|
|
83
|
+
* @description This method is used to extract parameters from the route path
|
|
84
|
+
* @param {*} routePath
|
|
85
|
+
* @param {*} hash
|
|
86
|
+
* @returns {Object} params
|
|
87
|
+
* @memberof Express
|
|
167
88
|
*/
|
|
168
|
-
get(path, callback) {
|
|
169
|
-
const paramNames = [];
|
|
170
|
-
const queryNames = [];
|
|
171
|
-
const parsedPath = path
|
|
172
|
-
.split("/")
|
|
173
|
-
.map((part) => {
|
|
174
|
-
if (part.startsWith(":")) {
|
|
175
|
-
paramNames.push(part.substring(1));
|
|
176
|
-
return "([^/]+)";
|
|
177
|
-
}
|
|
178
|
-
if (part.startsWith("*")) {
|
|
179
|
-
paramNames.push(part.substring(1));
|
|
180
|
-
return "(.*)";
|
|
181
|
-
}
|
|
182
|
-
if (part.startsWith("?")) {
|
|
183
|
-
queryNames.push(part.substring(1));
|
|
184
|
-
return "([^/]+)";
|
|
185
|
-
}
|
|
186
|
-
return part;
|
|
187
|
-
})
|
|
188
|
-
.join("/");
|
|
189
|
-
const regex = new RegExp("^" + parsedPath + "(\\?(.*))?$");
|
|
190
|
-
|
|
191
|
-
if (window.location.hash.substring(1).match(regex)) {
|
|
192
|
-
this.storedroutes.push(window.location.hash.substring(1));
|
|
193
|
-
const matches = window.location.hash.substring(1).match(regex);
|
|
194
|
-
const params = {};
|
|
195
89
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
90
|
+
extractParams(routePath, hash) {
|
|
91
|
+
const routeParts = routePath.split('/');
|
|
92
|
+
const hashParts = hash.split('/');
|
|
93
|
+
const params = {};
|
|
94
|
+
routeParts.forEach((part, index) => {
|
|
95
|
+
if (part.startsWith(':')) {
|
|
96
|
+
const paramName = part.slice(1);
|
|
97
|
+
params[paramName] = hashParts[index];
|
|
98
|
+
}else if(part.startsWith('*')){
|
|
99
|
+
// remove queries from this par
|
|
100
|
+
params[0] = hashParts.slice(index).join('/').split('?')[0];
|
|
199
101
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
window.location.hash.substring(1).split("?")[1]
|
|
203
|
-
) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
const query = {};
|
|
209
|
-
|
|
210
|
-
const queryString = window.location.hash.substring(1).split("?")[1];
|
|
211
|
-
if (queryString) {
|
|
212
|
-
const queryParts = queryString.split("&");
|
|
213
|
-
for (let i = 0; i < queryParts.length; i++) {
|
|
214
|
-
const queryParam = queryParts[i].split("=");
|
|
215
|
-
query[queryParam[0]] = queryParam[1];
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* @alias req
|
|
220
|
-
* @type {Object}
|
|
221
|
-
* @property {Object} params - The params object.
|
|
222
|
-
* @returns {Object} current url params
|
|
223
|
-
*/
|
|
224
|
-
|
|
225
|
-
const req = {
|
|
226
|
-
params: params,
|
|
227
|
-
query: query,
|
|
228
|
-
url: window.location.hash.substring(1),
|
|
229
|
-
method: "GET",
|
|
230
|
-
};
|
|
231
|
-
// @ts-ignore
|
|
232
|
-
window.$URL_PARAMS = params;
|
|
233
|
-
// @ts-ignore
|
|
234
|
-
window.$URL_QUERY = query;
|
|
235
|
-
// @ts-ignore
|
|
236
|
-
window.$CURRENT_URL = window.location.hash.substring(1);
|
|
237
|
-
/**
|
|
238
|
-
* @alias render
|
|
239
|
-
* @param {*} selector
|
|
240
|
-
* @param {*} data
|
|
241
|
-
* @returns {void}
|
|
242
|
-
* @memberof VaderRouter
|
|
243
|
-
* @description Allows you to perform actions when the currentRoute changes.
|
|
244
|
-
*/
|
|
245
|
-
const res = {
|
|
246
|
-
return: function (data) {
|
|
247
|
-
this.hooked = false;
|
|
248
|
-
},
|
|
249
|
-
render: function (selector, data) {
|
|
250
|
-
document.querySelector(selector).innerHTML = data;
|
|
251
|
-
},
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
callback(req, res);
|
|
255
|
-
// @ts-ignore
|
|
256
|
-
return true;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
this.hooked = false;
|
|
260
|
-
return false;
|
|
102
|
+
});
|
|
103
|
+
return params;
|
|
261
104
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
105
|
+
extractQueryParams(hash){
|
|
106
|
+
|
|
107
|
+
const queryParams = hash.split('?')[1];
|
|
108
|
+
if(!queryParams){
|
|
109
|
+
return {};
|
|
266
110
|
}
|
|
111
|
+
const params = {};
|
|
112
|
+
queryParams.split('&').forEach((param)=>{
|
|
113
|
+
const [key, value] = param.split('=');
|
|
114
|
+
params[key] = value;
|
|
115
|
+
})
|
|
116
|
+
return params;
|
|
267
117
|
}
|
|
118
|
+
|
|
268
119
|
/**
|
|
269
|
-
* @
|
|
270
|
-
* @param {String}
|
|
271
|
-
* @
|
|
272
|
-
* @returns {void}
|
|
273
|
-
* @memberof VaderRouter
|
|
274
|
-
* @description Allows you to set routes to be used throughout your spa.
|
|
120
|
+
* @method handleRoute
|
|
121
|
+
* @param {String} hash
|
|
122
|
+
* @description This method is used to handle the route
|
|
275
123
|
*/
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
// Get params
|
|
286
|
-
const match = window.location.hash.substring(1).match(regex);
|
|
287
|
-
|
|
288
|
-
if (match) {
|
|
289
|
-
this.storedroutes.push(window.location.hash.substring(1));
|
|
290
|
-
const matches = match.slice(1); // Extract matched groups
|
|
291
|
-
|
|
292
|
-
// Extract named params from the pattern
|
|
293
|
-
const paramNames = pattern.match(/:[^/]+/g) || [];
|
|
294
|
-
for (let i = 0; i < paramNames.length; i++) {
|
|
295
|
-
const paramName = paramNames[i].substring(1); // Remove the leading ":"
|
|
296
|
-
params[paramName] = matches[i];
|
|
124
|
+
|
|
125
|
+
handleRoute(hash) {
|
|
126
|
+
hash = hash.slice(1);
|
|
127
|
+
let status = 200;
|
|
128
|
+
let route = this.routes.find((route) => {
|
|
129
|
+
|
|
130
|
+
if (route.path === hash) {
|
|
131
|
+
return true;
|
|
297
132
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if
|
|
303
|
-
|
|
304
|
-
for (let i = 0; i < queryParts.length; i++) {
|
|
305
|
-
const queryParam = queryParts[i].split("=");
|
|
306
|
-
query[queryParam[0]] = queryParam[1];
|
|
307
|
-
}
|
|
133
|
+
const routePathParts = route.path.split('/');
|
|
134
|
+
const hashParts = hash.split('/');
|
|
135
|
+
if (routePathParts.length !== hashParts.length) {
|
|
136
|
+
return false;
|
|
137
|
+
}else if(routePathParts[routePathParts.length-1].startsWith('*')){
|
|
138
|
+
return true;
|
|
308
139
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// @ts-ignore
|
|
313
|
-
window.$URL_QUERY = query;
|
|
314
|
-
//@ts-ignore
|
|
315
|
-
if (callback) {
|
|
316
|
-
this.routes[pattern] = callback;
|
|
317
|
-
} else {
|
|
318
|
-
this.routes[pattern] = true;
|
|
319
|
-
this.storedroutes.push(window.location.hash.substring(1));
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
140
|
+
const params = this.extractParams( route.path, hash);
|
|
141
|
+
return Object.keys(params).length > 0;
|
|
142
|
+
});
|
|
323
143
|
|
|
144
|
+
if (!route) {
|
|
145
|
+
route = this.routes.find((route) => {
|
|
146
|
+
|
|
147
|
+
if(route.path === '/404'){
|
|
148
|
+
return true;
|
|
149
|
+
}else{
|
|
150
|
+
window.location.hash = this.basePath
|
|
151
|
+
}
|
|
152
|
+
});
|
|
324
153
|
|
|
325
|
-
|
|
326
|
-
// await dom to be done make sure no new elements are added
|
|
327
|
-
if (
|
|
328
|
-
document.readyState === "complete" ||
|
|
329
|
-
// @ts-ignore
|
|
330
|
-
document.readyState === "loaded" ||
|
|
331
|
-
document.readyState === "interactive"
|
|
332
|
-
) {
|
|
333
|
-
callback();
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* @alias on
|
|
339
|
-
* @param {String} path
|
|
340
|
-
* @param {Function} callback
|
|
341
|
-
* @returns {void}
|
|
342
|
-
* @memberof VaderRouter
|
|
343
|
-
* @description Allows you to perform actions when the currentRoute changes.
|
|
344
|
-
*
|
|
345
|
-
*/
|
|
346
|
-
on(path, callback) {
|
|
347
|
-
window.addEventListener("hashchange", () => {
|
|
348
|
-
const paramNames = [];
|
|
349
|
-
const queryNames = [];
|
|
350
|
-
const parsedPath = path
|
|
351
|
-
.split("/")
|
|
352
|
-
.map((part) => {
|
|
353
|
-
if (part.startsWith(":")) {
|
|
354
|
-
paramNames.push(part.substring(1));
|
|
355
|
-
return "([^/]+)";
|
|
356
|
-
}
|
|
357
|
-
if (part.startsWith("*")) {
|
|
358
|
-
paramNames.push(part.substring(1));
|
|
359
|
-
return "(.*)";
|
|
360
|
-
}
|
|
361
|
-
if (part.startsWith("?")) {
|
|
362
|
-
queryNames.push(part.substring(1));
|
|
363
|
-
return "([^/]+)";
|
|
364
|
-
}
|
|
365
|
-
return part;
|
|
366
|
-
})
|
|
367
|
-
.join("/");
|
|
368
|
-
const regex = new RegExp("^" + parsedPath + "(\\?(.*))?$");
|
|
369
|
-
|
|
370
|
-
let hash = window.location.hash.split("#")[1]
|
|
371
|
-
? window.location.hash.split("#")[1]
|
|
372
|
-
: window.location.hash;
|
|
154
|
+
route ? status = 200 :
|
|
373
155
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
basePath = hash.split("/")[0] + "/" + hash.split("/")[1];
|
|
377
|
-
} else {
|
|
378
|
-
basePath = hash[0];
|
|
379
|
-
}
|
|
380
|
-
const route = basePath;
|
|
381
|
-
this.currentUrl = route;
|
|
382
|
-
// @ts-ignore
|
|
383
|
-
window.$CURRENT_URL = route;
|
|
384
|
-
// @ts-ignore
|
|
385
|
-
window.$URL_PARAMS = {};
|
|
386
|
-
if (
|
|
387
|
-
window.location.hash.substring(1).match(regex) &&
|
|
388
|
-
// @ts-ignore
|
|
389
|
-
this.routes[window.$CURRENT_URL]
|
|
390
|
-
) {
|
|
391
|
-
this.storedroutes.push(window.location.hash.substring(1));
|
|
392
|
-
const matches = window.location.hash.substring(1).match(regex);
|
|
393
|
-
const params = {};
|
|
156
|
+
status = 404;
|
|
157
|
+
}
|
|
394
158
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
159
|
+
|
|
160
|
+
const queryParams = this.extractQueryParams(hash);
|
|
161
|
+
const params = route && route.path ? this.extractParams(route.path, hash) : {};
|
|
162
|
+
const req = {
|
|
163
|
+
headers: {},
|
|
164
|
+
params: params,
|
|
165
|
+
query: queryParams,
|
|
166
|
+
path: hash,
|
|
167
|
+
method: route ? route.method : 'get',
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
window.$CURRENT_URL = req.path
|
|
172
|
+
|
|
173
|
+
// @ts-ignore
|
|
174
|
+
window.$FULL_URL = window.location.href.replace('#', '')
|
|
175
|
+
|
|
176
|
+
const res = {
|
|
177
|
+
status: status,
|
|
178
|
+
/**
|
|
179
|
+
* @method log
|
|
180
|
+
* @param {String} type
|
|
181
|
+
* @description This method is used to log the request and response
|
|
182
|
+
*/
|
|
183
|
+
log: (type) => {
|
|
184
|
+
if(type === undefined){
|
|
185
|
+
console.log(`${req.path} ${req.method} ${res.status} ${req.timestamp}`);
|
|
186
|
+
}else{
|
|
187
|
+
console.table({
|
|
188
|
+
'Request Path': req.path,
|
|
189
|
+
'Request Method': route.method,
|
|
190
|
+
'Response Status': res.status,
|
|
191
|
+
'Request Timestamp': req.timestamp,
|
|
192
|
+
});
|
|
398
193
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
return false;
|
|
194
|
+
},
|
|
195
|
+
send: (selector, data) => {
|
|
196
|
+
if(typeof selector === 'string'){
|
|
197
|
+
// @ts-ignore
|
|
198
|
+
document.querySelector(selector).innerHTML = data;
|
|
199
|
+
}else if(typeof selector === 'number'){
|
|
200
|
+
res.status = selector;
|
|
201
|
+
}else if(typeof selector === 'object'){
|
|
202
|
+
res.status = selector.status;
|
|
409
203
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
204
|
+
},
|
|
205
|
+
json: (selector, data) => {
|
|
206
|
+
|
|
207
|
+
if(typeof selector === 'string'){
|
|
208
|
+
// @ts-ignore
|
|
209
|
+
let obj = document.createElement('object');
|
|
210
|
+
// data url
|
|
211
|
+
obj.data = URL.createObjectURL(new Blob([JSON.stringify(data)], {type: 'application/json'}));
|
|
212
|
+
// @ts-ignore
|
|
213
|
+
document.querySelector(selector).appendChild(obj);
|
|
214
|
+
}else{
|
|
215
|
+
throw new Error('Selector must be a string');
|
|
419
216
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
method: "POST",
|
|
425
|
-
};
|
|
426
|
-
const res = {
|
|
427
|
-
return: function (data) {
|
|
428
|
-
this.hooked = false;
|
|
429
|
-
},
|
|
430
|
-
/**
|
|
431
|
-
* @alias send
|
|
432
|
-
* @param {String} selector
|
|
433
|
-
* @param {String} data
|
|
434
|
-
* @returns {void}
|
|
435
|
-
* @memberof VaderRouter
|
|
436
|
-
* @description Allows you to perform actions when the currentRoute changes.
|
|
437
|
-
* @example
|
|
438
|
-
* res.send('#root', '<h1>Hello World</h1>');
|
|
439
|
-
* */
|
|
440
|
-
send: function (selector, data) {
|
|
441
|
-
//@ts-ignore
|
|
442
|
-
document.querySelector(selector).innerHTML = data;
|
|
443
|
-
},
|
|
444
|
-
/**
|
|
445
|
-
* @alias render
|
|
446
|
-
* @param {String} selector
|
|
447
|
-
* @param {String} data
|
|
448
|
-
* @returns {void}
|
|
449
|
-
* @memberof VaderRouter
|
|
450
|
-
* @description Allows you to perform actions when the currentRoute changes.
|
|
451
|
-
*/
|
|
452
|
-
render: function (selector, data) {
|
|
453
|
-
//@ts-ignore
|
|
454
|
-
document.querySelector(selector).innerHTML = data;
|
|
455
|
-
},
|
|
456
|
-
};
|
|
457
|
-
// @ts-ignore
|
|
458
|
-
window.$URL_QUERY = query;
|
|
459
|
-
// @ts-ignore
|
|
460
|
-
window.$URL_PARAMS = params;
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* @alias callback
|
|
464
|
-
* @type {function}
|
|
465
|
-
* @param {Object} req - The request object.
|
|
466
|
-
* @returns {void}
|
|
467
|
-
* @memberof VaderRouter
|
|
468
|
-
* @description Allows you to perform actions when the currentRoute changes.
|
|
469
|
-
*/
|
|
470
|
-
callback(req, res);
|
|
471
|
-
}else{
|
|
472
|
-
console.log('no route')
|
|
473
|
-
}
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
this.middlewares.forEach((middleware) => {
|
|
220
|
+
middleware(req, res);
|
|
474
221
|
});
|
|
222
|
+
|
|
223
|
+
route ? route.handler(req, res) : null;
|
|
224
|
+
|
|
475
225
|
}
|
|
226
|
+
|
|
476
227
|
}
|
|
477
|
-
|
|
228
|
+
|
|
229
|
+
export default VaderRouter;
|
|
230
|
+
|
|
231
|
+
|