rjweb-server
Version:
Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS
107 lines (106 loc) • 3.71 kB
JavaScript
import parseURL from "../functions/parseURL";
import { isRegExp } from "util/types";
export default class Route {
/**
* Create a new Route
* @since 9.0.0
*/ constructor(type, urlMethod, path, data) {
this.type = type;
this.urlMethod = urlMethod;
/**
* The Validators of this Route
* @since 9.0.0
*/ this.validators = [];
/**
* The Ratelimit of this Route
* @since 9.0.0
*/ this.ratelimit = null;
/**
* The OpenAPI Schema of this Route
* @since 9.0.0
*/ this.openApi = {};
this.data = data;
if (isRegExp(path)) {
this.urlData = {
type: 'regexp',
value: path,
prefix: '/',
segments: [{
raw: '',
paramsRegExp: new RegExp(''),
params: []
}, {
raw: '',
paramsRegExp: new RegExp(''),
params: []
}]
};
}
else if (typeof path === 'string') {
const segments = parseURL(path).path.split('/');
this.urlData = {
type: 'normal',
value: segments.join('/'),
segments: []
};
for (const segment of segments) {
this.urlData.segments.push({
raw: segment,
paramsRegExp: new RegExp(segment.replace(/{([^}]+)}/g, '(.*\\S)')),
params: (segment.match(/{([^}]+)}/g) ?? []).map((m) => m.slice(1, -1))
});
}
}
else {
throw new Error(`Invalid Path (${typeof path})`);
}
}
/**
* Test the Path against the Request Path
* @warn NOT FOR STATIC ROUTES
* @since 9.0.0
*/ matches(method, collection, requestPath, requestPathSplit) {
if (this.urlMethod !== method)
return false;
if (this.urlData.type === 'normal' && this.urlData.segments.length !== requestPathSplit.length)
return false;
if (this.urlData.type === 'regexp' && !this.urlData.value.test(parseURL(requestPath.slice(this.urlData.prefix.length)).path))
return false;
if (this.urlData.type === 'regexp')
return true;
let found = false;
const pathParams = {};
for (let i = 1; i < requestPathSplit.length; i++) {
const reqSegment = requestPathSplit[i], segment = this.urlData.segments[i];
if (!segment) {
if (this.urlData.type === 'normal')
break;
found = true;
break;
}
if (segment.params.length === 0) {
if (segment.raw === reqSegment) {
if (i === requestPathSplit.length - 1 && this.urlData.type === 'normal') {
found = true;
break;
}
}
else
break;
}
const params = reqSegment.match(segment.paramsRegExp);
if (params) {
if (i === requestPathSplit.length - 1)
found = true;
for (let i = 0; i < segment.params.length; i++) {
pathParams[segment.params[i]] = params[i + 1];
}
}
else
break;
}
if (found)
Object.entries(pathParams).forEach(([key, value]) => collection.set(key, value));
return found;
}
}