Skip to content

Commit

Permalink
feat: detect array membership with '_contains'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Jackson committed Feb 4, 2019
1 parent d2a0b1b commit e82efbc
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 36 deletions.
37 changes: 2 additions & 35 deletions lib/firegraph/Collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", { value: true });
const Document_1 = require("./Document");
const Where_1 = require("./Where");
/**
* Retrieves documents from a specified collection path. Currently retrieves
* all fields indicated in the GraphQL selection set. Eventually this will
Expand All @@ -27,41 +28,7 @@ function resolveCollection(store, collectionName, collectionArgs, selectionSet)
if (collectionArgs) {
if (collectionArgs['where']) {
const where = collectionArgs['where'];
where.forEach((filter) => {
const key = filter['key'];
const value = filter['value'];
const splitKey = key.split('_');
const whereOp = splitKey[splitKey.length - 1];
switch (whereOp) {
case 'neq':
collectionQuery = collectionQuery
.where(key, '>', value)
.where(key, '<', value);
break;
case 'gt':
collectionQuery = collectionQuery
.where(key, '>', value);
break;
case 'gte':
collectionQuery = collectionQuery
.where(key, '>', value)
.where(key, '==', value);
break;
case 'lt':
collectionQuery = collectionQuery
.where(key, '<', value);
break;
case 'lte':
collectionQuery = collectionQuery
.where(key, '<', value)
.where(key, '==', value);
break;
default:
collectionQuery = collectionQuery
.where(key, '==', value);
break;
}
});
collectionQuery = Where_1.setQueryFilters(collectionQuery, where);
}
}
const collectionSnapshot = yield collectionQuery.get();
Expand Down
11 changes: 11 additions & 0 deletions lib/firegraph/Where.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
/**
* Parses GraphQL AST to get complex parameters to GraphQL queries.
* @param objectFields Set of key-value pairs in GraphQL AST form.
*/
export declare const parseObjectValue: (objectFields: any) => any;
/**
* Applies filters to a Firestore query. Basically chains a series of
* calls to `firestore.collection#where`.
* @param collectionQuery The query to be made against some collection.
* @param where Set of filters formatted as `KEY_COMPARATOR: VALUE` pairs
*/
export declare const setQueryFilters: (collectionQuery: any, where: any[]) => import("firebase").firestore.Query;
42 changes: 42 additions & 0 deletions lib/firegraph/Where.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Parses GraphQL AST to get complex parameters to GraphQL queries.
* @param objectFields Set of key-value pairs in GraphQL AST form.
*/
exports.parseObjectValue = (objectFields) => {
return objectFields.map((field) => {
const { name, value } = field;
if (value.kind === 'IntValue')
value.value = parseInt(value.value);
return {
key: name.value,
value: value.value
};
});
};
/**
* Applies filters to a Firestore query. Basically chains a series of
* calls to `firestore.collection#where`.
* @param collectionQuery The query to be made against some collection.
* @param where Set of filters formatted as `KEY_COMPARATOR: VALUE` pairs
*/
exports.setQueryFilters = (collectionQuery, where) => {
where.forEach((filter) => {
const key = filter['key'];
const value = filter['value'];
const splitKey = key.split('_');
const whereOp = splitKey[splitKey.length - 1];
const actualKey = key.slice(0, -1 * (whereOp.length + 1));
switch (whereOp) {
case 'eq':
collectionQuery = collectionQuery.where(actualKey, '==', value);
break;
case 'gt':
collectionQuery = collectionQuery.where(actualKey, '>', value);
break;
case 'gte':
collectionQuery = collectionQuery.where(actualKey, '>=', value);
break;
case 'lt':
collectionQuery = collectionQuery.where(actualKey, '<', value);
break;
case 'lte':
collectionQuery = collectionQuery.where(actualKey, '<=', value);
break;
default:
collectionQuery = collectionQuery.where(key, '==', value);
break;
}
});
return collectionQuery;
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "firegraph",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"version": "1.0.9",
"version": "1.0.10",
"license": "MIT",
"scripts": {
"test": "jest --env=jsdom --browser",
Expand Down
4 changes: 4 additions & 0 deletions src/firegraph/Where.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export const setQueryFilters = (
case 'lte':
collectionQuery = collectionQuery.where(actualKey, '<=', value);
break;
case 'contains':
collectionQuery = collectionQuery
.where(actualKey, 'array-contains', value);
break;
default:
collectionQuery = collectionQuery.where(key, '==', value);
break;
Expand Down
16 changes: 16 additions & 0 deletions test/firegraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,21 @@ describe('firegraph', () => {

expect(posts).toHaveLength(2);
});

it('can detect array membership with `_contains`', async () => {
const someUserId = 'sZOgUC33ijsGSzX17ybT';
const { posts } = await firegraph.resolve(firestore, gql`
query {
posts(where: {
likes_contains: ${someUserId},
}) {
id
score
}
}
`);

expect(posts).toHaveLength(1);
});
});
});

0 comments on commit e82efbc

Please sign in to comment.