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

@tswei/odata-resource

v2.3.1

Published

Redfish

Downloads

9

Readme

Redfish odata-resource

Node.Js module to allow for creation of REST resources served up via ExpressJS and persisting data via Mongoose that:

  • Supports OData query arguments like; $filter, $orderby, $select, $expand, $top and $skip.
  • Supports simple, resource definitions requiring minimal code.
  • Supports static and instance based relationships between entities.
  • Allows for Mongoose models to be defined and used independent of the resource implementation.
  • Allows for a high degree of customization/over-riding of default behavior.

Limitations

The $filter implementation is not entirely complete and is only odata'ish in nature. Support for all operators is not complete. Two non-odata operators in and notin have been implemented. What is implemented:

Logical Operators

  • eq - Equal. E.g. /redfish/v1/AccountService/Accounts?$filter=email eq '[email protected]'
  • ne - Not equal. E.g. /redfish/v1/AccountService/Accounts?$filter=email ne '[email protected]'
  • lt - Less than. E.g. /redfish/v1/AccountService/Accounts?$filter=pages lt 200
  • le - Less than or equal. E.g. /redfish/v1/AccountService/Accounts?$filter=pages le 200
  • gt - Greater than. E.g. /redfish/v1/AccountService/Accounts?$filter=pages gt 200
  • le - Greater than or equal. E.g. /redfish/v1/AccountService/Accounts?$filter=pages ge 200
  • and - Logical and. E.g. /redfish/v1/AccountService/Accounts?$filter=pages ge 200 and pages le 400
  • or - Logical and. E.g. /redfish/v1/AccountService/Accounts?$filter=email eq '[email protected]' or email eq '[email protected]'

Functions

  • startswith E.g. /redfish/v1/AccountService/Accounts?$filter=startswith(email,'root')
  • endswith E.g. /redfish/v1/AccountService/Accounts?$filter=endswith(email,'mail')
  • contains E.g. /redfish/v1/AccountService/Accounts?$filter=contains(email,'test')

Non-Odata

  • in E.g. /redfish/v1/AccountService/Accounts?$filter=in(email,'Action','Drama')
  • notin E.g. /redfish/v1/AccountService/Accounts?$filter=notin(email,'Action','Drama')

Parenthesis can be used in $filter to group logical conditions. You just cannot mix and and or within a single sub-expression (set of parenthesis).

Examples: /redfish/v1/AccountService/Accounts?$filter=(email eq '[email protected]' or email eq '[email protected]') and pages lt 500 /redfish/v1/AccountService/Accounts?$filter=(email eq '[email protected]' or email eq '[email protected]') and (contains(email,'mail') or contains(email,'test'))

Case Sensitivity: Due to the performance implications on large collections all string related filtering is unadulterated meaning it's case sensitive. For the time being if you need case insensitive filtering you may need to consider a solution like storing a lower case version of the property you wish to perform such filtering on.

Page structure

This package is split into four different structures for redfish. Its design comes from binary tree.

root

The Root Node is the starting point in a tree-like structure or graph, much like the homepage of Redfish at /redfish/v1/. It displays links to various pages.

redfish_v1.js

var setting = {
    otype: '#redfish_test_server',
    oname: 'Root Service',
    rel: '/redfish/v1',
    node_type: 'root'
};

var resource = new Resource(setting);
root_page = resource.initRouter(router);

root_page.get('/', (req, res) => {
    console.log(req.query)
    
    const main_nodes = trunkModel.getService();
    const links = linksModel.getLink();
    var response = {
        "@odata.id": resource.getRel(),
        "@odata.type": resource.getOType(),
        "Id": "RootService",
        "RedfishVersion": "1.9.0",
        "Name": "Root Service"
    };

    main_nodes.forEach(function(value){
        response[value] = {"@odata.id": "/redfish/v1/" + value}
    });
    response['Links'] = {}
    Object.keys(links).forEach(function(key) {
        var value = links[key];
        response['Links'][key] = {"@odata.id": "/redfish/v1/" + value}
    });
    return res.json(response);
});

Output :

{
    "@odata.id": "/redfish/v1",
    "@odata.type": "#redfish_test_server",
    "Id": "RootService",
    "RedfishVersion": "1.9.0",
    "Name": "Root Service",
    "AccountService": {
        "@odata.id": "/redfish/v1/AccountService"
    },
    "Links": {
        "Sessions": {
            "@odata.id": "/redfish/v1/SessionService/Sessions"
        }
    }
}

internal

The Internal Node is a node in a tree structure that lies between the root node and the leaf nodes. It is akin to the /redfish/v1/AccountService in Redfish, which provides static data and lists links to other nodes.

account_service.js

var setting = {
    otype: '#AccountService.v1_10_0.AccountService',
    oname: 'Account Service',
    rel: '/redfish/v1/AccountService',
    node_type: 'internal',
    content:{
        "Id":"AccountService",
        "Description":"Account Service",
        "Status": {
            "State":"Enabled",
            "Health":"OK"
        } ,
        "ServiceEnabled":true,
        "MaxPasswordLength": 20,
        "MinPasswordLength": 8,
        "AuthFailureLoggingThreshold": 0,
        "Accounts":{
            "@odata.id": "/redfish/v1/AccountService/Accounts"
        },
        "ServiceEnabled": true
    }
};

var resource = new Resource(setting);
accountService = resource.initRouter(router);

Output :

{
    "@odata.id": "/redfish/v1/AccountService",
    "@odata.type": "#AccountService.v1_10_0.AccountService",
    "Id": "AccountService",
    "Description": "Account Service",
    "Status": {
        "State": "Enabled",
        "Health": "OK"
    },
    "ServiceEnabled": true,
    "MaxPasswordLength": 20,
    "MinPasswordLength": 8,
    "AuthFailureLoggingThreshold": 0,
    "Accounts": {
        "@odata.id": "/redfish/v1/AccountService/Accounts"
    },
    "Name": "Account Service"
}

internal_db

The Internal DB Node differs from the Internal Node in that it presents the data of a database in a list format. It is used for pages like /redfish/v1/AccountService/Accounts, where it lists links to all the accounts.

account.js

var setting = {
    otype: '#ManagerAccountCollection.ManagerAccountCollection',
    oname: 'Accounts Collection',
    rel: '/redfish/v1/AccountService/Accounts',
    node_type: 'internal_db',
    model: userModel,
    okey: 'email',
    content:{
        "Description":"NMC User Accounts"
    }
};

var resource = new Resource(setting);
account = resource.initRouter(router);

Output :

{
    "@odata.id": "/redfish/v1/AccountService/Accounts",
    "@odata.type": "#ManagerAccountCollection.ManagerAccountCollection",
    "Members": [
        {
            "@odata.id": "/redfish/v1/AccountService/Accounts/[email protected]"
        },
        {
            "@odata.id": "/redfish/v1/AccountService/Accounts/[email protected]"
        },
        {
            "@odata.id": "/redfish/v1/AccountService/Accounts/[email protected]"
        },
        {
            "@odata.id": "/redfish/v1/AccountService/Accounts/[email protected]"
        }
    ],
    "[email protected]": 4,
    "Name": "Accounts Collection",
    "Description": "NMC User Accounts"
}

leaf

The Leaf Node is the bottom-most node in a tree structure, and it does not have any child nodes. In this package, it is used for pages like /redfish/v1/AccountService/Accounts/{email}, where data retrieved from the database is displayed based on specific fields.

account_leaf.js

var setting = {
    otype: '#ManagerAccount.v1_10_0.ManagerAccount',
    oname: 'User Account',
    rel: '/redfish/v1/AccountService/Accounts',
    node_type: 'leaf',
    model: userModel,
    okey: 'email',
    content:{
        "Description": "User Account"
    }
};

var resource = new Resource(setting);
accountLeaf = resource.initRouter(router);

Output :

{
    "_id": "60c1d32353993811c08488bf",
    "email": "[email protected]",
    "password": "$2b$10$xGX0JJNNQQaq5hmnedqT.OjRnzsmJFoKF.3QEJfvlVCg5owZr7U1a",
    "Description": "User Account",
    "@odata.type": "#ManagerAccount.v1_10_0.ManagerAccount",
    "Name": "User Account",
    "@odata.id": "/redfish/v1/AccountService/Accounts/[email protected]",
    "Enabled": true,
    "Locked": false
}

[email protected]

An implicit relationship [email protected] (similar to the odata $count) has been added that will return the integer count of a resource when listed or traversed from another entity relationship.

Important: [email protected] will be automatically applied to internal_db.

Testing

cd example

npm install

node app.js

go to browser and enter the URL : 127.0.0.1:3000/redfish/v1