grpc-reflection-js
Advanced tools
Comparing version 0.0.7 to 0.1.0
@@ -9,2 +9,7 @@ import { ChannelCredentials } from '@grpc/grpc-js'; | ||
fileContainingSymbol(symbol: string): Promise<Root>; | ||
fileByFilename(filename: string): Promise<Root>; | ||
private resolveFileDescriptorSet; | ||
private resolveDescriptorRecursive; | ||
private getFileContainingSymbol; | ||
private getFileByFilename; | ||
} |
@@ -21,2 +21,5 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -27,2 +30,4 @@ exports.Client = void 0; | ||
const reflection_pb_1 = require("./reflection_pb"); | ||
const descriptor_2 = require("protobufjs/ext/descriptor"); | ||
const lodash_set_1 = __importDefault(require("lodash.set")); | ||
class Client { | ||
@@ -57,7 +62,42 @@ constructor(url, credentials, options) { | ||
return new Promise((resolve, reject) => { | ||
this.getFileContainingSymbol(symbol) | ||
.then(val => resolve(this.resolveFileDescriptorSet(val))) | ||
.catch(err => reject(err)); | ||
}); | ||
} | ||
fileByFilename(filename) { | ||
return new Promise((resolve, reject) => { | ||
this.getFileByFilename(filename) | ||
.then(val => resolve(this.resolveFileDescriptorSet(val))) | ||
.catch(err => reject(err)); | ||
}); | ||
} | ||
async resolveFileDescriptorSet(fileDescriptorProtoBytes) { | ||
const fileDescriptorSet = descriptor_2.FileDescriptorSet.create(); | ||
const fileDescriptorProtos = await this.resolveDescriptorRecursive(fileDescriptorProtoBytes); | ||
lodash_set_1.default(fileDescriptorSet, 'file', fileDescriptorProtos); | ||
return descriptor_1.getDescriptorRootFromDescriptorSet(fileDescriptorSet); | ||
} | ||
async resolveDescriptorRecursive(fileDescriptorProtoBytes) { | ||
let fileDescriptorProtos = []; | ||
for (const descriptorByte of fileDescriptorProtoBytes) { | ||
const fileDescriptorProto = descriptor_2.FileDescriptorProto.decode(descriptorByte); | ||
if (fileDescriptorProto.dependency) { | ||
const dependencies = fileDescriptorProto.dependency; | ||
for (const dep of dependencies) { | ||
const depProtoBytes = await this.getFileByFilename(dep); | ||
const protoDependencies = await this.resolveDescriptorRecursive(depProtoBytes); | ||
fileDescriptorProtos = fileDescriptorProtos.concat(protoDependencies); | ||
} | ||
} | ||
fileDescriptorProtos.push(fileDescriptorProto); | ||
} | ||
return fileDescriptorProtos; | ||
} | ||
getFileContainingSymbol(symbol) { | ||
return new Promise((resolve, reject) => { | ||
function dataCallback(response) { | ||
var _a; | ||
if (response.hasFileDescriptorResponse()) { | ||
const root = descriptor_1.getDescriptorRoot((_a = response.getFileDescriptorResponse()) === null || _a === void 0 ? void 0 : _a.getFileDescriptorProtoList()); | ||
resolve(root); | ||
resolve((_a = response.getFileDescriptorResponse()) === null || _a === void 0 ? void 0 : _a.getFileDescriptorProtoList()); | ||
} | ||
@@ -76,4 +116,23 @@ else { | ||
} | ||
getFileByFilename(symbol) { | ||
return new Promise((resolve, reject) => { | ||
function dataCallback(response) { | ||
var _a; | ||
if (response.hasFileDescriptorResponse()) { | ||
resolve((_a = response.getFileDescriptorResponse()) === null || _a === void 0 ? void 0 : _a.getFileDescriptorProtoList()); | ||
} | ||
else { | ||
reject(Error()); | ||
} | ||
} | ||
const request = new reflection_pb_1.ServerReflectionRequest(); | ||
request.setFileByFilename(symbol); | ||
const grpcCall = this.grpcClient.serverReflectionInfo({}); | ||
grpcCall.on('data', dataCallback); | ||
grpcCall.write(request); | ||
grpcCall.end(); | ||
}); | ||
} | ||
} | ||
exports.Client = Client; | ||
//# sourceMappingURL=client.js.map |
/** | ||
* @typedef {import('protobufjs').Root} Root | ||
* @typedef {import('protobufjs').Message} Message | ||
*/ | ||
@@ -11,2 +12,9 @@ /** | ||
export function getDescriptorRoot(file_descriptor_protos: Array<Uint8Array | string> | undefined): Root; | ||
/** | ||
* Get Protobuf.js Root object from FileDescriptorSet | ||
* @param {Message file_descriptor_set - File descriptor set | ||
* @return {Root} Protobuf.js Root object | ||
*/ | ||
export function getDescriptorRootFromDescriptorSet(file_descriptor_set: Message): Root; | ||
export type Root = import("protobufjs").Root; | ||
export type Message = import("protobufjs").Message<object>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getDescriptorRoot = void 0; | ||
exports.getDescriptorRootFromDescriptorSet = exports.getDescriptorRoot = void 0; | ||
const protobuf = require('protobufjs'); | ||
@@ -9,2 +9,3 @@ const Descriptor = require('protobufjs/ext/descriptor'); | ||
* @typedef {import('protobufjs').Root} Root | ||
* @typedef {import('protobufjs').Message} Message | ||
*/ | ||
@@ -27,2 +28,12 @@ /** | ||
exports.getDescriptorRoot = getDescriptorRoot; | ||
/** | ||
* Get Protobuf.js Root object from FileDescriptorSet | ||
* @param {Message file_descriptor_set - File descriptor set | ||
* @return {Root} Protobuf.js Root object | ||
*/ | ||
// eslint-disable-next-line node/no-unsupported-features/es-syntax | ||
function getDescriptorRootFromDescriptorSet(file_descriptor_set) { | ||
return protobuf.Root.fromDescriptor(file_descriptor_set); | ||
} | ||
exports.getDescriptorRootFromDescriptorSet = getDescriptorRootFromDescriptorSet; | ||
//# sourceMappingURL=descriptor.js.map |
@@ -59,2 +59,67 @@ "use strict"; | ||
}); | ||
// eslint-disable-next-line no-undef | ||
describe('fileContainingSymbol', () => { | ||
// eslint-disable-next-line no-undef | ||
it('should return Root', async () => { | ||
const reflectionClient = new client_1.Client('localhost:4770', grpc_js_1.credentials.createInsecure()); | ||
const grpcCallPhone = { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
on: function (_event, listener) { | ||
const res = new reflection_pb_1.ServerReflectionResponse(); | ||
const fileDescriptorResponse = new reflection_pb_1.FileDescriptorResponse(); | ||
// eslint-disable-next-line prettier/prettier | ||
const protoBytes = Buffer.from([10, 11, 112, 104, 111, 110, 101, 46, 112, 114, 111, 116, 111, 18, 5, 112, 104, 111, 110, 101, 26, 13, 99, 111, 110, 116, 97, 99, 116, 46, 112, 114, 111, 116, 111, 34, 97, 10, 11, 84, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 18, 14, 10, 2, 105, 100, 24, 1, 32, 1, 40, 9, 82, 2, 105, 100, 18, 24, 10, 7, 109, 101, 115, 115, 97, 103, 101, 24, 2, 32, 1, 40, 9, 82, 7, 109, 101, 115, 115, 97, 103, 101, 18, 40, 10, 7, 99, 111, 110, 116, 97, 99, 116, 24, 3, 32, 1, 40, 11, 50, 14, 46, 112, 104, 111, 110, 101, 46, 67, 111, 110, 116, 97, 99, 116, 82, 7, 99, 111, 110, 116, 97, 99, 116, 34, 40, 10, 12, 84, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 18, 24, 10, 7, 115, 117, 99, 99, 101, 115, 115, 24, 1, 32, 1, 40, 8, 82, 7, 115, 117, 99, 99, 101, 115, 115, 50, 63, 10, 9, 77, 101, 115, 115, 101, 110, 103, 101, 114, 18, 50, 10, 7, 77, 101, 115, 115, 97, 103, 101, 18, 18, 46, 112, 104, 111, 110, 101, 46, 84, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 26, 19, 46, 112, 104, 111, 110, 101, 46, 84, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 98, 6, 112, 114, 111, 116, 111, 51]); | ||
fileDescriptorResponse.addFileDescriptorProto(protoBytes); | ||
res.setFileDescriptorResponse(fileDescriptorResponse); | ||
listener(res); | ||
}, | ||
write: function () { }, | ||
end: function () { }, | ||
}; | ||
const grpcCallContact = { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
on: function (_event, listener) { | ||
const res = new reflection_pb_1.ServerReflectionResponse(); | ||
const fileDescriptorResponse = new reflection_pb_1.FileDescriptorResponse(); | ||
// eslint-disable-next-line prettier/prettier | ||
const protoBytes = Buffer.from([10, 13, 99, 111, 110, 116, 97, 99, 116, 46, 112, 114, 111, 116, 111, 18, 5, 112, 104, 111, 110, 101, 34, 53, 10, 7, 67, 111, 110, 116, 97, 99, 116, 18, 18, 10, 4, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 4, 110, 97, 109, 101, 18, 22, 10, 6, 110, 117, 109, 98, 101, 114, 24, 2, 32, 1, 40, 9, 82, 6, 110, 117, 109, 98, 101, 114, 98, 6, 112, 114, 111, 116, 111, 51]); | ||
fileDescriptorResponse.addFileDescriptorProto(protoBytes); | ||
res.setFileDescriptorResponse(fileDescriptorResponse); | ||
listener(res); | ||
}, | ||
write: function () { }, | ||
end: function () { }, | ||
}; | ||
const mock = sinon.mock(reflectionClient.grpcClient); | ||
mock.expects('serverReflectionInfo').once().returns(grpcCallPhone); | ||
mock.expects('serverReflectionInfo').once().returns(grpcCallContact); | ||
const root = await reflectionClient.fileContainingSymbol('phone.Messenger'); | ||
chai_1.assert.deepEqual(root.files, ['contact.proto', 'phone.proto']); | ||
}); | ||
}); | ||
// eslint-disable-next-line no-undef | ||
describe('fileByFilename', () => { | ||
// eslint-disable-next-line no-undef | ||
it('should return Root', async () => { | ||
const reflectionClient = new client_1.Client('localhost:4770', grpc_js_1.credentials.createInsecure()); | ||
const grpcCallContact = { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
on: function (_event, listener) { | ||
const res = new reflection_pb_1.ServerReflectionResponse(); | ||
const fileDescriptorResponse = new reflection_pb_1.FileDescriptorResponse(); | ||
// eslint-disable-next-line prettier/prettier | ||
const protoBytes = Buffer.from([10, 13, 99, 111, 110, 116, 97, 99, 116, 46, 112, 114, 111, 116, 111, 18, 5, 112, 104, 111, 110, 101, 34, 53, 10, 7, 67, 111, 110, 116, 97, 99, 116, 18, 18, 10, 4, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 4, 110, 97, 109, 101, 18, 22, 10, 6, 110, 117, 109, 98, 101, 114, 24, 2, 32, 1, 40, 9, 82, 6, 110, 117, 109, 98, 101, 114, 98, 6, 112, 114, 111, 116, 111, 51]); | ||
fileDescriptorResponse.addFileDescriptorProto(protoBytes); | ||
res.setFileDescriptorResponse(fileDescriptorResponse); | ||
listener(res); | ||
}, | ||
write: function () { }, | ||
end: function () { }, | ||
}; | ||
const mock = sinon.mock(reflectionClient.grpcClient); | ||
mock.expects('serverReflectionInfo').once().returns(grpcCallContact); | ||
const root = await reflectionClient.fileByFilename('contact.proto'); | ||
chai_1.assert.deepEqual(root.files, ['contact.proto']); | ||
}); | ||
}); | ||
//# sourceMappingURL=client.test.js.map |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -6,2 +9,6 @@ const descriptor_1 = require("../src/descriptor"); | ||
const chai_1 = require("chai"); | ||
const descriptor_2 = require("protobufjs/ext/descriptor"); | ||
const lodash_set_1 = __importDefault(require("lodash.set")); | ||
// eslint-disable-next-line prettier/prettier | ||
const protoBytes = Buffer.from([10, 11, 112, 104, 111, 110, 101, 46, 112, 114, 111, 116, 111, 18, 5, 112, 104, 111, 110, 101, 34, 55, 10, 11, 84, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 18, 14, 10, 2, 105, 100, 24, 1, 32, 1, 40, 9, 82, 2, 105, 100, 18, 24, 10, 7, 109, 101, 115, 115, 97, 103, 101, 24, 2, 32, 1, 40, 9, 82, 7, 109, 101, 115, 115, 97, 103, 101, 34, 40, 10, 12, 84, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 18, 24, 10, 7, 115, 117, 99, 99, 101, 115, 115, 24, 1, 32, 1, 40, 8, 82, 7, 115, 117, 99, 99, 101, 115, 115, 50, 63, 10, 9, 77, 101, 115, 115, 101, 110, 103, 101, 114, 18, 50, 10, 7, 77, 101, 115, 115, 97, 103, 101, 18, 18, 46, 112, 104, 111, 110, 101, 46, 84, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 26, 19, 46, 112, 104, 111, 110, 101, 46, 84, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 98, 6, 112, 114, 111, 116, 111, 51]); | ||
// eslint-disable-next-line no-undef | ||
@@ -11,4 +18,2 @@ describe('getDescriptorRoot', () => { | ||
it('should return Root', () => { | ||
// eslint-disable-next-line prettier/prettier | ||
const protoBytes = Buffer.from([10, 11, 112, 104, 111, 110, 101, 46, 112, 114, 111, 116, 111, 18, 5, 112, 104, 111, 110, 101, 34, 55, 10, 11, 84, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 18, 14, 10, 2, 105, 100, 24, 1, 32, 1, 40, 9, 82, 2, 105, 100, 18, 24, 10, 7, 109, 101, 115, 115, 97, 103, 101, 24, 2, 32, 1, 40, 9, 82, 7, 109, 101, 115, 115, 97, 103, 101, 34, 40, 10, 12, 84, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 18, 24, 10, 7, 115, 117, 99, 99, 101, 115, 115, 24, 1, 32, 1, 40, 8, 82, 7, 115, 117, 99, 99, 101, 115, 115, 50, 63, 10, 9, 77, 101, 115, 115, 101, 110, 103, 101, 114, 18, 50, 10, 7, 77, 101, 115, 115, 97, 103, 101, 18, 18, 46, 112, 104, 111, 110, 101, 46, 84, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 26, 19, 46, 112, 104, 111, 110, 101, 46, 84, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 98, 6, 112, 114, 111, 116, 111, 51]); | ||
const root = descriptor_1.getDescriptorRoot([protoBytes]); | ||
@@ -18,2 +23,12 @@ chai_1.assert.deepEqual(root.files, ['phone.proto']); | ||
}); | ||
// eslint-disable-next-line no-undef | ||
describe('getDescriptorRootFromDescriptorSet', () => { | ||
// eslint-disable-next-line no-undef | ||
it('should return Root', () => { | ||
const descriptorSet = descriptor_2.FileDescriptorSet.create(); | ||
lodash_set_1.default(descriptorSet, 'file[0]', descriptor_2.FileDescriptorProto.decode(protoBytes)); | ||
const root = descriptor_1.getDescriptorRootFromDescriptorSet(descriptorSet); | ||
chai_1.assert.deepEqual(root.files, ['phone.proto']); | ||
}); | ||
}); | ||
//# sourceMappingURL=descriptor.test.js.map |
{ | ||
"name": "grpc-reflection-js", | ||
"version": "0.0.7", | ||
"version": "0.1.0", | ||
"main": "build/src/index.js", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/redhoyasa/grpc-reflection-js", |
# gRPC Reflection JS | ||
[![npm version](https://badge.fury.io/js/grpc-reflection-js.svg)](https://badge.fury.io/js/grpc-reflection-js) | ||
![CI](https://github.com/redhoyasa/grpc-reflection-js/workflows/CI/badge.svg) | ||
@@ -14,3 +15,9 @@ [![codecov](https://codecov.io/gh/redhoyasa/grpc-reflection-js/branch/master/graph/badge.svg)](https://codecov.io/gh/redhoyasa/grpc-reflection-js) | ||
## Usage | ||
- [Initialize client](#Initialize) | ||
- [listServices](#listServices): List gRPC services | ||
- [fileContainingSymbol](#fileContainingSymbol): Get protobuf Root using fully-qualified symbol name | ||
- [fileByFilename](#fileByFilename): Get protobuf Root using proto file name | ||
### Initialize | ||
```js | ||
@@ -25,3 +32,27 @@ const grpc = require('grpc'); | ||
); | ||
``` | ||
### listServices | ||
```js | ||
const services = await reflectionClient.listServices() | ||
``` | ||
Output | ||
```text | ||
['grpc.reflection.v1alpha.ServerReflection', 'phone.Messenger'] | ||
``` | ||
### fileContainingSymbol | ||
```js | ||
const root = await reflectionClient.fileContainingSymbol('phone.Messenger') | ||
``` | ||
### fileByFilename | ||
```js | ||
const root = await reflectionClient.fileContainingSymbol('contact.proto') | ||
``` | ||
## License | ||
[![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg?maxAge=2592000)](https://raw.githubusercontent.com/apollostack/apollo-ios/master/LICENSE) | ||
MIT |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
159657
2070
57