# final-orm

> > Please check out https://github.com/oknoah/final and https://github.com/oknoah/final/packages/arangolize for similar projects that MAY be more up to date

Latest version **1.0.9** (published 2020-04-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install final-orm
pnpm add final-orm
yarn add final-orm
bun add final-orm
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.9 |
| Published | 2020-04-23 |
| First published | 2017-11-27 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 7 |
| Unpacked size | 44.3 KB |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| Author | Noah Gray |
| Maintainers | noah-kun |
| Keywords | database, orm, ormjs, arango, arangodb, odm, mongo, mongodb, document, nosql |

## Links

- npm: https://www.npmjs.com/package/final-orm
- Repository: https://gitlab.com/NoahGray/final-orm
- npm.io page: https://npm.io/package/final-orm

## Dependencies (7)

- [open](https://npm.io/package/open.md) 0.0.5
- [dotenv](https://npm.io/package/dotenv.md) ^4.0.0
- [lodash](https://npm.io/package/lodash.md) ^4.17.4
- [moment](https://npm.io/package/moment.md) ^2.19.3
- [arangojs](https://npm.io/package/arangojs.md) ^5.7.0
- [arangolize](https://npm.io/package/arangolize.md) 0.10.2
- [core-decorators](https://npm.io/package/core-decorators.md) ^0.20.0

## Alternatives

- [angular-pipes](https://npm.io/package/angular-pipes.md) — 5.6K weekly downloads
- [@ng-web-apis/midi](https://npm.io/package/@ng-web-apis/midi.md) — 2.6K weekly downloads
- [happn-3](https://npm.io/package/happn-3.md) — 1.6K weekly downloads
- [@opensip-cli/lang-go](https://npm.io/package/@opensip-cli/lang-go.md) — 1.2K weekly downloads
- [mongoose-typescript](https://npm.io/package/mongoose-typescript.md) — 85 weekly downloads

## Recent versions

- 1.0.9 (latest) — 2020-04-23
- 1.0.8 — 2019-09-01
- 1.0.7 — 2019-09-01
- 1.0.6 — 2019-09-01
- 1.0.5 — 2019-09-01
- 1.0.4 — 2019-08-22
- 1.0.3 — 2019-08-22
- 1.0.2 — 2019-08-22
- 1.0.1 — 2019-08-22
- 1.0.0 — 2019-07-18
- 1.0.0-alpha.13 — 2018-06-12
- 1.0.0-alpha.12 — 2018-04-18
- 1.0.0-alpha.11 — 2018-03-25
- 1.0.0-alpha.10 — 2018-03-25
- 1.0.0-alpha.9 — 2018-03-24
- … 6 more at https://npm.io/package/final-orm/versions

## README

# Final ORM

> Please check out https://github.com/oknoah/final and https://github.com/oknoah/final/packages/arangolize for similar projects that MAY be more up to date

This is a javascript OOP interface for ArangoDB

Conception: Using the ES7 operator `await`, `getters` and `promises`, we can navigate the graph objects tree.

It is recommended for use with the ES7 (async await) For a more beautiful syntax.

Never heard of ArangoDB? Check out these benchmarks: https://www.arangodb.com/2015/10/benchmark-postgresql-mongodb-arangodb/

Please see `./index.test.js` for most up-to-date examples.

API
---

static:
```javascript
Model.get(_id) // get model by id
Model.add(obj) // add model by description obj
Model.remove(model) // remove model
Model.restore(model) // restore removed model
Model.save(model) // save modified model to db
Model.update(model) // update modified model from db
Model.find({ where: { key: value }, skip: 0, limit: 10 }) // find models by where obj
Model.findAndCount({ where: { key: value }, skip: 0, limit: 10 }) // find models by where obj and return as { data: [data], meta: { count: 123 } }
Model.findOne({ where: { key: value } }) // find one model by selector obj
Model.count(selector) // return count models matches of selector
Model.have(selector) // returns true if there is at least one model suitable for selector
```

instance:
```javascript
Model.prototype.save() // alias  Model.save(this)
Model.prototype.update() // alias  Model.update(this)
Model.prototype.remove() // alias  Model.remove(this)
Model.prototype.restore() // alias  Model.remove(this)
```

Basic usage:
---

create init class model.js
```javascript
var orm = require('final-orm')
var options = {
  database: 'test', // db name
  // You can initialize the database using just a url.
  url: 'http://root:@localhost:8529',
  // Or supply each of these values. You do not need both.
  host: 'localhost',
  port: '8529',
  username: 'root',
  password: '',
  // You can also supply a protocol. If localhost, it's `http` by default, otherwise `https`
  protocol: 'tcp'
}

var { Model, Edge } = orm.connect(options)

export default Model

export { Model, Edge }
```

`orm.connect()` returns `Model` and `Edge` classes, and you need export and extend it


Define collection User (class name will be collection name), and edge collection "Like"

```javascript
import { Model, Edge } from './model.js'

class User extends Model {
  static schema = {
    // basic types
    name: String,
    male: Boolean,
    age: Number,
    birth: Date,
    tags: Set, // like array but items are unique

    // structures
    messages: [String], // array of types
    prop1: {prop2: [{tags: [String]}] }, // sub schemas

    // relations with other (or self) db collections
    bestFriend: User, // link to model
    friends: [User], // link to array models

    // field options
    name: String,
    name: {$type: String},
    name: {$type: String, test: /^\w+$/},
    status: {
      $type: String,
      enum: ['sleep', 'eat'], // enum
      optional: true // allows null value
    }
  }
}

class Like extends Edge {
  static schema = {
    date: Date
  }
}
```


Example 0:
---


```javascript
import Model from './model.js'


class User extends Model {

  static schema = {
    name: String,
    age: Number,
  }

}
```

Usage:

```javascript
(async function () {

  // adding user to db
  var user = await User.add({
    name: 'Ашот',
    age: 24,
    })

  user._id // 'User/434370324723'
  user._removed // false
  user.name // 'Ашот'
  user.age // 24

  // change field
  user.name = 'Ololo'
  console.log(user.name) // 'Ololo' field is changed

  // reset changes
  await user.update() // load state from db
  user.name // 'Ашот'

  // saving changes
  user.name = 'Ololo' // change field
  await user.save() // save changes to db
  await user.update() // load state from db
  user.name // 'Ololo' because we save

  // like via edge collection
  const rose = await User.findOne({ where: { name: 'Rose' } })
  // in edge collections, the usage is Edge.add(from, to, data)
  Like.add(rose, user, { date: new Date() })

}())
```

Example 1: Instance methods
---

```javascript
import Model from './model.js'


class User extends Model {
  static schema = {
    name: String,
    age: Number,
    friends: [User]
  }

  async addFriend(user) {
    var friends = await this.friends
    friends.push(user)
    await this.save()
  }

  async removeAllFriends(){
    this.friends = []
    await this.save()
  }

}
```
Usage:

```javascript
(async function(){

  var user = await User.add({
    name: 'Ivan',
    age: 24,
    friends: []
  })

  await user.addFriend(user)
  await user.addFriend(user)
  await user.friends // [user, user]  two itself =)

  await user.removeAllFriends()
  await user.friends // []

  await user.friends === await user.friends // true

  user.name = 22
  await user.save() // ValidationError: Field `name` must be String, but have Number

  await user.removeAllFriends() // since this method uses this.update, you must do user.save() first

})()
```


Example 2:
---
```javascript
import Model from './model.js'


class Sector extends Model {

  static schema = {
    size: Number
  }

}


class User extends Model {

  static schema = {
    name: String,
    sector: Sector,
  }

}

```

Usage:

```javascript
(async function () {

  var sector = await Sector.add({
    size: 236
  })

  var user = await User.add({
    name: 'Ашот',
    sector: sector
  })

  (await user.sector).size // 236


  var sector2 = await Sector.add({
    size: 1004
  })
  user.sector = sector2
  await user.save()

  (await user.sector).size // 1004 because this another sector ^__^


})()
```

Custom types:
---
System types is: String, Number, Boolean, Data, Set
Actually we can use custom types:

```javascript
import Model from './model.js'


class Color {

  constructor(r, g, b) {
    this.r = r
    this.g = g
    this.b = b
  }


  // convert to db document
  toJSON() {
    return {
      r: this.r,
      g: this.g,
      b: this.b
    }
  }


  // restore from db document
  static fromJSON(json) {
    return new Color(json.r, json.g, json.b)
  }

}


class User extends Model {

  static schema = {
    name: String,
    color: Color
  }

}
```

Usage:

```javascript
(async function () {

  var user = await User.add({
    name: 'Ашот',
    color: new Color(0, 255, 0)
  })

  user.color instanceof Color //true

}())
```

Schemas
---

Number
```javascript
schema = {
  age: Number,
  age: {$type: Number},
  age: {$type: Number, min:0, max:100}
}
```

=======
String
```javascript
schema = {
  name: String,
  name: {$type: String},
  name: {$type: String, min:3, max:20, test:/^\w+$/}
}
```

=======
Set
```javascript
schema = {
  tags: Set,
  tags: {$type: Set},
  tags: {$type: Set, set: ['soviet', 'movies']}
}
```

---
_Source: https://npm.io/package/final-orm · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
