Skip to content

Commit 592fad2

Browse files
committed
initial commit with failing test
0 parents  commit 592fad2

13 files changed

+3619
-0
lines changed

.eslintrc.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "./node_modules/gts/",
3+
"plugins": [
4+
"jest"
5+
],
6+
"env": {
7+
"jest/globals": true
8+
},
9+
"parserOptions": {
10+
"sourceType": "module"
11+
}
12+
}

.gitignore

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
### Build ###
2+
build/
3+
4+
# Created by https://www.gitignore.io/api/node,visualstudiocode
5+
# Edit at https://www.gitignore.io/?templates=node,visualstudiocode
6+
7+
### Node ###
8+
# Logs
9+
logs
10+
*.log
11+
npm-debug.log*
12+
yarn-debug.log*
13+
yarn-error.log*
14+
lerna-debug.log*
15+
16+
# Diagnostic reports (https://nodejs.org/api/report.html)
17+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
18+
19+
# Runtime data
20+
pids
21+
*.pid
22+
*.seed
23+
*.pid.lock
24+
25+
# Directory for instrumented libs generated by jscoverage/JSCover
26+
lib-cov
27+
28+
# Coverage directory used by tools like istanbul
29+
coverage
30+
*.lcov
31+
32+
# nyc test coverage
33+
.nyc_output
34+
35+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
36+
.grunt
37+
38+
# Bower dependency directory (https://bower.io/)
39+
bower_components
40+
41+
# node-waf configuration
42+
.lock-wscript
43+
44+
# Compiled binary addons (https://nodejs.org/api/addons.html)
45+
build/Release
46+
47+
# Dependency directories
48+
node_modules/
49+
jspm_packages/
50+
51+
# TypeScript v1 declaration files
52+
typings/
53+
54+
# TypeScript cache
55+
*.tsbuildinfo
56+
57+
# Optional npm cache directory
58+
.npm
59+
60+
# Optional eslint cache
61+
.eslintcache
62+
63+
# Optional REPL history
64+
.node_repl_history
65+
66+
# Output of 'npm pack'
67+
*.tgz
68+
69+
# Yarn Integrity file
70+
.yarn-integrity
71+
72+
# dotenv environment variables file
73+
.env
74+
.env.test
75+
76+
# parcel-bundler cache (https://parceljs.org/)
77+
.cache
78+
79+
# next.js build output
80+
.next
81+
82+
# nuxt.js build output
83+
.nuxt
84+
85+
# rollup.js default build output
86+
dist/
87+
88+
# Uncomment the public line if your project uses Gatsby
89+
# https://nextjs.org/blog/next-9-1#public-directory-support
90+
# https://create-react-app.dev/docs/using-the-public-folder/#docsNav
91+
# public
92+
93+
# Storybook build outputs
94+
.out
95+
.storybook-out
96+
97+
# vuepress build output
98+
.vuepress/dist
99+
100+
# Serverless directories
101+
.serverless/
102+
103+
# FuseBox cache
104+
.fusebox/
105+
106+
# DynamoDB Local files
107+
.dynamodb/
108+
109+
# Temporary folders
110+
tmp/
111+
temp/
112+
113+
### VisualStudioCode ###
114+
.vscode/
115+
!.vscode/settings.json
116+
!.vscode/tasks.json
117+
!.vscode/launch.json
118+
!.vscode/extensions.json
119+
120+
### VisualStudioCode Patch ###
121+
# Ignore all local history of files
122+
.history
123+
124+
# End of https://www.gitignore.io/api/node,visualstudiocode

.prettierignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
build
3+
dist
4+
res
5+
coverage

.prettierrc.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
...require('gts/.prettierrc.json')
3+
}

docker-compose.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: "3"
2+
services:
3+
gripmock:
4+
image: tkpd/gripmock
5+
restart: always
6+
volumes:
7+
- ./test/fixtures:/proto
8+
ports:
9+
- 4770:4770
10+
- 4771:4771
11+
command: /proto/phone.proto

package.json

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "grpc-reflection-js",
3+
"version": "0.0.1",
4+
"main": "index.js",
5+
"author": "[email protected]",
6+
"license": "MIT",
7+
"dependencies": {
8+
"@grpc/grpc-js": "^1.0.3",
9+
"@grpc/proto-loader": "^0.5.4",
10+
"@types/async": "^3.2.3",
11+
"@types/lodash.get": "^4.4.6",
12+
"@types/lodash.set": "^4.3.6",
13+
"@types/protobufjs": "^6.0.0",
14+
"async": "^3.2.0",
15+
"grpc": "^1.24.2",
16+
"lodash.get": "^4.4.2",
17+
"lodash.set": "^4.3.2",
18+
"protobufjs": "^6.9.0"
19+
},
20+
"devDependencies": {
21+
"@types/chai": "^4.2.11",
22+
"@types/mocha": "^7.0.2",
23+
"@types/node": "^13.11.1",
24+
"@typescript-eslint/eslint-plugin": "^2.33.0",
25+
"@typescript-eslint/parser": "^2.33.0",
26+
"chai": "^4.2.0",
27+
"eslint": "^7.0.0",
28+
"eslint-config-prettier": "^6.11.0",
29+
"eslint-plugin-jest": "^23.11.0",
30+
"eslint-plugin-node": "^11.1.0",
31+
"eslint-plugin-prettier": "^3.1.3",
32+
"gts": "^2.0.2",
33+
"mocha": "^7.2.0",
34+
"prettier": "^2.0.5",
35+
"ts-node": "^8.10.2",
36+
"typescript": "^3.9.2"
37+
},
38+
"scripts": {
39+
"check": "gts check",
40+
"clean": "gts clean",
41+
"compile": "tsc",
42+
"fix": "gts fix",
43+
"test": "mocha -r ts-node/register test/**/*.test.ts",
44+
"prepare": "yarn run compile",
45+
"pretest": "yarn run compile",
46+
"posttest": "yarn run check"
47+
}
48+
}

src/descriptor.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const protobuf = require('protobufjs');
2+
const Descriptor = require('protobufjs/ext/descriptor');
3+
const set = require('lodash.set');
4+
5+
/**
6+
* @typedef {import('protobufjs').Root} Root
7+
*/
8+
9+
/**
10+
* Get Protobuf.js Root object from the serialized FileDescriptorProto messages
11+
* that gotten from reflection service.
12+
* @param {Buffer[]} file_descriptor_protos - Reflection descriptor protos
13+
* @return {Root} Protobuf.js Root object
14+
*/
15+
// eslint-disable-next-line node/no-unsupported-features/es-syntax
16+
export function getDescriptorRoot(file_descriptor_protos) {
17+
const descriptorSet = Descriptor.FileDescriptorSet.create();
18+
19+
file_descriptor_protos.forEach((descriptorByte, i) => {
20+
const descriptor = Descriptor.FileDescriptorProto.decode(descriptorByte);
21+
set(descriptorSet, 'file[' + i + ']', descriptor);
22+
});
23+
24+
return protobuf.Root.fromDescriptor(descriptorSet);
25+
}

src/index.ts

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as loader from '@grpc/proto-loader';
2+
import * as grpc from 'grpc';
3+
import get from 'lodash.get';
4+
import {getDescriptorRoot} from './descriptor';
5+
6+
const PROTO_PATH =
7+
__dirname + '/../static/grpc/reflection/v1alpha/reflection.proto';
8+
const PACKAGE_NAME = 'grpc.reflection.v1alpha';
9+
const SERVICE_NAME = 'ServerReflection';
10+
11+
export function createReflectionClient(
12+
url: string,
13+
credentials: grpc.ChannelCredentials,
14+
options?: object
15+
): grpc.Client {
16+
const packageDefinition = loader.loadSync(PROTO_PATH, {
17+
keepCase: true,
18+
longs: String,
19+
enums: String,
20+
defaults: true,
21+
oneofs: true,
22+
});
23+
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); // eslint-disable-line no-console
24+
const reflection = get(protoDescriptor, PACKAGE_NAME);
25+
const reflectionService = get(reflection, SERVICE_NAME);
26+
const client = new reflectionService(url, credentials, options);
27+
return client;
28+
}
29+
30+
export async function listServices(client: any) {
31+
return new Promise((resolve, reject) => {
32+
function dataCallback(response: any) {
33+
if ('list_services_response' in response) {
34+
resolve(response.list_services_response.service);
35+
} else {
36+
reject(Error());
37+
}
38+
}
39+
40+
const input = {
41+
list_services: '*',
42+
};
43+
const callGrpc = client['ServerReflectionInfo']({});
44+
callGrpc.on('data', dataCallback);
45+
callGrpc.write(input);
46+
callGrpc.end();
47+
});
48+
}
49+
50+
export async function fileContainingSymbol(service_name: string, client: any) {
51+
return new Promise((resolve, reject) => {
52+
function dataCallback(response: any) {
53+
if ('file_descriptor_response' in response) {
54+
const root = getDescriptorRoot(
55+
response.file_descriptor_response.file_descriptor_proto
56+
);
57+
const res = grpc.loadObject(root);
58+
resolve(res);
59+
} else {
60+
reject(Error());
61+
}
62+
}
63+
64+
const input = {
65+
file_containing_symbol: service_name,
66+
};
67+
const callGrpc = client['ServerReflectionInfo']({});
68+
callGrpc.on('data', dataCallback);
69+
callGrpc.write(input);
70+
callGrpc.end();
71+
});
72+
}

0 commit comments

Comments
 (0)