Coder Social home page Coder Social logo

typegoose / typegoose Goto Github PK

View Code? Open in Web Editor NEW
2.1K 19.0 135.0 26.37 MB

Typegoose - Define Mongoose models using TypeScript classes.

Home Page: https://typegoose.github.io/typegoose/

License: MIT License

TypeScript 92.26% Shell 0.03% JavaScript 7.37% CSS 0.34%
mongoose typescript mongodb nodejs js ts odm db models model

typegoose's Introduction

Typegoose

(These badges are from typegoose:master)
Node.js Tests codecov.io npm

Define Mongoose models using TypeScript classes

Migration

Migration Guides:
(Date format: dd-mm-yyyy)

Basic usage

import { prop, getModelForClass } from '@typegoose/typegoose';
import * as mongoose from 'mongoose';

class User {
  @prop()
  public name?: string;

  @prop({ type: () => [String] })
  public jobs?: string[];
}

const UserModel = getModelForClass(User); // UserModel is a regular Mongoose Model with correct types

(async () => {
  await mongoose.connect('mongodb://localhost:27017/', { dbName: 'test' });

  const { _id: id } = await UserModel.create({ name: 'JohnDoe', jobs: ['Cleaner'] });
  const user = await UserModel.findById(id).exec();

  console.log(user); // prints { _id: 59218f686409d670a97e53e0, name: 'JohnDoe', __v: 0 }
})();

Motivation

A common problem when using Mongoose with TypeScript is that you have to define both the Mongoose model and the TypeScript interface. If the model changes, you also have to keep the TypeScript interface file in sync or the TypeScript interface would not represent the real data structure of the model.

Typegoose aims to solve this problem by defining only a TypeScript interface (class), which needs to be enhanced with special Typegoose decorators (like @prop).

Under the hood it uses the Reflect & reflect-metadata API to retrieve the types of the properties, so redundancy can be significantly reduced.

Instead of writing this:

// This is a representation of how typegoose's compile output would look like
interface Car {
  model?: string;
}

interface Job {
  title?: string;
  position?: string;
}

interface User {
  name?: string;
  age!: number;
  preferences?: string[];
  mainJob?: Job;
  jobs?: Job[];
  mainCar?: Car | string;
  cars?: (Car | string)[];
}

const JobSchema = new mongoose.Schema({
  title: String;
  position: String;
});

const CarModel = mongoose.model('Car', {
  model: string,
});

const UserModel = mongoose.model('User', {
  name: { type: String },
  age: { type: Number, required: true },
  preferences: [{ type: String }],
  mainJob: { type: JobSchema },
  jobs: [{ type: JobSchema }],
  mainCar: { type: Schema.Types.ObjectId, ref: 'Car' },
  cars: [{ type: Schema.Types.ObjectId, ref: 'Car' }],
});

You can just write this:

class Job {
  @prop()
  public title?: string;

  @prop()
  public position?: string;
}

class Car {
  @prop()
  public model?: string;
}

class User {
  @prop()
  public name?: string;

  @prop({ required: true })
  public age!: number; // This is a single Primitive

  @prop({ type: () => [String] })
  public preferences?: string[]; // This is a Primitive Array

  @prop()
  public mainJob?: Job; // This is a single SubDocument

  @prop({ type: () => Job })
  public jobs?: Job[]; // This is a SubDocument Array

  @prop({ ref: () => Car })
  public mainCar?: Ref<Car>; // This is a single Reference

  @prop({ ref: () => Car })
  public cars?: Ref<Car>[]; // This is a Reference Array
}

Extra Examples


Requirements & Install

Typegoose's Quick Start Guide

Testing

yarn install
yarn run test

Versioning

This Project should comply with Semver. It uses the Major.Minor.Fix standard (or in NPM terms, Major.Minor.Patch).

Join Our Discord Server

To ask questions or just talk with us, join our Discord Server.

Documentation

Known Issues

Here are the known-issues

FAQ

Here is the FAQ

Notes

  • Please don't add +1 or similar comments to issues. Use the reactions instead.

typegoose's People

Contributors

afgthecat avatar aljazerzen avatar andreialecu avatar b-stefan avatar ben305 avatar captaincaius avatar dandv avatar dependabot[bot] avatar ggurkal avatar hasezoey avatar johndeved avatar kaihaase-wd avatar kerolloz avatar lioness100 avatar luxcium avatar mdstaff avatar megahertz avatar michallytek avatar noseworthy avatar richardsimko avatar rjmunro avatar semantic-release-bot avatar simonb12 avatar smolinari avatar szokodiakos avatar thevaan avatar ukoester avatar vinay360 avatar yardenshoham avatar zoeleu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typegoose's Issues

Typegoose & Mongoose on client side

Typegoose allows sharing of types between back-end and front-end. But it requires Mongose on client side for no reason.

So Mongoose is embedded inside the client bundle. Hence packages as Buffer. Furthermore with eg Angular 8 the need of some polyfills as:

// to avoid "ReferenceError: global is not defined" */
(window as any)['global'] = window;

// global.Buffer = global.Buffer || require('buffer').Buffer;
// @ts-ignore
window.Buffer = window.Buffer || require('buffer').Buffer;

(window as any).process = {
  env: { DEBUG: undefined }
};

Is there any plan that previous works/discussion threads on the subject would be taken in account soon?
See:

Versions

  • NodeJS: 12.3.1
  • @hasezoey/typegoose: 6.0.0-27
  • mongoose: 5.6.6
  • mongodb: 4.0.9

Code Example

import { prop, Typegoose } from 'typegoose';

export class Dummy extends Typegoose {
  _id?: string;  // surrogate key
  @prop({ unique: true, required: true }) id?: string;  // business key
  @prop() title?: string;
  @prop() description?: string;
  @prop() nature?: string;
  @prop() statut?: string;
}

[Question] Type is invalid error

Hi @hasezoey , thanks for maintaining this project

I just refactored a project to use Typegoose instead of just Mongoose. I'm using the 6.0 "next" version on NPM. But when I start my server, I get this error:

Error: "undefined.users"'s Type is invalid! Type is: "undefined"

The error is quite vague, and it's hard to know where it comes from, especially since I just made a lot of changes. All I know is that users is one of my collections.

Is it introspecting my database to see if it matches the generated schema ? Did I mess up a prop() ?

Thanks

Add default Classes

  • add class for GridFS szokodiakos#216 hasezoey#10
  • add class for options @modelOptions({ schemaOptions: { timestamps: true } }) (6.0.0-14)

(striked means canceled)

[Question] - Use Jest instead of Mocha?

I would suggest using jest instead of mocha.
For several reasons:

  1. Reduce dependency for chai
  2. More advanced mocking features
  3. Support to execute one test only direct inside the Webstorm GUI.

What do you think about this suggestion?

Discriminators for nested Arrays

Support Discriminators feature for arrays in documents

To support the discriminator feature altogether, we need to think about structures like this:

export class Building {
  @prop({default: 100})
  public width: number;

  @prop({enum: BuildingTypes})
  public type: BuildingTypes;
}

export class Garage extends Building {
  @prop({default: 10})
  public slotsForCars: number;
}
export class SummerHouse extends  Building {
  @prop({default: 100})
  public distanceToLake: number;
}

export class Area  {
  @arrayProp({items: Building})
  public buidlings: Building[];
}

const area = AreaModel.create({})
area.buildings.push({__t: "SummerHouse", distanceToLake: 100})
area.buildings.push({__t: "Garage", slotsForCars: 20})
area.save()

The current behaviour is that all properties that are not in the Building model will be deleted

Do you have already an idea for the implementation?

enum BuildingTypes {
  Garage = "Garage",
  SummerHouse = "SummerHouse"
@modelOptions({
  schemaOptions: {
    discriminatorKey: 'type',
  }
})
export class Building {
  @prop({default: 100})
  public width: number;

  @prop({enum: BuildingTypes})
  public type: BuildingTypes;
}
@modelOptions({
  discriminatorId: BuildingTypes.Garage
})
export class Garage extends Building {
  @prop({default: 10})
  public slotsForCars: number;
}
@modelOptions({
  discriminatorId: BuildingTypes.SummerHouse
})
export class SummerHouse extends  Building {
  @prop({default: 100})
  public distanceToLake: number;
}

export class Area  {
  @arrayProp({items: Building, discriminatorClasses: [SummerHouse, Garage]})
  public buidlings: Building[];
}

const area = AreaModel.create({})
area.buildings.push({__t: "SummerHouse", distanceToLake: 100})
area.buildings.push({__t: "Garage", slotsForCars: 20})
area.save()

Implemented this solution in B-Stefan#1

What do you think about this feature and the potential solution?

[Request] Set custom model name in modelOptions

Describe what you need | want

Currently, the class name is used as the model name in mongoose. In plain mongoose, there is the option to set a different model name.

This probably doesn't matter for most users, but I'm currently writing migrations for MongoDB where I have a few similar, but different versions of the same model. When using the same name for all of them, a lot of weird errors came up and it took me quite some time to figure out what the problem was.

Do you have already an idea for the implementation?

Add an additional parameter to the modelOptions decorator, e.g. modelName and use it if it's present instead of the class name in getModelForClass.

[Request] make model configuration classes throw when new()ing by default

Describe what you need | want

Model configuration classes (a term i just made up) are easy to be used accidentally instead of the model itself.

I know r6 seemed to make efforts to avoid decorators on the classes themselves, but I think it would be useful to have them.

I know it's not a HUGE deal, but it's pretty easy to implement.

Do you have already an idea for the implementation?

yes... for example:

@typegoosemodelconfig()
class CarConfig {
  @prop()
  passengers: number;
  @prop()
  name: string;
}

typegoosemodelconfig can decorate the constructor so it throws (the behavior can be disabled w/ options). Also, the prop processors can throw if some metadata that typegoosemodelconfig sets isn't set.

Actually... technically, prop's decorator can do it too and avoid the decorator, since you have access to target - but I'm not sure I'd prefer that approach.

Getter: `Error: Virtual path "name" conflicts with a real path in the schema`

Versions

  • NodeJS: 12
  • Typegoose(NPM): 6.0.0-26
  • Typegoose(GIT): commithash
  • mongoose: 0.0.0
  • mongodb: 0.0.0

Code Example

import { getModelForClass, prop } from "@hasezoey/typegoose";
import * as mongoose from "mongoose"; // [email protected]

class User {
    @prop()
    public username?: string;

    @prop()
    get name(){
      return this.username
    }
}
const UserModel = getModelForClass(User);

(async () => {
    await mongoose.connect(`mongodb://localhost:27017/test`, { useNewUrlParser: true });
    const user = new UserModel({ username: "user1" });
    await user.save()

    console.log(user);
})();

Output:

/Users/johnny/projects/test/typegoose-test/node_modules/mongoose/lib/schema.js:1712
    throw new Error('Virtual path "' + name + '"' +
          ^
Error: Virtual path "name" conflicts with a real path in the schema
    at Schema.virtual (/Users/johnny/projects/test/typegoose-test/node_modules/mongoose/lib/schema.js:1712:11)
    at Schema.<anonymous> (/Users/johnny/projects/test/typegoose-test/node_modules/mongoose/lib/schema.js:1869:12)
    at Array.forEach (<anonymous>)
    at Schema.loadClass (/Users/johnny/projects/test/typegoose-test/node_modules/mongoose/lib/schema.js:1858:47)
    at Object._buildSchema (/Users/johnny/projects/test/typegoose-test/node_modules/@hasezoey/typegoose/src/internal/schema.ts:49:7)
    at buildSchema (/Users/johnny/projects/test/typegoose-test/node_modules/@hasezoey/typegoose/src/typegoose.ts:141:9)
    at Object.getModelForClass (/Users/johnny/projects/test/typegoose-test/node_modules/@hasezoey/typegoose/src/typegoose.ts:96:42)
    at Object.<anonymous> (/Users/johnny/projects/test/typegoose-test/src/main.ts:12:19)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Module.m._compile (/usr/local/lib/node_modules/ts-node/src/index.ts:473:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Object.require.extensions.<computed> [as .ts] (/usr/local/lib/node_modules/ts-node/src/index.ts:476:12)
    at Module.load (internal/modules/cjs/loader.js:643:32)
    at Function.Module._load (internal/modules/cjs/loader.js:556:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:839:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/ts-node/src/bin.ts:158:12)

Do you know why it happenes?

no

[Request] Don't enforce suffix on model name

Hello,

Model names are being suffixed with the collection name when schemaOptions.collection is passed as model options.

We dynamically use these model names and therefore prefer to have control over them. If I name my model X, then it should be named X, nonetheless of whether I specify a collection name. I think it is better to not make any decisions for the user of how models should be named, but instead use the class name as model name while providing an option to override it.

function getName(cl) {
    const options = Reflect.getMetadata(constants_1.DecoratorKeys.ModelOptions, cl) || {};
    const baseName = cl.name;
    const suffix = (options.options ? options.options.customName : undefined) ||
        (options.schemaOptions ? options.schemaOptions.collection : undefined);
    return suffix ? `${baseName}_${suffix}` : baseName;
}

Maybe use customName as name instead of suffix.

I humbly request you to reconsider,

Chris

Support for multidimensional array types

Hi, thanks for maintaining this amazing project.

We ran into a problem during porting our Mongoose schemas to Typegoose definitions. We use multidimensional arrays in our schemas, but I haven't found any information about this use-case in the documentation. Is it supported by the lib?

E.g. I have a class definition like this:

class Foo {
  @arrayProp({
    items: [Number]
  })
  public bar: number[][];
}

const FooModel = getModelForClass(Foo);

When I run the code it gives me an error:
Error: "Foo.bar"'s Type is invalid! Type is: "function Number() { [native code] }"

As far as I know this is a valid Mongoose schema:

new mongoose.Schema({
  bar: [[Number]]
})

Could you provide some information about this problem?
Thanks

How to use Typegoose with type definitions?

I had a class which looked like this:

interface Car {
  model: string;
}

function insertCar(car: Car) {
// use mongodb js driver to insert
}

insertCar({model: "Tesla"});

Now when I convert that to Typegoose, I am unable to use Car as the type of my function parameter:

class Car extends Typegoose {
  @prop()
  model!: string;
}

function insertCar(car: Car) {
// use typegoose to insert
}

insertCar({model: "Tesla"});   
    // Error: Type '{model: string}' is missing the
    // following properties from type 'Car': 
    // getModelForClass, setModelForClass, buildSchema

How to fix this error?

RangeError: Maximum call stack size exceeded - .find({}) function - find all

I'm new to using your package and think it's fantastic and makes my life a lot easier so thank you firstly.
I am currently stuck on an issue I can't seem to work around, I put data into a database absolutely fine but when i try to retrieve it, even with it being small amounts it returns RangeError: Maximum call stack size exceeded. I am trying to use the .find({}) function on my model and it weirdly returns to the variable locally as a correct object but when the function itself tries to return it, it splays out that message on four different models I have. These are triple nested objects, I have attached a few of these objects. If anyone can work it out, I would be grateful. I have uploaded my three DTO files that link to one another. If anyone would like anymore information, please ask. Thanks.
Archive.zip

Better ModelType & ReturnModelType Documentation

Continuation of hasezoey#22

Make Better Documentation of the difference between ModelType and ReturnModelType

Current situation: sometimes ReturnModelType cannot be used (needs repo script, because i cant find a case where it happens) and ModelType seems to solve it, but has actually not a good documentation on what it does

@Ben305 @B-Stefan


Help is appreciated, because i dont really understand what ModelType and ReturnModelType do differently (i know i made ReturnModelType, but only because i dont really understand ModelType) ... they seem to do the same thing, but actually dont

[Request] Prevent implicit "Mixed" by default

Describe what you need | want

We have a code path that adds "Mixed" fields. These can be a bit dangerous IMO because you might think you have a field that's guaranteed to be of a certain type, but literally anything can be jammed into it.

I can see how some applications might be okay with Mixed, but I think it should always be explicit (there was an issue on mongoose's issue queue where vkarpov was discussing this too).

Mongoose itself was talking about deprecating implicit mixed too. I think typegoose should step with the best foot forward on r6 and throw in the "Mixed" branch by default (unless some "implicitMixedOkay" option is set). Or just disallow implicit mixed altogether.

Do you have already an idea for the implementation?

Yes - mentioned above.

Help wanted for adding Guides & Documentation

Anyone who wants to write guides can write one and Pull-Request it

Guidelines:

  • the files must be markdown (.md)
  • place them in github-page/_guides
  • if they are "advanced behavior" put them in github-page/_guides/advanced
  • if it is documentation put it into github-page/_docs and the folder most appropriate for it

jekyll got added in e37001a, help is here wanted too to make it better, its currently just bare-bones

PS: when someone wants to do an icon for typegoose, it would be appreciated :)

[Request] document the fact that class names must be globally unique

Describe what you need | want

Hi. I read through the code a bit, and correct me if I'm wrong, but it seems typegoose maintains a registry that maintains mongoosey information, and that registry is keyed by the name of the class as it's defined.

I think this creates a gotcha that most users won't realize that if they use the same class name in different files, things will very likely break.

So:

  1. I think this gotcha should be documented.
  2. This may sound naive since I've just barely looked at the code today, but can't we keep the registry ON the classes themselves instead of having a singleton, which would avoid this gotcha entirely?

Do you have already an idea for the implementation?

Yes - Assuming it's option one, I think I could submit a PR to README that explains this pretty fast.

And if it's option 2, I wouldn't mind taking a whack at it either ;).

DeprecationWarning

I receive the following warning:

DeprecationWarning: This Package got moved, please use @hasezoey/typegoose | github:hasezoey/typegoose

I removed typegoose and add it again but the warning is still there. What to do?

Code of ReturnModelType documentation results in TS2344 and TS2742

I'm adapting my Nest.js application to the latest typegoose . One issue I stumbled upon was that my static methods didn't transpile anymore.

I had to use "typeof" (like in the test classes of typegoose) to address TS2344 and an explicit return type to address TS2742.

Strange thing with ref

Versions

  • NodeJS: unkown
  • Typegoose(NPM): 6.0.0-28, and 29 not working anymore
  • mongoose: unkown
  • mongodb: unkown

Code Example

someprop in the following example saves as an string, which shouldnt happen

function somefunc(arg: string) {
  // unkown
  return 'some string';
}

class something {
  @prop({ ref: 'Business', default: () => somefunc('business') })
  public someprop: Ref<Business>;
}

class Business {} // was not provided

Do you know why it happenes?

no, it is really confusing because when chaning Ref<T> to mongoose.Schema.Types.ObjectId, it works again

  • the type public something: type should have no effect in ref
  • refType (to force the type) has absolutely no effect

proposed things:

  • not an issue with typegoose and an "error" by mongoose's handling of 'defaults'
  • something really tricky

discovered by @RyannGalea on discord

Notes to this Repository

What this Fork currently has, and the original not:

  • Github pages, where later typedoc will get deployed
  • Wiki, which currently points to readme & typedoc, in the future it will point to the pages
  • Milestones, to know which Issues will be worked on in which version

Q: References - Population and Required

Hi everyone

I looked in the issues here and tried to derive it myself from the documentation but wasn't able to fully cope the functionality.

I have a model with a ref myReference!: Ref<MyReference> annotated as @prop({ required: true, ref: Customer}). MyReference is just a class with name for testing purposes.

How, two problems I faced:

  • When creating the model with passed data, I didn't have to add myReference. It worked without, the required did not pose an issue
  • The other thing: I put the MyReference _id into the model, it stored fine and I can see the $oid saved in the model. If I retrieve the model I get the $oid. How can I populate myReference while loading? I tried the Virtual-Populate documentation but wasn't able to figure it out.

If anybody can maybe point me in the right direction it would be awesome.

Thanks a lot in advance

6.0 usage with class-transformer

Pre 6.0 we were using our model schema along with the library class-transformer in order to hide/expose certain properties when they were serialized for use in a response.

We were able to annotate our schema like so:

import { Expose, Exclude } from 'class-transformer'

@Exclude()
@index('parent', { sparse: true })
export class Organization extends Typegoose {
  @Expose()
  public readonly _id: Types.ObjectId

  @Expose()
  @prop({ required: true })
  public name: string

  @Expose()
  @prop({ default: null })
  public parent: Ref<Organization> | null
}

My hope with 6.0 was to get rid of having to use things like DeepPartial in order to use the class model definition type as an argument type to enforce the right data to functions that acted on the model.

My main issue is with the @Expose on the _id field. Since that field is present when dealing with a document, but not at object creation time. Now when trying to pass in a plain object with properties that match all the other class properties to an argument that is typed to Organization TS complains that my object does not have an _id.

Imagine a function like this:

class SomeService {
  public createNewOrganization(data: Organization) {
    //
  }
}

And then trying to call it:

const data = {
  name: 'TheOrg',
  parent: null
}
someService.createNewOrganization(data)

Any idea on how to get around this? I know this may not be specifically a typegoose issue, but since this was a heavy use case in our past usage of Typegoose, I figured I would pose the question here.

[Question] TypeScript questions

Here's my model.

import {
  Ref,
  arrayProp,
  getModelForClass,
  modelOptions,
  prop
} from '@hasezoey/typegoose'

import { User } from './user'

export class Person {
  @prop({ default: new Date(), required: true })
  joined!: Date

  @prop({ required: true })
  approved!: Date

  @prop({ ref: User })
  user!: Ref<User>

  get isOwner() {
    return false

    // console.log('parent', this.parent)
    // return this.parent().user._id.equals(this.user)
  }
}

const PersonModel = getModelForClass(Person)

@modelOptions({
  schemaOptions: {
    timestamps: {
      createdAt: 'created',
      updatedAt: 'updated'
    }
  }
})
export class Plan {
  @prop({ required: true })
  description!: string

  @prop({ required: true })
  location!: number[]

  @arrayProp({ items: Person })
  people!: Person[]

  @prop({ ref: User, required: true })
  user!: Ref<User>

  static async add(
    description: string,
    location: {
      latitude: number
      longitude: number
    },
    user: User
  ) {
    const { latitude, longitude } = location

    const owner = new PersonModel({
      user,
      approved: new Date()
    })

    const plan = await PlanModel.create({
      description,
      user,
      location: [longitude, latitude],
      people: [owner]
    })

    return plan
  }

  json() {
    const { _id, created, description, location, people, updated } = this

    const [longitude, latitude] = location

    return {
      created,
      description,
      updated,
      id: _id.toString(),
      location: {
        latitude,
        longitude
      },
      people: people.map(({ approved, joined, isOwner, user }) => ({
        approved,
        isOwner,
        joined,
        user: {
          id: user._id.toString(),
          name: user.name
        }
      }))
    }
  }
}

const PlanModel = getModelForClass(Plan)

export default PlanModel

Questions

  1. How can I use this.parent() inside a sub-document so I can populate the isOwner field?
  2. How can I populate the isOwner virtual field?
  3. How can I override the toJSON method from mongoose so I don't have to create my custom json method?
  4. VS Code complains that _id, created, and updated don't exist on type Plan, even though _id should exist and I've added created and updated timestamps through schemaOptions. How can I resolve this? The response, as expected, works fine.
  5. I have called await plan.populate('people.user').execPopulate() before plan.json() but json doesn't know that the people.user field has been populated. Is this a bug or am I doing this wrong? VS Code complains that Property 'name' does not exist on type 'Ref<User, ObjectId>' even though according to the documentation, it's T if populated, and ObjectID if not.
  6. When I type _id.equals, VS Code complains Property 'equals' does not exist on type 'Ref<User, ObjectId>'. Is this a bug? You can't compare strings against ObjectIds without equals.

All Props are empty after v6.0.0-22

Versions

  • NodeJS: 12.6.0
  • Typegoose(NPM): 6.0.0-26
  • Typegoose(GIT): commithash
  • mongoose: 0.0.0
  • mongodb: 0.0.0

Code Example

export class User{
  @prop()
  username:string
}
export const UserModel = getModelForClass(User)

const user = new UserModel({username: 'user1'})

console.log(user)

// there is no `username` property in `user`.

Do you know why it happenes?

no

Move data.ts collections to Maps

This is an "Issue" for what is included in version 6.0.0
Move collections to use Map<T, S>

These Changes can be found in branch r6/master

  • methods (6.0.0-3)
  • schema (6.0.0-8)
  • models (6.0.0-7)
  • virtuals (6.0.0-4)
  • hooks (6.0.0-2)
  • plugins (6.0.0-5)
  • constructors (6.0.0-6)

next method on @Pre middleware as undefined type

Screen Shot 2019-10-02 at 13 56 43

Versions

  • NodeJS: 12.10
  • Typegoose(NPM): 6.0
  • mongoose: 5.7.3

Code Example

@Pre<User>('save', function(next) {
  if (this.isModified('password')) {
    const salt = bcrypt.genSaltSync();
    this.password = bcrypt.hashSync(this.password, salt);
  }
  next();
})

Do you know why it happenes?

declare type PreFnWithDT<T> = (this: DocumentType<T>, next?: EmptyVoidFn) => void;

// hooks.d.ts

type next as optional

Everyone that has a clone / fork

For everyone who has a clone / fork, please know that the master branch will get replaced by r6/master (will be merged, but please know, until the actual tag of the version, it might be not working commits)

and that the package will change again to @typegoose/typegoose

Remove Deprecated Method Decorators

Title

its currently planned for version 6.1.0 to remove all the deprecated things (at least these that serve absolutely no purpose anymore (like instanceMethod & staticMethod), others might be in longer for backwards-compatibility

Consider Opening Public Organizations on GitHub and NPM to Host Typegoose Project

Consider Opening Public Organizations on GitHub and NPM to Host Typegoose Project

Overview

As typegoose is in the middle of a repo migration. I would suggest opening official orgs on GitHub and NPM to host the official versions of typegoose. Fortunately, the typegoose org names are available on npm and GitHub as the time of this issue creation.

This would allow users to install typegoose via the npm scope @typegoose:

npm install @typegoose/typegoose

Notes

Thanks @hasezoey for taking over this project. Our team was planning to start adopting this project in the near future.

[Discussion] Removal of options from getModelForClass making existingConnection usage challenging

I am attempting to migrate to 6.0. We are using NestJS as our framework, and more specifically, kpfromer/nestjs-typegoose for integrating Typegoose with NestJS.

In an effort to migrate nestjs-typegoose to 6.0, the first hangup I am running into is the removal of options from getModelForClass. Since the mongoose connection is setup ahead of time, and does not use the default connection, passing this connection into each model is challenging.

Giving this some additional thought, since the connection is added as part of a decorator, I'm having a hard time seeing how this could be done for even non-NestJS apps. Usually, an additional connection needs to be setup async ahead of time, which makes it hard to pass a connection to an imported file at module load time, without forcing the creation of a wrapper for each model that allows passing in a connection post module load time.

Any thoughts on how to get the existingConnection back into the model load time in a way more similar to how it was passed in via getModelForClass?

staticMethod, with or without decorator still doesn't work

Versions

  • NodeJS: 10.16.0
  • Typegoose(NPM): 6.0.0 (@typegoose/typegoose)
  • Typegoose(GIT): commithash
  • mongoose: 5.7.3

Code Example

class Post {
  @prop() _id!: string;
  @prop({ required: true, unique: true }) title!: string;
  @prop() date?: Date;
  @prop({ default: [] }) tag!: string[];
  @prop({ required: true }) content!: string;

  async findByQ(q: string, offset: number = 0, limit: number | null = 10, sort?: ISortOptions<Post>) {
    ...
    return {count, data};
  }
}

const PostModel = getModelForClass(Post);
// PostModel.findByQ = new Post().findByQ;  // TypeScript will complain findByQ is not a function, without this line.

Adding decorator @staticMethod doesn't help.

Do you know why it happens?

no

Self-Containing Classes

Continuation of szokodiakos/typegoose#19

Versions

  • NodeJS: 12.10.0
  • Typegoose(GIT): 38b9f79

Code Example

class SelfContaining {
  @prop()
  public nest?: SelfContaining;
}

getModelForClass(SelfContaining);

Do you know why it happenes?

Typegoose tries to build the schemas that are a prop


PS: i have absolutely no clue on how to fix this

Edit 1: addition, i didnt just meant like the code example, it was just very basic, here an proper example:

class SelfContaining {
  @prop()
  public nest?: SelfContaining;
}

const selfContainedModel = getModelForClass(SelfContaining);
const doc = new selfContainedModel({ nest: new selfContainedModel({ nest: new selfContainedModel({}) }) });

Using Typegoose with BaseEntity, multiple inheritance [Question]

Hi,

i've got this error (intermediate value).setModelForClass is not a function , i read the note section and i found this Typegoose cannot be used with classes of the same name, it will always return the first build class with that name, so i want to implement in my class User and extend it with Typegoose and BaseEntity using the function of TS applyMixins, this will broken my code ? because my class and the interface have the same name ? Anyways i just trying to use typegoose to avoid using schemas and trying to use Base Entity to use repository for DB stuff.

image

[Bug] References in array schemas translate to Mixed instead of ObjectID

Hello,

References in array schemas translate to Mixed instead of ObjectID.

Consider the following code:

export class ChatChannelGroup {
  @prop({ enum: ChatChannelGroupType, required: true })
  public type!: ChatChannelGroupType;

  @prop({ ref: TEvent, required: true })
  public id!: Ref<TEvent>;
}

export class ChatChannel {
  @arrayProp({ _id: false, items: ChatChannelGroup, required: true })
  public access_groups!: ChatChannelGroup[];
}

When inspecting ChatChannel.schema.paths.access_groups.schema.paths.id I get a type of instance Mixed:

    "id": {
      "path": "id",
      "instance": "Mixed",
      "validators": [
        {
          "message": "Path `{PATH}` is required.",
          "type": "required"
        }
      ],
      "getters": [],
      "setters": [],
      "options": {
        "required": true
      },
      "_index": null,
      "isRequired": true,
      "originalRequiredValue": true,
      "$isUnderneathDocArray": true
    }
  },

When passing the class instead of the class name on line https://github.com/typegoose/typegoose/blob/master/src/prop.ts#L116 it correctly translates into ObjectID:

    "_id": {
      "path": "_id",
      "instance": "ObjectID",
      "validators": [],
      "getters": [],
      "setters": [
        null
      ],
      "options": {
        "auto": true
      },
      "_index": null,
      "$isUnderneathDocArray": true
    }

Best regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.