# mongo-class-models

> Easy mongoose class models and repos

Latest version **1.4.0** (published 2022-11-25) · ISC license · 0 weekly downloads

## Install

```sh
npm install mongo-class-models
pnpm add mongo-class-models
yarn add mongo-class-models
bun add mongo-class-models
```

## Health

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

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.4.0 |
| Published | 2022-11-25 |
| First published | 2022-11-25 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 67.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Strange |
| Maintainers | lil_strange |
| Keywords | mongoose, oop-mongoose, mongoose-repos |

## Links

- npm: https://www.npmjs.com/package/mongo-class-models
- Repository: https://github.com/LilStrange/mongo-class-models
- Homepage: https://github.com/LilStrange/mongo-class-models#readme
- Issues: https://github.com/LilStrange/mongo-class-models/issues
- npm.io page: https://npm.io/package/mongo-class-models

## Dependencies (1)

- [mongoose](https://npm.io/package/mongoose.md) ^6.6.5

## 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.4.0 (latest) — 2022-11-25

## README

# MongoDB Class Models
Simple package for fast work with mongoose package and typescript + OOP
- OOP pattern
- Repos and Models
- Easy to use

## Instalation

### [npm](https://www.npmjs.com/package/mongo-class-models)
```bash
npm i mongo-class-models
```

## Usage

### Creating Repos

1. Create `repos/` folder in your app folder
2. Create Repo file (Recommended use this name pattern - `{ModelName}Repo.(ts|js)`)

### Setup Repo

#### Configuring model interface

1. Create new interface (Recommended name - `{ModelName}Model`)
2. Add extensions to your interface from [DBHelper.ModelExtension](#model-extension) (It should extends [DBHelper.ModelExtension.ID](#model-extension__id). Others extensions are optional). Example:
```ts
interface ArticleModel extends
    //ID is required
    DBHelper.ModelExtension.ID.Default,
    //Timestamps are optional
    DBHelper.ModelExtension.Timestamps<"snake_case">
{
    name: string,
    tags: string[]
}
```
3. Create Repo class. It should extend [DBHelper.Repo.RootRepo]() abstract class (Recommended name - `{ModelName}Repo`). Example:
```ts
class ArticleRepo extends DBHelper.Repo.RootRepo<ArticleModel> {
    //Here you can create custom properties and methods and use it later
}
```

4. Create exported instance of your Repo class (Recommended name - `{modelName}Repo`). Example: 

```ts
export const articleRepo = new ArticleRepo(
    "Article", //Model Name
    "atricles", //Collection Name
    DBHelper.Repo.init({ //Init Options and Schema definition
        name: DBHelper.MV({type: "String", required: true}),
        tags: [DBHelper.MV({type: "String"})]
    },{ //Schema options
        ...DBHelper.RepoOptions.timestamps("snake_case")
    })
);
```

5. Use Repo in your app. Example:
```ts
let article = await articleRepo.createModel({
    name: "First Article",
    tags: ["cool", "fast"]
})

let articles = await articleRepo.findMany({});

console.log(articles);
```

## Docs
DBHelper is main namespace in this package. All package functional gets from it

### `DBHelper.ModelExtension` {#model-extension}
Extensions for model interface

`ModelInterface` Example: {#model-interface}
```ts 
interface SectionModel extends
    DBHelper.ModelExtension.ID.Default,
    DBHelper.ModelExtension.Timestamps<"snake_case">
{
    name: string,
    tags: string[]
}
```

#### `DBHelper.ModelExtension.ID` {#model-extension__id}

- `DBHelper.ModelExtension.ID.Default` - `mongoose.Types.ObjectId` (default mongodb model id)

- `DBHelper.ModelExtension.ID.String`

- `DBHelper.ModelExtension.ID.Number`

---

#### `DBHelper.ModelExtension.Timestamps<TimestampsStyle>` {#timestamps-style}

```ts
type TimestampsStyle = "camelCase" | "snake_case";
```

### `DBHelper.Model` {#model}
Additional types for [ModelInterface](#model-interface)

- `DBHelper.Model.Ref` - Reference to another Repo. Example:
```ts
interface IArticle extends
    DBHelper.ModelExtension.ID.Default,
    DBHelper.ModelExtension.Timestamps<"snake_case">
{
    name: string,
    desc: string,
    main_section: DBHelper.Model.Ref<SectionModel>,
}
```

- `DBHelper.Model.SubSchema` - Nested Object. If you want to use nested object you should use `SubSchema`. Example:
```ts
interface IArticle extends
    DBHelper.ModelExtension.ID.Default,
    DBHelper.ModelExtension.Timestamps<"snake_case">
{
    name: string,
    desc: string,
    stats: DBHelper.Model.SubSchema<{
        views: number,
        shows: number
    }>
}
```


### `DBHelper.Repo` {#repo}
Everything to initialize the Repo

- `DBHelper.Repo.RootRepo<ModelType>` - RootRepo. Your Repos should extends it.

Usage Example:
```ts
class ArticleRepo extends DBHelper.Repo.RootRepo<IArticle> {
    //Here you can create custom properties and methods and use it later
}
``` 
[More About It](#root-repo)

---

- `DBHelper.Repo.init(definition,options)` - Initialize PreSchema for [RootRepo](#root-repo) {#preschema-init}

@definition - Object of model keys value's type 

@options - Simple Mongoose Schema Options

Usage Example: 
```ts
const sectionRepo = new SectionRepo(
    "Section",
    "sections",
    DBHelper.Repo.init({
        name: DBHelper.MV({type: String, required: true}),
        tags: [DBHelper.MV({type: String})]
    })
);
```

---

- `DBHelper.Repo.initSubSchema(definition,options)` - Initialize SubPreSchema for [PreSchema](#preschema-init)

@definition - Object of model keys value's type 

@options - Simple Mongoose Schema Options

Usage Example: 
```ts
export const articleRepo = new ArticleRepo(
    "Article",
    "atricles",
    DBHelper.Repo.init({
        name: DBHelper.MV({type: "String", required: true}),
        desc: DBHelper.MV({type: "String", required: true}),
        stats: DBHelper.Repo.initSubSchema<IArticle["stats"]>({
            views: DBHelper.MV({type: Number, required: true}),
            shows: DBHelper.MV({type: Number, required: true})
        })
    })
);
```

---

- `DBHelper.Repo.mongooseValue(valueType)` - Value type constructor {#mongoose-value}

@valueType - Simple Mongoose SchemaTypes
```ts
DBHelper.MV({type: Number}) //It will be in your schema - {type: Number}
DBHelper.MV({type: Number, required: true}) // {type: Number, required: true}
DBHelper.MV({type: String}) // {type: String}
DBHelper.MV({type: Boolean, required: true}) // {type: Boolean, required: true}
DBHelper.MV({type: mongoose.Types.ObjectId, required: true, unique: true}) // {type: mongoose.Types.ObjectId, required: true, unique: true}
```

---

### `DBHelper.MV(valueType)` - [mongooseValue](#mongoose-value)

---

### `DBHelper.RepoOptions`
Option shortcuts

#### `DBHelper.RepoOptions.timestamps(timestampsStyle)`

[timestampsStyle](#timestamps-style)

Usage Example:
```ts
export const sectionRepo = new SectionRepo(
    "Section",
    "sections",
    DBHelper.Repo.init({
        name: DBHelper.MV({type: String, required: true}),
        tags: [DBHelper.MV({type: String})]
    },{
        ...DBHelper.RepoOptions.timestamps("snake_case")
    })
);
```

---

### `DBHelper.FinalModel` {#final-model}
FinalModel Types

- `DBHelper.FinalModel.FinalModel<ModelType>` - [FinalModel](#final-model)

- `DBHelper.FinalModel.DataType<ModelType>` - all fields without _id

- `DBHelper.FinalModel.FullDataType<ModelType>` - all fields with _id

- `DBHelper.FinalModel.PlainModel<ModelType>` - ModelDataType used for creating new model

---

## Types, Classes, Interfaces

### abstract class `RootRepo` {#root-repo}
- `constructor`(
        modelName: string,
        collectionName: string,
        [initSchema](#preschema-init),
        modelOptions?: mongoose.CompileModelOptions
    ){}
- `Model` - Mongoose Model
- `modelKeys` - all first level keys in model (with _id)
- `changeableModelKeys` - all first level keys in model (without _id)
- `getRefSchemaType`(fieldOptions: mongoose.SchemaDefinitionProperty<ModelType["_id"]> & object = {}) - Ref type for others repos
- `createModel`(modelData) - create new model in collection. Returns [FinalModel](#final-model)
- `findOne`, `findMany`, `findById` - exact same as in mongoose but returns [FinalModel](#final-model) and `find` changed to `findMany`
- `deleteOne`, `deleteMany`, `updateOne`, `updateMany` - exact same as in mongoose
- `bulkSave`, `bulkWrite` - exact same as in mongoose but requires finalModels in parameters

### class `FinalModel`\<ModelType\> {#final-model}
- `constructor`(
    dbModel: mongoose.HydratedDocument\<ModelType\>,
    repo: RootRepo\<ModelType\>
){}
- `dbModel` - mongoose.HydratedDocument\<ModelType\>;
- `Repo`: RootRepo\<ModelType\>;
- `data` - get, set model data (except _id)
- `id` - readonly model id
- `syncSave`, `save` - save data (Recommended use async `save`)
- `delete` - delete model from db
- `partialDataUpdate` - (unsafe) way to update data takes any object and updates same fields
- `update` - copy data and paste to private dbModel (without saving in DB)
- `restore` - copy private dbModel data and paste to data

## License
Allowed to use in (private|commercial) projects.

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