diff --git a/.gitignore b/.gitignore index 710276c..f1b1423 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,4 @@ dist .yarn/unplugged .yarn/build-state.yml .pnp.* +.idea diff --git a/packages/core/README.md b/packages/core/README.md index 60e9e15..65b529d 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -171,6 +171,7 @@ you can also use Query and Edge directives: - **cascade** +- **groupBy** Query only directives: - **ignoreReflex** diff --git a/packages/core/src/directive/directive-builder.ts b/packages/core/src/directive/directive-builder.ts index ddf50eb..a527b7a 100644 --- a/packages/core/src/directive/directive-builder.ts +++ b/packages/core/src/directive/directive-builder.ts @@ -3,12 +3,14 @@ import { OpBuilderTypes } from '../operator'; import { DirectiveArgs, Directive } from './directive'; import { extractRefs } from '../ref'; import { RecurseBuilderArgs } from './recurse' +import { GroupByBuilderArgs } from './group-by' export interface DirectiveBuilderArgs { filter: [OpBuilderTypes]; cascade: undefined; ignoreReflex: undefined; recurse: RecurseBuilderArgs; + groupBy: GroupByBuilderArgs; } export class DirectiveBuilder { diff --git a/packages/core/src/directive/directive.ts b/packages/core/src/directive/directive.ts index 641daaa..01f320c 100644 --- a/packages/core/src/directive/directive.ts +++ b/packages/core/src/directive/directive.ts @@ -1,12 +1,14 @@ import { LogicalOperator, Operator } from '../operator'; import { Param } from '../param'; import { RecurseArgs } from './recurse'; +import { GroupByArgs } from './group-by'; export interface DirectiveArgs { filter: LogicalOperator | Operator; cascade: undefined; ignoreReflex: undefined; recurse: RecurseArgs | undefined; + groupBy: GroupByArgs; } export class Directive { @@ -22,6 +24,7 @@ export class Directive { params(): Param[] { const argsValues = !this.hasArgs() ? [] : Array.isArray(this.args) ? this.args + : typeof this.args!=='object'? [this.args] : Object.entries(this.args).map(([_, value]) => value); return argsValues.reduce((r, arg) => { @@ -36,9 +39,10 @@ export class Directive { toString() { const argsList = !this.hasArgs() ? [] : Array.isArray(this.args) ? this.args + : typeof this.args!=='object'? [this.args] : Object.entries(this.args).map(([key, value]) => `${key}: ${value}`); - return `@${this.name}${ + return `@${this.name.toLowerCase()}${ !argsList.length ? '' : `(${argsList.join(', ')})` }`; } diff --git a/packages/core/src/directive/group-by.ts b/packages/core/src/directive/group-by.ts new file mode 100644 index 0000000..6473f48 --- /dev/null +++ b/packages/core/src/directive/group-by.ts @@ -0,0 +1,8 @@ + +import { Param, ParamBuilder } from '../param'; + +/** @see https://dgraph.io/docs/query-language/groupby/ */ +// predicate +export type GroupByBuilderArgs = string | ParamBuilder<'string'> + +export type GroupByArgs = string | Param<'string'>; diff --git a/packages/core/src/edge/edge-builder.ts b/packages/core/src/edge/edge-builder.ts index 9189ae9..f1adcbf 100644 --- a/packages/core/src/edge/edge-builder.ts +++ b/packages/core/src/edge/edge-builder.ts @@ -17,6 +17,7 @@ import { GenericProjection, } from './common'; import { DirectiveBuilder } from '../directive'; +import { GroupByBuilderArgs } from '../directive/group-by'; import { Ref } from '../ref'; import { Runnable } from '../types'; import { @@ -247,6 +248,11 @@ export class EdgeBuilder extends FieldBuilder { return this; } + groupBy(predicate: GroupByBuilderArgs) { + this.directives.groupBy = new DirectiveBuilder('groupBy', predicate); + return this; + } + keyToField(key: string) { if (['id', 'uid'].includes(key)) return 'uid'; diff --git a/packages/core/test/directive.test.ts b/packages/core/test/directive.test.ts index 5cb92b5..dc3fc4b 100644 --- a/packages/core/test/directive.test.ts +++ b/packages/core/test/directive.test.ts @@ -15,7 +15,7 @@ describe('Directive test', () => { it('`@ignoreReflex` directive', () => { expect(query().ignoreReflex().toString()) - .toMatch(/@ignoreReflex \{/); + .toMatch(/@ignorereflex \{/); }); it('`@recurse` directive no args', () => { @@ -51,4 +51,9 @@ describe('Directive test', () => { expect(myParams[0].getValue()).toEqual('false'); expect(myParams[1].getValue()).toEqual('5'); }); + + it('`@groupBy` directive', () => { + expect(edge({}).groupBy('predicate').toString()) + .toMatch(/@groupby\(predicate\) \{/); + }); });