npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

adosearch

v0.1.95

Published

typed, deeply nested database search for adonis.js applications

Downloads

565

Readme

adosearch

Adosearch is an Adonis.js Query Scope that makes advanced search across multiple models trivial to implement. Inspired by the sofa/eloquence-base laravel package.

Installation

Using NPM

npm install adosearch

Or Yarn

yarn add adosearch

Usage

All you have to do is is define it as static property on the model class by calling the search function from adosearch.

import { BaseModel } from '@ioc:Adonis/Lucid/Orm'
import { search } from 'adosearch'

export default class User extends BaseModel {
  // ... other model properties
  public static search = search(this, ['name', 'email', 'username', 'phone'])
}

And then apply the search scope like so:

User.query().withScopes((scopes) => scopes.search('john doe'))

Just like that we've created a Query Scope that searches for john doe in the name, email, username & phone columns of the users table.

We could also specify the columns to search on the fly like so:

// search columns name and email for john doe
User.query().withScopes((scopes) => scopes.search('john doe', ['name', 'email']))

Searching Related Models

Adosearch allows you to search across multiple related models several layers deep. For example, if we have a Post model that belongs to a Category model and has many comments, we would typically set these relationships up in Adonis like so:

import { column, BaseModel, hasMany, HasMany, belongsTo, BelongsTo } from '@ioc:Adonis/Lucid/Orm'

class Post extends BaseModel {
  @column()
  public title: string

  @belongsTo(() => Category)
  public category: BelongsTo<typeof Category>

  @hasMany(() => Comment)
  public comments: HasMany<typeof Comment>
}

class Category extends BaseModel {
  @column()
  public name: string

  @hasMany(() => Post)
  public posts: HasMany<typeof Post>
}

class Comment extends BaseModel {
  @column()
  public text: string

  @belongsTo(() => Post)
  public post: BelongsTo<typeof Post>
}

Now, say we wanted to search for all the posts for a certain category name. We specify that in our Post model:

import { search } from 'adosearch'

class Post extends BaseModel {
  //... other properties
  public static search = search(this, [
    // other fields to search
    'category.name',
  ])
}

And then we can apply the search scope:

Post.query().withScopes((scopes) => scopes.search('life style'))

// or on the fly
Post.query().withScopes((scopes) => scopes.search('life style', ['title', 'category.name']))

We could go deeper and search for all comments on posts belonging to a category. For example:

import { search } from 'adosearch'

class Comment extends BaseModel {
  //... other properties
  public static search = search(this, [
    // other fields to search
    'post.category.name',
  ])
}

Apply the search scope:

Comment.query().withScopes((scopes) => scopes.search('life style'))

This is a relatively simple example, but we could go as deep as we want while adosearch generates the complex SQL queries for us on the fly.

And guess what? It has type support 🤩

Computed Search

Adosearch also provides a handy way to change the search value for a specific column before searching for it. In the example below we want to search by post status which are stored as numbers in the database:

import { column, BaseModel, hasMany, HasMany, belongsTo, BelongsTo } from '@ioc:Adonis/Lucid/Orm'
import { search } from '../src/search'
import Category from './Category'
import Comment from './Comment'

enum PostStatus {
  draft = 0,
  public = 1,
}

export default class Post extends BaseModel {
  @column()
  public title: string

  @column({ serialize: (s) => PostStatus[s] })
  public status: PostStatus

  @belongsTo(() => Category)
  public category: BelongsTo<typeof Category>

  @hasMany(() => Comment)
  public comments: HasMany<typeof Comment>

  public static search = search(this, ['title', 'category.name', 'comments.text', 'status'], {
    status: (s: string) => PostStatus[s.trim().toLowerCase()],
  })
}

Now when a user types draft or public it gets converted to the respective enum values before searching the status column in the Database.

Limitations

  1. Does not yet support the hasManyThrough relationship.
  2. The column suggestions in typescript might include getter properties if their return type is string | number | bigint | boolean | DateTime.