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 🙏

© 2026 – Pkg Stats / Ryan Hefner

oresm

v1.0.1

Published

ObjectResourceMapper to deal with REST APIs

Readme

oresm

logo

ObjectResourceMapper - A client ORM for REST APIs

Installation

npm install oresm

Introduction

import User from "./Resources/User"

(async () => {
    const user = await User.find(1)

    user.username = "newName"
    await user.update()

    await user.delete()
})()

The above code executes the following requests.

GET /api/users/1

PUT /api/users/1

DELETE /api/users/1

Getting Started

Let's start of by creating a user model. The following model would create endpoints like http://127.0.0.1/api/user

import { Model } from "oresm"

class User extends Model {
    get host() {
        return 'http://127.0.0.1' // defaults to empty string
    }

    get prefix() {
        return 'api' // defaults to empty string
    }

    get resource() {
        // from the example url this is the actual resource part `user`
        // defaults to lowercase plualized version of classname, in this case `users`
        return 'user'
    }

    get key() {
        // defaults to the key to be used as the identifier. E.g. when you call user.delete() it needs to find the user id to create the endpoint.
        return 'id'
    }
}

export default User

GET

Getting a collection of documents

const users = await User.get()

GET /api/users

const users = await User.get({ sort: 'name' })

GET /api/users?sort=name

Getting a single document

const user = await User.find(1)

GET /api/users/1

const users = await User.find(1, { xxx: 'yyy' })

GET /api/users/1?xxx=yyy

POST

Use save() to store a new document.

const user = new User({ // set values in the constructor
    name: 'Son Goku',
    type: 2,
})

user.type = 3 // set them manually

await user.save({
    type: 4, // set them when saving
})

POST /api/users


Once you have retrieved a document, you can perform delete and update operations on it.

DELETE

const user = await User.find(1)
await user.delete()

GET /api/users/1

DELETE /api/users/1

PUT, PATCH

There is more than one way to update a resource, let's look at each individually. Let's imagine the User.find(1) returns an object that looks like this:

{
    id: 1,
    username: 'xxx',
    type: 1
}

Using save()

Like with POSTing resources, you can use the save() method to update an existing resource.

const user = await User.find(1)
user.type = 3 // override fields like this
await user.save({
    type: 2 // override or add new fields like this
})

GET /api/users/1

PUT /api/users/1

The PUT request sends the following payload:

{
    id: 1,
    username: 'xxx',
    type: 2
}

Using PATCH

We can use patch to update individual fields.

const user = await User.find(1)
await user.patch({
    type: 2
})

GET /api/users/1

PATCH /api/users/1

It sends the following payload

{
    type: 2
}

Computed / virtual fields

Let's go back to our user example

const user = await User.find(1)
if (user.type === 2) { // if user is admin
    // do something
}

While this works, there is a much cleaner way of doing this. We can use the User object we created to have computed fields.

import ObjectResourceMapper from "./ObjectResourceMapper"

class User extends ObjectResourceMapper {
    get isAdmin() {
        return this.type === 2
    }
}

export default User

And back to our script from before

const user = await User.find(1)
if (user.isAdmin) {
    // do something
}

Of course you can move other logic to the model as well.

Get raw data

Getting the raw data is easy.

const user = await User.find(1)
const userData = user.getEntity()

Configure fetch

For available configurations please check out https://github.com/MZanggl/fetch-me-json

import { configureFetch } from 'oresm'

const configurations = {}
configureFetch(configurations)

Limitations

You can not dynamically add new fields.

const user = new User({
    name: 'Son Goku',
})

user.type = 3 // add new field

await user.save() // will not insert `type`

This could be solved using proxies in the future. As a workaround you should do

const user = new User({
    name: 'Son Goku',
})

await user.save({
    type: 3,
})