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

@omneo/cf

v1.2.0

Published

Omneo CF helps you develop cloud function plugins for Omneo

Downloads

10

Readme

Omneo Cloud Function Helpers

This is a small library to help boilerplate cloud functions for Omneo. It includes a bunch of handy helpers to help you get started and internal Express handlers for your routes and controllers.

Getting started

Install with yarn or npm

yarn add @omneo/cf
# OR
npm install @omneo/cf

Require @omneo/cf then call the returned function with an object containing top level route path and controller. To make things simple, OmneoCF will register your controllers with the Express.js use() call.

const app = require('@omneo/cf');

const profileController = (req, res) => {
    res.status(200).json({
        message: `You made a ${req.method} request to the profile controller`
    })   
}

const transactionController = () => {
    const router = express.Router();
    router.get('/', (req, res)=>{
        res.status(200).json({
            message: "Transactions"
        })  
    })

    router.post('/items', (req, res)=>{
        res.status(200).json({
            message: "Transaction items"
        })    
    })
}

return app({
    profiles: profileController,
    transactions: transactionController()
})

Automatic environment handling

This library looks at NODE_ENV and will either export just the routes or will start a local express server. The local server will run on NODE_PORT || 3000

This local server will also apply the same bodyParser as GCP, to give you access to both res.body and res.rawBody - Useful when validating webhooks etc. It also uses dotenv() to include your .env file in process.env.

Batteries-included middleware

The basics

Both local and production outputs include cors() and compression() Express libraries and a basic request logger. Logging can be disabled by setting the following environment variable: LOGGING=disabled

Error handling

All routes are wrapped in an error handler to ensure the service returns an error http response if possible. Note: You should still wrap your controllers in a try/catch to ensure the best handling of this.

Tenant validation

All routes registered with the main function will sit under a /:tenant route. This is used by the middleware/validateOmneoTenant function to check for tenant configuration in process.env. By default, only [tenant]_omneo_token and [tenant]_omneo_secret should be stored in env - All other configurations should be stored elsewhere, such as Omneo Tenant Fields or a DB.

This middleware also adds the omneo_token and omneo_secret to globals.tenant, along with omneo_url, matching the following format: [tenant].getomneo.com

Omneo Plugin validation

All routes will be valiadated and make sure plugin has been configured in omneo. It's handled by middleware/validateOmneoPluginConfig. Plugin handle needs to match the PluginNamespace and "Enabled" field is required and needs to be true for successful validation. This requirement is valid for version >= 1.0.0.

Webhook validation

This library includes middleware for Omneo webhook validation at middleware/validateOmneoWebhook This middleware accepts an array of allowed events and will automatically check against the headers Omneo uses for webhook HMAC signatures and event.

In addition, an abstracted middleware/validateWebhook is availble for services that use similar methods for webhook validation:

validateWebhook(
    events, // Array of allowed event strings eg. ['profile.created']
    headerSignature, // Header key for the HMAC signature eg. 'x-omneo-hmac-sha256'
    headerEvent, // Header key for the webhook event eg. 'x-omneo-event'
    hmacSecret, // Secret key used to decode. For Omneo we use the OMNEO_SECRET
    alg // HMAC algorithm to use when decoding
)

A handful of handy utilities

To help make your development life easier, this library includes a small set of useful utility functions.

Fetch

Our own wrapper for the popular node-fetch library. This includes a number of helpers to construct your requsts, as well as response parsing, so you don't have to separately run response.json().

Note that config.global is only available after the validateOmneoTenant middleware has run, not at initialization. This means that any function relying on these will need to be initialized after that.

// omneo.js
const {Fetch} = require('@omneo/cf/utilities');

export.default = () => new Fetch(`https://api.${global.config.omneo_url}/api/v3`, {
    headers: {
        Authorization: `Bearer ${global.config.omneo_token}`
    }
})
// route.js
const omneoClient = require('./omneo');

const route = async (req, res) => {
    const omneo = omneoClient();
    // Searching profiles. get(url, params)  
    const search = await omneo.get('/profiles', {
        "filter[email]":"[email protected]"
    })

    // Creating a profile: post(url, body)
    const create = await omneo.post('/profiles', {
        first_name: "Gavin",
        last_name: "Belson",
        email: "[email protected]"
    })

    res.send()
}

Pluck

Dives through a js/json object, by key, to find the value. Returns the value if found, or null where not available. Uses memoizee to memoize the value for subsequent attempts.

const {pluck} = require('@omneo/cf/utilities');
const data = {
    "some":{
        "nested":{
            "value":"Success value"
        }
    }
}

pluck(data, 'some.nested.value') // Returns "Success value"
pluck(data, 'some.other.value') // Returns null"

Pluck By

Iterates through an array of objects, to find matching key:value pair and return that object. Can take a 3rd argument to find the array in an object first, using pluck;

const {pluckBy} = require('@omneo/cf/utilities');
const {
    data: {
        profile: {
            "first_name":"Erlich",
            "last_name":"Bachman",
            "email":"[email protected]",
            "attributes":{...},
            "identities":[
                {
                    "handle":"shopify",
                    "identifier":"SHOP12345"
                },
                {
                    "handle":"zendesk",
                    "identifier":"ZEN67890"
                }
            ]
        }
    }
}

pluckBy(data.profile.identities, 'identifier', 'ZEN67890') // Returns {"handle":"zendesk","identifier":"ZEN67890"}
pluckBy(data.profile.identities, 'identifier', 'ZEN12345') // Returns null
pluckBy(profile, 'handle', 'shopify', 'profile.identities') // Returns {"handle":"shopify","identifier":"SHOP12345"}

ErrorHandler

Error constructor used to append additional details to the handleErrors middleware. Takes status, message and a json payload

const route = require('express').Router();
const {ErrorHandler} = require('@omneo/cf/utilities');

route.post('/', (req, res, next)=>{
    const profile = req.body
    try{
        if(!profile.email){
            throw new ErrorHandler(400, "Profile is incomplete", {
                errors:{
                    email: "This field is required"
                }
            })
        }
        return profile
    }catch(e){
        next(e);
    }
})

module.exports = route