New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@douglasgabr/cypher-builder

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@douglasgabr/cypher-builder - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

17

CHANGELOG.md

@@ -0,1 +1,18 @@

# 2.1.0 / 2021-10-09
- fix(patterns): don't add brackets to empty relationship patterns (`.relationship()`)
- before: `-[]-`
- after: `--`
- feat(clauses): add label predicates to where:
```typescript
builder.where((w) => {
w.andLabel('user', 'User').andLabel('admin', ['User', 'Admin']);
});
```
```
WHERE user:User AND admin:User:Admin
```
# 2.0.0 / 2021-10-07

@@ -2,0 +19,0 @@

9

dist/clauses/where.clause.d.ts
import { StringBuilder } from '../types/string-builder';
import { ParametersBag } from '../parameters/ParametersBag';
import { PatternBuilder } from '../patterns/PatternBuilder';
import { CypherBuilderNodes } from '..';
declare type Comparisons = '=' | '=~' | '>' | '>=' | '<' | '<=' | '<>' | 'IN' | 'STARTS WITH' | 'ENDS WITH' | 'CONTAINS';
declare type NullComparison = 'IS NULL';
declare type NullComparison = 'IS NULL' | 'IS NOT NULL';
/**

@@ -57,2 +58,8 @@ * @see [WHERE](https://neo4j.com/docs/cypher-manual/current/clauses/where/)

xorNotLiteral(field: string, comparator: Comparisons, value: string): this;
andLabel<Label extends keyof CypherBuilderNodes & string>(alias: string, labels: Label | Label[]): this;
andNotLabel<Label extends keyof CypherBuilderNodes & string>(alias: string, labels: Label | Label[]): this;
orLabel<Label extends keyof CypherBuilderNodes & string>(alias: string, labels: Label | Label[]): this;
orNotLabel<Label extends keyof CypherBuilderNodes & string>(alias: string, labels: Label | Label[]): this;
xorLabel<Label extends keyof CypherBuilderNodes & string>(alias: string, labels: Label | Label[]): this;
xorNotLabel<Label extends keyof CypherBuilderNodes & string>(alias: string, labels: Label | Label[]): this;
}

@@ -59,0 +66,0 @@ export declare class WhereClauseStringBuilder extends WhereClause implements StringBuilder {

@@ -7,3 +7,3 @@ "use strict";

};
var _WhereClause_instances, _WhereClause_addPredicate, _WhereClause_addWhere, _WhereClause_addPattern, _WhereClause_add, _WhereClause_addLiteral;
var _WhereClause_instances, _WhereClause_addPredicate, _WhereClause_addWhere, _WhereClause_addPattern, _WhereClause_add, _WhereClause_addLiteral, _WhereClause_addLabel;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -13,3 +13,3 @@ exports.WhereClauseStringBuilder = exports.WhereClause = void 0;

const PatternBuilder_1 = require("../patterns/PatternBuilder");
const nullComparison = 'IS NULL';
const nullComparisons = ['IS NULL', 'IS NOT NULL'];
class Comparator {

@@ -34,2 +34,11 @@ constructor(comparator, field, value) {

}
class LabelComparator {
constructor(alias, labels) {
this.alias = alias;
this.labels = labels;
}
build() {
return `${this.alias}:${this.labels.join(':')}`;
}
}
class WherePredicate {

@@ -134,2 +143,20 @@ constructor(prefix, predicate, not, shouldAddPrefix, shouldAddParenthesis) {

}
andLabel(alias, labels) {
return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addLabel).call(this, 'AND', false, alias, labels);
}
andNotLabel(alias, labels) {
return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addLabel).call(this, 'AND', true, alias, labels);
}
orLabel(alias, labels) {
return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addLabel).call(this, 'OR', false, alias, labels);
}
orNotLabel(alias, labels) {
return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addLabel).call(this, 'OR', true, alias, labels);
}
xorLabel(alias, labels) {
return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addLabel).call(this, 'XOR', false, alias, labels);
}
xorNotLabel(alias, labels) {
return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addLabel).call(this, 'XOR', true, alias, labels);
}
}

@@ -179,2 +206,5 @@ exports.WhereClause = WhereClause;

return __classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addPredicate).call(this, prefix, comp, not);
}, _WhereClause_addLabel = function _WhereClause_addLabel(prefix, not, alias, labels) {
__classPrivateFieldGet(this, _WhereClause_instances, "m", _WhereClause_addPredicate).call(this, prefix, new LabelComparator(alias, typeof labels === 'string' ? [labels] : labels), not);
return this;
};

@@ -194,3 +224,4 @@ class WhereClauseStringBuilder extends WhereClause {

function isNullComparator(comparator) {
return nullComparison === comparator;
return (typeof comparator === 'string' &&
nullComparisons.includes(comparator));
}

@@ -8,2 +8,3 @@ import { StringBuilder } from '../types/string-builder';

export declare class Relationship implements StringBuilder {
#private;
private direction;

@@ -10,0 +11,0 @@ private alias;

87

dist/patterns/Relationship.js
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Relationship_instances, _Relationship_buildArrowsString, _Relationship_buildLimitsString, _Relationship_buildBracketsString, _Relationship_buildPropertiesString, _Relationship_buildTypesString;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -9,2 +15,3 @@ exports.Relationship = void 0;

constructor(direction, alias, types, properties, limits) {
_Relationship_instances.add(this);
this.direction = direction !== null && direction !== void 0 ? direction : 'either';

@@ -17,38 +24,54 @@ this.alias = alias !== null && alias !== void 0 ? alias : '';

build() {
let relationshipString = '';
if (this.direction === 'in') {
relationshipString += '<';
const aliasString = this.alias;
const typesString = __classPrivateFieldGet(this, _Relationship_instances, "m", _Relationship_buildTypesString).call(this);
const limitsString = __classPrivateFieldGet(this, _Relationship_instances, "m", _Relationship_buildLimitsString).call(this);
const propertiesString = __classPrivateFieldGet(this, _Relationship_instances, "m", _Relationship_buildPropertiesString).call(this);
const [leftBracket, rightBracket] = __classPrivateFieldGet(this, _Relationship_instances, "m", _Relationship_buildBracketsString).call(this, aliasString, typesString, limitsString, propertiesString);
const [leftArrow, rightArrow] = __classPrivateFieldGet(this, _Relationship_instances, "m", _Relationship_buildArrowsString).call(this);
return `${leftArrow}${leftBracket}${aliasString}${typesString}${limitsString}${propertiesString}${rightBracket}${rightArrow}`;
}
}
exports.Relationship = Relationship;
_Relationship_instances = new WeakSet(), _Relationship_buildArrowsString = function _Relationship_buildArrowsString() {
switch (this.direction) {
case 'in':
return ['<-', '-'];
case 'out':
return ['-', '->'];
case 'either':
default:
return ['-', '-'];
}
}, _Relationship_buildLimitsString = function _Relationship_buildLimitsString() {
let limitsString = '';
if (this.limits) {
limitsString += '*';
if (typeof this.limits === 'number') {
limitsString += this.limits.toString();
}
relationshipString += `-[${this.alias}`;
if (this.types.length > 0) {
relationshipString += `:${this.types.join('|')}`;
}
if (this.limits) {
relationshipString += '*';
if (typeof this.limits === 'number') {
relationshipString += this.limits.toString();
else if (Array.isArray(this.limits)) {
const [start, end] = this.limits;
if (typeof start === 'number') {
limitsString += start.toString();
}
else if (Array.isArray(this.limits)) {
const [start, end] = this.limits;
if (typeof start === 'number') {
relationshipString += start.toString();
}
relationshipString += '..';
if (typeof end === 'number') {
relationshipString += end.toString();
}
limitsString += '..';
if (typeof end === 'number') {
limitsString += end.toString();
}
}
if (this.properties) {
relationshipString += ` { ${Object.entries(this.properties)
.map(([label, value]) => `${label}: ${value}`)
.join(', ')} }`;
}
relationshipString += ']-';
if (this.direction === 'out') {
relationshipString += '>';
}
return relationshipString;
}
}
exports.Relationship = Relationship;
return limitsString;
}, _Relationship_buildBracketsString = function _Relationship_buildBracketsString(aliasString, typesString, limitsString, propertiesString) {
return aliasString || typesString || limitsString || propertiesString
? ['[', ']']
: ['', ''];
}, _Relationship_buildPropertiesString = function _Relationship_buildPropertiesString() {
if (this.properties) {
return ` { ${Object.entries(this.properties)
.map(([label, value]) => `${label}: ${value}`)
.join(', ')} }`;
}
return '';
}, _Relationship_buildTypesString = function _Relationship_buildTypesString() {
return this.types.length > 0 ? `:${this.types.join('|')}` : '';
};
{
"name": "@douglasgabr/cypher-builder",
"version": "2.0.0",
"version": "2.1.0",
"description": "Fluent CQL builder for Neo4j",

@@ -29,2 +29,4 @@ "main": "dist/index.js",

"devDependencies": {
"@commitlint/cli": "^13.2.1",
"@commitlint/config-conventional": "^13.2.0",
"@types/jest": "^27.0.0",

@@ -35,2 +37,3 @@ "@typescript-eslint/eslint-plugin": "^4.28.2",

"eslint-config-prettier": "^8.3.0",
"husky": "^7.0.2",
"jest": "^27.0.6",

@@ -37,0 +40,0 @@ "jest-extended": "^0.11.5",

@@ -23,12 +23,51 @@ # cypher-builder

### Type inference (required for typescript projects)
First, you must create a `*.d.ts` file in your project, in order to type the possible nodes, relationships and their properties.
```typescript
// neo4j-types.d.ts
import '@douglasgabr/cypher-builder';
declare module '@douglasgabr/cypher-builder' {
export interface CypherBuilderNodes {
User: {
id: string;
};
}
export interface CypherBuilderRelationships {
KNOWS: {
level: 'friendship' | 'colleague';
};
}
}
```
That will enable your IDE (tested only in VSCode) to suggest values for your node labels, relationship types and its properties.
**Node Label suggestion:**
![node label suggestion](./images/node-label.png)
**Node Properties suggestion:**
![node properties suggestion](./images/node-properties.png)
**Relationship Type suggestion:**
![relationship type suggestion](./images/relationship-type.png)
### Example
```typescript
import { Builder, RelationshipDirection } from '@douglasgabr/cypher-builder';
const queryBuilder = new Builder()
.match((match) =>
.match((match) => {
match
.node('person', 'Person', { name: 'Alice' })
.relationship(RelationshipDirection.Either, 'KNOWS')
.relationship('either', 'KNOWS')
.node('friend', 'Person'),
)
})
.where((where) => where.and('friend.age', '>=', 18))

@@ -42,4 +81,4 @@ .return('person', 'friend');

```
MATCH (alice:Person{ name: $param1 })-[:KNOWS]-(friend:Person)
WHERE friend.age >= $param2
MATCH (person:Person{ name: $person_name })-[:KNOWS]-(friend:Person)
WHERE friend.age >= $friend_age
RETURN person, friend

@@ -52,5 +91,5 @@ ```

{
param1: 'Alice',
param2: 18
person_name: 'Alice',
friend_age: 18
}
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc