From 6e23d0b774b00c5b104250dd4a1e584edd7a93bb Mon Sep 17 00:00:00 2001 From: mernxl Date: Tue, 24 Jul 2018 23:41:35 +0100 Subject: [PATCH] doc: update README.md with recent changes --- README.md | 221 +++++++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 129 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index 7894091..bbbb30c 100644 --- a/README.md +++ b/README.md @@ -2,96 +2,26 @@ [![Build Status](https://travis-ci.org/mernxl/mongoose-id-assigner.svg?branch=master)](https://travis-ci.org/mernxl/mongoose-id-assigner) [![codecov](https://codecov.io/gh/mernxl/mongoose-id-assigner/branch/master/graph/badge.svg)](https://codecov.io/gh/mernxl/mongoose-id-assigner) -Plugin for `mongoose`, Automatically assign and/or increment any field on your mongoose models that needs to be identified(ID). +A [Mongoose](http://mongoosejs.com) Plugin. Easily Manage fields that need an id(unique value) on your mongoose model. This plugin does the work of generating, incrementing, and assigning those values(unique) to those fields. -It offers support for assigning with `MongoDB's ObjectId`, `UUID`, `Number Increments`, `String Generators` or you provide your custom `Generator Function`. +This plugin assigns values base on your configurations, be it `MongoDB's ObjectId`, `UUID`, `Number Increments`, `String Generators` or you provide your custom `nextIdFunction`. -It also works if you have multiple mongooseConnection instances by using your underlying doc connections to update ids. +It creates a collection with name `id_assigner` that store the `nextId` for a configured field. This only happens if you have fields configured with type `String` or `Number`. As `ObjectId` and `UUID` can be generated locally unique, they do not use this collection for assigning values. ## Installation ``` +yarn add mongoose-id-assigner +or npm install mongoose-id-assigner ``` ## Basic Usage ### Plugin Options TypeName: **AssignerOptions** -- *modelName*: **String** Name for the Model your are working with. -- *fields*: **AssignerFieldsConfigMap?** The configuration Map of the fields you want the assigner to assign ids to. - If Null, then plugin assigns ids to _id field, (ObjectId). +- `modelName`: **String** Name for the Model your are working with. +- `fields`: **AssignerFieldsConfigMap?** The configuration Map of the fields you want the assigner to assign ids to. + If Null, then plugin assigns ids to `_id` field, (ObjectId). - [fieldName: string]: FieldConfig | string | number | boolean | 'GUID' | 'UUID' - -### TypeDefinitions -```typescript -/** - * If Option does not contain an AssignerFieldsConfigMap, then we use the config options for _id - */ -interface AssignerOptions { - modelName: string; - fields?: AssignerFieldsConfigMap; -} - -/** - * fieldOption = string, then nextId = string, default incrementer, - * fieldOption = number, then nextId = number, incrementBy = 1 - * fieldOption = boolean(true), then fieldType = ObjectId - * fieldOption = GUID | UUID, then use UUID v4 - */ -interface AssignerFieldsConfigMap { - [fieldName: string]: - | FieldConfig - | string - | number - | boolean - | 'GUID' - | 'UUID'; -} - -// noSpace, insure we consume all possible values, i.e. we must have 1, 2, 3, 4 -// order doesn't matter but all those keys must be present, no 1, 3, 4, 6 -type FieldConfig = { - index?: boolean; - unique?: boolean; - noSpace?: boolean; -} & ( - | DefaultFieldConfig - | StringFieldConfig - | NumberFieldConfig - | UUIDFieldConfig); - -enum FieldConfigTypes { - UUID = 'UUID', - GUID = 'GUID', - String = 'String', - Number = 'Number', - ObjectId = 'ObjectId', -} - -interface DefaultFieldConfig { - type: 'ObjectId'; -} - -interface StringFieldConfig { - type: 'String'; - nextId: string; - separator?: string; - nextIdFunction?: (nextId: string) => string; -} - -interface NumberFieldConfig { - type: 'Number'; - nextId: number; - incrementBy?: number; - nextIdFunction?: (nextId: number, incrementBy?: number) => number; -} - -interface UUIDFieldConfig { - type: 'UUID' | 'GUID'; - asBinary?: boolean; // default string - version?: number; // supports 1 and 4, default 1 - versionOptions?: any; -} -``` ## Examples Lets create our Mongoose Schema. @@ -101,6 +31,7 @@ import * as mongoose from 'mongoose'; const ExampleSchema = new mongoose.Schema({ _id: String, + name: String, photoId: Number, emailId: String, @@ -112,30 +43,41 @@ const ExampleSchema = new mongoose.Schema({ }); ``` -Configure the Plugin on any Model you want to use with Passing the Configuration options. -**Method 1**: Quick Config, Good if your ids need no network use, case ObjectId, UUID +Configure the Plugin on Schema you want to work with. You need at least the modelName passed as AssignerOption. +### Configuration methods +**Method 1**: Quick Config, Good if your ids need no network use, case `ObjectId`, `UUID`. It carries out a lazy Initialisation of Model ```js const options = { modelName: 'ExampleModel', fields: { - // if no _id field config, assigner auto adds with type = "ObjectId" - uuidField: 'UUID', + // if no _id field config, assigner auto adds _id field with type = "ObjectId" + uuidFieldString: 'UUID', } }; ExampleSchema.plugin(MongooseIdAssigner.plugin, options); -// You need plugin instance to initialise Plugin // No need to initialise if you don't intent to start saving files immediately +// Saving the first doc triggers the plugin Assigner initialisation for this model. const ExampleModel = mongoose.model('ExampleModel', ExampleSchema); + +const doc = await ExampleModel.create({name: 'Mernxl'}) + +console.log(doc._id) ---> 5b57a1d929239e59b4e3d7f3 // schema field type is String +console.log(doc.uuidFieldString) ---> 7729e2e0-8f8b-11e8-882d-2dade78bb893 ``` -**Method 2**: Request Assigner Instance +**Method 2**: Request Assigner Instance, If you have initialisation logic, you need to initialise the plugin. ```js const options = { modelName: 'ExampleModel', fields: { - personId: '0000' // needs network, + photoId: { + type: FieldConfigTypes.Number, + nextId: 0000, + incrementBy: 4, + nextIdFunction: (nextId, incrementBy) => nextId + incrementBy, + } } }; @@ -146,17 +88,39 @@ const ExampleModel = mongoose.model('ExampleModel', ExampleSchema); // returns a promise... ExampleIA.initialise(ExampleModel) - .then((readyCode) => /* ...do stuff */) - .catch((error) => /* ... do stuff */) + .then((readyCode) => { + const doc1 = await ExampleModel.create({name: 'Mongoose'}); + + console.log(doc1._id) ---> 5b57a1d929239e59b4e3d7f3 + console.log(doc1.photoId) ---> 0000 + + const doc2 = await ExampleModel.create({name: 'IdAssigner'}); + + console.log(doc1._id) ---> 5b57a3612000c406eceaefc2 + console.log(doc1.photoId) ---> 0004 + }) + .catch((error) => /* ... Error at initialisation process, do error stuff */) ``` -**Method 3**: Request Assigner Instance +**Method 3**: Request Assigner Instance, This method also returns IdAssigner instance. ```js const options = { modelName: 'ExampleModel', fields: { - personId: '0000' // needs network, - } + _id: { + type: FieldConfigTypes.String, + separator: 'T', + nextId: '34T5565', + }, + uuidFieldBuffer: { + type: FieldConfigTypes.UUID, + version: 4, + asBinary: true, + versionOptions: { + rng: (Function) Random # generator function that returns an Array[16] of byte values (0-255) // UUID doc + } + } + }, }; // If you have startup logic that needs to save files, request instance then initialise @@ -166,8 +130,80 @@ const ExampleModel = mongoose.model('ExampleModel', ExampleSchema); // returns a promise... ExampleIA.initialise(ExampleModel) - .then((readyCode) => /* ...do stuff */) - .catch((error) => /* ... do stuff */) + .then((readyCode) => { + const doc1 = await ExampleModel.create({name: 'Mongoose'}); + + console.log(doc1._id) ---> 34T5565 + console.log(doc1.uuidFieldBuffer) ---> Binary { _bsontype: 'Binary', sub_type: 4, position: 36, buffer: B... } + + const doc2 = await ExampleModel.create({name: 'IdAssigner'}); + + console.log(doc1._id) ---> 34T5566 + console.log(doc1.uuidFieldBuffer) ---> Binary { _bsontype: 'Binary', sub_type: 4, position: 36, buffer: B... } + }) + .catch((error) => /* ... do error stuff */) +``` + +### TypeDefinitions +```typescript +/** + * If Option does not contain an AssignerFieldsConfigMap, then we use the config options for _id + */ +interface AssignerOptions { + modelName: string; + fields?: AssignerFieldsConfigMap; +} + +/** + * fieldOption = string, then nextId = string, default incrementer, + * fieldOption = number, then nextId = number, incrementBy = 1 + * fieldOption = boolean(true), then fieldType = ObjectId + * fieldOption = GUID | UUID, then use UUID v4 + */ +interface AssignerFieldsConfigMap { + [fieldName: string]: FieldConfig | string | number | boolean | 'GUID' | 'UUID'; +} + +// noSpace, insure we consume all possible values, i.e. we must have 1, 2, 3, 4 +// order doesn't matter but all those keys must be present, no 1, 3, 4, 6 +type FieldConfig = { + index?: boolean; + unique?: boolean; + noSpace?: boolean; +} & ( DefaultFieldConfig | StringFieldConfig | NumberFieldConfig | UUIDFieldConfig ); + +enum FieldConfigTypes { + UUID = 'UUID', + GUID = 'GUID', + String = 'String', + Number = 'Number', + ObjectId = 'ObjectId', +} + +interface DefaultFieldConfig { + type: 'ObjectId'; +} + +interface StringFieldConfig { + type: 'String'; + nextId: string; // the id that will be assigned next + separator?: string; + nextIdFunction?: (nextId: string) => string; // custom function to generate nextIds +} + +interface NumberFieldConfig { + type: 'Number'; + nextId: number; + incrementBy?: number; + nextIdFunction?: (nextId: number, incrementBy?: number) => number; // custom function to generate nextIds +} + +interface UUIDFieldConfig { + type: 'UUID' | 'GUID'; + asBinary?: boolean; // default string, if true, saves as Binary + version?: number; // supports 1 and 4, default 1 + versionOptions?: any; +} ``` ### Strain test, Performs the task below on a locally hosted db instance. @@ -252,4 +288,3 @@ describe('MongooseIdAssigner', () => { ## LICENSE [MIT](https://github.com/mernxl/mongoose-id-assigner/blob/master/LICENSE.md) - diff --git a/package.json b/package.json index cd8b246..90f8e1c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mongoose-id-assigner", "version": "0.1.0", - "description": "Plugin for `mongoose`, Automatically assign and increment any uniquely identified field on your mongoose models.", + "description": "A Mongoose Plugin. Easily Manage fields that need an id(unique value) on your mongoose model. This plugin does the work of generating, incrementing, and assigning those values(unique) to those fields.", "main": "lib/index.js", "repository": "https://github.com/mernxl/mongoose-assign-id.git", "author": "mernxl ",