mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-21 16:06:16 -04:00
Multiple REST endpoints (one per version)
This commit is contained in:
parent
8f279a6710
commit
a5987285e0
1 changed files with 123 additions and 107 deletions
|
@ -1,13 +1,9 @@
|
||||||
var log4js = require('log4js');
|
var log4js = require('log4js');
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var swagger = require("swagger-node-express");
|
|
||||||
var apiHandler = require('../../handler/APIHandler');
|
var apiHandler = require('../../handler/APIHandler');
|
||||||
var apiCaller = require('./apicalls').apiCaller;
|
var apiCaller = require('./apicalls').apiCaller;
|
||||||
var settings = require("../../utils/Settings");
|
var settings = require("../../utils/Settings");
|
||||||
|
|
||||||
var versions = Object.keys(apiHandler.version)
|
|
||||||
var version = versions[versions.length - 1];
|
|
||||||
|
|
||||||
var swaggerModels = {
|
var swaggerModels = {
|
||||||
'models': {
|
'models': {
|
||||||
'SessionInfo' : {
|
'SessionInfo' : {
|
||||||
|
@ -83,14 +79,14 @@ var API = {
|
||||||
|
|
||||||
// Group
|
// Group
|
||||||
"group": {
|
"group": {
|
||||||
"create" : {
|
"create" : {
|
||||||
"func" : "createGroup",
|
"func" : "createGroup",
|
||||||
"description": "creates a new group",
|
"description": "creates a new group",
|
||||||
"response": {"groupID":{"type":"string"}}
|
"response": {"groupID":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"createIfNotExistsFor" : {
|
"createIfNotExistsFor" : {
|
||||||
"func": "createGroupIfNotExistsFor",
|
"func": "createGroupIfNotExistsFor",
|
||||||
"description": "this functions helps you to map your application group ids to etherpad lite group ids",
|
"description": "this functions helps you to map your application group ids to etherpad lite group ids",
|
||||||
"response": {"groupID":{"type":"string"}}
|
"response": {"groupID":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"delete" : {
|
"delete" : {
|
||||||
|
@ -98,23 +94,23 @@ var API = {
|
||||||
"description": "deletes a group"
|
"description": "deletes a group"
|
||||||
},
|
},
|
||||||
"listPads" : {
|
"listPads" : {
|
||||||
"func": "listPads",
|
"func": "listPads",
|
||||||
"description": "returns all pads of this group",
|
"description": "returns all pads of this group",
|
||||||
"response": {"padIDs":{"type":"List", "items":{"type":"string"}}}
|
"response": {"padIDs":{"type":"List", "items":{"type":"string"}}}
|
||||||
},
|
},
|
||||||
"createPad" : {
|
"createPad" : {
|
||||||
"func": "createGroupPad",
|
"func": "createGroupPad",
|
||||||
"description": "creates a new pad in this group"
|
"description": "creates a new pad in this group"
|
||||||
},
|
},
|
||||||
"listSessions": {
|
"listSessions": {
|
||||||
"func": "listSessionsOfGroup",
|
"func": "listSessionsOfGroup",
|
||||||
"responseProcessor": sessionListResponseProcessor,
|
"responseProcessor": sessionListResponseProcessor,
|
||||||
"description": "",
|
"description": "",
|
||||||
"response": {"sessions":{"type":"List", "items":{"type":"SessionInfo"}}}
|
"response": {"sessions":{"type":"List", "items":{"type":"SessionInfo"}}}
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"func": "listAllGroups",
|
"func": "listAllGroups",
|
||||||
"description": "",
|
"description": "",
|
||||||
"response": {"groupIDs":{"type":"List", "items":{"type":"string"}}}
|
"response": {"groupIDs":{"type":"List", "items":{"type":"string"}}}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -122,24 +118,24 @@ var API = {
|
||||||
// Author
|
// Author
|
||||||
"author": {
|
"author": {
|
||||||
"create" : {
|
"create" : {
|
||||||
"func" : "createAuthor",
|
"func" : "createAuthor",
|
||||||
"description": "creates a new author",
|
"description": "creates a new author",
|
||||||
"response": {"authorID":{"type":"string"}}
|
"response": {"authorID":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"createIfNotExistsFor": {
|
"createIfNotExistsFor": {
|
||||||
"func": "createAuthorIfNotExistsFor",
|
"func": "createAuthorIfNotExistsFor",
|
||||||
"description": "this functions helps you to map your application author ids to etherpad lite author ids",
|
"description": "this functions helps you to map your application author ids to etherpad lite author ids",
|
||||||
"response": {"authorID":{"type":"string"}}
|
"response": {"authorID":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"listPads": {
|
"listPads": {
|
||||||
"func": "listPadsOfAuthor",
|
"func": "listPadsOfAuthor",
|
||||||
"description": "returns an array of all pads this author contributed to",
|
"description": "returns an array of all pads this author contributed to",
|
||||||
"response": {"padIDs":{"type":"List", "items":{"type":"string"}}}
|
"response": {"padIDs":{"type":"List", "items":{"type":"string"}}}
|
||||||
},
|
},
|
||||||
"listSessions": {
|
"listSessions": {
|
||||||
"func": "listSessionsOfAuthor",
|
"func": "listSessionsOfAuthor",
|
||||||
"responseProcessor": sessionListResponseProcessor,
|
"responseProcessor": sessionListResponseProcessor,
|
||||||
"description": "returns all sessions of an author",
|
"description": "returns all sessions of an author",
|
||||||
"response": {"sessions":{"type":"List", "items":{"type":"SessionInfo"}}}
|
"response": {"sessions":{"type":"List", "items":{"type":"SessionInfo"}}}
|
||||||
},
|
},
|
||||||
// We need an operation that return a UserInfo so it can be picked up by the codegen :(
|
// We need an operation that return a UserInfo so it can be picked up by the codegen :(
|
||||||
|
@ -158,7 +154,7 @@ var API = {
|
||||||
"session": {
|
"session": {
|
||||||
"create" : {
|
"create" : {
|
||||||
"func": "createSession",
|
"func": "createSession",
|
||||||
"description": "creates a new session. validUntil is an unix timestamp in seconds",
|
"description": "creates a new session. validUntil is an unix timestamp in seconds",
|
||||||
"response": {"sessionID":{"type":"string"}}
|
"response": {"sessionID":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"delete" : {
|
"delete" : {
|
||||||
|
@ -167,7 +163,7 @@ var API = {
|
||||||
},
|
},
|
||||||
// We need an operation that returns a SessionInfo so it can be picked up by the codegen :(
|
// We need an operation that returns a SessionInfo so it can be picked up by the codegen :(
|
||||||
"info": {
|
"info": {
|
||||||
"func": "getSessionInfo",
|
"func": "getSessionInfo",
|
||||||
"description": "returns informations about a session",
|
"description": "returns informations about a session",
|
||||||
"responseProcessor": function(response) {
|
"responseProcessor": function(response) {
|
||||||
// move this to info
|
// move this to info
|
||||||
|
@ -177,22 +173,22 @@ var API = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {"info":{"type":"SessionInfo"}}
|
"response": {"info":{"type":"SessionInfo"}}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
"pad": {
|
"pad": {
|
||||||
"listAll" : {
|
"listAll" : {
|
||||||
"func": "listAllPads",
|
"func": "listAllPads",
|
||||||
"description": "list all the pads",
|
"description": "list all the pads",
|
||||||
"response": {"padIDs":{"type":"List", "items": {"type" : "string"}}}
|
"response": {"padIDs":{"type":"List", "items": {"type" : "string"}}}
|
||||||
},
|
},
|
||||||
"createDiffHTML" : {
|
"createDiffHTML" : {
|
||||||
"func" : "createDiffHTML",
|
"func" : "createDiffHTML",
|
||||||
"description": "",
|
"description": "",
|
||||||
"response": {}
|
"response": {}
|
||||||
},
|
},
|
||||||
"create" : {
|
"create" : {
|
||||||
"func" : "createPad",
|
"func" : "createPad",
|
||||||
"description": "creates a new (non-group) pad. Note that if you need to create a group Pad, you should call createGroupPad",
|
"description": "creates a new (non-group) pad. Note that if you need to create a group Pad, you should call createGroupPad"
|
||||||
},
|
},
|
||||||
"getText" : {
|
"getText" : {
|
||||||
"func" : "getText",
|
"func" : "getText",
|
||||||
|
@ -205,7 +201,7 @@ var API = {
|
||||||
},
|
},
|
||||||
"getHTML": {
|
"getHTML": {
|
||||||
"func" : "getHTML",
|
"func" : "getHTML",
|
||||||
"description": "returns the text of a pad formatted as HTML",
|
"description": "returns the text of a pad formatted as HTML",
|
||||||
"response": {"html":{"type":"string"}}
|
"response": {"html":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"setHTML": {
|
"setHTML": {
|
||||||
|
@ -214,12 +210,12 @@ var API = {
|
||||||
},
|
},
|
||||||
"getRevisionsCount": {
|
"getRevisionsCount": {
|
||||||
"func" : "getRevisionsCount",
|
"func" : "getRevisionsCount",
|
||||||
"description": "returns the number of revisions of this pad",
|
"description": "returns the number of revisions of this pad",
|
||||||
"response": {"revisions":{"type":"long"}}
|
"response": {"revisions":{"type":"long"}}
|
||||||
},
|
},
|
||||||
"getLastEdited": {
|
"getLastEdited": {
|
||||||
"func" : "getLastEdited",
|
"func" : "getLastEdited",
|
||||||
"description": "returns the timestamp of the last revision of the pad",
|
"description": "returns the timestamp of the last revision of the pad",
|
||||||
"response": {"lastEdited":{"type":"long"}}
|
"response": {"lastEdited":{"type":"long"}}
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
|
@ -228,16 +224,16 @@ var API = {
|
||||||
},
|
},
|
||||||
"getReadOnlyID": {
|
"getReadOnlyID": {
|
||||||
"func" : "getReadOnlyID",
|
"func" : "getReadOnlyID",
|
||||||
"description": "returns the read only link of a pad",
|
"description": "returns the read only link of a pad",
|
||||||
"response": {"readOnlyID":{"type":"string"}}
|
"response": {"readOnlyID":{"type":"string"}}
|
||||||
},
|
},
|
||||||
"setPublicStatus": {
|
"setPublicStatus": {
|
||||||
"func": "setPublicStatus",
|
"func": "setPublicStatus",
|
||||||
"description": "sets a boolean for the public status of a pad"
|
"description": "sets a boolean for the public status of a pad"
|
||||||
},
|
},
|
||||||
"getPublicStatus": {
|
"getPublicStatus": {
|
||||||
"func": "getPublicStatus",
|
"func": "getPublicStatus",
|
||||||
"description": "return true of false",
|
"description": "return true of false",
|
||||||
"response": {"publicStatus":{"type":"boolean"}}
|
"response": {"publicStatus":{"type":"boolean"}}
|
||||||
},
|
},
|
||||||
"setPassword": {
|
"setPassword": {
|
||||||
|
@ -245,27 +241,27 @@ var API = {
|
||||||
"description": "returns ok or a error message"
|
"description": "returns ok or a error message"
|
||||||
},
|
},
|
||||||
"isPasswordProtected": {
|
"isPasswordProtected": {
|
||||||
"func": "isPasswordProtected",
|
"func": "isPasswordProtected",
|
||||||
"description": "returns true or false",
|
"description": "returns true or false",
|
||||||
"response": {"passwordProtection":{"type":"boolean"}}
|
"response": {"passwordProtection":{"type":"boolean"}}
|
||||||
},
|
},
|
||||||
"authors": {
|
"authors": {
|
||||||
"func": "listAuthorsOfPad",
|
"func": "listAuthorsOfPad",
|
||||||
"description": "returns an array of authors who contributed to this pad",
|
"description": "returns an array of authors who contributed to this pad",
|
||||||
"response": {"authorIDs":{"type":"List", "items":{"type" : "string"}}}
|
"response": {"authorIDs":{"type":"List", "items":{"type" : "string"}}}
|
||||||
},
|
},
|
||||||
"usersCount": {
|
"usersCount": {
|
||||||
"func": "padUsersCount",
|
"func": "padUsersCount",
|
||||||
"description": "returns the number of user that are currently editing this pad",
|
"description": "returns the number of user that are currently editing this pad",
|
||||||
"response": {"padUsersCount":{"type": "long"}}
|
"response": {"padUsersCount":{"type": "long"}}
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"func": "padUsers",
|
"func": "padUsers",
|
||||||
"description": "returns the list of users that are currently editing this pad",
|
"description": "returns the list of users that are currently editing this pad",
|
||||||
"response": {"padUsers":{"type":"List", "items":{"type": "UserInfo"}}}
|
"response": {"padUsers":{"type":"List", "items":{"type": "UserInfo"}}}
|
||||||
},
|
},
|
||||||
"sendClientsMessage": {
|
"sendClientsMessage": {
|
||||||
"func": "sendClientsMessage",
|
"func": "sendClientsMessage",
|
||||||
"description": "sends a custom message of type msg to the pad"
|
"description": "sends a custom message of type msg to the pad"
|
||||||
},
|
},
|
||||||
"checkToken" : {
|
"checkToken" : {
|
||||||
|
@ -273,13 +269,13 @@ var API = {
|
||||||
"description": "returns ok when the current api token is valid"
|
"description": "returns ok when the current api token is valid"
|
||||||
},
|
},
|
||||||
"getChatHistory": {
|
"getChatHistory": {
|
||||||
"func": "getChatHistory",
|
"func": "getChatHistory",
|
||||||
"description": "returns the chat history",
|
"description": "returns the chat history",
|
||||||
"response": {"messages":{"type":"List", "items": {"type" : "Message"}}}
|
"response": {"messages":{"type":"List", "items": {"type" : "Message"}}}
|
||||||
},
|
},
|
||||||
// We need an operation that returns a Message so it can be picked up by the codegen :(
|
// We need an operation that returns a Message so it can be picked up by the codegen :(
|
||||||
"getChatHead": {
|
"getChatHead": {
|
||||||
"func": "getChatHead",
|
"func": "getChatHead",
|
||||||
"description": "returns the chatHead (chat-message) of the pad",
|
"description": "returns the chatHead (chat-message) of the pad",
|
||||||
"responseProcessor": function(response) {
|
"responseProcessor": function(response) {
|
||||||
// move this to info
|
// move this to info
|
||||||
|
@ -334,82 +330,102 @@ for (var resource in API) {
|
||||||
// Store the response model id
|
// Store the response model id
|
||||||
API[resource][func]["responseClass"] = responseModelId;
|
API[resource][func]["responseClass"] = responseModelId;
|
||||||
|
|
||||||
// get the api function
|
|
||||||
var apiFunc = apiHandler.version[version][API[resource][func]["func"]];
|
|
||||||
|
|
||||||
// Add the api function parameters
|
|
||||||
API[resource][func]["params"] = apiFunc.map( function(param) {
|
|
||||||
return swagger.queryParam(param, param, "string");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function newSwagger() {
|
||||||
|
var swagger_module = require.resolve("swagger-node-express");
|
||||||
|
if (require.cache[swagger_module]) {
|
||||||
|
// delete the child modules from cache
|
||||||
|
require.cache[swagger_module].children.forEach(function(m) {delete require.cache[m.id];});
|
||||||
|
// delete the module from cache
|
||||||
|
delete require.cache[swagger_module];
|
||||||
|
}
|
||||||
|
return require("swagger-node-express");
|
||||||
|
}
|
||||||
|
|
||||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
|
||||||
// Let's put this under /rest for now
|
for (var version in apiHandler.version) {
|
||||||
var subpath = express();
|
|
||||||
|
var swagger = newSwagger();
|
||||||
|
var basePath = "/rest/" + version;
|
||||||
|
|
||||||
args.app.use(express.bodyParser());
|
// Let's put this under /rest for now
|
||||||
args.app.use("/rest", subpath);
|
var subpath = express();
|
||||||
|
|
||||||
swagger.setAppHandler(subpath);
|
args.app.use(express.bodyParser());
|
||||||
|
args.app.use(basePath, subpath);
|
||||||
|
|
||||||
swagger.addModels(swaggerModels);
|
swagger.setAppHandler(subpath);
|
||||||
|
|
||||||
for (var resource in API) {
|
swagger.addModels(swaggerModels);
|
||||||
|
|
||||||
for (var funcName in API[resource]) {
|
for (var resource in API) {
|
||||||
var func = API[resource][funcName];
|
|
||||||
|
|
||||||
var swaggerFunc = {
|
for (var funcName in API[resource]) {
|
||||||
'spec': {
|
var func = API[resource][funcName];
|
||||||
"description" : func["description"],
|
|
||||||
"path" : "/" + resource + "/" + funcName,
|
|
||||||
"summary" : funcName,
|
|
||||||
"nickname" : funcName,
|
|
||||||
"method": "GET",
|
|
||||||
"params" : func["params"],
|
|
||||||
"responseClass" : func["responseClass"]
|
|
||||||
},
|
|
||||||
'action': (function(func, responseProcessor) {
|
|
||||||
return function (req,res) {
|
|
||||||
req.params.version = version;
|
|
||||||
req.params.func = func; // call the api function
|
|
||||||
|
|
||||||
//wrap the send function so we can process the response
|
// get the api function
|
||||||
res.__swagger_send = res.send;
|
var apiFunc = apiHandler.version[version][func["func"]];
|
||||||
res.send = function (response) {
|
|
||||||
// ugly but we need to get this as json
|
// Skip this one if it does not exist in the version
|
||||||
response = JSON.parse(response);
|
if(!apiFunc) {
|
||||||
// process the response if needed
|
continue;
|
||||||
if (responseProcessor) {
|
}
|
||||||
response = responseProcessor(response);
|
|
||||||
}
|
var swaggerFunc = {
|
||||||
// Let's move everything out of "data"
|
'spec': {
|
||||||
if (response.data) {
|
"description" : func["description"],
|
||||||
for(var prop in response.data) {
|
"path" : "/" + resource + "/" + funcName,
|
||||||
response[prop] = response.data[prop];
|
"summary" : funcName,
|
||||||
delete response.data;
|
"nickname" : funcName,
|
||||||
|
"method": "GET",
|
||||||
|
"params" : apiFunc.map( function(param) {
|
||||||
|
return swagger.queryParam(param, param, "string");
|
||||||
|
}),
|
||||||
|
"responseClass" : func["responseClass"]
|
||||||
|
},
|
||||||
|
'action': (function(func, responseProcessor) {
|
||||||
|
return function (req,res) {
|
||||||
|
req.params.version = version;
|
||||||
|
req.params.func = func; // call the api function
|
||||||
|
|
||||||
|
//wrap the send function so we can process the response
|
||||||
|
res.__swagger_send = res.send;
|
||||||
|
res.send = function (response) {
|
||||||
|
// ugly but we need to get this as json
|
||||||
|
response = JSON.parse(response);
|
||||||
|
// process the response if needed
|
||||||
|
if (responseProcessor) {
|
||||||
|
response = responseProcessor(response);
|
||||||
}
|
}
|
||||||
}
|
// Let's move everything out of "data"
|
||||||
response = JSON.stringify(response);
|
if (response.data) {
|
||||||
res.__swagger_send(response);
|
for(var prop in response.data) {
|
||||||
}
|
response[prop] = response.data[prop];
|
||||||
|
delete response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = JSON.stringify(response);
|
||||||
|
res.__swagger_send(response);
|
||||||
|
};
|
||||||
|
|
||||||
apiCaller(req, res, req.query);
|
apiCaller(req, res, req.query);
|
||||||
};
|
};
|
||||||
})(func["func"], func["responseProcessor"]) // must use a closure here
|
})(func["func"], func["responseProcessor"]) // must use a closure here
|
||||||
};
|
};
|
||||||
|
|
||||||
swagger.addGet(swaggerFunc);
|
swagger.addGet(swaggerFunc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swagger.setHeaders = function setHeaders(res) {
|
||||||
|
res.header('Access-Control-Allow-Origin', "*");
|
||||||
|
};
|
||||||
|
|
||||||
|
swagger.configureSwaggerPaths("", "/api" , "");
|
||||||
|
|
||||||
|
swagger.configure("http://" + settings.ip + ":" + settings.port + basePath, version);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
swagger.setHeaders = function setHeaders(res) {
|
|
||||||
res.header('Access-Control-Allow-Origin', "*");
|
|
||||||
};
|
|
||||||
|
|
||||||
swagger.configureSwaggerPaths("", "/api" , "");
|
|
||||||
|
|
||||||
swagger.configure("http://" + settings.ip + ":" + settings.port + "/rest", version);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue