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

exp-mgo-toolings

v1.0.20

Published

Made faster query for express and mongoose

Downloads

9

Readme

exp-mgo-toolings

Made faster query for express and mongoose

Modules

  • Query helper for MongoDB mongoose Required packages
    • bson
  • AWS helper easy use and include resize before upload Required packages
    • aws-sdk
    • uuid
    • dotenv
    • sharp
  • Pubnub helper a little helper made more understandable for using pubnub as realtime app Required packages
    • pubnub
  • Mail helper Required packages
    • nodemailer
  • Api Response for express made code easier to handle error and standard response
  • asyncHandler handler all error and no more try catch block every where

If you want to ignore package from other modules

  • Import directly from DIR
const asyncHandle = require("exp-mgo-toolings/src/async-handler")
const ApiResponse = require("exp-mgo-toolings/src/api-response")
const Aws = require("exp-mgo-toolings/src/aws")
const Mail = require("exp-mgo-toolings/src/mail")
const PubNub = require("exp-mgo-toolings/src/pubnub")

# Query function's description

Automatic Detect query params from query string page Perform paginate current page. Note: must follow with limit limit Perform paginate current limit. Note: must follow with page q Perform search keyword, work with setSearchField method start_date Perform filtering by date rate required with end_date end_date Perform filtering by date rate required with start_date sort Perform sorting concept column|arg ex: created_at|asc summary Get full paginate response such like: total, total_page, total_in_page, etc...

Simple usage

const { Query } = require("exp-mgo-toolings")
const mongoose = require("mongoose")

// Register somewhere for future use
const query = new Query(mongoose)

// ex1: "order" as collection's name
const execute = query.model("order") 

// ex2: Put model instance of mongoose
const ExampleModel = require("./some-mongoose-model")
const execute = query.model(ExampleModel) // ex2: "order" as collection's name

// Perform sample query
const result = await execute.exec(req) // "req" coming from express request

// ex3: Perform select and unset. Important select & unset cannot combine together
const result = await excute.
	unset("removeField1 removeField2") // or ["removeField1","removeField1"]
	.exec(req) // "req" coming from express request

const result = await excute.
	select("field1","field2") // or ["field1","field2"]
	.exec(req) // "req" coming from express request

Example usage of $lookup

// Peform sample lookup aggreagte concept
const result = await excute.
	lookup({ from: "modelName", localField: "localField", foreignField: "_id", as: "localField" })
	.exec(req) // "req" coming from express request

// Peform sample lookup aggreagte concept with select
const result = await excute.
	lookup({ from: "modelName", localField: "localField", foreignField: "_id", as: "localField", select: "field1 field2" })
	.exec(req) // "req" coming from express request

// Peform sample lookup aggreagte concept with unset
const result = await excute.
	lookup({ from: "modelName", localField: "localField", foreignField: "_id", as: "localField", unset: ["field1", "field2"] })
	.exec(req) // "req" coming from express request

// Peform sample lookup aggreagte concept with many. Default is true
const result = await excute.
	lookup({ from: "modelName", localField: "localField", foreignField: "_id", as: "localField", many: false })
	// many false return as object
	.exec(req) // "req" coming from express request

Example usage of $populate

// Peform sample populate mongoose concept with many. Default is true
// ex1: Sample usage
const result = await excute.
	populate("ref_field", "field1 field2") // 1. ref model 2.select field
	.exec(req) // "req" coming from express request

// ex2: With $select
const result = await excute.
	populate({ path: "ref_field", select: "field1 field2" })
	.exec(req) // "req" coming from express request

// ex3:With $unset
const result = await excute.
	populate({ path: "ref_field", unset: ["field1", "field2"] })
	.exec(req) // "req" coming from express request

// ex3: With $many  deafult is false
const result = await excute.
	populate({ path: "ref_field", many: true })
	.exec(req) // "req" coming from express request

// ex4: With sub populate required "modelName"
const result = await excute.
	populate({
		path: "ref_field",
		populate: {
			modelName: "ref_model", path: "ref_field"
			// Can use unset, select, many, etc...
		}
	})
	.exec(req) // "req" coming from express request

// ex5: With many sub populate required "modelName"
const result = await excute.
	populate({
		path: "ref_field",
		populate: [{
			modelName: "ref_model", path: "ref_field"
			// Can use unset, select, many, etc...
		}]
	})
	.exec(req) // "req" coming from express request

// ex6: With sub populate required "modelName"
const result = await excute.
	populate({
		path: "ref_field",
		populate: {
			modelName: "ref_model", path: "ref_field",
			// Can use unset, select, many, etc...
			populate: {
				modelName: "ref_model", path: "ref_field"
				// Can use unset, select, many, etc...
			}
		}
	})
	.exec(req) // "req" coming from express request

Example usage of $match

// ex1: simple match
const result = await excute.
	match({
		name: "bank"
	})
	.exec(req) // "req" coming from express request


// ex2: Perform match with populate
/* 
[
	{
		"name":"bank",
		"office_id":"18273817231927371892731"
	}
]
*/
const result = await excute.
	populate({
		path: "office_id",
		select: "name"
	}).
	match({
		"office_id.name": "where is my office data"
	})
	.exec(req) // "req" coming from express request

Example usage of $setSearchField work with "q" from query string

// ex1: simple match
const result = await excute.
	.setSearchField("name", "another_field")
	.exec(req) // "req" coming from express request


// ex2: Perform match with populate
/* 
[
	{
		"name":"bank",
		"office_id":"18273817231927371892731"
	}
]
*/
const result = await excute.
	populate({
		path: "office_id",
		select: "name"
	}).
	.setSearchField("office_id.name", "another_field")
	.exec(req) // "req" coming from express request

lookup Perform join document in aggregate concept

  • path Reference path
  • select Filter only given select field
  • populate Sub populate
  • many Perform default "false"
  • unset Filter out field

populate Perform join document in mongoose concept

  • path Reference path
  • select Filter only given select field
  • populate Sub populate
  • many Perform default "false"
  • unset Filter out field
  • modelName Models's name to reference to. Required only in sub populate

set(String) Set response json like $project ex: "field1 field2"

match(Object) Perform $match condition

setSearchField(...String) Perform $match condition ("field1","field2")

custom(Object) Perform custom pipeline in aggregate concept

forcePaginate(Boolean) True: required page, limit in query

select(String) Perform Select field ex: "field1 field2" or ["field1","field2"]

unset(...String) Perform filter out parameters in response ex: ("field1","field2")

setOption(Object)

  • performPaginateBeforeLogic Advance usage perform paginate before condition or end of condition
  • dateField Set filter field from query "start_date" and "end_date"

Final query must be called (Promise function)

exec(req) Combine all condition and Automatic detect query string and perform query

# ApiResponse with asyncHandler

API RESPONSE Usage description

  • Overview Ex: Throw new Error(StatusCode-ErrorCode::Message)
  • Ex1: Throw new Error(400::Your error message)
  • Ex2: Throw new Error(Your error message) Default 500 status
  • Ex3: Multi language: Throw new Error(400::en=English message && la=Lao message)
  • Ex4: With error CODE as ER001: Throw new Error(400-ER001::Your error message)
  • EX5: No Message use throw new Error(400-ERR001) Default message "Request failed"
  • EX6: No Message & No Error Code use throw new Error(400) Default message "Request failed" and "ERR500" for error code

Let's try in express and asyncHandle

const { asyncHandle, ApiResponse } = require("exp-mgo-toolings")

// ex1: sample use sage
app.get("/", asyncHandle(async ({ req, res }) => {
	const resp = new ApiResponse(res)

	if (checkError) throw new Error(`400::Your response message`)

	// Your code here
	return resp.response({})
}))

// ex2: sample with mongoose transaction
app.get("/",asyncHandle(async ({ body, res, opts, commit }) => {
	const resp = new ApiResponse(res)

	// Dont worry about abort 
	// If there is error automatic abort transaction

	await ExampleModel.insertOne(body, opts)

	await commit() // commit transaction

	return resp.response({})
}, mongoose))

#AWS File upload

Important ENV must specific Don't worry I wont save your credential XD

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_KEY
  • AWS_S3_BUCKET_NAME

Methods

uploadFile()

file file as buffer ex: req.file.image

bucket (optional) default is set in ENV

fileType file's format jpg,png...

path storage path

file_name by default it will generate file name as uuid string for you if you want to generate your own file's name then use this

origin_filename use original file's name

return_only_name by default will return with path if you want to return only filename then set this to "true"

upload() and uploadMany()

file file as buffer ex: req.file.image

bucket (optional) default is set in ENV

fileType file's format jpg,png...

path storage path

resize (Optional) ex: we want to resize image to 256px then set [256] or multiple size [500,256]

Example usage

// Ex1: Sample usage
const filename = await AwsFunc.upload({
	file: req.files.image,
	fileType: "jpg",
	path: "some_path/"
})

// Ex2: With resize
const filename = await AwsFunc.upload({
	file: req.files.image,
	fileType: "jpg",
	resize: [256, 800],
	path: "some_path/"
})

// Ex3: Multiple File
const filename = await AwsFunc.uploadMany({
	file: req.files.image,
	fileType: "jpg",
	path: "some_path/"
})

// Ex4: Multiple File With resize
const filename = await AwsFunc.uploadMany({
	file: req.files.image,
	fileType: "jpg",
	resize: [256, 800],
	path: "some_path/"
})

Validator Usage with express

WORK WELL with API-RESPONSE ASYN-HANDLE and mongoose

const { Validator } = require("exp-mgo-toolings")
const mongoose = require("mongoose")

// Perform as req from express
const example1 = {
    body: {
        id: "",
        uuidVs: "e09e2870-4c66-11ed-979f-00163e9b33ca",
        uuidV2: "9f0f0cd0-4c66-11ed-bdc3-0242ac120002",
        uuidV3: "078c5665-3df4-3b1c-8fd0-1c530f9a062b",
        uuidV4: null,
        uuidV5: null,
        birthDate: "2022-01-22",
        name: "sdsd",
        age: 10,
        email: null,
        gender: "male",
        isActive: true,
        ip: "128.0.0.1",
        array: ["1", "2", "3", "4", "5"],
        contact: {
            id: "1",
            name: "souksavanhm",
            age: 10,
            email: "[email protected]",
            gender: "male",
            isActive: true,
            ip: "128.0.0.1",
            object: {
                id: "1",
                name: "asdasd",
                age: 10,
                email: null,
                gender: "male"
            },
        },
        permission: [
            {
                id: "1",
                age: 10,
                name: "22",
                email: "[email protected]",
                object: {
                    id: "1",
                    age: "10",
                    name: "234",
                    email: "souksavanhgmail.com",
                    object: {
                        id: "1",
                        age: 10,
                        name: "nsame 1",
                        email: "[email protected]"
                    }
                }
            },
            {
                id: "2",
                name: "name 2",
                age: 10,
                email: "[email protected]",
                object: {
                    id: "1",
                    age: 10,
                    name: "name 1",
                    email: "[email protected]",
                    object: {
                        id: "1",
                        age: 10,
                        name: "name 1",
                        email: "[email protected]"
                    }
                }
            },
            {
                id: "1",
                name: "name 2",
                age: 10,
                email: "[email protected]",
                object: {
                    id: "1",
                    age: 10,
                    name: "name 1",
                    email: "[email protected]",
                    object: {
                        id: "1",
                        age: 10,
                        name: "name 1",
                        email: "[email protected]"
                    }
                }
            },
        ]
    }
}

Let's start!!!

// Ex1: with mongoose validate exist data
const rule = new Validator(example1)

// Ex2: simple use
const rule = new Validator(example1, mongoose)

SIMPLE USE

rule.body("uuidV1", "validate_uuidV1").required().uuid(1) // UUID V1
rule.body("uuidV3", "validate_uuidV3").required().uuid(3) // UUID V3
rule.body("uuidV4", "validate_uuidV4").optional(true).uuid(4) // UUID V4
rule.body("uuidV5", "validate_uuidV5").optional(true).uuid(5) // UUID V5
rule.body("birthDate", "validate_birthDate").optional(true).date()
rule.body("name", "validate_name").required().string()
rule.body("age", "validate_age").optional().int()
rule.body("email", "validate_email").optional(true).email()
rule.body("gender", "validate_gender").required().enum("male", "female")
rule.body("isActive", "validate_isActive").optional().bool()
rule.body("ip", "validate_ip").required().IP()
rule.body("id", "validate_id").optional(true).string()

Array without object item

rule.body("array", "validate_array").required().array({ maxLength: 5 })

// Find inside mongoose model by given "model's name" and "target key"
// ex: find in user's model where name === xxxx
rule.body("array.*", "validate_array").required().string().mustExistIn("user", { key: "name" })

Object items

rule.body("contact.id", "validate_contact_id").required().string()
rule.body("contact.age", "validate_age").optional().int()
rule.body("contact.email", "validate_email").optional(true).email()
rule.body("contact.gender", "validate_gender").required().enum("male", "female")

Array with item inside

Not support nested array, ONYLY WORK WITH nested OBJECT

rule.body("permission", "validate_contact_id").required().array()
rule.body("permission.*.id", "validate_permission_id").required().string()
rule.body("permission.*.name", "validate_permission_name").required().string()
rule.body("permission.*.email", "validate_permission_email").required().email()
rule.body("permission.*.object.name", "validate_permission_name").required().string()
rule.body("permission.*.object.object.name", "validate_permission_name").required().string().mustExistIn("user", { key: "name" })

Perform validate

soreContext Will store mongoose data if found in database

const isValid = await rule.validate({ 
    storeContext: true , // Store result from mongoose in req
    useError: true // Throw error if detected
})

isValid.throwError() // if useError is not set. Can use this one to trigger error
isValid.isEmpty() // Check if empty error
isValid.errors() // Get all detected error

Eample with array body

const example2 = {
    body: [
        {
            id: "1",
            name: "name 2",
            age: 10,
            email: "[email protected]",
            object: {
                id: "1",
                age: 10,
                name: "Dsemo",
                email: "[email protected]",
            }
        },
        {
            id: "2",
            name: "13",
            age: 10,
            email: "[email protected]",
            object: {
                id: "1",
                age: 10,
                name: "Demso",
                email: "[email protected]",
            }
        }
    ]
}



const _ = new Validator(example2)

_.body("*").required().array()
_.body("*.id").required().string()
_.body("*.name").required().string()
_.body("*.object").required().object(true)
_.body("*.object.id").required().string()
_.body("*.object.age").required().string()
_.body("*.object.name").optional().string().mustExistIn("user")
_.body("*.object.email").required().email()

_.validate()