Objection.js: Typings are missing .mixin and .compose

Created on 5 Oct 2017  路  13Comments  路  Source: Vincit/objection.js

Typings are for v0.8.4 not v0.8.9 and are missing at least mixin and compose exports.

enhancement

Most helpful comment

I'm happy to help when I can. Feel free to ping me, just know there might be latency in my response.

I'm grateful for objection!

All 13 comments

The typings usually lag a little behind since they were contributed by the community and are not actively maintained by more active members of the project. I don't use typescript myself, but I'll try to remember to at least add simple things like this in the future.

@mceachen has kindly been maintaining the typings for the most part.

There's also QueryBuilder.resultSize(): Promise<Number> but objection returns a string for this as far as I can tell.

We also can't use undefined values in where followed by skipUndefined because of the way Value works.

I can take this.

@koskimas maybe you can open issues (and at-reference me?) to track adding typings for new features, so typings expose new features as they're released.

@drew-r I'll ping you when my PR is ready so you can make sure I understood you correctly.

@drew-r:

There's also QueryBuilder.resultSize(): Promise but objection returns a string for this as far as I can tell.

I'm floating off master:

$ grep objection package.json
    "objection": "Vincit/objection.js",

and I see a number from the promise:

 Asset.query().where("foo", 123).resultSize().then(console.dir)
Promise {
  _bitField: 0,
  _fulfillmentHandler0: undefined,
  _rejectionHandler0: undefined,
  _promise0: undefined,
  _receiver0: undefined }
> 0

@mceachen I'd love to delegate the typing related tasks to you if you have time to take care of them! I've avoided doing that because I haven't wanted to bother you. I'm really grateful for your contributions!!

I'm happy to help when I can. Feel free to ping me, just know there might be latency in my response.

I'm grateful for objection!

I don't know if it's helpful for me to point out other missing typings or not, but the chained query() method on models appears to be missing typings as well.

  .query() // <--- query does not exist on typeof User
  .insert({ username: '[email protected]', password: 'secret' })
  .then((user: User) => {
    console.log(user.id);
  });

@mtpultz if your User class directly extends Model, things will work:

public class User extends objection.Model {
  static tableName = "users"
  ...
}

The typings that I submitted this morning only support .mixin and .compose for instance-level methods, not static methods. I'll look into making that work now.

Thanks @mceachen.

I am extending Model through a BaseModel so I'm not sure what the issue might be, but this is only day two using Objection, but can't run an insert query since the project won't build, and throws error TS2339: Property 'query' does not exist on type 'typeof User'.. If I remove the insert the migrations run properly and the database structure is setup.

import { BaseModel } from './base.model';

export class User extends BaseModel {
  static tableName = 'Users';

  // ... removed for brevity
}
import { Model, mixin } from 'objection';
import * as Password from 'objection-password';
import * as Unique from 'objection-unique';
import * as Visibility from 'objection-visibility';

export class BaseModel extends mixin(Model, [
  Password,
  Unique({
    fields: ['username'],
    identifiers: ['id']
  }),
  Visibility
]) {
  // ... removed for brevity
}

@mtpultz fwiw I have a non-trivial app using Objection, and have not needed to use plugins yet--I wouldn't get hung up on that bit.

I'd use the knex migration to set up unique constraints and PKs:

exports.up = function (knex, Promise) {
  return knex.schema
    .createTable("Example", table => {
      table.increments("id").primary()
      table.string("name").notNullable().unique()
      table.dateTime("createdAt").notNullable()
      table.dateTime("updatedAt").notNullable()
    })

Don't be afraid to hook into the $beforeInsert and $beforeUpdate hooks, and even the $parseDatabaseJson method in your base model class. You can do date serialization, ensure columns are set, and encrypt passwords (or better yet, have a method in your model that writes the encrypted contents to a column, rather than relying on magicks in a plugin).

I don't think my PR is quite right, after looking at the implementation of these composable plugins. I'm hoping to get answers to what @koskimas would like for the official public API before I send an update to my PR.

Thanks @mceachen you're right it has something to do with the plugins. If I just use Model directly in my BaseModel then the issue stops occurring, but the addition of multiple or a single plugin causes TypeScript to throw. I'll stick to using what's available through Knex and skip the magic.

@mtpultz you can try this

const plugins: typeof Model = mixin(...)

Then extend your BaseModel with plugins
I haven't tried it yet but it should probably work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nazar picture nazar  路  3Comments

AhmadRaza786 picture AhmadRaza786  路  3Comments

zacharynevin picture zacharynevin  路  4Comments

apronin83 picture apronin83  路  3Comments

chen7david picture chen7david  路  3Comments