A high performance MongoDB ORM for Node.js

Overview

Iridium

A High Performance, IDE Friendly ODM for MongoDB

NPM Module Build Status Coverage Status bitHound Overall Score bitHound Code bitHound Dependencies

Iridium is designed to offer a high performance, easy to use and above all, editor friendly ODM for MongoDB on Node.js. Rather than adopting the "re-implement everything" approach often favoured by ODMs like Mongoose and friends, requiring you to learn an entirely new API and locking you into a specific coding style, Iridium tries to offer an incredibly lightweight implementation which makes your life easier where it counts and gets out of your way when you want to do anything more complex.

It also means that, if you're familiar with the MongoDB CLI you should find working with Iridium very natural, with all database methods returning promises for their results and sensible, type annotated results being provided if you wish to make use of them.

Installation

Iridium makes use of the latest set of @types TypeScript definitions files, allowing you to install everything using just a simple npm install.

npm install iridium --save

Features

  • Built with TypeScript and designed for ease of use, you'll be hard pressed to find another Node.js ORM as easy to pick up and learn when combined with a supporting editor.
  • Promises Throughout mean that you can easily start working with your favourite A+ compliant promise library and writing more readable code. Don't think promises are the way forward? Stick with callbacks, Iridium supports both.
  • Fully Tested with over 300 unit tests and over 95% test coverage, helping to ensure that Iridium always behaves the way it's supposed to.
  • Decorator Support helps describe your classes in an easy to understand and maintain manner, embrace ES7 with strong fallbacks on ES5 compliant approaches.
  • Fall into Success with Iridium's carefully designed API - which is structured to help ensure your code remains maintainable regardless of how large your project becomes.
  • Amazing Documentation which covers the full Iridium API, and is always up to date thanks to the brilliant TypeDoc project, can be found at sierrasoftworks.github.io/Iridium.

Requirements

Iridium is built on top of a number of very modern technologies, including TypeScript 2.0, JavaScript ES6 and the latest MongoDB Node.js Driver (version 2.2). You'll need to be running Node.js 6.x, or 4.x with the --harmony flag to run version 7 of Iridium. For older versions of Node.js, please considering using version 6 of Iridium instead.

For starters, you will need to be running MongoDB 2.6 or later in order to use Iridium - however we recommend you use MongoDB 3.1 due to the various performance improvements they've made. If you're working with TypeScript, you will also need to use the 2.0 compiler or risk having the Iridium type definitions break your project.

Using Iridium

Rather than opt of the usual "Look how quickly you can do something" approach, we thought it might be useful to see an example which covers most of the stuff you'd need to do in Iridium. This example covers defining your own document interfaces, a custom schema and instance type which provides some additional methods.

You'll notice that the House class extends Iridium's Instance class, which gives it methods like save() as well as change tracking when calling save() on the instance. If you'd prefer a lighter approach or to use your own home-grown implementation then you can do so by taking a look at the Custom Instances section.

import {Core, Model, Instance, Collection, Index, Property, ObjectID} from 'iridium';

interface Colour {
    r: number;
    g: number;
    b: number;
}

interface Car {
    make: string;
    model: string;
    colour: Colour;
}

interface HouseDocument {
    _id?: string;
    name: string;

    cars?: Car[];
}

@Index({ name: 1 })
@Collection('houses')
class House extends Instance<HouseDocument, House> implements HouseDocument {
    @ObjectID _id: string;
    @Property(/^.+$/)
    name: string;

    @Property([{
        make: String,
        model: String,
        colour: {
            r: Number,
            g: Number,
            b: Number
        }
    }])
    cars: Car[];

    static onCreating(doc: HouseDocument) {
        doc.cars = doc.cars || [];
    }

    addCar(make: string, model: string, colour: Colour) {
        this.cars.push({
            make: make,
            model: model,
            colour: colour
        });
    }

    get numberOfCars() {
        return this.cars.length;
    }
}

class MyDatabase extends Core {
    Houses = new Model<HouseDocument, House>(this, House);
}

var myDb = new MyDatabase({ database: 'houses_test' });

myDb.connect().then(() => myDb.Houses.insert({
        name: 'My House',
        cars: [{
            make: 'Audi',
            model: 'A4',
            colour: { r: 0, g: 0, b: 0 }
        }]
    }))
    .then(() => myDb.Houses.get())
    .then((house) => {
        house.addCar('Audi', 'S4', { r: 255, g: 255, b: 255 });
        return house.save();
    })
    .then(() => myDb.close());

Defining a Model

Iridium models are created with a reference to their Core (which provides the database connection) and an InstanceType which is composed of a constructor function as well as a number of static properties providing configuration information for the instance.

JavaScript

new Model(core, InstanceType);

TypeScript

new Model<DocumentInterface, InstanceType>(core, InstanceType);

If you're working with TypeScript, you can provide an interface for the document structure used by the database, which will allow you to get useful type hints when you are creating documents. You can also provide the InstanceType to provide useful type information for any instances which are retrieved from the database. This information is carried through all promises and callbacks you will use within Iridium and it makes your life significantly easier.

Typically you will expose your models as variables on a custom Core implementation like this.

class MyCore extends Core {
    MyModel = new Model<MyDocumentInterface, MyInstanceType>(this, MyInstanceType);
}

The InstanceType Constructor

The InstanceType constructor is responsible for creating objects which represent a document retrieved from the database. It also provides a number of configuration details which are used to determine how Iridium works with the model.

There are two approaches to defining an instance constructor - the first is to create a true wrapper like the one provided by Iridium.Instance which offers helper methods like save() and remove(), which comes in very handy for writing concise descriptive code, while the other approach is to simply return the document received from the database - great for performance or security purposes.

TypeScript

interface Document {
    _id?: string;
}

class InstanceType {
    constructor(model: Model<Document, Instance>, document: Document, isNew: boolean = true, isPartial: boolean = false) {

    }

    _id: string;

    static schema: Iridium.Schema = {
        _id: false
    };

    static collection = 'myCollection';
}

JavaScript

module.exports = function(model, document, isNew, isPartial) {

}

module.exports.collection = 'myCollection';
module.exports.schema = {
    _id: false
};

Configuration Options

As we mentioned, configuration of a model is conducted through static properties on its constructor. These configuration options include the schema which is used to validate that all data inserted into the database through Iridium meets certain conditions, the collection which specifies the name of the MongoDB collection into which the documents are stashed and a couple of others worth noting.

Schema

Iridium uses Skmatc for schema validation, you can read more about it on its project page but we'll give a quick rundown of the way you make use of it here.

The model's schema is defined using an object in which keys represent their document property counterparts while the values represent a validation rule. You can also make use of the @Property decorator to automatically build up your schema object.

TypeScript

class InstanceType {
    _id: string;
    email: string;

    static schema: Iridium.Schema = {
        _id: false,
        email: /^.+@.+$/
    };
}
class InstanceType extends Iridium.Instance<any, InstanceType> {
    @Iridium.ObjectID
    _id: string;
    
    @Iridium.Property(String)
    email: string;
}

JavaScript

function InstanceType() {}

InstanceType.schema = {
    _id: false,
    email: /^.+@.+$/
};

The Iridium Instance Class

Instead of implementing your own instance constructor every time, Iridium offers a powerful and tested instance base class which provides a number of useful helper methods and a diff algorithm allowing you to make changes in a POCO manner.

To use it, simply inherit from it (if you need any computed properties or custom methods) or provide it as your instance type when instantiating the model.

TypeScript

class InstanceType extends Iridium.Instance<Document, InstanceType> {
    _id: string;
}

new Iridium.Model<Document, InstanceType>(core, InstanceType);

JavaScript

function InstanceType() {
    Iridium.Instance.apply(this, arguments);
}

require('util').inherits(InstanceType, Iridium.Instance);

new Iridium.Model(core, InstanceType);

If you've used the Iridium.Instance constructor then you'll have a couple of useful helper methods available to you. These include save(), refresh(), update(), remove() and delete() which do more or less what it says on the can - refresh and update are synonyms for one another as are remove and delete.

You'll also find first() and select() which allow you to select the first, or all, entr(y|ies) in a collection which match a predicate - ensuring that this maps to the instance itself within the predicate - helping to make comparisons somewhat easier within JavaScript ES5.

Best Practices

There are a number of best practices which you should keep in mind when working with Iridium to help get the best possible experience. For starters, Iridium is built up of a number of smaller components - namely the validation, transform and caching layers.

Validation Layer

The validation layer allows you to plug in your own custom validators, or simply make use of the built in ones, to quickly validate your documents against a strongly defined schema. It is designed to enable you to quickly generate meaningful and human readable validation messages, minimizing the need for error translation within your application.

Custom validators can be added either using the validators property or by using the @Validate decorator on your instance class.

@Iridium.Validate('myValidator', function(schema, data, path) {
    return this.assert(data == 42)
})
export class InstanceType extends Iridium.Instance<any, InstanceType> {
    @Iridium.Property('myValidator')
    myProperty: number;
}
var skmatc = require('skmatc');

function InstanceType() {
    Iridium.Instance.apply(this, arguments);
}

require('util').inherits(InstanceType, Iridium.Instance);

InstanceType.validators = [
    skmatc.create(function(schema) {
        return schema === 'myValidator';
    }, function(data, schema, path) {
        return data === 42;
    })
];

InstanceType.schema = {
    myProperty: 'myValidator'
};

Iridium expects validators to operate in a read-only mode, modifying documents within your validators (while possible) is strongly discouraged as it can lead to some strange side effects and isn't guaranteed to behave the same way between releases. If you need to make changes to documents, take a look at the Transform Layer.

Transform Layer

The transform layer is designed to make changes to the documents you store within MongoDB as well as the data presented to your application. A good example is the way in which ObjectIDs are treated, within your application they appear as plain strings - allowing you to quickly and easily perform many different operations with them. However, when you attempt to save an ObjectID field to the database, it is automatically converted into the correct ObjectID object before being persisted.

The transform layer allows you to register your own transforms both on a per-model and per-property basis. In the case of a model, the transform is given the whole document and is expected to return the transformed document. Property transforms work the same, except that they are presented with, and expected to return, the value of a single top-level property.

The easiest way to add a transform is using the @Transform decorator, however if you are working in a language which doesn't yet support decorators then you can easily use the transforms property on your instance class.

@Iridium.Transform(document => {
    document.lastFetched = new Date();
}, document => {
    document.lastFetched && delete document.lastFetched;
    return document;
})
export class InstanceType extends Iridium.Instance<any, InstanceType> {
    @Iridium.Transform(data => data.toUpperCase(), data => data.toLowerCase())
    email: string;
}
function InstanceType() {
    Iridium.Instance.apply(this, arguments);
}

require('util').inherits(InstanceType, Iridium.Instance);

InstanceType.transforms = {
    $document: {
        fromDB: document => {
            document.lastFetched = new Date();
        },
        toDB: document => {
            document.lastFetched && delete document.lastFetched;
            return document;
        }
    },
    email: {
        fromDB: value => value.toUpperCase(),
        toDB: value => value.toLowerCase()
    }
};

Transform Gotchas

It is important to note that property transforms are lazily evaluated on field access, rather than when the document is retrieved from the database. This is done for performance reasons, but has the side effect that complex objects which are the targets of property transforms must be re-assigned to the field if you wish to trigger the toDB transform function.

Let's take the following model definition for our example, here we have a GeoJSON representation of a location but we want our application to use the data in a {lat,lng} style object. In this case we can use a transform which translates from one form to another to accomplish our task.

import {inspect} from "util";

export class InstanceType extends Iridium.Instance<any, InstanceType> {
    // Converts a GeoJSON object into a simple {lat, lng} object and back.
    @Iridium.Transform(
        data => { lat: data.coordinates[1], lng: data.coordinates[0] },
        data => { type: "Point", coordinates: [data.lng, data.lat] }
    )
    position: {
        lat: number;
        lng: number;
    };
}

db.Model.findOne().then(instance => {
    console.log(inspect(instance.position)); // { lat: 1, lng: 2 }
    console.log(inspect(instance.document.position)); // { type: "Point", coordinates: [2, 1] }

    let pos = instance.pos;
    pos.lat = 3;
    console.log(inspect(pos)); // { lat: 3, lng: 2 }
    console.log(inspect(instance.position)); // { lat: 1, lng: 2 }
    console.log(inspect(instance.document.position)); // { type: "Point", coordinates: [2, 1] }

    instance.position = pos
    console.log(inspect(instance.position)); // { lat: 3, lng: 2 }
    console.log(inspect(instance.document.position)); // { type: "Point", coordinates: [2, 3] }
});

Useful Transform Tricks

There are a couple of clever tricks you can do using transforms to enable additional functionality within Iridium. An example would be cleaning your documents of properties not defined within your schemas whenever they are saved to the database.

Strict Schemas

Let's say you want to only insert values which appear in your schemas - an example would be if you accept documents from a REST API and don't wish to manually cherry-pick the properties you are going to insert. It could also simply be a way of lazily cleaning up old properties from documents as your schema evolves over time, helping to avoid complications if someone forgets to clean up the database after making changes to the schema. This can be easily achieved using the $document transform.

@Iridium.Transform(document => document, (document, property, model) => {
    Object.keys(document).forEach(key => {
        if(!model.schema.hasOwnProperty(key)) delete document[key];
    });
    
    return document;
})
export class InstanceType extends Iridium.Instance<any, InstanceType> {
    
}
function InstanceType() {
    Iridium.Instance.apply(this, arguments);
}

require('util').inherits(InstanceType, Iridium.Instance);

InstanceType.transforms = {
    $document: {
        fromDB: document => document,
        toDB: (document, property, model) => {
            Object.keys(document).forEach(key => {
                if(!model.schema.hasOwnProperty(key)) delete document[key];
            });
            
            return document;
        }
    }
};
Comments
  • TypeScript compile error

    TypeScript compile error

    TypeScript 1.8.10

    image

    image

    head in index.ts

    /// <reference path="../typings/node/node.d.ts" />
    /// <reference path="../typings/lib.es6/lib.es6.d.ts" />
    /// <reference path="../typings/socket.io/socket.io.d.ts" />
    /// <reference path="../typings/mongodb/mongodb.d.ts" />
    /// <reference path="../typings/lodash/lodash.d.ts" />
    /// <reference path="../typings/bluebird/bluebird.d.ts" />
    
    
    

    tsconfig.json

    {
      "compilerOptions": {
        "experimentalAsyncFunctions": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "moduleResolution": "node",
        "module": "commonjs",
        "sourceMap": true,
        "target": "ES6",
        "pretty": true
      },
    
      "externalTranspiler": "babel",
    
      "files": [
        "./server/index.ts"
      ],
      "exclude": [
        "node_modules"
      ]
    }
    
    opened by uMaxmaxmaximus 16
  • How to populate Instance?

    How to populate Instance?

    I have User Instance class:

    class User extends Instance {
        @Property(true)
        name:string
    
        @Property([User])
        friends:User[]
    }
    

    when i add user to friend list to another user, and try to save:

        firstUser.friends.push(newUser)
        firstUser.save() //error
    

    I get recursion error:

    image

    P.S. of course firstUser !== newUser and they have different ids

    opened by uMaxmaxmaximus 16
  • Added mapReduce on Model

    Added mapReduce on Model

    Sorry for late. I was a little busy with my classes.

    Yes, it went difficult to take Instance type as a generic parameter and I got stuck. So I've worked it out with a decorator on Instance. Sending the PR.

    opened by RagibHasin 12
  • Transform Layer Issues

    Transform Layer Issues

    Today I've tried to apply Transform decorator to my User model.

    @Collection("users")
    @Index({username: 1}, {unique: true})
    @Index({email: 1}, {unique: true})
    @Transform((document) => {
        console.log("From DB");
        return document;
    }, (document, property, model) => {
        console.log("To DB");
        return document;
    })
    export class User extends Instance<IUserDocument, User> implements IUserDocument { ... }
    

    But this resulted in the following TS error:

    TS2345: Argument of type 'typeof User' is not assignable to parameter of type 'Instance<any, any>'.
    

    Then I took a look at the Decorators.d.ts file and found Transform decorator factory function declaration, which is following:

    export declare function Transform(fromDB: (value: any, property: string, model: Model<any, any>) => any, toDB: (value: any, property: string, model: Model<any, any>) => any): (target: Instance<any, any>, property?: string) => void;
    

    it returns (target: Instance<any, any>, property?: string) => void;. I tried to replace Instance<any, any> with InstanceImplementation<any, any> and that fixed the TS error. However, I doubt that is a correct solution.

    Although, TS error has gone after I changed target type, added transform functions are not being executed.

    Then I also tried to add transform functions via transforms static property, like this:

    export class User extends Instance<IUserDocument, User> implements IUserDocument {
        static transforms = {
            $document: {
                fromDB: (document) => {
                    console.log("From DB");
                    return document;
                },
                toDB: (document) => {
                    console.log("To DB");
                    return document;
                }
            }
        };
    }
    

    And it started partially working, partially is because only fromDB function is being executed as expected. toDB is triggered by insert() method, but update() method doesn't trigger toDB.

    A bit about my environment: node 7.6.0 typescript 2.2.1

    Am I missing something or there is a bug in Iridium? Can someone please confirm or disconfirm the issues I've described above?

    opened by jsdream 11
  • Insert documents with upsert option doesn't create _id?

    Insert documents with upsert option doesn't create _id?

    I tried to insert multiple documents and also had the { upsert: true } flag and all the docs were beignt created with { _id: null } value and when upsert is false is works properly.

    opened by pyrossh 11
  • Update a single document with the _id

    Update a single document with the _id

    I want to update a single document with

        this.model.update(_id, item);
    

    However I receive from MongoDB

        multi update only works with $ operators
    

    I even receive the same error when I call

        this.model.update(_id, item, { multi: false });
    

    How would I update a single document? When the id is given why is Iridium using the multi update mode?

    Thank's for your work, regards, Christian

    opened by ChrLipp 11
  • Look at my ORM please =)

    Look at my ORM please =)

    npm https://www.npmjs.com/package/ormjs

    this is code https://github.com/uMaxmaxmaximus/ui-js/tree/master/server/lib/orm I think this is epic =) It is very very very very very elegant API. What do you think about it?

    1. Actually, ArangoDB a graph-oriented database, so that in the future, I will describe these relationships using the edges of the graph, for optimization.

    2. And add drivers platform for another databases, like Mongo e.t.c.

    opened by uMaxmaxmaximus 11
  • instance properties

    instance properties

    After I create an instance of some model I can't read it's properties directly in instance, they are in acc.document. But wen I do Model.findOne in it's callback I got a TInstance object with all properties accessible directly in this object and also in TInstance.document:

    var acc = new AccountInstance(authModule.storage.Accounts, {
        login: 'testUser'
    });
    console.log(acc.login);  // undefined
    console.log(acc.document.login);  // 'testUser'
    authModule.storage.Accounts.findOne().then((acc)=>{
        console.log(acc.login);  // 'testUser'
        console.log(acc.document.login);  // 'testUser'
        done();
    });
    

    Is this a bug or am I missing something? Is it possible to always have all properties in TInstance's root?

    opened by SET001 11
  • ES6: Class constructor Chunk cannot be invoked without 'new'

    ES6: Class constructor Chunk cannot be invoked without 'new'

    I was trying a simple example code:

    interface ChunkDocument{
        _id?: string
      name: string
    }
    
    @Index({ name: 1 })
    @Collection('chunks')
    class Chunk extends Instance<ChunkDocument, Chunk> implements ChunkDocument{
        @ObjectID _id: string;
      @Property(/^.+$/)
      name: string;
    }
    
    class MyDatabase extends Core {
        Chunks = new Model<ChunkDocument, Chunk>(this, Chunk);
      // Houses = new Model<HouseDocument, House>(this, House);
    }
    
    
    var myDb = new MyDatabase({ database: 'avalon' });
    myDb.connect().then(()=>{
        console.log("Database connected");
        myDb.Chunks.find().forEach((chunk: Chunk)=>{
            console.log("===>" + chunk._id + "  " + chunk.name);
            myDb.close();
         })
    }); 
    

    and if I compile it with "target": "es6" in tsconfig.json then I got this error on runtime:

    Unhandled rejection TypeError: Class constructor Chunk cannot be invoked without 'new'
        at new ModelSpecificInstance.constructor (/home/set/www/avalon/server/node_modules/iridium/dist/lib/ModelSpecificInstance.js:18:22)
        at ModelHelpers.wrapDocument (/home/set/www/avalon/server/node_modules/iridium/dist/lib/ModelHelpers.js:35:16)
        at /home/set/www/avalon/server/node_modules/iridium/dist/lib/Model.js:316:137
        at /home/set/www/avalon/server/node_modules/iridium/dist/lib/ModelHandlers.js:33:31
        at tryCatcher (/home/set/www/avalon/server/node_modules/bluebird/js/release/util.js:16:23)
        at Promise._settlePromiseFromHandler (/home/set/www/avalon/server/node_modules/bluebird/js/release/promise.js:502:31)
        at Promise._settlePromise (/home/set/www/avalon/server/node_modules/bluebird/js/release/promise.js:559:18)
        at Promise._settlePromiseCtx (/home/set/www/avalon/server/node_modules/bluebird/js/release/promise.js:596:10)
        at Async._drainQueue (/home/set/www/avalon/server/node_modules/bluebird/js/release/async.js:143:12)
        at Async._drainQueues (/home/set/www/avalon/server/node_modules/bluebird/js/release/async.js:148:10)
        at Immediate.Async.drainQueues [as _onImmediate] (/home/set/www/avalon/server/node_modules/bluebird/js/release/async.js:17:14)
        at tryOnImmediate (timers.js:543:15)
        at processImmediate [as _immediateCallback] (timers.js:523:5)
    
    
    opened by SET001 11
  • Add 'mapReduce' support to Model

    Add 'mapReduce' support to Model

    mapReduce is a often used function of collection and other ODMs support it already.

    It will be great to see it in this project. I'm ready to work out a PR for this (how to instantiate a Model form a MongoDB native collection?)

    opened by RagibHasin 9
  • @types npm scope

    @types npm scope

    Hi, awesome that you are using the new @types scope typings. It makes using iridium a breeze without having to postinstall typings dependencies. 👍

    Here are some additional thoughts regarding the fairly new @types scope:

    1. You should use 0.0.x notation for all @types scoped packages that are below 0.1.0 as ^ will cause unpredictable behaviour in my experience for the below 0.1.0 version range.
    2. You should not use pinned @types packages that are not designed as proper modules as this will cause conflicts when different packages in a node project rely on the same types package -> it will throw typescript errors for double definitions.

    Regards Phil

    opened by philkunz 9
  • chore(deps): bump hosted-git-info from 2.1.5 to 2.8.9

    chore(deps): bump hosted-git-info from 2.1.5 to 2.8.9

    Bumps hosted-git-info from 2.1.5 to 2.8.9.

    Changelog

    Sourced from hosted-git-info's changelog.

    2.8.9 (2021-04-07)

    Bug Fixes

    2.8.8 (2020-02-29)

    Bug Fixes

    • #61 & #65 addressing issues w/ url.URL implmentation which regressed node 6 support (5038b18), closes #66

    2.8.7 (2020-02-26)

    Bug Fixes

    • Do not attempt to use url.URL when unavailable (2d0bb66), closes #61 #62
    • Do not pass scp-style URLs to the WhatWG url.URL (f2cdfcf), closes #60

    2.8.6 (2020-02-25)

    2.8.5 (2019-10-07)

    Bug Fixes

    • updated pathmatch for gitlab (e8325b5), closes #51
    • updated pathmatch for gitlab (ffe056f)

    2.8.4 (2019-08-12)

    ... (truncated)

    Commits
    • 8d4b369 chore(release): 2.8.9
    • 29adfe5 fix: backport regex fix from #76
    • afeaefd chore(release): 2.8.8
    • 5038b18 fix: #61 & #65 addressing issues w/ url.URL implmentation which regressed nod...
    • 7440afa chore(release): 2.8.7
    • 2d0bb66 fix: Do not attempt to use url.URL when unavailable
    • f2cdfcf fix: Do not pass scp-style URLs to the WhatWG url.URL
    • e1b83df chore(release): 2.8.6
    • ff259a6 Ensure passwords in hosted Git URLs are correctly escaped
    • 624fd6f chore(release): 2.8.5
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by nlf, a new releaser for hosted-git-info since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.

    Dependabot will merge this PR once CI passes on it, as requested by @notheotherben.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • chore(deps): bump lodash from 4.17.19 to 4.17.21

    chore(deps): bump lodash from 4.17.19 to 4.17.21

    Bumps lodash from 4.17.19 to 4.17.21.

    Commits
    • f299b52 Bump to v4.17.21
    • c4847eb Improve performance of toNumber, trim and trimEnd on large input strings
    • 3469357 Prevent command injection through _.template's variable option
    • ded9bc6 Bump to v4.17.20.
    • 63150ef Documentation fixes.
    • 00f0f62 test.js: Remove trailing comma.
    • 846e434 Temporarily use a custom fork of lodash-cli.
    • 5d046f3 Re-enable Travis tests on 4.17 branch.
    • aa816b3 Remove /npm-package.
    • See full diff in compare view
    Maintainer changes

    This version was pushed to npm by bnjmnt4n, a new releaser for lodash since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.

    Dependabot will merge this PR once CI passes on it, as requested by @notheotherben.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • chore(deps): bump handlebars from 4.7.6 to 4.7.7

    chore(deps): bump handlebars from 4.7.6 to 4.7.7

    Bumps handlebars from 4.7.6 to 4.7.7.

    Changelog

    Sourced from handlebars's changelog.

    v4.7.7 - February 15th, 2021

    • fix weird error in integration tests - eb860c0
    • fix: check prototype property access in strict-mode (#1736) - b6d3de7
    • fix: escape property names in compat mode (#1736) - f058970
    • refactor: In spec tests, use expectTemplate over equals and shouldThrow (#1683) - 77825f8
    • chore: start testing on Node.js 12 and 13 - 3789a30

    (POSSIBLY) BREAKING CHANGES:

    • the changes from version 4.6.0 now also apply in when using the compile-option "strict: true". Access to prototype properties is forbidden completely by default, specific properties or methods can be allowed via runtime-options. See #1633 for details. If you are using Handlebars as documented, you should not be accessing prototype properties from your template anyway, so the changes should not be a problem for you. Only the use of undocumented features can break your build.

    That is why we only bump the patch version despite mentioning breaking changes.

    Commits

    Commits
    • a9a8e40 v4.7.7
    • e66aed5 Update release notes
    • 7d4d170 disable IE in Saucelabs tests
    • eb860c0 fix weird error in integration tests
    • b6d3de7 fix: check prototype property access in strict-mode (#1736)
    • f058970 fix: escape property names in compat mode (#1736)
    • 77825f8 refator: In spec tests, use expectTemplate over equals and shouldThrow (#1683)
    • 3789a30 chore: start testing on Node.js 12 and 13
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.

    Dependabot will merge this PR once CI passes on it, as requested by @notheotherben.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • chore(deps): bump highlight.js from 9.7.0 to 9.18.5

    chore(deps): bump highlight.js from 9.7.0 to 9.18.5

    Bumps highlight.js from 9.7.0 to 9.18.5.

    Release notes

    Sourced from highlight.js's releases.

    10.3.2 - Oops, "Javascript".

    Tiny tiny release, just to fix the website incorrectly not listing Javascript in the list of languages you could choose for a custom build. NPM and CDN build should not have been affected so 10.3.1 is effectively the same as 10.3.2 for those builds.

    If you made a custom build from the website with 10.3 or 10.3.1 you may want to check and make sure it includes Javascript, and if not, build it again.

    9.18.1 - Brrrrr, it’s freezing.

    Quick release to resolve #2375

    Changelog

    Sourced from highlight.js's changelog.

    Release v9.18.5

    Version 9 has reached end-of-support and will not receive future updates or fixes.

    Please see VERSION_10_UPGRADE.md and perhaps SECURITY.md.

    • enh: Post-install script can be disabled with HLJS_HIDE_UPGRADE_WARNING=yes
    • fix: Deprecation notice logged at library startup a console.log vs console.warn.
      • Notice only shown if actually highlighting code, not just requiring the library.
      • Node.js treats warn the same as error and that was problematic.
      • You (or perhaps your indirect dependency) may disable the notice with the hideUpgradeWarningAcceptNoSupportOrSecurityUpdates option
      • You can also set HLJS_HIDE_UPGRADE_WARNING=yes in your envionment to disable the warning

    Example:

    hljs.configure({
      hideUpgradeWarningAcceptNoSupportOrSecurityUpdates: true
    })
    

    Reference: highlightjs/highlight.js#2877

    Release v9.18.4

    Version 9 has reached end-of-support and will not receive future updates or fixes.

    Please see VERSION_10_UPGRADE.md and perhaps SECURITY.md.

    • fix(livescript) fix potential catastrophic backtracking (#2852) [commit]

    Version 9.18.3

    • fix(parser) Freezing issue with illegal 0 width illegals (#2524)
      • backported from v10.x

    Version 9.18.2

    Fixes:

    • fix(night) Prevent object prototype values from being returned by getLanguage (#2636) night

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • chore(deps): bump mongodb from 2.2.36 to 3.1.13

    chore(deps): bump mongodb from 2.2.36 to 3.1.13

    Bumps mongodb from 2.2.36 to 3.1.13.

    Commits
    • c6f417e chore(release): 3.1.13
    • 210c71d fix(db_ops): ensure we async resolve errors in createCollection
    • 5ad9fa9 fix(changeStream): properly handle changeStream event mid-close (#1902)
    • e806be4 fix(bulk): honor ignoreUndefined in initializeUnorderedBulkOp
    • 050267d fix(*): restore ability to webpack by removing makeLazyLoader
    • 6e896f4 docs: adding aggregation, createIndex, and runCommand examples
    • cb3cd12 chore(release): 3.1.12
    • 508d685 Revert "chore(release): 3.2.0"
    • e7619aa chore(release): 3.2.0
    • d0dc228 chore(travis): include forgotten stage info for sharded builds
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Index decorator not working

    Index decorator not working

    Working with [email protected] on v8.11.3 and 5.6.0

    I want to make an unique index of a collection with @Index decorator. But it seems not working, when I inserted the same object into the collection, it didn't throw any error.

    import { Collection, Core, Index, Instance, Model, ObjectID, Property } from 'iridium';
    
    interface Colour {
        r: number;
        g: number;
        b: number;
    }
    
    interface Car {
        make: string;
        model: string;
        colour: Colour;
    }
    
    interface HouseDocument {
        _id?: string;
        name: string;
    
        cars?: Car[];
    }
    
    
    @Index({ name: 1 }, {unique: true}) // It seems not work
    @Collection('houses')
    class House extends Instance<HouseDocument, House> implements HouseDocument {
        @ObjectID _id: string;
        @Property(/^.+$/)
        name: string;
    
        @Property([{
            make: String,
            model: String,
            colour: {
                r: Number,
                g: Number,
                b: Number
            }
        }])
        cars: Car[];
    
        static onCreating(doc: HouseDocument) {
            doc.cars = doc.cars || [];
        }
    
        addCar(make: string, model: string, colour: Colour) {
            this.cars.push({
                make: make,
                model: model,
                colour: colour
            });
        }
    
        get numberOfCars() {
            return this.cars.length;
        }
    }
    
    class MyDatabase extends Core {
        Houses = new Model<HouseDocument, House>(this, House);
    }
    
    var myDb = new MyDatabase({ database: 'houses_test' });
    myDb.connect()
        // I have to use this: 
        // .then(() => myDb.Houses.ensureIndex({name: 1}, { unique: true }))
        .then(() => myDb.Houses.insert({
            name: 'My House',
            cars: [{
                make: 'Audi',
                model: 'A4',
                colour: { r: 0, g: 0, b: 0 }
            }]
        }))
        .then(() => myDb.Houses.insert({
            name: 'My House',
            cars: [{
                make: 'Audi',
                model: 'A4',
                colour: { r: 0, g: 0, b: 0 }
            }]
        }))
        .then(() => myDb.close())
    
    opened by datdev98 1
Releases(v8.0.0-alpha.13)
  • v8.0.0-alpha.13(Mar 30, 2018)

    This release makes a number of improvements to Iridium's core to make it more intuitive to use and easier to reason about. Unfortunately this does involve changing aspects of how the core behaves when compared to v8.0.0-alpha.12, however this behaviour was unspec'ed and resulted in a poor user experience.

    Changes

    • Making modifications to transformed object properties (or array properties) will now be reflected when calling .save() on an instance - even if you have not assigned a new value to the field - see #118 for more information.
    • The TDocument type is now strictly treated as a representation of the DB data structure rather than the pseudo "post-transform" format it used to represent. Previously it would sometimes represent post-transform documents and other times it would represent pre-transform documents, making it difficult to understand its purpose or reason about its behaviour. This change affects the way .insert() and .create() behave, please see the Upgrading section for more information.
    • Support for using Instance-like objects within instance fields. The introduction of the new TransformClass and TransformClassList field decorators and the fixes for #118 make it possible to easily use class based objects to represent your collections (User { friends: Friend[] }).
    • Updated README.md file with a comprehensive example of how to leverage a number of the tools Iridium provides you with (and up-to-date code).
    • Updated MongoDB client library definitions: improved query type hints

    Updating

    1. TDocument changes

    As a result of the specification of TDocument (the first type parameter on your Instance and Model types) as the "type representation of the database's stored document", it is now no longer correct to represent the types of TDocument fields as the types that result from running transforms against them.

    Pre v8.0.0-alpha.13
    interface MyDoc {
      _id?: string
      name: string
    }
    
    class MyInstance extends Instance<MyDoc, MyInstance> implements MyDoc {
      @ObjectID
      _id: string
      
      @Property(String)
      name: string
    }
    
    Post v8.0.0-alpha.13

    Notice that the MyDoc._id field is now a mongodb.ObjectId type and that MyInstance no longer implements MyDoc.

    import {ObjectId} from "mongodb"
    
    interface MyDoc {
      _id?: ObjectId
      name: string
    }
    
    class MyInstance extends Instance<MyDoc, MyInstance> {
      @ObjectID
      _id: string
      
      @Property(String)
      name: string
    }
    

    2. .insert() and .create() changes

    In addition to the changes you should make to your Instance objects and TDocument interfaces, you should also curate your use of .insert() and .create() to replace instances where you pass untransformed data to them for insertion in raw document form.

    For the time being Iridium will provide backward support for the legacy way of inserting and creating documents, however in future this will be removed and you will need to either provide "DB ready" documents or utilize a (to be designed and implemented) API to transform an intermediary representation into a "DB ready" object.

    Pre v8.0.0-alpha.13
    db.User.insert({
      // Will be normalized by lowercasing and trimming
      email: "[email protected] "
    })
    
    Post v8.0.0-alpha.13
    Inserting a "DB-ready" object
    db.User.insert({
      email: "[email protected]"
    })
    
    Using an instance to generate the object
    const user = new db.User.Instance({})
    user.email = "[email protected] "
    
    db.User.insert(user)
    

    3. Updated Conditions interface

    With the MongoDB client driver's types now including their own implementation of this interface with support for schemas (and the standardization of TDocument as the DB schema) we have updated the Conditions type to point to the official mongodb.FilterQuery interface.

    For all intents and purposes it should behave as it used to, however if you have been referencing Conditions in your code you will need to update it to Conditions<TDocument> to take advantage of the new schema support.

    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.12(Feb 6, 2018)

    This release adds support for MongoDB's 3.x client driver, with the various new features provided by it. For most users, this should be a drop-in replacement with Iridium abstracting the API changes, however if you are interacting with the underling MongoDB connection objects, you may need to make some changes to your code.

    Changes

    • Iridium.Core.connection is now a MongoDB.MongoClient object rather than the original MongoDB.Db object.
    • Iridium.Core.db now exposes the MongoDB.Db object if you require it.
    • Updated the URL builder to meet the requirements of the MongoDB 3 client driver
    • Updated the Iridium.Model.update method to explicitly call MongoDB.collection.replaceOne when you provide it with a document that isn't composed entirely of atomic changes. It will also throw an error if you provide such a document (for replacement) and specify { multi: true } in your options.
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.11(Feb 6, 2018)

    This release updates the default Instance implementation to call the onCreate hook when an instance is first being saved to the DB - thanks @CatGuardian for the PR.

    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.10(Jan 16, 2018)

  • v8.0.0-alpha.9(Jan 16, 2018)

  • v8.0.0-alpha.8(Jan 13, 2018)

    This release adds support for renaming DB fields using the new @Rename decorator as requested in #108.

    It can be used as follows:

    import * from "iridium"
    
    @Collection("houses")
    export class House extends Instance<HouseDocument, House> implements HouseDocument {
      @ObjectID
      public _id: string;
    
      @Property(String)
      @Rename("house_name")
      public houseName: string;
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.7(Jan 13, 2018)

  • v8.0.0-alpha.6(Jan 13, 2018)

    This release adds the ability to pass options to MongoDB's underlying aggregate() method when using it through Iridum's Model class, as requested in #106. For more information on the types of options which can be passed, as well as how to use the Aggregate method, please consult the official MongoDB documentation.

    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.5(Jan 13, 2018)

    This release adds a regression test to prevent the type of issue described in #96 as well as adding various BSON type helpers (like Iridium.toObjectID) for Numeric types (#103).

    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.4(Jan 13, 2018)

  • v8.0.0-alpha.3(Jan 13, 2018)

    This release adds a number of fixes for v2.4.1 of TypeScript as well as a regression test for #91. More notably, it also removes Bluebird as a dependency, allowing you to use Iridium with native promises (#95). You can still use Bluebird if you wish by importing it as a poly-fill, but this is now at the discretion of the user.

    Source code(tar.gz)
    Source code(zip)
  • v8.0.0-alpha.2(Jul 13, 2017)

  • v8.0.0-alpha.1(Jul 13, 2017)

    This release removes the [name: string]: any indexer type from the Iridium.Instance class. This means that you will be forced, when working with TypeScript, to sub-class Iridium.Instance for any custom models (already the best practice and most commonly used approach).

    It also adds support for TypeScript 2.4.1's stricter generic checks, which has resulted in a few interfaces being slightly changed. These changes should have no affect on your code, however as they are changes to the public API, this has resulted in a major version bump.

    Source code(tar.gz)
    Source code(zip)
  • v7.2.5(Jul 7, 2017)

    This release addresses an issue in the diff calculator which is showcased in #83, specifically when you are computing a diff on an array of documents where properties of some change while other documents are removed. This would result in only the removal operation being generated and would leave the changed documents in their original state.

    const original = { array: [
      { x: 1, y: 1 },
      { x: 2, y: 2 }
    ]}
    
    const current = { array: [
      { x: 1, y: 2 }
    ]}
    
    const expectedDiff = {
      "$set": {
        "array": [
          { x: 1, y: 2 }
        ]
      }
    }
    
    const brokenDiff = {
      "$pull": {
        "array": { x: 2, y: 2 }
      }
    }
    

    Thank you to @fduplessisduplessis for the comprehensive reproduction case which enabled us to identify and resolve the issue.

    Source code(tar.gz)
    Source code(zip)
  • v7.2.4(Jul 5, 2017)

    This version fixes #82, a particularly painful bug that had taken a while to track down. It is finally fixed thanks to the hard work of @fduplessisduplessis and EMSSConsulting, thanks to everyone involved in getting that addressed.

    npm install [email protected]
    

    Changes

    Source code(tar.gz)
    Source code(zip)
  • v7.2.1(May 29, 2017)

    This patch release updates the mapReduce implementation to reduce the dependency on TypeScript type checking for reliable operation of the methods - instead using runtime checks to ensure that expected values are present. This should not only make them safer for pure JavaScript users but also simplify implementation constraints for TypeScript users. Thanks to @RagibHasin for #78 which addresses these issues.

    Source code(tar.gz)
    Source code(zip)
  • v7.2.0(May 18, 2017)

    This release adds support for MongoDB's mapReduce operation thanks to a brilliant PR by @RagibHasin. It supports both inline mapReduce and reducing into a typed Iridium collection. It also includes a number of improvements to Iridum's documentation and some regression tests to help avoid situations like we saw in #73.

    Using MapReduce

    Inline Reduce

    Inline reductions are great for once-off operations where you do not wish to persist the results to a collection. It allows you to provide a map and reduce function and will return the resulting documents that leave the reduce function.

    interface MySourceDoc {
      _id: string;
      group_key: string;
      value: number;
    }
    
    @Iridium.Collection("source")
    class MySourceModel extends Iridium.Instance<MySourceDoc, MySourceModel> {
      _id: string;
      group_key: string;
      value: number;
    }
    
    const core = new Iridium.Core("mongodb://localhost:27017")
    await core.connect()
    
    const source = new Iridium.Model<MySourceDoc, MySourceModel>(core, MySourceModel);
    
    const result = await source.mapReduce({
      map: function() {
        emit(this.group_key, this.value);
      },
      reduce: function(key, values) {
        return Array.sum(values);
      }
    }, { out: "inline" });
    
    result.forEach(item => {
      console.log(`group '${item._id}': ${item.value}`);
    });
    

    Reduce into a Collection

    In situations where you require more control over the documents you receive from mapReduce (performing transforms etc) you can use the @Iridium.MapReduce decorator function on an instance class and provide that to the mapReduce method call. This will allow you to retroactively access the results of the mapReduce operation in the specified @Iridium.Collection.

    interface MySourceDoc {
      _id: string;
      group_key: string;
      value: number;
    }
    
    @Iridium.Collection("source")
    class MySourceModel extends Iridium.Instance<MySourceDoc, MySourceModel> {
      _id: string;
      group_key: string;
      value: number;
    }
    
    interface MyReducedDoc {
      _id: string;
      value: number;
    }
    
    @Iridium.Collection("reduced")
    @Iridium.MapReduce<MySourceDoc, string, number>(function() {
      emit(this.group_key, this.value);
    }, function(key, values) {
      return Array.sum(values);
    })
    class MyReducedModel extends Iridium.Instance<MyReducedDoc, MyReducedModel> {
      _id: string;
      value: number;
    }
    
    const core = new Iridium.Core("mongodb://localhost:27017")
    await core.connect()
    
    const source = new Iridium.Model<MySourceDoc, MySourceModel>(core, MySourceModel);
    const reduced = new Iridium.Model<MyReduceDoc, MyReduceModel>(core, MyReduceModel);
    
    await source.mapReduce(reduced, { out: "replace" })
    await reduced.find().forEach(item => {
      console.log(`group '${item._id}': ${item.value}`);
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v7.1.3(Feb 11, 2017)

  • v7.1.2(Feb 11, 2017)

    This release fixes the behavior of the Model.insert and Model.create methods when the { upsert: true } option is provided and documents do not include an _id field. Previously, documents would be "upserted" with { _id: null } leading to issues.

    As of this release, documents will be upserted using { _id: { $exists: false } } as the default upsert condition when an _id is not provided - resolving this problem.

    Please be aware that using { upsert: true } imparts a significant performance penalty on bulk inserts and should be avoided in situations where you are working with a large number of documents. The better approach is to split your document set into documents with _ids and those without, using { upsert: true } only for those in the former set and using { upsert: false } for the rest.

    Source code(tar.gz)
    Source code(zip)
  • v7.1.0(Dec 16, 2016)

    This release includes a large amount of refactoring to ensure compatibility with TypeScript 2.1 and enabling of the noImplicitAny build flag (which is disabled by default).

    In addition to that, the requirements on what type of promise is allowed for Core.onConnecting and Core.onConnected has been relaxed thanks to the work of @aikoven.

    We've also put in some work to reducing code quality warnings on BitHound which should also make it easier to follow portions of our codebase.

    The final change, and reason for the minor version bump, is the inclusion of Iridium's Changes type in our external API. This type neatly enforces the MongoDB changes object, allowing you to strongly type aspects of your code which generate these.

    Source code(tar.gz)
    Source code(zip)
  • v7.0.3(Nov 23, 2016)

    This version refactors the types used for the Iridium Core's constructor configuration options so that they accurately track the MongoDB driver's connection options. This should make connecting using complex configurations less prone to failure as a result of version discrepancies.

    More information about these connection options can be found in the official MongoDB driver documentation:

    • http://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html
    • http://mongodb.github.io/node-mongodb-native/2.2/api/Db.html
    • http://mongodb.github.io/node-mongodb-native/2.2/api/Server.html
    • http://mongodb.github.io/node-mongodb-native/2.2/api/ReplSet.html
    • http://mongodb.github.io/node-mongodb-native/2.2/api/Mongos.html
    Source code(tar.gz)
    Source code(zip)
  • v7.0.2(Nov 7, 2016)

    This patch fixes the return value of the Model.update() function when { multi: false } is provided, specifically that non-error operations which didn't update any documents would previously return a 1. This has been addressed such that it will return 1 when the document is updated and 0 when it is not (no properties changed or no documents were matched).

    Source code(tar.gz)
    Source code(zip)
  • v7.0.1(Nov 1, 2016)

    This is a patch release which addresses an issue in the Model.update() function which would prevent it from correctly handling the { multi: false } option. This would prevent you from being able to perform replacement updates as well as leading to potentially unwanted multi-updates.

    Source code(tar.gz)
    Source code(zip)
  • v7.0.0(Sep 28, 2016)

    This is the release version of Iridium 7, it has been in Alpha for a while as we've worked on stabilizing the APIs on TypeScript 2.0 and getting TypeScript type definitions sorted out.

    TL;DR

    1. Switched from typings to @types/....
    2. Smaller npm packages with the same developer experience.
    3. Switched to TypeScript 2.0
      1. Much better custom validator developer experience.
      2. Fewer edge case bugs thanks to strictNullChecking in TypeScript 2.0.
    4. Breaking changes since 7.0.0-alpha.10
      1. Core.connection throws an exception if the core is not connected.
      2. All database methods now resolve to undefined if the item is not found.

    Changes

    Specifically, we've moved to using @types/... through npm as a replacement for typings, this should significantly improve the developer workflow and we've updated the Example Project to showcase this.

    We've also moved towards bundling only the type definitions, compiled JS and source maps in the NPM package, this should help reduce the installed size of Iridium while still being extremely easy to use. For bonus points, take a look at source-map-support to start getting accurate stack traces against the TypeScript files in your project.

    For those of you who use custom validators, TypeScript 2.0's support for typing this in functions should make your declarations easier than ever, finally providing accurate type information in your custom validators. This should help make them far easier to use going forward.

    Last, but certainly not least, we've gone through the codebase and updated it to work with strictNullChecking enabled, which caught a number of small corner cases which we had missed in testing.

    Breaking Changes

    There are, unfortunately, a couple of breaking changes in this release. This was primarily the result of switching to strict null checking, requiring us to specify the exact behaviour of certain methods.

    1. Accessing Core.connection before calling Core.connect() will now result in an exception warning you of the fact. This was previously handled in the model and could result in situations where you received a null connection from Core.connection.
    2. All database method callbacks and promises resolve to undefined when items are not found (they were previously unconstrained to either undefined or null). If you are explicitly checking for null you will need to update your code from this:
    model.get().then(item => {
      if (item === null) {
        // do something
      }
    });
    

    to this:

    model.get().then(item => {
      if (item === undefined) {
        // do something
      }
    });
    

    or this:

    model.get().then(item => {
      if (!item) {
        // do something
      }
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v7.0.0-alpha.14(Aug 1, 2016)

    This release is primarily a tooling improvement over v7.0.0-alpha.11 which makes our code coverage tools aware of that magical thing called TypeScript and fixes a couple of small bugs in the way type safety was enforced for query and change arguments in MongoDB.

    Source code(tar.gz)
    Source code(zip)
  • v7.0.0-alpha.11(Aug 1, 2016)

    This release adds support for TypeScript 2.0 and takes advantage of some of its new features to make Iridium better than ever. :fireworks:

    TL;DR

    1. Switched from typings to @types/....
    2. Smaller npm packages with the same developer experience.
    3. Switched to TypeScript 2.0
      1. Much better custom validator developer experience.
      2. Fewer edge case bugs thanks to strictNullChecking in TypeScript 2.0.
    4. Breaking changes since 7.0.0-alpha.10
      1. Core.connection throws an exception if the core is not connected.
      2. All database methods now resolve to undefined if the item is not found.

    Changes

    Specifically, we've moved to using @types/... through npm as a replacement for typings, this should significantly improve the developer workflow and we've updated the Example Project to showcase this.

    We've also moved towards bundling only the type definitions, compiled JS and source maps in the NPM package, this should help reduce the installed size of Iridium while still being extremely easy to use. For bonus points, take a look at source-map-support to start getting accurate stack traces against the TypeScript files in your project.

    For those of you who use custom validators, TypeScript 2.0's support for typing this in functions should make your declarations easier than ever, finally providing accurate type information in your custom validators. This should help make them far easier to use going forward.

    Last, but certainly not least, we've gone through the codebase and updated it to work with strictNullChecking enabled, which caught a number of small corner cases which we had missed in testing.

    Breaking Changes

    There are, unfortunately, a couple of breaking changes in this release. This was primarily the result of switching to strict null checking, requiring us to specify the exact behaviour of certain methods.

    1. Accessing Core.connection before calling Core.connect() will now result in an exception warning you of the fact. This was previously handled in the model and could result in situations where you received a null connection from Core.connection.
    2. All database method callbacks and promises resolve to undefined when items are not found (they were previously unconstrained to either undefined or null). If you are explicitly checking for null you will need to update your code from this:
    model.get().then(item => {
      if (item === null) {
        // do something
      }
    });
    

    to this:

    model.get().then(item => {
      if (item === undefined) {
        // do something
      }
    });
    

    or this:

    model.get().then(item => {
      if (!item) {
        // do something
      }
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v7.0.0-alpha.3(Apr 15, 2016)

  • v7.0.0-alpha.2(Apr 15, 2016)

    This release changes from using DefinitelyTyped for type definition management to instead adopt the new Typings tool. Typings is set to replace definitely typed (and more specifically, the tsd CLI) for type definitions going forward and provides a vastly improved developer experience.

    We recommend that you switch to Typings as part of your upgrade to Iridium 7 as it will likely improve your development workflow and will also enable us to improve the way Iridium integrates going forward.

    You'll also find a new Installation section in the README which showcases how one would go about installing Iridium on a new (or existing) project. It's a little bit more complex than just npm install, however nothing too crazy and something we're working on improving.

    Source code(tar.gz)
    Source code(zip)
  • v6.7.0(Apr 15, 2016)

    This release updates the typescript definitions that Iridium uses to their latest publicly available versions, it should help resolve issues people are having with the references they make use of in their projects.

    Source code(tar.gz)
    Source code(zip)
  • v6.6.1(Mar 18, 2016)

    This is primarily a maintenance release involving updating the TypeScript compiler to 1.8 and making a number of style changes to the code to make life easier for contributors

    You'll also notice that we've switched to BitHound as the primary code quality platform (from CodeClimate). We'll continue to evaluate BitHound and CodeClimate going forward to determine whether we should switch back at any point.

    Source code(tar.gz)
    Source code(zip)
Owner
Sierra Softworks
We're a group of people with a passion for software development and extensive experience on both the development and operations side of large scale systems.
Sierra Softworks
A Node.js ORM for MySQL, SQLite, PostgreSQL, MongoDB, GitHub and serverless service like Deta, InspireCloud, CloudBase, LeanCloud.

Dittorm A Node.js ORM for MySQL, SQLite, PostgreSQL, MongoDB, GitHub and serverless service like Deta, InspireCloud, CloudBase, LeanCloud. Installatio

Waline 21 Dec 25, 2022
Execute one command (or mount one Node.js middleware) and get an instant high-performance GraphQL API for your PostgreSQL database!

PostGraphile Instant lightning-fast GraphQL API backed primarily by your PostgreSQL database. Highly customisable and extensible thanks to incredibly

Graphile 11.7k Jan 4, 2023
An easy-to-use multi SQL dialect ORM tool for Node.js

Sequelize Sequelize is a promise-based Node.js ORM tool for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction s

Sequelize 27.3k Jan 4, 2023
A simple Node.js ORM for PostgreSQL, MySQL and SQLite3 built on top of Knex.js

bookshelf.js Bookshelf is a JavaScript ORM for Node.js, built on the Knex SQL query builder. It features both Promise-based and traditional callback i

Bookshelf.js 6.3k Jan 2, 2023
An SQL-friendly ORM for Node.js

Objection.js Objection.js is an ORM for Node.js that aims to stay out of your way and make it as easy as possible to use the full power of SQL and the

Vincit 6.9k Jan 5, 2023
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server & SQLite

Prisma Quickstart • Website • Docs • Examples • Blog • Slack • Twitter • Prisma 1 What is Prisma? Prisma is a next-generation ORM that consists of the

Prisma 28k Jan 2, 2023
An adapter-based ORM for Node.js with support for mysql, mongo, postgres, mssql (SQL Server), and more

Waterline is a next-generation storage and retrieval engine, and the default ORM used in the Sails framework. It provides a uniform API for accessing

Balderdash 5.4k Jan 4, 2023
Adapter based JavaScript ORM for Node.js and the browser

firenze.js A database agnostic adapter-based object relational mapper (ORM) targetting node.js and the browser. Visit http://firenze.js.org for docume

Fahad Heylaal 130 Jul 14, 2022
The Blog system developed by nest.js based on node.js and the database orm used typeorm, the development language used TypeScript

考拉的 Nest 实战学习系列 readme 中有很多要说的,今天刚开源还没来及更新,晚些慢慢写,其实本人最近半年多没怎么写后端代码,主要在做低代码和中台么内容,操作的也不是原生数据库而是元数据Meta,文中的原生数据库操作也当作复习下,数据库的操作为了同时适合前端和Node开发小伙伴,所以并不是很

程序员成长指北 148 Dec 22, 2022
ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, SAP Hana, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.

TypeORM is an ORM that can run in NodeJS, Browser, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo, and Electron platforms and can be used

null 30.1k Jan 3, 2023
This is a demo sample of linking NODEJS via ORM and MYSQL

Demons(Demo of Nodejs with SQL) This is a demo sample of linking NODEJS with ORM and MYSQL Connecting Node to SQL is a hard task and not much help is

Shivam Sourav Jha 3 Apr 14, 2022
Ecommerce-backend-nestjs - Ecommerce app with Nestjs + Prisma ORM + GraphQL + SQLite

ECOMMERCE BACKEND NESTJS APP Nestjs + Prisma ORM + GraphQL + SQLite USER Create Account Login Product Create Product Get Products Get Product Search P

Rui Paulo Calei 5 Apr 6, 2022
just a graphql example created by typescript + fastify + mikro-orm(postgresql) + mercurius(graphql adaptor) + type-graphql

fastify-mikro-orm-mercurius-graphql-example A MikroORM boilerplate for GraphQL made with Fastify, Mercurius, Typescript using TypeGraphQL ?? Packages

Vigen 10 Aug 28, 2022
A typescript data mapping tool. To support mutual transforming between domain model and orm entity.

ts-data-mapper A typescript mapping tool supports mutual transforming between domain model and orm entity. In most case, domain model is not fully com

zed 8 Mar 26, 2022
A javascript REST ORM that is offline and real-time capable

Rekord Rekord is an ORM - a way to define properties and relationships - that interacts with local storage, a RESTful service, and a real-time service

Rekord 177 Oct 18, 2022
A typesafe database ORM that exposes the full power of handwritten sql statements to the developer.

TORM A typesafe database ORM that exposes the full power of handwritten sql statements to the developer. import { torm, z } from 'https://deno.land/x/

Andrew Kaiser 15 Dec 22, 2022
🚀 A robust, performance-focused and full-featured Redis client for Node.js.

A robust, performance-focused and full-featured Redis client for Node.js. Supports Redis >= 2.6.12 and (Node.js >= 6). Completely compatible with Redi

Zihua Li 11.6k Jan 8, 2023
Modular Redis connection and PUBSUB subscription manager for node. Easily extendable. Built for performance, powered by ioredis.

RediBox Redis connection and PUBSUB subscription manager for node. Built for performance, powered by ioredis (for now). Maintained by TeamFA. What is

RediBox 83 Dec 15, 2022
The Official MongoDB Node.js Driver

MongoDB NodeJS Driver The official MongoDB driver for Node.js. NOTE: v3.x released with breaking API changes. You can find a list of changes here. Ver

mongodb 9.6k Dec 28, 2022