190 lines
6.7 KiB
JavaScript
190 lines
6.7 KiB
JavaScript
/*
|
|
The MIT License (MIT)
|
|
|
|
Copyright (c) 2014 Oliver Moran
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do
|
|
so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
var JSON_RPC = {};
|
|
|
|
|
|
|
|
var id = 0, callbacks = {};
|
|
|
|
/**
|
|
* Constructs a new JSON-RPC Request
|
|
* @param method A String containing the name of the method to be invoked.
|
|
* @param params (optional) A Structured value that holds the parameter values to be used during the invocation of the method.
|
|
*/
|
|
JSON_RPC.Request = function (method, params) {
|
|
this.jsonrpc = "2.0";
|
|
this.method = method;
|
|
if (typeof params !== "undefined") {
|
|
this.params = params;
|
|
}
|
|
|
|
this.id = id++;
|
|
};
|
|
|
|
// Implements getters and setters for the result of a JSON-RPC Request.
|
|
// The result may be an any Object or primitive
|
|
Object.defineProperty(JSON_RPC.Request.prototype, "result", {
|
|
get: function () { return this._result; },
|
|
set: function (result) {
|
|
delete this.method; // remove the method name
|
|
delete this.params; // remove the params
|
|
delete this.error; // remove error state if it exists
|
|
this._result = result;
|
|
}
|
|
});
|
|
|
|
// Implements getters and setters for the error state of a JSON-RPC Request.
|
|
// Error should be a JSON_RPC.Error object
|
|
Object.defineProperty(JSON_RPC.Request.prototype, "error", {
|
|
get: function () { return this._error; },
|
|
set: function (error) {
|
|
delete this.method; // remove the method name
|
|
delete this.params; // remove the params
|
|
delete this.result; // remove result state if it exists
|
|
this._error = error;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Returns a String representation of a JSON-RPC Request
|
|
* @returns A JSON String
|
|
*/
|
|
JSON_RPC.Request.prototype.toString = function () {
|
|
var rpc = {
|
|
jsonrpc: this.jsonrpc,
|
|
id: this.id
|
|
};
|
|
|
|
if (this.method !== undefined) rpc.method = this.method;
|
|
if (this.params !== undefined) rpc.params = this.params;
|
|
if (this.result !== undefined) rpc.result = this.result;
|
|
if (this.error !== undefined) rpc.error = this.error;
|
|
|
|
return JSON.stringify(rpc);
|
|
};
|
|
|
|
/**
|
|
* Constructs a new JSON-RPC Notification
|
|
* @param method A String containing the name of the method to be invoked.
|
|
* @param params (optional) A Structured value that holds the parameter values to be used during the invocation of the method.
|
|
*/
|
|
JSON_RPC.Notification = function (method, params) {
|
|
this.jsonrpc = "2.0";
|
|
this.method = method;
|
|
if (typeof params !== "undefined") {
|
|
this.params = params;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns a String representation of a JSON-RPC Notification
|
|
* @returns A JSON String
|
|
*/
|
|
JSON_RPC.Notification.prototype.toString = function () {
|
|
var rpc = {
|
|
jsonrpc: this.jsonrpc,
|
|
method: this.method,
|
|
params: this.params
|
|
};
|
|
|
|
return JSON.stringify(rpc);
|
|
};
|
|
|
|
/**
|
|
* Constructs a new JSON-RPC Errror object
|
|
* @params code A Number that indicates the error type that occurred. -32768 to -32000 are reserved.
|
|
* @param message (optional) A String providing a short description of the error.
|
|
* @param data (optional) A Primitive or Structured value that contains additional information about the error.
|
|
*/
|
|
JSON_RPC.Error = function (code, message, data) {
|
|
this.code = code;
|
|
if (typeof message == "string") this.message = message;
|
|
if (data !== undefined) this.data = data;
|
|
};
|
|
|
|
// stock errors
|
|
JSON_RPC.PARSE_ERROR = new JSON_RPC.Error(-32700, "An error occurred on the server while parsing the JSON text.");
|
|
JSON_RPC.INVALID_REQUEST = new JSON_RPC.Error(-32600, "The JSON sent is not a valid Request object.");
|
|
JSON_RPC.METHOD_NOT_FOUND = new JSON_RPC.Error(-32601, "The method does not exist / is not available.");
|
|
JSON_RPC.INVALID_PARAMS = new JSON_RPC.Error(-32602, "Invalid method parameter(s).");
|
|
JSON_RPC.INTERNAL_ERROR = new JSON_RPC.Error(-32603, "Internal JSON-RPC error.");
|
|
|
|
/**
|
|
* Parses a JSON-RPC string and converts to a JSON-RPC object or an Array of such strings.
|
|
* @params rpc A String or Array to parse to a JSON-RPC object.
|
|
*/
|
|
JSON_RPC.parse = function (rpc) {
|
|
// batch?
|
|
if (rpc.constructor === Array) {
|
|
var arr = [];
|
|
rpc.forEach(function (el) {
|
|
arr.push(JSON_RPC.parse(el));
|
|
});
|
|
return arr;
|
|
}
|
|
|
|
// parsable?
|
|
var rpc;
|
|
try {
|
|
rpc = JSON.parse(rpc);
|
|
} catch (err) {
|
|
var obj = new JSON_RPC.Request();
|
|
obj.result = JSON_RPC.PARSE_ERROR;
|
|
obj.id = null;
|
|
return obj;
|
|
}
|
|
|
|
// 2.0?
|
|
if (rpc.jsonrpc !== "2.0") {
|
|
var obj = new JSON_RPC.Request();
|
|
obj.result = JSON_RPC.INVALID_REQUEST;
|
|
obj.id = null;
|
|
return obj;
|
|
}
|
|
|
|
// request or notification?
|
|
var obj = (rpc.id === undefined)
|
|
? new JSON_RPC.Notification(rpc.method, rpc.params)
|
|
: new JSON_RPC.Request(rpc.method, rpc.params);
|
|
// have an ID?
|
|
if (rpc.id !== undefined) obj.id = rpc.id;
|
|
// is it a result?
|
|
if (rpc.result !== undefined) obj.result = rpc.result;
|
|
// is it a error?
|
|
if (rpc.error !== undefined) {
|
|
obj.error = new JSON_RPC.Error(
|
|
rpc.error.code,
|
|
rpc.error.message,
|
|
rpc.error.data
|
|
);
|
|
}
|
|
|
|
// parsed :-)
|
|
return obj;
|
|
};
|
|
|
|
|
|
|