Skip to content

Commit 3e49595

Browse files
author
Robert Kesterson
committed
Converted to typescript
1 parent e8bf88d commit 3e49595

21 files changed

+853
-533
lines changed

Diff for: .circleci/config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545

4646
# run tests!
4747
- run: sudo npm install -g istanbul codecov
48+
- run: npx tsc
4849
- run: istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec --exit
4950
- early_return_for_forked_pull_requests
5051
- run: codecov -t ${CODECOV_TOKEN}

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ yarn.lock
77
examples/node_modules
88
coverage/
99
.DS_Store
10+
dist/

Diff for: examples/redisGraphExample.js renamed to examples/redisGraphExample.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const RedisGraph = require("redisgraph.js").Graph;
1+
2+
import {Graph as RedisGraph} from 'redisgraph.js';
23

34
let graph = new RedisGraph("social");
45

@@ -18,7 +19,7 @@ try {
1819
let record = res.next();
1920
console.log(record.get("a.name"));
2021
}
21-
console.log(res.getStatistics().queryExecutionTime());
22+
console.log(res.getStatistics()?.queryExecutionTime());
2223

2324
// Match with parameters.
2425
let param = { age: 30 };

Diff for: examples/tsconfig.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"module": "UMD",
5+
"lib": ["es5"],
6+
"strict": true,
7+
"allowJs": true,
8+
"inlineSourceMap": true,
9+
"inlineSources": true,
10+
"outDir": "./dist",
11+
"moduleResolution": "node",
12+
"downlevelIteration": true,
13+
"rootDir": "./",
14+
"baseUrl": "./",
15+
"declaration": true,
16+
17+
},
18+
"include": ["./"],
19+
"exclude": ["dist"]
20+
}

Diff for: index.js

-13
This file was deleted.

Diff for: package.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
"redis": "^3.0.2"
1414
},
1515
"devDependencies": {
16-
"mocha": "^7.0.1"
16+
"@types/deep-equal": "^1.0.1",
17+
"@types/redis": "^2.8.28",
18+
"mocha": "^7.0.1",
19+
"typescript": "^4.1.3"
1720
},
1821
"scripts": {
19-
"test": "mocha --exit"
22+
"test": "npx tsc && mocha --exit"
2023
},
21-
"main": "index.js"
24+
"main": "dist/index.js"
2225
}

Diff for: src/edge.js renamed to src/edge.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
"use strict";
1+
import {Node} from "./node";
22
/**
33
* An edge connecting two nodes.
44
*/
5-
class Edge {
5+
export class Edge {
6+
7+
private id?: number;
68
/**
79
* Builds an Edge object.
810
* @constructor
@@ -11,7 +13,7 @@ class Edge {
1113
* @param {Node} destNode - Destination node of the edge.
1214
* @param {Map} properties - Properties map of the edge.
1315
*/
14-
constructor(srcNode, relation, destNode, properties) {
16+
constructor(private srcNode: Node, private relation: string, private destNode: Node, private properties: Map<string, any>) {
1517
this.id = undefined; //edge's id - set by RedisGraph
1618
this.relation = relation; //edge's relationship type
1719
this.srcNode = srcNode; //edge's source node
@@ -23,7 +25,7 @@ class Edge {
2325
* Sets the edge ID.
2426
* @param {int} id
2527
*/
26-
setId(id) {
28+
setId(id:number) {
2729
this.id = id;
2830
}
2931

@@ -35,4 +37,3 @@ class Edge {
3537
}
3638
}
3739

38-
module.exports = Edge;

Diff for: src/graph.ts

+279
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
import * as redis from "redis";
2+
import { ClientOpts, RedisClient } from "redis";
3+
import * as util from "util";
4+
import { ResultSet } from "./resultSet";
5+
6+
function isString(value: any): value is string {
7+
return typeof value === "string";
8+
}
9+
10+
/**
11+
* RedisGraph client
12+
*/
13+
export class Graph {
14+
private _labels: string[] = []; // List of node labels.
15+
private _relationshipTypes: string[] = []; // List of relation types.
16+
private _properties: string[] = []; // List of properties.
17+
18+
private _labelsPromise: Promise<string[]> | undefined; // used as a synchronization mechanizom for labels retrival
19+
private _propertyPromise: Promise<string[]> | undefined; // used as a synchronization mechanizom for property names retrival
20+
private _relationshipPromise: Promise<string[]> | undefined; // used as a synchronization mechanizom for relationship types retrival
21+
private _client: RedisClient;
22+
private _sendCommand:
23+
| ((command: string) => Promise<any>)
24+
| ((command: string, args?: any[]) => Promise<any>);
25+
/**
26+
* Creates a client to a specific graph running on the specific host/post
27+
* See: node_redis for more options on createClient
28+
*
29+
* @param {string} graphId the graph id
30+
* @param {string | RedisClient} [host] Redis host or node_redis client
31+
* @param {string | int} [port] Redis port
32+
* @param {ClientOpts} [options] node_redis options
33+
*/
34+
constructor(
35+
private _graphId: string,
36+
host?: string | RedisClient,
37+
port?: number,
38+
options?: ClientOpts
39+
) {
40+
this._labels = []; // List of node labels.
41+
this._relationshipTypes = []; // List of relation types.
42+
this._properties = []; // List of properties.
43+
44+
this._labelsPromise = undefined; // used as a synchronization mechanizom for labels retrival
45+
this._propertyPromise = undefined; // used as a synchronization mechanizom for property names retrival
46+
this._relationshipPromise = undefined; // used as a synchronization mechanizom for relationship types retrival
47+
48+
this._client =
49+
host instanceof redis.RedisClient
50+
? host
51+
: port
52+
? redis.createClient(port, host, options)
53+
: redis.createClient();
54+
this._sendCommand = util
55+
.promisify<string, any>(this._client.send_command)
56+
.bind(this._client);
57+
}
58+
/**
59+
* Closes the client.
60+
*/
61+
close() {
62+
this._client.quit();
63+
}
64+
65+
/**
66+
* Auxiliary function to extract string(s) data from procedures such as:
67+
* db.labels, db.propertyKeys and db.relationshipTypes
68+
* @param {ResultSet} resultSet - a procedure result set
69+
* @returns {string[]} strings array.
70+
*/
71+
_extractStrings(resultSet: ResultSet): string[] {
72+
var strings = [];
73+
while (resultSet.hasNext()) {
74+
strings.push(resultSet.next().getString(0));
75+
}
76+
return strings;
77+
}
78+
79+
/**
80+
* Transforms a parameter value to string.
81+
* @param {object} paramValue
82+
* @returns {string} the string representation of paramValue.
83+
*/
84+
paramToString(paramValue: null | string | any[]): string {
85+
if (paramValue == null) return "null";
86+
if (isString(paramValue)) {
87+
let strValue = "";
88+
paramValue = paramValue.replace(/[\\"']/g, "\\$&");
89+
if (paramValue[0] != '"') strValue += '"';
90+
strValue += paramValue;
91+
if (!paramValue.endsWith('"') || paramValue.endsWith('\\"'))
92+
strValue += '"';
93+
return strValue;
94+
}
95+
if (Array.isArray(paramValue)) {
96+
let stringsArr = new Array(paramValue.length);
97+
for (var i = 0; i < paramValue.length; i++) {
98+
stringsArr[i] = this.paramToString(paramValue[i]);
99+
}
100+
return ["[", stringsArr.join(", "), "]"].join("");
101+
}
102+
return paramValue;
103+
}
104+
105+
/**
106+
* Extracts parameters from dictionary into cypher parameters string.
107+
* @param {Map} params parameters dictionary.
108+
* @return {string} a cypher parameters string.
109+
*/
110+
buildParamsHeader(params: any) {
111+
let paramsArray = ["CYPHER"];
112+
113+
for (var key in params) {
114+
let value = this.paramToString(params[key]);
115+
paramsArray.push(`${key}=${value}`);
116+
}
117+
paramsArray.push(" ");
118+
return paramsArray.join(" ");
119+
}
120+
121+
/**
122+
* Execute a Cypher query
123+
* @async
124+
* @param {string} query Cypher query
125+
* @param {Map} [params] Parameters map
126+
* @returns {ResultSet} a promise contains a result set
127+
*/
128+
async query(query: string, params?: object) {
129+
if (params) {
130+
query = this.buildParamsHeader(params) + query;
131+
}
132+
var res = await this._sendCommand("graph.QUERY", [
133+
this._graphId,
134+
query,
135+
"--compact",
136+
]);
137+
var resultSet = new ResultSet(this);
138+
return resultSet.parseResponse(res);
139+
}
140+
141+
/**
142+
* Deletes the entire graph
143+
* @async
144+
* @returns {ResultSet} a promise contains the delete operation running time statistics
145+
*/
146+
async deleteGraph() {
147+
var res = await this._sendCommand("graph.DELETE", [this._graphId]);
148+
//clear internal graph state
149+
this._labels = [];
150+
this._relationshipTypes = [];
151+
this._properties = [];
152+
var resultSet = new ResultSet(this);
153+
return resultSet.parseResponse(res);
154+
}
155+
156+
/**
157+
* Calls procedure
158+
* @param {string} procedure Procedure to call
159+
* @param {string[]} [args] Arguments to pass
160+
* @param {string[]} [y] Yield outputs
161+
* @returns {ResultSet} a promise contains the procedure result set data
162+
*/
163+
callProcedure(procedure: string, args = new Array(), y = new Array()) {
164+
let q = "CALL " + procedure + "(" + args.join(",") + ")" + y.join(" ");
165+
return this.query(q);
166+
}
167+
168+
/**
169+
* Retrieves all labels in graph.
170+
* @async
171+
*/
172+
async labels() {
173+
if (this._labelsPromise == undefined) {
174+
this._labelsPromise = this.callProcedure("db.labels").then((response) => {
175+
return this._extractStrings(response);
176+
});
177+
this._labels = await this._labelsPromise;
178+
this._labelsPromise = undefined;
179+
} else {
180+
await this._labelsPromise;
181+
}
182+
}
183+
184+
/**
185+
* Retrieves all relationship types in graph.
186+
* @async
187+
*/
188+
async relationshipTypes() {
189+
if (this._relationshipPromise == undefined) {
190+
this._relationshipPromise = this.callProcedure(
191+
"db.relationshipTypes"
192+
).then((response) => {
193+
return this._extractStrings(response);
194+
});
195+
this._relationshipTypes = await this._relationshipPromise;
196+
this._relationshipPromise = undefined;
197+
} else {
198+
await this._relationshipPromise;
199+
}
200+
}
201+
202+
/**
203+
* Retrieves all properties in graph.
204+
* @async
205+
*/
206+
async propertyKeys() {
207+
if (this._propertyPromise == undefined) {
208+
this._propertyPromise = this.callProcedure("db.propertyKeys").then(
209+
(response) => {
210+
return this._extractStrings(response);
211+
}
212+
);
213+
this._properties = await this._propertyPromise;
214+
this._propertyPromise = undefined;
215+
} else {
216+
await this._propertyPromise;
217+
}
218+
}
219+
220+
/**
221+
* Retrieves label by ID.
222+
* @param {int} id internal ID of label.
223+
* @returns {string} String label.
224+
*/
225+
getLabel(id: number): string {
226+
return this._labels[id];
227+
}
228+
229+
/**
230+
* Retrieve all the labels from the graph and returns the wanted label
231+
* @async
232+
* @param {int} id internal ID of label.
233+
* @returns {string} String label.
234+
*/
235+
async fetchAndGetLabel(id: number) {
236+
await this.labels();
237+
return this._labels[id];
238+
}
239+
240+
/**
241+
* Retrieves relationship type by ID.
242+
* @param {int} id internal ID of relationship type.
243+
* @return String relationship type.
244+
*/
245+
getRelationship(id: number) {
246+
return this._relationshipTypes[id];
247+
}
248+
249+
/**
250+
* Retrieves al the relationships types from the graph, and returns the wanted type
251+
* @async
252+
* @param {int} id internal ID of relationship type.
253+
* @returns {string} String relationship type.
254+
*/
255+
async fetchAndGetRelationship(id: number): Promise<string> {
256+
await this.relationshipTypes();
257+
return this._relationshipTypes[id];
258+
}
259+
260+
/**
261+
* Retrieves property name by ID.
262+
* @param {int} id internal ID of property.
263+
* @returns {string} String property.
264+
*/
265+
getProperty(id: number): string {
266+
return this._properties[id];
267+
}
268+
269+
/**
270+
* Retrieves al the properties from the graph, and returns the wanted property
271+
* @async
272+
* @param {int} id internal ID of property.
273+
* @returns {string} String property.
274+
*/
275+
async fetchAndGetProperty(id: number): Promise<string> {
276+
await this.propertyKeys();
277+
return this._properties[id];
278+
}
279+
}

0 commit comments

Comments
 (0)