Skip to content

Commit

Permalink
Merge pull request #52 from synatic/develop
Browse files Browse the repository at this point in the history
adding types for mongo query & collection
  • Loading branch information
eXigentCoder authored Jun 7, 2024
2 parents b1ba6e0 + c49fb3f commit c3b7ede
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 77 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
"es6": true,
"mocha": true
},
"parserOptions": { "ecmaVersion": 2018 },
"parserOptions": {"ecmaVersion": 2018},
"extends": ["eslint:recommended", "google", "prettier"],
"globals": {},
"rules": {
"indent": ["error", 4, {"SwitchCase": 1}],
"max-len": ["off"],
"no-prototype-builtins": "off",
"valid-jsdoc": "off",
"require-jsdoc": [
"warn",
{
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org/
Expand All @@ -52,7 +52,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org/
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -42,4 +42,4 @@ jobs:
# queries: ./path/to/local/query, your-org/your-repo/queries@main

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
4 changes: 2 additions & 2 deletions .github/workflows/ci-npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org/
Expand All @@ -43,7 +43,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: https://registry.npmjs.org/
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"cSpell.words": ["Aggr"]
"cSpell.words": ["Aggr", "deepmerge", "Mergeable"]
}
98 changes: 65 additions & 33 deletions lib/Collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ const _defaultQueryTimeoutMS = 120000;

/** A wrapper around the mongodb collection with some helper functions
* @class Collection
* @template {Document} TSchema
*/
class Collection {
/** Creates an instance of Collection.
*
* @param {import('mongodb').Collection} collection - the underlying mongo collection
* @param {import('mongodb').Collection<TSchema>} collection - the underlying mongo collection
* @param {object} [options] - the query options
* @param {number} [options.queryTimeout] - the query timeout defaults to 120000ms
* @param {boolean} [options.estimatedDocumentCount] - use estimated document count when calling count
Expand All @@ -37,20 +38,24 @@ class Collection {
/**
* Counts the documents in the collection
* @deprecated in favour of using countDocuments
* @param {Object} query
* @param {MongoQuery<TSchema>} query
* @param {EstimatedDocumentCountOptions | CountDocumentsOptions} [options={}]
* @param {Function} callback
* @param {CountDocumentsCallback} callback
* @return {*}
*/
count(query, options = {}, callback) {
this.countDocuments(query, options, callback);
}

/**
* @callback CountDocumentsCallback
* @param {Error|null} [err]
* @param {number} [count]
*
* Counts the documents in the collection
* @param {Object} query
* @param {EstimatedDocumentCountOptions | CountDocumentsOptions} [options={}]
* @param {Function} callback
* @param {MongoQuery<TSchema>} query
* @param {EstimatedDocumentCountOptions | CountDocumentsOptions|CountDocumentsCallback} [options={}]
* @param {CountDocumentsCallback} callback
* @return {*}
*/
countDocuments(query, options = {}, callback) {
Expand All @@ -60,7 +65,9 @@ class Collection {
} else {
options = options || {};
}
if (!$check.instanceStrict(query, MongoQuery)) return callback('Invalid query object');
if (!$check.instanceStrict(query, MongoQuery)) {
return callback(new Error('Invalid query object'));
}

const filter = query.parsedQuery.query || {};
this._collection
Expand All @@ -77,9 +84,9 @@ class Collection {

/**
* Creates a cursor given the MongoQuery Object
* @param {Object} query - the MongoQuery Object
* @param {import('mongodb').FindOptions} [options={}]
* @return {import('mongodb').FindCursor}
* @param {MongoQuery<TSchema>} query - the MongoQuery Object
* @param {import('mongodb').FindOptions<TSchema>} [options={}]
* @return {import('mongodb').FindCursor<TSchema>}
*/
queryAsCursor(query, options = {}) {
if (!$check.instanceStrict(query, MongoQuery)) throw new Error('Invalid query object');
Expand Down Expand Up @@ -113,11 +120,16 @@ class Collection {
return cursor;
}

/**
* @callback QueryCallback
* @param {Error|null} [err]
* @param {TSchema[]} [results]
*/
/**
* Executes the MongoQuery as an Array
* @param {Object} query - the MongoQuery Object
* @param {import('mongodb').FindOptions} [options={}]
* @param {function} callback
* @param {MongoQuery<TSchema>} query - the MongoQuery Object
* @param {import('mongodb').FindOptions<TSchema>} [options={}]
* @param {QueryCallback} callback
* @return {*}
*/
query(query, options = {}, callback) {
Expand All @@ -127,26 +139,31 @@ class Collection {
} else {
options = options || {};
}
if (!$check.instanceStrict(query, MongoQuery)) return callback('Invalid query object');
if (!$check.instanceStrict(query, MongoQuery)) {
return callback(new Error('Invalid query object'));
}
try {
const cursor = this.queryAsCursor(query, options);

cursor.toArray().then((results)=>{
if (!results) {
return callback(null, []);
}
return callback(null, results);
}).catch((err) => {
return callback(err);
});
cursor
.toArray()
.then((results) => {
if (!results) {
return callback(null, []);
}
return callback(null, results);
})
.catch((err) => {
return callback(err);
});
} catch (exp) {
return callback(exp);
}
}

/**
* Executes the MongoQuery as a stream
* @param {Object} query - the MongoQuery Object
* @param {MongoQuery<TSchema>} query - the MongoQuery Object
* @param {import('mongodb').FindOptions} [options={}]
* @param {CursorStreamOptions} [streamOptions={}]
* @return {import('stream').Readable}
Expand All @@ -160,16 +177,28 @@ class Collection {
}

/**
* @param {Object} options
* @callback UpdateStatsCallback
* @param {Error|null} [err]
* @param {import('mongodb'.UpdateResult<TSchema>} [result]
* //
* @param {import('./types').UpdateStatsOptions<TSchema>} options
* @param {function} callback
* @return {function}
* @return {UpdateStatsCallback}
* @memberof Collection
*/
updateStats(options, callback) {
if (!options.statsField) return callback('Missing stats field');
if (!options.increments) return callback('Missing increments field');
if (!options.date) return callback('Missing date field');
if (!options.query) return callback('Missing query');
if (!options.statsField) {
return callback(new Error('Missing stats field'));
}
if (!options.increments) {
return callback(new Error('Missing increments field'));
}
if (!options.date) {
return callback(new Error('Missing date field'));
}
if (!options.query) {
return callback(new Error('Missing query'));
}

let incrementFields = null;
if ($check.array(options.increments)) {
Expand All @@ -196,14 +225,17 @@ class Collection {
update.$inc[dayPath + '.' + increment.field] = increment.value;
update.$inc[hourPath + '.' + increment.field] = increment.value;
}
this._collection.updateOne(options.query, update).then((result) => {
return callback(null, result);
}).catch(callback);
this._collection
.updateOne(options.query, update)
.then((result) => {
return callback(null, result);
})
.catch(callback);
}

/**
* Gets the underlying MongoDB collection
* @return {import('mongodb').Collection}
* @return {import('mongodb').Collection<TSchema>}
*/
get collection() {
return this._collection;
Expand Down
Loading

0 comments on commit c3b7ede

Please sign in to comment.