Skip to content
This repository has been archived by the owner on Jan 12, 2023. It is now read-only.

Typescript version #98

Closed
panigrah opened this issue Jun 24, 2020 · 3 comments
Closed

Typescript version #98

panigrah opened this issue Jun 24, 2020 · 3 comments

Comments

@panigrah
Copy link

I tried to convert the plugin to typescript. Leaving it here for you to use if of value. Its missing the hashing overrides for now as I did not need them in my project as yet.

import HashId from 'hashids/cjs'
import memoize from 'nano-memoize'
import { Model } from "objection"

const memoizeHashId = memoize(
  (salt:string, minLength: number, alphabet?:string, seps?:string) =>
    new HashId(salt, minLength, alphabet, seps)
)

interface IConstructor extends Function {
  _hashIdInstance: {
    encode: (id: number) => string;
    decode: (hashId: string) => number;
  };
  hashIdField: string;
  hashedFields: string [];
}

class HashedQueryBuilder<M extends Model, R = M[]> extends Model.QueryBuilder<M, R> {

  findByHashId (hashId: string) {
    const id = (this.modelClass() as unknown as IConstructor)._hashIdInstance.decode(hashId)
    const compoundPK = Array.isArray(this.modelClass().idColumn)

    return this.findById(compoundPK ? id : id[0])
  }
}

export default <M extends typeof Model>(ModelClass: typeof Model): M => {
  return class extends ModelClass {
    static get hashIdSalt () {
      return this.name
    }

    static get hashIdMinLength () {
      return 6
    }

    static get _hashIdInstance () {
      return memoizeHashId(this.hashIdSalt, this.hashIdMinLength)
    }

    get hashId () {
      const conf = this.constructor as IConstructor;
      return conf._hashIdInstance.encode(this.$id())
    }

    get hashid () {
      return this.hashId
    }

    // This field indicates what property the hashid is written under.
    // By default, it overwrites id, but if you're using Algolia, for example,
    // it may be useful to set a custom id field as "ObjectID".
    static get hashIdField () {
      return 'id'
    }

    // These are all of the **non-id** fields that are hashed.
    // Useful if you have FK references that points to an id that is hashed.
    static get hashedFields () {
      return []
    }

    $formatJson (obj: {}) {
      let formattedJson = super.$formatJson(obj)
      const conf = this.constructor as IConstructor;

      // inject the hashed PK into the resulting JSON - a reminder
      // that hashId/hashid fields are virtual and do not get written to JSON.
      if (conf?.hashIdField) {
        formattedJson[conf.hashIdField] = this.hashId
      }

      // hash the rest of the fields
      conf.hashedFields.forEach(field => {
        formattedJson[field] = conf._hashIdInstance.encode(formattedJson[field])
      })

      return formattedJson
    }

    QueryBuilderType!: HashedQueryBuilder<this>
    static QueryBuilder = HashedQueryBuilder

  } as unknown as M
}
@issue-label-bot
Copy link

Issue Label Bot is not confident enough to auto-label this issue. See dashboard for more details.

@JaneJeon
Copy link
Owner

Like I said on the other issue, if you could make a PR with the tests passing I'd greatly appreciate it. Thanks!

@JaneJeon
Copy link
Owner

JaneJeon commented Oct 4, 2020

See #51 and #61 if you want to continue, thanks!

@JaneJeon JaneJeon closed this as completed Oct 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants