diff --git a/lib/api/activity/index.js b/lib/api/activity/index.js index 7d67926b4d0..ca1f7572ca6 100644 --- a/lib/api/activity/index.js +++ b/lib/api/activity/index.js @@ -88,7 +88,7 @@ function configure(app, wares, ctx) { api.post('/activity/', ctx.authorization.isPermitted('api:activity:create'), post_response); api.delete('/activity/:_id', ctx.authorization.isPermitted('api:activity:delete'), function(req, res) { - ctx.activity.remove(req.params._id, function() { + ctx.activity.deleteOne(req.params._id, function() { res.json({}); }); }); diff --git a/lib/api/food/index.js b/lib/api/food/index.js index 5db962db403..fbd56ceefd8 100644 --- a/lib/api/food/index.js +++ b/lib/api/food/index.js @@ -71,7 +71,7 @@ function configure (app, wares, ctx) { }); // delete record api.delete('/food/:_id', ctx.authorization.isPermitted('api:food:delete'), function(req, res) { - ctx.food.remove(req.params._id, function ( ) { + ctx.food.deleteOne(req.params._id, function ( ) { res.json({ }); }); }); diff --git a/lib/api/profile/index.js b/lib/api/profile/index.js index 57cce59e69a..9b6e1960a1a 100644 --- a/lib/api/profile/index.js +++ b/lib/api/profile/index.js @@ -92,7 +92,7 @@ function configure (app, wares, ctx) { }); api.delete('/profile/:_id', ctx.authorization.isPermitted('api:profile:delete'), function(req, res) { - ctx.profile.remove(req.params._id, function ( ) { + ctx.profile.deleteOne(req.params._id, function ( ) { res.json({ }); }); }); diff --git a/lib/api3/storage/mongoCollection/modify.js b/lib/api3/storage/mongoCollection/modify.js index 7183f1c971a..20b4013d206 100644 --- a/lib/api3/storage/mongoCollection/modify.js +++ b/lib/api3/storage/mongoCollection/modify.js @@ -69,7 +69,7 @@ function updateOne (col, identifier, setFields) { if (err) { reject(err); } else { - resolve({ updated: result.result.nModified }); + resolve({ updated: result.modifiedCount }); } }); }); @@ -91,7 +91,7 @@ function deleteOne (col, identifier) { if (err) { reject(err); } else { - resolve({ deleted: result.result.n }); + resolve({ deleted: result.deletedCount }); } }); }); diff --git a/lib/api3/storage/mongoCollection/utils.js b/lib/api3/storage/mongoCollection/utils.js index a2f7b16520c..094d663ca24 100644 --- a/lib/api3/storage/mongoCollection/utils.js +++ b/lib/api3/storage/mongoCollection/utils.js @@ -2,7 +2,7 @@ const _ = require('lodash') , checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$") - , ObjectID = require('mongodb').ObjectID + , ObjectID = require('mongodb-legacy').ObjectId ; @@ -112,7 +112,7 @@ function filterForOne (identifier) { // fallback to "identifier = _id" if (checkForHexRegExp.test(identifier)) { - filterOpts.push({ _id: ObjectID(identifier) }); + filterOpts.push({ _id: new ObjectID(identifier) }); } return { $or: filterOpts }; @@ -137,7 +137,7 @@ function identifyingFilter (identifier, doc, dedupFallbackFields) { // fallback to "identifier = _id" (APIv1) if (checkForHexRegExp.test(identifier)) { - filterItems.push({ identifier: { $exists: false }, _id: ObjectID(identifier) }); + filterItems.push({ identifier: { $exists: false }, _id: new ObjectID(identifier) }); } } diff --git a/lib/authorization/storage.js b/lib/authorization/storage.js index 614f8c78051..c119cd7e1cd 100644 --- a/lib/authorization/storage.js +++ b/lib/authorization/storage.js @@ -3,7 +3,7 @@ var _ = require('lodash'); var crypto = require('crypto'); var shiroTrie = require('shiro-trie'); -var ObjectID = require('mongodb').ObjectID; +var ObjectID = require('mongodb-legacy').ObjectId; var find_options = require('../server/query'); @@ -27,14 +27,14 @@ function init (env, ctx) { if (!Object.prototype.hasOwnProperty.call(obj, 'created_at')) { obj.created_at = (new Date()).toISOString(); } - collection.insert(obj, function (err, doc) { + collection.insertOne(obj, function (err, doc) { if (err != null && err.message) { console.log('Data insertion error', err.message); fn(err.message, null); return; } storage.reload(function loaded() { - fn(null, doc.ops); + fn(null, obj); }); }); } @@ -42,7 +42,7 @@ function init (env, ctx) { } function list (collection) { - function doList(opts, fn) { + function doList(opts, fn) { // these functions, find, sort, and limit, are used to // dynamically configure the request, based on the options we've // been given @@ -65,6 +65,8 @@ function init (env, ctx) { fn(err, entries); } + console.log('Loading',opts); + // now just stitch them all together limit.call(collection .find(query_for(opts)) @@ -77,7 +79,7 @@ function init (env, ctx) { function remove (collection) { function doRemove (_id, callback) { - collection.remove({ '_id': new ObjectID(_id) }, function (err) { + collection.deleteOne({ '_id': new ObjectID(_id) }, function (err) { storage.reload(function loaded() { callback(err, null); }); @@ -92,7 +94,7 @@ function init (env, ctx) { if (!obj.created_at) { obj.created_at = (new Date()).toISOString(); } - collection.save(obj, function (err) { + collection.insertOne(obj, function (err) { //id should be added for new docs storage.reload(function loaded() { callback(err, obj); @@ -135,8 +137,14 @@ function init (env, ctx) { storage.reload = function reload (callback) { + console.log('Reloading auth data'); + storage.listRoles({sort: {name: 1}}, function listResults (err, results) { + + console.log('Roles listed'); + if (err) { + console.log('Problem listing roles', err); return callback && callback(err); } @@ -152,6 +160,7 @@ function init (env, ctx) { storage.listSubjects({sort: {name: 1}}, function listResults (err, results) { if (err) { + console.log('Problem listing subjects', err); return callback && callback(err); } diff --git a/lib/client/index.js b/lib/client/index.js index 0f0d17b7d64..5d08e34616e 100644 --- a/lib/client/index.js +++ b/lib/client/index.js @@ -68,7 +68,7 @@ client.init = function init (callback) { }).done(function success (serverSettings) { if (serverSettings.runtimeState !== 'loaded') { console.log('Server is still loading data'); - $('#loadingMessageText').html('Server is starting and still loading data, retrying load in 5 seconds'); + $('#loadingMessageText').html('Nightscout is still starting and should be available within about 15 seconds.'); window.setTimeout(window.Nightscout.client.init, 5000); return; } diff --git a/lib/server/activity.js b/lib/server/activity.js index 45b77e60587..7be7d3d1581 100644 --- a/lib/server/activity.js +++ b/lib/server/activity.js @@ -4,7 +4,7 @@ var find_options = require('./query'); function storage (env, ctx) { - var ObjectID = require('mongodb').ObjectID; + var ObjectID = require('mongodb-legacy').ObjectId; function create (obj, fn) { obj.created_at = (new Date( )).toISOString( ); @@ -62,7 +62,7 @@ function storage (env, ctx) { function remove (_id, fn) { var objId = new ObjectID(_id); - return api( ).remove({ '_id': objId }, fn); + return api( ).deleteOne({ '_id': objId }, fn); } function api ( ) { diff --git a/lib/server/bootevent.js b/lib/server/bootevent.js index b377abcce98..61a6149a43d 100644 --- a/lib/server/bootevent.js +++ b/lib/server/bootevent.js @@ -1,13 +1,15 @@ 'use strict'; const _ = require('lodash'); -const UPDATE_THROTTLE = 5000; +const UPDATE_THROTTLE = 15000; function boot (env, language) { function startBoot(ctx, next) { - console.log('Executing startBoot'); + console.log('++++++++++++++++++++++++++++++'); + console.log('Nightscout Executing startBoot'); + console.log('++++++++++++++++++++++++++++++'); ctx.bootErrors = [ ]; ctx.moment = require('moment-timezone'); @@ -38,7 +40,7 @@ function boot (env, language) { const isLTS = process.release.lts ? true : false; - if (isLTS && (semver.satisfies(nodeVersion, '^20.0.0') || semver.satisfies(nodeVersion, '^18.0.0') || semver.satisfies(nodeVersion, '^16.0.0') || semver.satisfies(nodeVersion, '^14.0.0'))) { + if (isLTS || (semver.satisfies(nodeVersion, '^20.0.0') || semver.satisfies(nodeVersion, '^18.0.0') || semver.satisfies(nodeVersion, '^16.0.0') || semver.satisfies(nodeVersion, '^14.0.0'))) { //Latest Node 14 LTS and Node 16 LTS are recommended and supported. //Require at least Node 14 without known security issues console.debug('Node LTS version ' + nodeVersion + ' is supported'); @@ -148,16 +150,6 @@ function boot (env, language) { } try { - if (_.startsWith(env.storageURI, 'openaps://')) { - require('../storage/openaps-storage')(env, function ready (err, store) { - if (err) { - throw err; - } - ctx.store = store; - console.log('OpenAPS Storage system ready'); - next(); - }); - } else { //TODO assume mongo for now, when there are more storage options add a lookup require('../storage/mongo-storage')(env, function ready(err, store) { // FIXME, error is always null, if there is an error, the index.js will throw an exception @@ -170,7 +162,6 @@ function boot (env, language) { ctx.store = store; next(); }); - } } catch (err) { console.info('ERROR CONNECTING TO MONGO', err); ctx.bootErrors = ctx.bootErrors || [ ]; @@ -295,6 +286,7 @@ function boot (env, language) { ctx.bus.on('data-received', function forceReloadData ( ) { console.info('got data-received event, requesting reload'); + ctx.bus.emit('data-loaded'); // Since we update local sandbox instantly, process data-loaded right away in case this gets debounced updateData(); }); diff --git a/lib/server/devicestatus.js b/lib/server/devicestatus.js index bf71437d646..0bde778a6a6 100644 --- a/lib/server/devicestatus.js +++ b/lib/server/devicestatus.js @@ -24,16 +24,16 @@ function storage (collection, ctx) { obj.utcOffset = d.utcOffset(); api().insertOne(obj, function(err, results) { - if (err !== null && err.message) { + + if (err) { console.log('Error inserting the device status object', err.message); errorOccurred = true; fn(err.message, null); return; } - if (!err) { - - if (!obj._id) obj._id = results.insertedIds[0]._id; + if (results) { + if (!obj._id) obj._id = results.insertedId; r.push(obj); ctx.bus.emit('data-update', { @@ -47,6 +47,11 @@ function storage (collection, ctx) { fn(null, r); ctx.bus.emit('data-received'); } + } else { + console.log('Error inserting the device status object', err.message); + errorOccurred = true; + fn(err.message, null); + return; } }); }; @@ -100,17 +105,19 @@ function storage (collection, ctx) { function removed (err, stat) { + console.log('removed', err, stat); + ctx.bus.emit('data-update', { type: 'devicestatus' , op: 'remove' - , count: stat.result.n + , count: stat.deletedCount , changes: opts.find._id }); fn(err, stat); } - return api().remove( + return api().deleteMany( query_for(opts), removed); } diff --git a/lib/server/entries.js b/lib/server/entries.js index 7e6ac90d35f..0fbe46acca4 100644 --- a/lib/server/entries.js +++ b/lib/server/entries.js @@ -2,7 +2,7 @@ var es = require('event-stream'); var find_options = require('./query'); -var ObjectID = require('mongodb').ObjectID; +var ObjectId = require('mongodb-legacy').ObjectId; var moment = require('moment'); /**********\ @@ -46,12 +46,12 @@ function storage (env, ctx) { } function remove (opts, fn) { - api().remove(query_for(opts), function(err, stat) { + api().deleteMany(query_for(opts), function(err, stat) { ctx.bus.emit('data-update', { type: 'entries' , op: 'remove' - , count: stat.result.n + , count: stat.deletedCount , changes: opts.find._id }); @@ -110,12 +110,12 @@ function storage (env, ctx) { if (doc.dateString) doc.dateString = doc.sysTime; var query = (doc.sysTime && doc.type) ? { sysTime: doc.sysTime, type: doc.type } : doc; - api().update(query, doc, { upsert: true }, function(err, updateResults) { + api().replaceOne(query, doc, { upsert: true }, function(err, updateResults) { firstErr = firstErr || err; - if (!err) { - if (updateResults.result.upserted) { - doc._id = updateResults.result.upserted[0]._id + if (updateResults) { + if (updateResults.upsertedCount == 1) { + doc._id = updateResults.upsertedId } ctx.bus.emit('data-update', { @@ -135,7 +135,7 @@ function storage (env, ctx) { } function getEntry (id, fn) { - api().findOne({ _id: ObjectID(id) }, function(err, entry) { + api().findOne({ "_id": new ObjectId(id) }, function(err, entry) { if (err) { fn(err); } else { diff --git a/lib/server/food.js b/lib/server/food.js index 92c41843f7b..8076ad5aa7a 100644 --- a/lib/server/food.js +++ b/lib/server/food.js @@ -1,7 +1,7 @@ 'use strict'; function storage (env, ctx) { - var ObjectID = require('mongodb').ObjectID; + var ObjectID = require('mongodb-legacy').ObjectId; function create (obj, fn) { obj.created_at = (new Date( )).toISOString( ); @@ -42,7 +42,7 @@ function storage (env, ctx) { function remove (_id, fn) { var objId = new ObjectID(_id); - return api( ).remove({ '_id': objId }, fn); + return api( ).deleteOne({ '_id': objId }, fn); } diff --git a/lib/server/profile.js b/lib/server/profile.js index e49e366d15a..6f5b2b96194 100644 --- a/lib/server/profile.js +++ b/lib/server/profile.js @@ -4,7 +4,7 @@ var find_options = require('./query'); var consts = require('../constants'); function storage (collection, ctx) { - var ObjectID = require('mongodb').ObjectID; + var ObjectID = require('mongodb-legacy').ObjectId; function create (obj, fn) { obj.created_at = (new Date( )).toISOString( ); @@ -79,7 +79,7 @@ function storage (collection, ctx) { function remove (_id, fn) { var objId = new ObjectID(_id); - api( ).remove({ '_id': objId }, fn); + api( ).deleteOne({ '_id': objId }, fn); ctx.bus.emit('data-received'); } diff --git a/lib/server/query.js b/lib/server/query.js index 8279d5ad1e8..0e9750ad562 100644 --- a/lib/server/query.js +++ b/lib/server/query.js @@ -1,7 +1,7 @@ 'use strict'; const traverse = require('traverse'); -const ObjectID = require('mongodb').ObjectID; +const ObjectID = require('mongodb-legacy').ObjectId; const moment = require('moment'); const TWO_DAYS = 172800000; diff --git a/lib/server/treatments.js b/lib/server/treatments.js index a9107ea99b2..687d7cfd914 100644 --- a/lib/server/treatments.js +++ b/lib/server/treatments.js @@ -6,7 +6,7 @@ var moment = require('moment'); var find_options = require('./query'); function storage (env, ctx) { - var ObjectID = require('mongodb').ObjectID; + var ObjectID = require('mongodb-legacy').ObjectId; function create (objOrArray, fn) { @@ -46,18 +46,18 @@ function storage (env, ctx) { , eventType: obj.eventType }; - api( ).update(query, obj, {upsert: true}, function complete (err, updateResults) { + api( ).replaceOne(query, obj, {upsert: true}, function complete (err, updateResults) { if (err) console.error('Problem upserting treatment', err); - if (!err) { - if (updateResults.result.upserted) { - obj._id = updateResults.result.upserted[0]._id + if (updateResults) { + if (updateResults.upsertedCount == 1) { + obj._id = updateResults.upsertedId } } // TODO document this feature - if (!err && obj.preBolus) { + if (updateResults && obj.preBolus) { //create a new object to insert copying only the needed fields var pbTreat = { created_at: (new Date(new Date(results.created_at).getTime() + (obj.preBolus * 60000))).toISOString(), @@ -70,11 +70,11 @@ function storage (env, ctx) { } query.created_at = pbTreat.created_at; - api( ).update(query, pbTreat, {upsert: true}, function pbComplete (err, updateResults) { + api( ).replaceOne(query, pbTreat, {upsert: true}, function pbComplete (err, updateResults) { - if (!err) { - if (updateResults.result.upserted) { - pbTreat._id = updateResults.result.upserted[0]._id + if (updateResults) { + if (updateResults.upsertedCount == 1) { + pbTreat._id = updateResults.upsertedId } } @@ -122,14 +122,14 @@ function storage (env, ctx) { } function remove (opts, fn) { - return api( ).remove(query_for(opts), function (err, stat) { + return api( ).deleteMany(query_for(opts), {}, function (err, stat) { //TODO: this is triggering a read from Mongo, we can do better //console.log('Treatment removed', opts); // , stat); ctx.bus.emit('data-update', { type: 'treatments', op: 'remove', - count: stat.result.n, + count: stat.deletedCount, changes: opts.find._id }); diff --git a/lib/server/websocket.js b/lib/server/websocket.js index 2924db0554d..b3ad9df59af 100644 --- a/lib/server/websocket.js +++ b/lib/server/websocket.js @@ -2,7 +2,7 @@ var times = require('../times'); var calcData = require('../data/calcdelta'); -var ObjectID = require('mongodb').ObjectID; +var ObjectID = require('mongodb-legacy').ObjectId; const forwarded = require('forwarded-for'); function getRemoteIP (req) { @@ -220,7 +220,7 @@ function init (env, ctx, server) { id = new ObjectID(); } - ctx.store.collection(collection).update({ '_id': id } + ctx.store.collection(collection).updateOne({ '_id': id } , { $set: data.data } , function(err, results) { @@ -268,7 +268,7 @@ function init (env, ctx, server) { } var objId = new ObjectID(data._id); - ctx.store.collection(collection).update({ '_id': objId }, { $unset: data.data } + ctx.store.collection(collection).updateOne({ '_id': objId }, { $unset: data.data } , function(err, results) { if (!err) { @@ -394,7 +394,7 @@ function init (env, ctx, server) { console.log(LOG_DEDUP + 'Found similiar', array[0]); array[0].created_at = data.data.created_at; var objId = new ObjectID(array[0]._id); - ctx.store.collection(collection).update({ '_id': objId }, { $set: { created_at: data.data.created_at } }); + ctx.store.collection(collection).updateOne({ '_id': objId }, { $set: { created_at: data.data.created_at } }); if (callback) { callback([array[0]]); } @@ -506,14 +506,14 @@ function init (env, ctx, server) { } var objId = new ObjectID(data._id); - ctx.store.collection(collection).remove({ '_id': objId } + ctx.store.collection(collection).deleteOne({ '_id': objId } , function(err, stat) { if (!err) { ctx.bus.emit('data-update', { type: data.collection , op: 'remove' - , count: stat.result.n + , count: stat.deletedCount , changes: data._id }); diff --git a/lib/storage/mongo-storage.js b/lib/storage/mongo-storage.js index 987e41ef67d..1175cb0d81a 100644 --- a/lib/storage/mongo-storage.js +++ b/lib/storage/mongo-storage.js @@ -1,6 +1,6 @@ 'use strict'; -const MongoClient = require('mongodb').MongoClient; +const MongoClient = require('mongodb-legacy').MongoClient; const mongo = { client: null, @@ -82,10 +82,11 @@ function init(env, cb, forceNewConnection) { mongo.ensureIndexes = function ensureIndexes(collection, fields) { fields.forEach(function (field) { - console.info('ensuring index for: ' + field); + const name = collection.collectionName + "." + field; + console.info('ensuring index for: ' + name); collection.createIndex(field, { 'background': true }, function (err) { if (err) { - console.error('unable to ensureIndex for: ' + field + ' - ' + err); + console.error('unable to ensureIndex for: ' + name + ' - ' + err); } }); }); diff --git a/lib/storage/openaps-storage.js b/lib/storage/openaps-storage.js deleted file mode 100644 index 0c9c238015e..00000000000 --- a/lib/storage/openaps-storage.js +++ /dev/null @@ -1,191 +0,0 @@ -'use strict'; - -var _ = require('lodash'); -var fs = require('fs'); -var crypto = require('crypto'); -var MongoMock = require('mongomock'); - -var config = { - collections: {} -}; - -function init (env, callback) { - - if (!env.storageURI || !_.isString(env.storageURI)) { - throw new Error('openaps config uri is missing or invalid'); - } - - var configPath = env.storageURI.split('openaps://').pop(); - - function addId (data) { - var shasum = crypto.createHash('sha1'); - shasum.update(JSON.stringify(data)); - data._id = shasum.digest('hex'); - } - - function loadData (path) { - - if (!path || !_.isString(path)) { - return [ ]; - } - - try { - purgeCache(path); - var inputData = require(path); - if (_.isArray(inputData)) { - //console.info('>>>input is an array', path); - _.forEach(inputData, addId); - } else if (!_.isEmpty(inputData) && _.isObject(inputData)) { - //console.info('>>>input is an object', path); - inputData.created_at = new Date(fs.statSync(path).mtime).toISOString(); - addId(inputData); - inputData = [ inputData ]; - } else { - //console.info('>>>input is something else', path, inputData); - inputData = [ ]; - } - - return inputData; - } catch (err) { - console.error('unable to find input data for', path, err); - return [ ]; - } - - } - - function reportAsCollection (name) { - var data = { }; - var input = _.get(config, 'collections.' + name + '.input'); - - if (_.isArray(input)) { - //console.info('>>>input is an array', input); - data[name] = _.flatten(_.map(input, loadData)); - } else { - data[name] = loadData(input); - } - - var mock = new MongoMock(data); - - var collection = mock.collection(name); - - var wrapper = { - findQuery: null - , sortQuery: null - , limitCount: null - , find: function find (query) { - query = _.cloneDeepWith(query, function booleanize (value) { - //TODO: for some reason we're getting {$exists: NaN} instead of true/false - if (value && _.isObject(value) && '$exists' in value) { - return {$exists: true}; - } - }); - wrapper.findQuery = query; - return wrapper; - } - , limit: function limit (count) { - wrapper.limitCount = count; - return wrapper; - } - , sort: function sort (query) { - wrapper.sortQuery = query; - return wrapper; - } - , toArray: function toArray(callback) { - collection.find(wrapper.findQuery).toArray(function intercept (err, results) { - if (err) { - return callback(err, results); - } - - if (wrapper.sortQuery) { - var field = _.keys(wrapper.sortQuery).pop(); - //console.info('>>>sortField', field); - if (field) { - results = _.sortBy(results, field); - if (-1 === wrapper.sortQuery[field]) { - //console.info('>>>sort reverse'); - results = _.reverse(results); - } - } - } - - if (wrapper.limitCount !== null && _.isNumber(wrapper.limitCount)) { - //console.info('>>>limit count', wrapper.limitCount); - results = _.take(results, wrapper.limitCount); - } - - //console.info('>>>toArray', name, wrapper.findQuery, wrapper.sortQuery, wrapper.limitCount, results.length); - - callback(null, results); - }); - return wrapper; - } - }; - - return wrapper; - - } - - try { - var customConfig = require(configPath); - - config = _.merge({}, customConfig, config); - - callback(null, { - collection: reportAsCollection - , ensureIndexes: _.noop - }); - } catch (err) { - callback(err); - } -} - -/** - * Removes a module from the cache - * - * see http://stackoverflow.com/a/14801711 - */ -function purgeCache(moduleName) { - // Traverse the cache looking for the files - // loaded by the specified module name - searchCache(moduleName, function (mod) { - delete require.cache[mod.id]; - }); - - // Remove cached paths to the module. - // Thanks to @bentael for pointing this out. - Object.keys(module.constructor._pathCache).forEach(function(cacheKey) { - if (cacheKey.indexOf(moduleName)>0) { - delete module.constructor._pathCache[cacheKey]; - } - }); -} - -/** - * Traverses the cache to search for all the cached - * files of the specified module name - * - * see http://stackoverflow.com/a/14801711 - */ -function searchCache(moduleName, callback) { - // Resolve the module identified by the specified name - var mod = require.resolve(moduleName); - - // Check if the module has been resolved and found within - // the cache - if (mod && ((mod = require.cache[mod]) !== undefined)) { - // Recursively go over the results - (function traverse(mod) { - // Go over each of the module's children and - // traverse them - mod.children.forEach(function (child) { - traverse(child); - }); - - // Call the specified callback providing the - // found cached module - callback(mod); - }(mod)); - } -} - -module.exports = init; diff --git a/package-lock.json b/package-lock.json index 10c5ff1aeb9..53146c954f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1223,6 +1223,20 @@ "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", "dev": true }, + "@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "requires": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -1723,53 +1737,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - } - } - }, "bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -1920,9 +1887,9 @@ } }, "bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.3.0.tgz", + "integrity": "sha512-ukmCZMneMlaC5ebPHXIkP8YJzNl5DC41N5MAIvKDqLggdao342t4McltoJBQfQya/nHBWAcSsYRqlXPoQkTJag==" }, "buffer": { "version": "6.0.3", @@ -2776,11 +2743,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, - "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4212,6 +4174,11 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" }, + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4293,7 +4260,8 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "isexe": { "version": "2.0.0", @@ -5107,6 +5075,11 @@ "tough-cookie": "^4.0.0" }, "dependencies": { + "@types/tough-cookie": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", + "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -6308,16 +6281,55 @@ "integrity": "sha512-mv0RXncyzNt+gtnKOjD3YJK4I6+r9jk3aU5psa8/E8zvpN03AsQ0DkLJPBs5vPAzCfMs4T8gA2UQgaFx3QANHw==" }, "mongodb": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.3.tgz", - "integrity": "sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==", - "requires": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.1.8", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.5.0.tgz", + "integrity": "sha512-XgrkUgAAdfnZKQfk5AsYL8j7O99WHd4YXPxYxnh8dZxD+ekYWFRA3JktUsBnfg+455Smf75/+asoU/YLwNGoQQ==", + "requires": { + "bson": "^5.3.0", + "mongodb-connection-string-url": "^2.6.0", + "saslprep": "^1.0.3", + "socks": "^2.7.1" + } + }, + "mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "requires": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + }, + "dependencies": { + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + } + } + }, + "mongodb-legacy": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mongodb-legacy/-/mongodb-legacy-5.0.0.tgz", + "integrity": "sha512-q2G+MRwde6114bCAF/EZLmMXSsebIKMHmzsfOJq6M/Tj4gr3wLT50+rJsJNkiR0e0kjFx3dllWjqwRR1n11Zsw==", + "requires": { + "mongodb": "^5.0.0" } }, "mongomock": { @@ -6367,9 +6379,9 @@ "dev": true }, "nightscout-connect": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/nightscout-connect/-/nightscout-connect-0.0.11.tgz", - "integrity": "sha512-O7wMMG6BgW7Wxm0hr4Fj9SO1IH/7f29obKSnN8V9I2Ko4v5XxL5FqoONpmvlgI6So0MwksoMCcedSCiCL6Lj4A==", + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/nightscout-connect/-/nightscout-connect-0.0.12.tgz", + "integrity": "sha512-y4Dc+shzkmGQqJG2w2zNp1Jnu4Yzc4VtSCoBiinrssjy+7ksjmOenxVDyh0Xw2UCWMkqr4A4o+iJ28KvrHWcvw==", "requires": { "axios": "^1.3.4", "axios-cookiejar-support": "^4.0.6", @@ -6380,9 +6392,9 @@ }, "dependencies": { "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -6843,14 +6855,6 @@ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, - "optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "requires": { - "require-at": "^1.0.6" - } - }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -7121,7 +7125,8 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "progress": { "version": "2.0.3", @@ -7462,11 +7467,6 @@ "tough-cookie": "^2.3.3" } }, - "require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==" - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8846,6 +8846,11 @@ } } }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, "socket.io": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", @@ -8884,6 +8889,15 @@ "debug": "~4.3.1" } }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/package.json b/package.json index 1464611841d..9c192b7de8a 100644 --- a/package.json +++ b/package.json @@ -114,9 +114,9 @@ "moment-timezone": "^0.5.31", "moment-timezone-data-webpack-plugin": "^1.5.0", "mongo-url-parser": "^1.0.2", - "mongodb": "^3.6.0", + "mongodb-legacy": "^5.0.0", "mongomock": "^0.1.2", - "nightscout-connect": "^0.0.11", + "nightscout-connect": "^0.0.12", "node-cache": "^4.2.1", "parse-duration": "^0.1.3", "process": "^0.11.10", diff --git a/tests/XX_clean.test.js b/tests/XX_clean.test.js index 9b921a01721..3549baa4ba9 100644 --- a/tests/XX_clean.test.js +++ b/tests/XX_clean.test.js @@ -25,13 +25,13 @@ describe('Clean MONGO after tests', function ( ) { }); it('wipe treatment data', function (done) { - self.ctx.treatments().remove({ }, function ( ) { + self.ctx.treatments().deleteMany({ }, function ( ) { done(); }); }); it('wipe entries data', function (done) { - self.ctx.entries().remove({ }, function ( ) { + self.ctx.entries().deleteMany({ }, function ( ) { done(); }); }); diff --git a/tests/api.entries.test.js b/tests/api.entries.test.js index 07fe0cc4aeb..c4cbf90c948 100644 --- a/tests/api.entries.test.js +++ b/tests/api.entries.test.js @@ -63,11 +63,11 @@ describe('Entries REST api', function ( ) { }); afterEach(function (done) { - self.archive( ).remove({ }, done); + self.archive( ).deleteMany({ }, done); }); after(function (done) { - self.archive( ).remove({ }, done); + self.archive( ).deleteMany({ }, done); }); // keep this test pinned at or near the top in order to validate all @@ -238,7 +238,7 @@ describe('Entries REST api', function ( ) { it('/entries/:id', function (done) { var app = self.app; - self.archive.list({count: 1}, function(err, records) { + self.archive.list({count: 10}, function(err, records) { var currentId = records.pop()._id.toString(); request(app) .get('/entries/'+currentId+'.json') diff --git a/tests/api.treatments.test.js b/tests/api.treatments.test.js index 40e2d052de7..17241643a43 100644 --- a/tests/api.treatments.test.js +++ b/tests/api.treatments.test.js @@ -35,7 +35,7 @@ describe('Treatment API', function ( ) { it('post single treatments', function (done) { - self.ctx.treatments().remove({ }, function ( ) { + self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { var now = (new Date()).toISOString(); request(self.app) .post('/api/treatments/') @@ -88,8 +88,8 @@ describe('Treatment API', function ( ) { var current_time = Date.now(); console.log('Testing date with local format: ', _moment(current_time).format("YYYY-MM-DDTHH:mm:ss.SSSZZ")); - - self.ctx.treatments().remove({ }, function ( ) { + + self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { request(self.app) .post('/api/treatments/') .set('api-secret', api_secret_hash || '') @@ -122,7 +122,7 @@ describe('Treatment API', function ( ) { it('post a treatment array', function (done) { - self.ctx.treatments().remove({ }, function ( ) { + self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { var now = (new Date()).toISOString(); request(self.app) .post('/api/treatments/') @@ -149,7 +149,7 @@ describe('Treatment API', function ( ) { }); it('post a treatment array and dedupe', function (done) { - self.ctx.treatments().remove({ }, function ( ) { + self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { var now = (new Date()).toISOString(); request(self.app) .post('/api/treatments/') diff --git a/tests/api.unauthorized.test.js b/tests/api.unauthorized.test.js index e1cfae62ac8..594e2dc6bf7 100644 --- a/tests/api.unauthorized.test.js +++ b/tests/api.unauthorized.test.js @@ -39,11 +39,11 @@ describe('authed REST api', function ( ) { }); afterEach(function (done) { - this.archive( ).remove({ }, done); + this.archive( ).deleteMany({ }, done); }); after(function (done) { - this.archive( ).remove({ }, done); + this.archive( ).deleteMany({ }, done); }); it('disallow unauthorized POST', function (done) { diff --git a/tests/openaps-storage.test.js b/tests/openaps-storage.test.js deleted file mode 100644 index 36714181a40..00000000000 --- a/tests/openaps-storage.test.js +++ /dev/null @@ -1,115 +0,0 @@ -'use strict'; - -var should = require('should'); - -describe('openaps storage', function () { - - var env = require('../lib/server/env')(); - - - before(function (done) { - delete env.api_secret; - env.storageURI = 'openaps://../../tests/fixtures/openaps-storage/config'; - done(); - }); - - it('The module class should be OK.', function (done) { - require('../lib/storage/openaps-storage')(env, function callback (err, storage) { - should.not.exist(err); - should.exist(storage.collection); - should.exist(storage.ensureIndexes); - done(); - }); - }); - - it('find sgv entries', function (done) { - require('../lib/storage/openaps-storage')(env, function callback (err, storage) { - should.not.exist(err); - should.exist(storage.collection); - - storage.collection('entries').find({type: 'sgv'}).toArray(function callback (err, results) { - should.not.exist(err); - should.exist(results); - - results.length.should.equal(4); - results[0].sgv.should.equal(102); - - done(); - }); - }); - }); - - it('find cal entries', function (done) { - require('../lib/storage/openaps-storage')(env, function callback (err, storage) { - should.not.exist(err); - should.exist(storage.collection); - - storage.collection('entries').find({type: 'cal'}).toArray(function callback (err, results) { - should.not.exist(err); - should.exist(results); - - results.length.should.equal(1); - results[0].slope.should.equal(841.6474113376482); - - done(); - }); - }); - }); - - it('find devicestatus entries', function (done) { - require('../lib/storage/openaps-storage')(env, function callback (err, storage) { - should.not.exist(err); - should.exist(storage.collection); - - storage.collection('devicestatus').find({}).toArray(function callback (err, results) { - should.not.exist(err); - should.exist(results); - - results.length.should.equal(1); - results[0].openaps.enacted.eventualBG.should.equal(82); - - done(); - }); - }); - }); - - it('find treatments', function (done) { - require('../lib/storage/openaps-storage')(env, function callback (err, storage) { - should.not.exist(err); - should.exist(storage.collection); - - storage.collection('treatments').find({}).toArray(function callback (err, results) { - should.not.exist(err); - should.exist(results); - - results.length.should.equal(2); - results[0].eventType.should.equal('Temp Basal'); - - done(); - }); - }); - }); - - it('When no connection-string is given the storage-class should throw an error.', function (done) { - delete env.storageURI; - should.not.exist(env.storageURI); - - (function () { - return require('../lib/storage/openaps-storage')(env); - }).should.throw('openaps config uri is missing or invalid'); - - done(); - }); - - it('An invalid connection-string should throw an error.', function (done) { - env.storageURI = 'This is not an openaps config path'; - - (function () { - return require('../lib/storage/openaps-storage')(env); - }).should.throw(Error); - - done(); - }); - -}); -