lib/api.js

1.
var json = require("./json");
2.
var policies = require("./api/policies");
3.

			
4.
/**
5.
 * This is the main api class. With this class you can add/manage api routes, manage policies and 
6.
 * change the api folders/urls. The api is used to easily obtain data from the server while also 
7.
 * respecting things like security by using policies. The response for the api works in a RESTful 
8.
 * manner and can be managed using the assigned JSON class object.
9.
 * @class api
10.
 */
11.
class api {
12.
	constructor(cerus) {
13.
		this._cerus = cerus;
14.
		this._policies = new policies(cerus);
15.
		this._folders = new folders();
16.
		this._urls = new urls();
17.
	}
18.

			
19.
	/**
20.
	 * This function will return the folders class for this module. With this class you can change 
21.
	 * the folders which are used to store the api classes and policy classes.
22.
	 * @summary Returns the folders class.
23.
	 * @return {Class} The api.folders class.
24.
	 * @function folders
25.
	 */
26.
	folders() {
27.
		return this._folders;
28.
	}
29.

			
30.
	/**
31.
	 * This function will return the urls class for this module. This class is used to store the 
32.
	 * url for the api.
33.
	 * @summary Returns the urls class.
34.
	 * @return {Class} The api.urls class.
35.
	 * @function urls
36.
	 */
37.
	urls() {
38.
		return this._urls;
39.
	}
40.

			
41.
	/**
42.
	 * With the class this function returns you can manage the policies for the api. The policies 
43.
	 * are used as middleware before the api function is called. These policies are used for things
44.
	 * like security and to check if the client is logged in. You can easily add policies using the
45.
	 * {@link api.policy} function.
46.
	 * @summary Returns the policies class.
47.
	 * @return {Class} The policies class.
48.
	 * @function policies
49.
	 */
50.
	policies() {
51.
		return this._policies;
52.
	}
53.

			
54.
	/**
55.
	 * This function is used for a shortcut to add a new policy. You can specify the name with the 
56.
	 * inserted parameter. This function will return a promise that will be called on the 'policy' 
57.
	 * event when the policy is used. The api request will be stopped when the policy has emitted
58.
	 * a response. The 'policy' event will e called with the request, json response and cerus as 
59.
	 * parameters.
60.
	 * @summary Creates a new policy.
61.
	 * @param {String} name The name of the new policy.
62.
	 * @return {Promise} This function will return a promise.
63.
	 * @function policy
64.
	 */
65.
	policy(name) {
66.
		return this._policies.add(name);
67.
	}
68.

			
69.
	/**
70.
	 * With this function you can load an api or policy class. The api classes should contain the 
71.
	 * functions used for routing api requests. The policy classes should contain the policies. To
72.
	 * load the class it will use the general require function. The folders that should contain the
73.
	 * classes can be changed using the {@link api.folders} function.
74.
	 * @summary Loads an api or policy file.
75.
	 * @param {String} name The name of the class to load.
76.
	 * @param {String} type The type of class to load.
77.
	 * @return {Class} This function will return the loaded class.
78.
	 * @function load
79.
	 */
80.
	load(name, type = "api") {
81.
		const _name = name.replace(/\\/g,"/");
82.

			
83.
		switch(type) {
84.
			case "policy":
85.
				return require(`${this._cerus.root()}${this._folders._policies}/${_name}`);
86.

			
87.
			case "api":
88.
			default:
89.
				return require(`${this._cerus.root()}${this._folders._api}/${_name}`);
90.
		}
91.
	}
92.

			
93.
	/**
94.
	 * This function is used to create a new api route. An api is a way to easily obtain data from 
95.
	 * you server that you need from your client. Apis can also be used to trigger actions on the 
96.
	 * server. This can be things like logging users in. For more information about api you can 
97.
	 * read the tutorial about it. You can set the url of the api with the url parameter. You can 
98.
	 * also add policies to your api route. Policies are functions that check if the client is 
99.
	 * allowed to continue on to the api function. You can manage policies using policies using the
100.
	 * policy class and there also is a tutorial about policies.
101.
	 * @example
102.
	 * cerus.api().add("test")
103.
	 * .then(function(req, res) {
104.
	 *   res.emit();
105.
	 * });
106.
	 * // -> routes the api route to "/api/test"
107.
	 * @emits request When the api route has been requested. With the request class as first 
108.
	 * parameter, the json class as second parameter and the cerus object as last parameter.
109.
	 * @summary Creates a new api route.
110.
	 * @param {String} url The url the new api will route to.
111.
	 * @param {Array|String} (policies = []) The policies for this api route.
112.
	 * @return {Promise} This function will return a promise.
113.
	 * @function add
114.
	 */
115.
	add(url, policies = []) {
116.
		const _policies = policies instanceof Array ? policies : [policies];
117.
		
118.
		return this._cerus.promise(event => {
119.
			this._cerus.router().route(this._clean_url(url))
120.
			.then((req, res) => {
121.
				const _json = new json(req, res);
122.

			
123.
				for(let policy of _policies) {
124.
					if(!this._policies.has(policy)) continue;
125.

			
126.
					this._policies.get(policy)("policy", req, _json, this._cerus);
127.

			
128.
					if(_json.emitted()) return;
129.
				}
130.

			
131.
				event("request", req, _json, this._cerus);
132.
			});
133.
		});
134.
	}
135.

			
136.
	/**
137.
	 * With this function you can remove an api route. It basically directly removes it from the 
138.
	 * router. 
139.
	 * @example
140.
	 * cerus.api().remove("/");
141.
	 * // -> this removes the "/" api route
142.
	 * @summary Removes the specified api route.
143.
	 * @param {String} url The url of the api route to remove.
144.
	 * @function remove
145.
	 */
146.
	remove(url) {
147.
		this._cerus.router().remove(this._clean_url(url));
148.
	}
149.

			
150.
	_clean_url(url) {
151.
		if(url.startsWith("/")) return `/${this._urls._api}${url}`;
152.

			
153.
		return `/${this._urls._api}/${url}`;
154.
	}
155.
}
156.

			
157.
module.exports = api;
158.

			
159.
/**
160.
 * This is the folders class. With this class you can change the folders that should be used to 
161.
 * store your policy and api classes.
162.
 * @class api.folders
163.
 */
164.
class folders {
165.
	constructor() {
166.
		this._policies = "policies";
167.
		this._api = "api";
168.
	}
169.

			
170.
	/**
171.
	 * This function is the getter and setter for the policies folder. This is the folder where the
172.
	 * policy classes should be put in. By default this path is "policies". This path is also fixed
173.
	 * (\\\\ is changed to /) before being used to support all the platforms.
174.
	 * @summary The getter/setter for the policy folder.
175.
	 * @param {String} (path) The new path for the policies folder.
176.
	 * @return {String} The path for the policies folder.
177.
	 * @function policies
178.
	 */
179.
	policies(path) {
180.
		if(typeof path !== "string") return this._policies;
181.
		
182.
		return this._policies = path.replace(/\\/g,"/");
183.
	}
184.

			
185.
	/**
186.
	 * This function is the getter and setter for the api folder. This is the folder where the api 
187.
	 * classes should be put in. This path is also fixed (\\\\ is changed to /) before being used 
188.
	 * to support all the platforms.
189.
	 * @summary The getter/setter for the api folder.
190.
	 * @param {String} (path) The new path for the api folder.
191.
	 * @return {String} The path for the api folder.
192.
	 * @function api
193.
	 */
194.
	api(path) {
195.
		if(typeof path !== "string") return this._api;
196.

			
197.
		return this._api = path.replace(/\\/g,"/");
198.
	}
199.
}
200.

			
201.
/**
202.
 * This is the urls class. With this class you can change the url that is used as prefix for all 
203.
 * the api routes.
204.
 * @class api.urls
205.
 * @id api.urls
206.
 */
207.
class urls {
208.
	constructor() {
209.
		this._api = "api";
210.
	}
211.

			
212.
	/**
213.
	 * This is the getter and setter for the api url. This url is used when a new api route is 
214.
	 * created. 
215.
	 * @summary The getter/setter for the api url.
216.
	 * @param {String} (url) The new url for the api routes.
217.
	 * @return {[type]} The urls for the api routes.
218.
	 * @function api
219.
	 */
220.
	api(url) {
221.
		if(typeof url !== "string") return this._api;
222.
			
223.
		return this._api = url;
224.
	}
225.
}
226.