Skip to content
This repository has been archived by the owner on Aug 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3 from South-Paw/1.1.0
Browse files Browse the repository at this point in the history
1.1.0
  • Loading branch information
South-Paw committed Oct 16, 2019
2 parents 2ee3be6 + 556c9bb commit 3b8c48b
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 55 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@

[![npm](https://img.shields.io/npm/v/@south-paw/koa-mongoose.svg)](https://www.npmjs.com/package/@south-paw/koa-mongoose)
[![CI Status](https://img.shields.io/travis/South-Paw/koa-mongoose.svg)](https://travis-ci.org/South-Paw/koa-mongoose)
[![Coveralls Status](https://img.shields.io/coveralls/github/South-Paw/koa-mongoose.svg)](https://coveralls.io/github/South-Paw/koa-mongoose)
[![Dependencies](https://david-dm.org/South-Paw/koa-mongoose/status.svg)](https://david-dm.org/South-Paw/koa-mongoose)
[![Dev Dependencies](https://david-dm.org/South-Paw/koa-mongoose/dev-status.svg)](https://david-dm.org/South-Paw/koa-mongoose?type=dev)

---

## Features

- Adds `model()` and `document()` to the koa `ctx`
- Config for automatically loading schemas and events on the mongoose instance

## Basic Usage

The middleware config accepts a `user` and `pass` or you can use a `uri` or `url` as an escape hatch for other url schemes.

Unauthenticated connections will also work by omitting the `user` and `pass` and only providing a `host`, `port` and `db`.

Note: If you're using the `mongodb+srv` syntax to connect to [MongoDB Atlas](https://www.mongodb.com/cloud/atlas), you [should use the mongoose `dbName` option to specify the database](https://stackoverflow.com/questions/48917591/fail-to-connect-mongoose-to-atlas/48917626#48917626) because you currently cannot in the connection string. ([source](https://mongoosejs.com/docs/connections.html)) Be sure to change the default koa-mongoose `db` option to match as well.

```js
const Koa = require('koa');
const mongoose = require('@south-paw/koa-mongoose');
Expand All @@ -33,7 +41,7 @@ const config = {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
reconnectTries: Number.MAX_SAFE_INTEGER, // Never stop trying to reconnect
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
bufferMaxEntries: 0, // If not connected, return errors immediately rather than waiting for reconnect
Expand Down Expand Up @@ -67,19 +75,19 @@ const config = {
disconnecting: () => console.log('mongoose: disconnecting'),
disconnected: () => console.log('mongoose: disconnected'),
},
useDefaultErrorHandler: false, // enable or disable the default error handler
};

// apply the middleware
app.use(mongoose(config));

// and you can now use the middleware via the ctx with
// ctx.model(modelName)
// ctx.document(modelName, document)
// `ctx.model(modelName)` and `ctx.document(modelName, document)`
```

## Issues and Bugs

If you find any, please report them [here](https://github.com/South-Paw/koa-mongoose/issues) so they can be squashed.
If you manage to find any, please report them [here](https://github.com/South-Paw/koa-mongoose/issues) so they can be squashed.

## Development and Contributing

Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@south-paw/koa-mongoose",
"version": "1.0.0",
"version": "1.1.0",
"description": "Mongoose middleware for Koa 2",
"keywords": [
"koa",
Expand Down Expand Up @@ -33,8 +33,7 @@
},
"dependencies": {
"debug": "^4.1.1",
"mongoose": "^5.7.5",
"muri": "^1.3.0"
"mongoose": "^5.7.5"
},
"devDependencies": {
"babel-eslint": "^10.0.3",
Expand Down
4 changes: 2 additions & 2 deletions src/__mocks__/mongoose.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const mongoose = {};

function __setupCreateConnectionMock(createConnection) {
const __setupCreateConnectionMock = createConnection => {
mongoose.createConnection = createConnection;
}
};

mongoose.__setupCreateConnectionMock = __setupCreateConnectionMock;

Expand Down
64 changes: 27 additions & 37 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const debug = require('debug')('koa:mongo');
const debug = require('debug')('southpaw:koamongoose');
const mongoose = require('mongoose');
const muri = require('muri');

const defaultMongoOptions = {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
reconnectTries: Number.MAX_SAFE_INTEGER, // Never stop trying to reconnect
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
bufferMaxEntries: 0, // If not connected, return errors immediately rather than waiting for reconnect
Expand All @@ -27,56 +26,47 @@ const middleware = (options = {}) => {
mongoOptions = defaultMongoOptions,
schemas = {},
events = {},
useDefaultErrorHandler = true,
} = options;

let dbName = db;
let mongoUrl = uri || url;
let mongoOpts = { ...defaultMongoOptions, ...mongoOptions };

const mongoUrl =
uri ||
url ||
(user && pass && authSource
? `mongodb://${user}:${pass}@${host}:${port}/${db}?authSource=${authSource}`
: `mongodb://${host}:${port}/${db}`);
const mongoOpts = { ...defaultMongoOptions, ...mongoOptions };
const models = {};

if (!mongoUrl) {
if (user && pass && authSource) {
mongoUrl = `mongodb://${user}:${pass}@${host}:${port}/${db}?authSource=${authSource}`;
} else {
mongoUrl = `mongodb://${host}:${port}/${db}`;
}
} else {
const o = muri(mongoUrl);
dbName = o.db;
}

debug('Create middleware');
const connection = mongoose.createConnection();

const conn = mongoose.createConnection();

conn.on('error', err => {
conn.close();
debug(`An error occured with the Mongoose connection.`);
throw new Error(err);
// Load each schema by it's key
Object.keys(schemas).forEach(schemaName => {
models[schemaName] = connection.model(schemaName, schemas[schemaName](mongoose));
});

if (schemas) {
// Load each schema by it's key
Object.keys(schemas).forEach(key => {
models[key] = conn.model(key, schemas[key](mongoose));
});
}
// Load each event by it's key
Object.keys(events).forEach(event => connection.on(event, events[event]));

if (events) {
// Load each event by it's key
Object.keys(events).forEach(key => conn.on(key, events[key]));
// Enable the default error handler
if (useDefaultErrorHandler) {
connection.on('error', err => {
connection.close();
debug(`An error occured with the Mongoose connection.`);
throw new Error(err);
});
}

conn.openUri(mongoUrl, mongoOpts);
connection.openUri(mongoUrl, mongoOpts);

function getModel(modelName) {
const getModel = modelName => {
if (!models.hasOwnProperty(modelName)) {
throw new Error(`Model '${modelName}' not found in '${dbName}'`);
throw new Error(`Model name '${modelName}' not found in '${db}'`);
}

return models[modelName];
}
};

return async (ctx, next) => {
ctx.model = modelName => {
Expand Down
8 changes: 4 additions & 4 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const defaultOpts = {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
reconnectTries: Number.MAX_VALUE,
reconnectTries: Number.MAX_SAFE_INTEGER,
reconnectInterval: 500,
poolSize: 10,
bufferMaxEntries: 0,
Expand Down Expand Up @@ -62,7 +62,7 @@ describe(name, () => {
it(`should call connect with a given uri`, () => {
const { openUriMock } = mongooseSetup();

const uri = 'mongodb://localhost/mydb';
const uri = 'mongodb+srv://localhost/mydb';
const opts = { ...defaultOpts };

middleware({ uri });
Expand Down Expand Up @@ -134,7 +134,7 @@ describe(name, () => {

middleware({ events: { error, connected }, useDefaultErrorHandler: false });

expect(onMock).toHaveBeenCalledTimes(3);
expect(onMock).toHaveBeenCalledTimes(2);
expect(onMock).toHaveBeenCalledWith('error', error);
expect(onMock).toHaveBeenCalledWith('connected', connected);
});
Expand Down Expand Up @@ -192,7 +192,7 @@ describe(name, () => {
ctx.model('users');

expect(throwMock).toHaveBeenCalledTimes(1);
expect(throwMock).toHaveBeenCalledWith(500, new Error(`Model 'users' not found in 'default'`));
expect(throwMock).toHaveBeenCalledWith(500, new Error(`Model name 'users' not found in 'default'`));
});

it(`calling ctx.document should return a provided model document`, () => {
Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2648,11 +2648,6 @@ ms@2.1.2, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==

muri@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/muri/-/muri-1.3.0.tgz#aeccf3db64c56aa7c5b34e00f95b7878527a4721"
integrity sha512-FiaFwKl864onHFFUV/a2szAl7X0fxVlSKNdhTf+BM8i8goEgYut8u5P9MqQqIYwvaMxjzVESsoEm/2kfkFH1rg==

mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
Expand Down

0 comments on commit 3b8c48b

Please sign in to comment.