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

@enfuce/nextgen-sdk

v0.0.11

Published

Enfuce nextgen client SDK (TypeScript). One namespaced export per API.

Readme

@enfuce/nextgen-sdk

Enfuce nextgen client SDK for TypeScript. One namespaced export per API, so identically-named schemas across APIs never collide. Ships both CommonJS and ESM builds.

Installation

npm install @enfuce/nextgen-sdk

Usage

Each API is exposed under its own namespace, and every module ships a fluent <Module>Client (e.g. card.CardClient, exchangeRate.ExchangeRateClient) that wires an OAuth-enabled axios instance to the module's configuration and exposes each API. Every request is authenticated with an OAuth2 client_credentials bearer token:

import { oauth, card, config } from '@enfuce/nextgen-sdk';

// Set the tenant + environment once; the config helper derives every base URL (and the token URL) from it.
const te = { tenant: '<tenant>', environment: '<environment>' };

// One token manager (cached client-credentials grant) — reuse it across every module.
const clientCredentialsManager = oauth.clientCredentials({
  tokenUrl: config.tokenUrl(te),
  clientId: '<client-id>',
  clientSecret: '<client-secret>',
  scopes: ['issuer/cardholder.read'],
});

const client = card.CardClient.builder()
  .baseUrl(config.issuerBaseUrl(te))
  .oauth(clientCredentialsManager)                           // token on every request + reactive 401 retry
  .configure((http) => { http.defaults.timeout = 10_000; }) // optional: timeout, proxy, headers …
  .build();

const { data } = await client.getCardApi().getCard(cardId, '[email protected]');

environment is the target platform — e.g. ext-uat1-sandbox (sandbox) or eu.live.prod (production). One clientCredentialsManager authenticates every module, so build it once and reuse it across all your clients. See Client customization for transport tuning (timeouts, proxy, interceptors).

Keeping the token URL separate from the client identity? Pass a ClientCredentials — e.g. with the config helper deriving the URL:

const clientCredentialsManager = oauth.clientCredentials(config.tokenUrl(te), {
  clientId: '<client-id>',
  clientSecret: '<client-secret>',
  scopes: ['issuer/cardholder.read'],
});

Inspecting scopes

oauth.availableScopes(...) discovers the scopes the client is entitled to — it requests a token with no scope narrowing and resolves to the granted scopes (sorted, de-duplicated). oauth.scopesOf(...) decodes the granted scopes from any JWT you already hold. Both yield an empty array for an opaque (non-JWT) token and never throw. Server-side only.

import { oauth, config } from '@enfuce/nextgen-sdk';

// The client's full entitlement (a live, uncached token request):
const available = await oauth.availableScopes(config.tokenUrl(te), {
  clientId: '<client-id>',
  clientSecret: '<client-secret>',
});

// Or decode the scopes granted on a token you already hold:
const granted = oauth.scopesOf(await clientCredentialsManager.getToken());

Client customization

.configure((http) => …) on any <Module>Client builder hands you the underlying axios instance for full transport control — timeout, proxy, headers, request/response interceptors, etc. It composes with .oauth(...); the OAuth token is attached independently via its own interceptor.

const client = card.CardClient.builder()
  .baseUrl(config.issuerBaseUrl(te))
  .oauth(clientCredentialsManager)
  .configure((http) => {
    http.defaults.headers.common['X-My-Header'] = 'value';
    http.interceptors.request.use(myInterceptor);
  })
  .build();

Prefer the lower level? Build your own axios and pass it through: oauth.createOAuthAxios(clientCredentialsManager, axios.create({ timeout: 10_000 })), then new card.GetCardApi(new card.Configuration({ basePath }), undefined, http).

Configuring timeouts

axios timeouts are a single value in milliseconds (applied per request). Set it on the axios instance via .configure(...):

const client = card.CardClient.builder()
  .baseUrl(config.issuerBaseUrl(te))
  .oauth(clientCredentialsManager)
  .configure((http) => { http.defaults.timeout = 10_000; }) // 10s
  .build();

API modules

Each module builds the same way — set its base URL with the matching accessor (config.issuerBaseUrl, config.processorBaseUrl, or config.exchangeRateBaseUrl) and reuse the shared clientCredentialsManager. Every call resolves to an axios response, so read .data. Snippets assume te and clientCredentialsManager are in scope.

cardholderissuerBaseUrl

import { cardholder, config } from '@enfuce/nextgen-sdk';

const client = cardholder.CardholderClient.builder().baseUrl(config.issuerBaseUrl(te)).oauth(clientCredentialsManager).build();

const { data: holder } = await client.getCardholderApi().getCardholderById(cardholderId, '[email protected]');
const { data: cards } = await client.getCardsByCardholderIdApi()
  .getCardsByCardholderId(cardholderId, undefined, undefined, '[email protected]');

cardissuerBaseUrl

import { card, config } from '@enfuce/nextgen-sdk';

const client = card.CardClient.builder().baseUrl(config.issuerBaseUrl(te)).oauth(clientCredentialsManager).build();

const { data } = await client.getCardApi().getCard(cardId, '[email protected]');
await client.updateCardApi().activateCard(cardId, undefined, '[email protected]'); // (id, idempotencyKey, auditUser)

walletissuerBaseUrl

import { wallet, config } from '@enfuce/nextgen-sdk';

const client = wallet.WalletClient.builder().baseUrl(config.issuerBaseUrl(te)).oauth(clientCredentialsManager).build();

const { data: tokens } = await client.getTokensApi().getTokens(cardId, false, undefined, '[email protected]');

pinissuerBaseUrl

import { pin, config } from '@enfuce/nextgen-sdk';

const client = pin.PinClient.builder().baseUrl(config.issuerBaseUrl(te)).oauth(clientCredentialsManager).build();

const { data } = await client.pINOperationsUsingPKIApi().viewPin(viewPinRequestBody, '[email protected]');

exchangeRateexchangeRateBaseUrl

import { exchangeRate, config } from '@enfuce/nextgen-sdk';

const client = exchangeRate.ExchangeRateClient.builder().baseUrl(config.exchangeRateBaseUrl(te)).oauth(clientCredentialsManager).build();

const { data: currencies } = await client.getECBSupportedCurrenciesApi().getEcbSupportedCurrenciesV1();
const { data: rate } = await client.getECBExchangeRateApi().getEcbRateV1('EUR', 'USD');

threedsprocessorBaseUrl

import { threeds, config } from '@enfuce/nextgen-sdk';

const client = threeds.ThreedsClient.builder().baseUrl(config.processorBaseUrl(te)).oauth(clientCredentialsManager).build();

await client.threeDSApi().handleAuthenticationChallengeResult(challengeResultBody);

cardsprocessorBaseUrl

import { cards, config } from '@enfuce/nextgen-sdk';

const client = cards.CardsClient.builder().baseUrl(config.processorBaseUrl(te)).oauth(clientCredentialsManager).build();

await client.cardsApi().resetPinCounter(cardId, sequenceNumber);

Webhooks

These are the calls Enfuce makes to you: you host the endpoint and Enfuce POSTs to it. Such modules export only the payload types — there is no client to call, since your app receives these rather than requesting them. Use the types to type the inbound request body:

import type { issuerEvents } from '@enfuce/nextgen-sdk';

const event = JSON.parse(payload) as issuerEvents.CardEvent;

authorisationControl is synchronous — Enfuce expects an approve/decline decision in the response, so you both consume a type and return one (AuthResponseCode is a runtime value, import it, not import type):

import { authorisationControl } from '@enfuce/nextgen-sdk';

const request = JSON.parse(payload) as authorisationControl.AuthRequestBody;
const decision: authorisationControl.AuthResponseBody = {
  authResponseCode: authorisationControl.AuthResponseCode.Approved,
};

| Namespace | Payload type(s) | | --- | --- | | issuerEvents | CardEvent, CardholderEvent, TokenEvent | | authorisationControl | AuthRequestBodyAuthResponseBody (synchronous decision) | | threedsOob | InitiateAuthenticationChallengeBody | | transactionEvent | TransactionEvent |

A runnable Express example of all of the above (both the API modules and the webhook receivers) lives in examples/backends/typescript.

File parsing

Enfuce delivers some data as a file rather than an HTTP API. These modules export only the types — parse the file's JSON into them. clearingFileCopy is a clearing (settlement) file: a FileData header plus a list of records.

import type { clearingFileCopy } from '@enfuce/nextgen-sdk';

const file = JSON.parse(clearingFileCopyJson) as clearingFileCopy.FileData;
file.records?.forEach((record) => { /* … */ });

| Namespace | Type(s) | | --- | --- | | clearingFileCopy | FileData (clearing file header + records) |

Requirements

  • Node.js >=18
  • TypeScript ^4.0 || ^5.0 (works in Node and the browser)

License

MIT