{"id":22819483,"url":"https://github.com/bdfoster/nomatic-data","last_synced_at":"2025-07-24T21:35:08.432Z","repository":{"id":44912029,"uuid":"103124079","full_name":"bdfoster/nomatic-data","owner":"bdfoster","description":"Extensible Object-relational Mapping Framework for Node.js","archived":false,"fork":false,"pushed_at":"2020-06-03T03:27:38.000Z","size":651,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-02T17:01:06.034Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://bdfoster.github.io/nomatic-data","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bdfoster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-11T10:45:43.000Z","updated_at":"2020-04-29T02:32:35.000Z","dependencies_parsed_at":"2022-09-05T18:01:11.534Z","dependency_job_id":null,"html_url":"https://github.com/bdfoster/nomatic-data","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/bdfoster/nomatic-data","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdfoster%2Fnomatic-data","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdfoster%2Fnomatic-data/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdfoster%2Fnomatic-data/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdfoster%2Fnomatic-data/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bdfoster","download_url":"https://codeload.github.com/bdfoster/nomatic-data/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bdfoster%2Fnomatic-data/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266905593,"owners_count":24004148,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-24T02:00:09.469Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-12T15:12:30.484Z","updated_at":"2025-07-24T21:35:08.403Z","avatar_url":"https://github.com/bdfoster.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nomatic-data\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/bdfoster/nomatic-data.svg)](https://greenkeeper.io/)\n[![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![GitHub release](https://img.shields.io/github/release/bdfoster/nomatic-data.svg)](https://github.com/bdfoster/nomatic-data/releases)\n[![npm](https://img.shields.io/npm/v/nomatic-data.svg)](https://www.npmjs.com/package/nomatic-data)\n[![Build Status](https://travis-ci.org/bdfoster/nomatic-data.svg?branch=greenkeeper%2Finitial)](https://travis-ci.org/bdfoster/nomatic-data)\n[![Coverage Status](https://coveralls.io/repos/github/bdfoster/nomatic-data/badge.svg)](https://coveralls.io/github/bdfoster/nomatic-data)\n[![Known Vulnerabilities](https://snyk.io/test/github/bdfoster/nomatic-data/badge.svg)](https://snyk.io/test/github/bdfoster/nomatic-data)\n[![dependencies Status](https://david-dm.org/bdfoster/nomatic-data/status.svg)](https://david-dm.org/bdfoster/nomatic-data)\n[![devDependencies Status](https://david-dm.org/bdfoster/nomatic-data/dev-status.svg)](https://david-dm.org/bdfoster/nomatic-data?type=dev)\n[![License](https://img.shields.io/github/license/bdfoster/nomatic-data.svg)](https://github.com/bdfoster/nomatic-data/blob/master/LICENSE)\n[![Join the chat at https://gitter.im/nomatic-data/Lobby](https://badges.gitter.im/nomatic-data/Lobby.svg)](https://gitter.im/nomatic-data/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nExtensible Object-relational Mapping Framework for Node.js\n\n### Overview\nWritten in TypeScript, this package uses Active Record, Data Mapper, and Adapter\npatterns to create an Object-Relational Mapping (ORM) tool that provides flexibility and extensibility.\n\nAdapters allow you to connect to a variety of data sources. You can use a pre-built Adapter (see table below), \nor you can write your own by implementing either the [Adapter](https://bdfoster.github.io/nomatic-data/classes/adapter.html) or [DatabaseAdapter](https://bdfoster.github.io/nomatic-data/classes/databaseadapter.html) abstract classes.\n\nEach `Adapter` is operated by one or more `Mapper` instances. Each `Mapper` instance is managed by a `Container`\ninstance. A `Mapper` will generate `Record` instances, which store the state of each document in the collection.\n\n### Installation\nYou can install from [npm](https://www.npmjs.com/package/nomatic-data) by doing:\n```\nnpm i --save nomatic-data\n```\n\nIf you want to write your own adapter, you can stop there. Otherwise, you'll need to install an adapter:\n\n| Adapter | Author | Links | Installation |\n| :--- | :--- | :--- | :--- |\n| [ArangoDB](https://arangodb.com) | [bdfoster](https://github.com/bdfoster) | [npm](https://npmjs.com/package/nomatic-arangodb-adapter), [GitHub](https://github.com/bdfoster/nomatic-arangodb-adapter) | `npm i --save nomatic-arangodb-adapter` |\n\n### Example\nThis example uses the [ArangoDB](https://npmjs.com/package/nomatic-arangodb-adapter) adapter.\n\n```javascript\nimport { Container } from 'nomatic-data';\nimport ArangoDBAdapter from 'nomatic-arangodb-adapter';\n\nconst adapter = new ArangoDBAdapter({\n    name: 'my-database',\n    host: '127.0.0.1',\n    port: 8579,\n    password: 'somethingMoreSecureThanThis'\n});\n\nconst store = new Container({\n    adapter: adapter,\n    \n    /**\n     * A few hooks are provided for your convenience, including:\n     * - beforeGet\n     * - afterGet\n     * - beforeInsert\n     * - afterInsert\n     * - beforeUpdate\n     * - afterUpdate\n     * - beforeValidate\n     * - afterValidate\n     */ \n    beforeInsert(mapper, record) {\n        record.createdAt = new Date();\n    },\n    beforeUpdate(mapper, record) {\n        record.updatedAt = new Date();\n    },\n    \n    /**\n     * Here, we define the schema of all of our mappers. Other options\n     * for each mapper can also be set here. Schema validation is provided\n     * by [ajv](https://github.com/epoberezkin/ajv).\n     */\n    mappers: {\n        people: {\n            properties: {\n                /**\n                 * Implicit properties, such as `id` and `rev`, need not be \n                 * defined here. \n                 */ \n                firstName: {\n                    type: 'string'\n                },\n                lastName: {\n                    type: 'string'\n                },\n                emailAddress: {\n                    type: 'string',\n                    format: 'email'\n                }\n            },\n            required: ['firstName', 'lastName'],\n            /**\n             * By default, additional properties are allowed in the record.\n             */\n            additionalProperties: false\n        },\n        accounts: {\n            properties: {\n                people: {\n                    type: 'array',\n                    items: {\n                        type: 'string',\n                        /**\n                         * The 'mapper' keyword enforces relational integrity. Each item\n                         * in this array matches an `id` of a record in the collection\n                         * managed by the 'people' mapper.\n                         */ \n                        mapper: 'people'\n                    },\n                    default: []\n                }\n            }\n        }\n    }\n});\n\n/**\n * The `load()` method will establish a connection with the database server, \n * ensure that the database exists (or it will try and create it), and \n * ensure all collection exists (or will create them).\n */\nstore.load().then(() =\u003e {\n    return store.insertAll('people', [\n        { firstName: 'John', lastName: 'Doe' },\n        { firstName: 'Jane', lastName: 'Doe' }\n    ]);\n}).then(() =\u003e {\n    /**\n     * This is one way you can query for documents.\n     */\n    store.find('people')\n        .where('lastName')\n        .eq('Doe')\n        .sort('firstName', 1)\n        .limit(2)\n        .skip(1)\n        .run().then((results) =\u003e {\n        //...\n    });\n    \n    /**\n     * You can also query much like how MongoDB query filters. The supported operators are:\n     *  - $and\n     *      Syntax: { $where: { $and: [ \u003cexpression\u003e, ..., \u003cexpression\u003e }, ... }\n     *  - $or\n     *      Syntax: { $where: { $or: [ \u003cexpression\u003e, ..., \u003cexpression\u003e }, ... }\n     *  - $eq (expression)\n     *      Syntax: { \u003cproperty\u003e: { $eq: { \u003cvalue\u003e } }\n     *  - $ne (expression)\n     *      Syntax: { \u003cproperty\u003e: { $ne: { \u003cvalue\u003e } }\n     *  - $gt (expression)\n     *      Syntax: { \u003cproperty\u003e: { $gt: { \u003cvalue\u003e } }\n     *  - $gte (expression)\n     *      Syntax: { \u003cproperty\u003e: { $gte: { \u003cvalue\u003e } }\n     *  - $lt (expression)\n     *      Syntax: { \u003cproperty\u003e: { $lt: { \u003cvalue\u003e } }\n     *  - $lte (expression)\n     *      Syntax: { \u003cproperty\u003e: { $lte: { \u003cvalue\u003e } }\n     *  - $in (expression)\n     *      Syntax: { \u003cproperty\u003e: { $in: [ \u003cvalue\u003e, ..., \u003cvalue\u003e ] }\n     *  - $nin (expression)\n     *      Syntax: { \u003cproperty\u003e: { $nin: [ \u003cvalue\u003e, ..., \u003cvalue\u003e ] }\n     *  - $exists (expression)\n     *      Syntax: { \u003cproperty\u003e: { $exists: \u003ctrue | false\u003e } }\n     * \n     * An expression always follows this form: \n     *  { \u003cproperty\u003e: { \u003coperator\u003e: \u003cvalue\u003e | [ \u003cvalue\u003e, ..., \u003cvalue\u003e] }\n     *  \n     * All the operators above can only be used in a $where object. \n     */\n    store.findAll('people', {\n        $where: {\n            firstName: 'Jane'\n        },\n        $sort: [\n            ['firstName', 1]\n        ],\n        $limit: 2,\n        $skip: 1\n    }).then((results) =\u003e {\n        //...\n    });\n});\n```\nThe API documentation (generated by [TypeDoc](http://typedoc.org/)) can be found \n[here](https://bdfoster.github.io/nomatic-data/).\n\nMore documentation will be added as moves forward, but if you have a question please feel free to \n[open an issue](https://github.com/bdfoster/nomatic-data/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbdfoster%2Fnomatic-data","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbdfoster%2Fnomatic-data","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbdfoster%2Fnomatic-data/lists"}