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

@xpsolutions/cdr-sdk

v1.0.0

Published

NodeJS middleware to handle error generation in line with Australian Consumer Data Standards technical specifications

Downloads

85

Readme

CDR SDK

This repo was forked from the code published by the Engineering team of Data Standards Body Australia. The original repo can be found on Github here.

Using the CDR SDK

This SDK is intended for developers implementing CDR-compliant APIs in NodeJS/ExpressJS applications. It reduces the complexity and repetition involved in coding compliant APIs by providing ready-to-use middleware that handles common requirements such as error checking, header validation, and endpoint verification.

This code is offered as an npm package available in the NPM registry. You can easily install this package in your project using npm. For more information, refer to the Quick Start section below.

Explore the key middleware functions provided by the JS Holder SDK in the Middleware Functions section below.

Implementation Guidelines and Usage

To integrate the SDK into your NodeJS/ExpressJS application, ensure npm is installed on your system and run the following command:

npm install @xpsolutions/cdr-sdk

or

yarn add @xpsolutions/cdr-sdk

The middleware functions cdrAuthorisationValidator, cdrResourceValidator require passing an implementation of ISessionService by the consuming application. The consuming application will provide information received from the the Identity and Access Management System (IdAM) via the getSessionData function of the ISessionService

All middleware functions optionally accept a configuration object (CdrConfig) that specifies the details of each endpoint the application implements, defined by the request type (GET/POST/DELETE) and path as outlined in the CDS.

If the config parameter is not provided, the middleware defaults to using predefined endpoints (DefaultEnergyEndpoints, DefaultBankingEndpoints, and DefaultCommonEndpoints) specified in this repository. These are based on the files found in the src/data directory

Example code for a consuming application:

const implementedEndpoints = [
    {
        "requestType":
        "GET",
        "requestPath": "/banking/payments/scheduled",
        "minSupportedVersion": 1,
        "maxSupportedVersion": 1
    },
    {
        "requestType": "GET",
        "requestPath": "/banking/accounts/{accountId}/balance",
        "minSupportedVersion": 1,
        "maxSupportedVersion": 1
    }
]

const sessionSession: ISessionService = {
    /// your implementation, could be in-memory, Redis or something else
}
const config: CdrConfig = {
    endpoints: implementedEndpoints
}

/// .....other middleware

app.use(cdrAuthorisationValidator(sessionService, config));
app.use(cdrHeaderValidator(config));
app.use(cdrResourceValidator(sessionService, config));
app.use(cdrEndpointValidator(config));

/// .....other middleware

Middleware Functions

Below is a detailed overview of the key middleware functions provided by the JS Holder SDK:

cdrHeaderValidator

Validates request headers and constructs CDR-compliant error responses as necessary.

| Scenario | Description | | --- | --- | | No x-v header is provided in the request | Http status code 400- An ErrorList is returned with Header/Missing. | | Invalid x-v header is provided with the request, eg alpha character | Http status code 400- An ErrorList is returned with Header/Invalid. | | Invalid x-min-v header is provided with the request | Http status code 400- An ErrorList is returned with Header/Invalid. | | A requested version is not supported | Http status code 406- An ErrorList is returned with Header/UnsupportedVersion. | | No x-fapi-interaction-id in the request | An x-fapi-interaction-id header is set in the response header | | Request has x-fapi-interaction-id header | The x-fapi-interaction-id from the request is returned with the response header | | Invalid x-fapi-interaction-id header is provided with the request | Http status code 400- An ErrorList is returned with Header/Invalid. |

cdrAuthorisationValidator

Handles authorisation checks and constructs CDR-compliant error responses as necessary. Performs scope validation against the API endpoint requirements using the scopes available in the access token.

| Scenario | Description | | --- | --- | | Invalid scope in access token | Http status code 403- An ErrorList is returned with Authorisation/InvalidScope | | No authorisation header present in Request | Http status code 401 | | An expired or invalid access token | Http status code 401 |

cdrEndpointValidator

Checks if the request URL corresponds to a CDR endpoint and constructs CDR-compliant error responses as necessary.

| Scenario | Description | | --- | --- | | Endpoint not implemented | Http status code 404- An ErrorList is returned with Resource/NotImplemented. | | Endpoint not is not a CDR endpoint | Http status code 404- An ErrorList is returned with Resource/NotFound. |

cdrResourceValidator

Ensures that the resource-specific identifiers like account IDs have proper consent for access within API calls.

| Scenario | Description | | --- | --- | | Access to the resource url has not been consented to | Http status code 404 | | An invalid POST request body was received | Http status code 400 |

Utility Functions

Additionally this SDK exposes wome useful functions which are CDR specific

buildErrorMessage

This function will return a ReponseErrorListV2. It will use the standard error codes as published by the Data Standards Body (eg urn:au-cds:error:cds-banking: Authorisation/InvalidBankingAccount) depending on the errorMessageId being passed in

| Parameter | Description | | --- | --- | | errorMessageId | an identifier as per DsbStandardError defintions | | errorDetail | which will be the details property on the returned error object | | errorList (optional) | an existing error list. The error object wil be appendd to that list | | metaData (optional) | options metadata object |

Example:

let msg = buildErrorMessage(DsbStandardError.INVALID_BANK_ACCOUNT, "123456");

// returns this as msg
    "errors": [
        {
            "code": "urn:au-cds:error:cds-banking:Authorisation/InvalidBankingAccount",
            "title": "Invalid Banking Account",
            "detail": "123456"
        }
    ]

getLinksPaginated

| Parameter | Description | | --- | --- | | req | The request object | | totalRecords | The total number of records in the dataset |

Example: if the req object has a url https://api.xpsol.com.au/cds-au/v1/energy/plans?category=ALL&page=4&page-size=2

getLinksPaginated(req, 1000)

will return

{
    self: "https://api.xpsol.com.au/cds-au/v1/energy/plans?category=ALL&page=4&page-size=2",
    next: "https://api.xpsol.com.au/cds-au/v1/energy/plans?category=ALL&page=5&page-size=2",
    prev: "https://api.xpsol.com.au/cds-au/v1/energy/plans?category=ALL&page=3&page-size=2",
    first: "https://api.xpsol.com.au/cds-au/v1/energy/plans?category=ALL&page=1&page-size=2",
    last: "https://api.xpsol.com.au/cds-au/v1/energy/plans?category=ALL&page=500&page-size=2"
}

getMetaPaginated

Will return a MetaPaginated object | Parameter | Description | | --- | --- | | totalRecords | The total number of records in the dataset | | query (optional) | The query property from the Request object |

Example:

getMetaPaginated(1000)

This use the default page-size=25 since no query parameters are passes in. Therefore, this will return

{
    totalRecords: 1000,
    totalPages: 40
}

paginateData

This will return a subset of data depending on the page-size and page properties from the Request query object

| Parameter | Description | | --- | --- | | data | an array of data objects. | | query | typycally this will be the query property from the Request object |

Example:

let data: any = [
            {
                "amount": "4439.65",
                "description": "payment transaction at Durgan and Sons using card ending with ***(...6407) for XAU 365.41 in account ***06028839",
            },
            {

                "accountId": "d339f6db-cd8d-413f-95e4-ec9e8e9d806f",
                "amount": "318.99",
                "description": "payment transaction at Gleason - Fadel using card ending with ***(...6904) for SYP 219.10 in 
            },
            {
                "extendedData": {
                    "service": "X2P1.01",
                    "payer": "Angelica Beatty"
                },
            },
            {
                "amount": "4013.89",
                "description": "payment transaction at Watson, Braun and Bartell using card ending with ***(...6802) for GEL 281.13 in account ***74872985",
                "isDetailAvailable": true,
            },
            {
                "executionDateTime": "2024-01-20T12:49:36.782Z",
                "apcaNumber": "572618"
            },
]

and a query object

let query: any = {
   "page-size": "2",
   "page" : "2"
}

then paginateData(data, query) returns

    [
            {
                "extendedData": {
                    "service": "X2P1.01",
                    "payer": "Angelica Beatty"
                },
            },
            {
                "amount": "4013.89",
                "description": "payment transaction at Watson, Braun and Bartell using card ending with ***(...6802) for GEL 281.13 in account ***74872985",
                "isDetailAvailable": true,
            }
    ]

.

Licensing Information

This repository contains code from a project originally created by Consumer Data Standards Australia, which is licensed under the MIT License. All code in this repository remains under its original license.