xud
Version:
Exchange Union Daemon
134 lines • 5.38 kB
JavaScript
;
// MIT License
//
// Copyright (c) 2019 Echo
//
// 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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// code taken from https://github.com/echo-health/node-grpc-interceptors with some adjustments
const grpc_1 = __importDefault(require("grpc"));
const getType = (method) => {
if (method.requestStream === false && method.responseStream === false) {
return 'unary';
}
return 'unknown';
};
const toLowerCamelCase = (str) => {
return str.charAt(0).toLowerCase() + str.slice(1);
};
const lookupServiceMetadata = (service, implementation) => {
const serviceKeys = Object.keys(service);
const implementationKeys = Object.keys(implementation);
const intersectingMethods = serviceKeys
.filter((k) => {
return implementationKeys.map(k => toLowerCamelCase(k)).indexOf(k) !== -1;
})
.reduce((acc, k) => {
const method = service[k];
if (!method) {
throw new Error(`cannot find method ${k} on service`);
}
const components = method.path.split('/');
acc[k] = {
name: components[1],
method: components[2],
type: getType(method),
path: method.path,
responseType: method.responseType,
requestType: method.requestType,
};
return acc;
}, {});
return (key) => {
return Object.keys(intersectingMethods)
.filter(k => toLowerCamelCase(key) === k)
.map(k => intersectingMethods[k]).pop();
};
};
const handler = {
get(target, propKey) {
if (propKey !== 'addService') {
return target[propKey];
}
return (service, implementation) => {
const newImplementation = {};
const lookup = lookupServiceMetadata(service, implementation);
for (const k in implementation) {
const name = k;
const fn = implementation[k];
newImplementation[name] = (call, callback) => {
const ctx = {
call,
service: lookup(name),
};
const newCallback = (callback) => {
return (...args) => {
ctx.status = {
code: grpc_1.default.status.OK,
};
const err = args[0];
if (err) {
ctx.status = {
code: grpc_1.default.status.UNKNOWN,
details: err,
};
}
callback(...args);
};
};
const interceptors = target.intercept();
const first = interceptors.next();
if (!first.value) { // if we don't have any interceptors
return new Promise((resolve) => {
return resolve(fn(call, newCallback(callback)));
});
}
first.value(ctx, function next() {
return new Promise((resolve) => {
const i = interceptors.next();
if (i.done) {
return resolve(fn(call, newCallback(callback)));
}
return resolve(i.value(ctx, next));
});
});
};
}
return target.addService(service, newImplementation);
};
},
};
exports.default = (server) => {
server.interceptors = [];
server.use = (fn) => {
server.interceptors.push(fn);
};
server.intercept = function* intercept() {
let i = 0;
while (i < server.interceptors.length) {
yield server.interceptors[i];
i = i + 1;
}
};
return new Proxy(server, handler);
};
//# sourceMappingURL=serverProxy.js.map