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

@stedi-oss/typesuite

v1.1.4

Published

TypeScript client for NetSuite SuiteTalk SOAP API

Downloads

139

Readme

TypeSuite™

TypeSuite™ is a TypeScript client for the NetSuite SuiteTalk Web Services API.

Note: TypeSuite is no longer being worked on, supported, or maintained. Check out SuiteTalk REST Web Services as an alternative to integrate with NetSuite.

TypeSuite was built by the team at Stedi, a platform for B2B trade. If you're using TypeSuite to improve how your business operates, we'd love to hear from you.

Usage

Installation

You can install TypeSuite via npm:

npm install --save @stedi-oss/typesuite

Or add it to your package.json manually.

Quickstart

import { Configuration, TypeSuiteClient } from "typesuite";

// You can fetch your credentials from your NetSuite instance
// We recommend storing them somewhere secure like AWS Secrets Manager
const config: Configuration = {
  account: "NetSuite Account ID",
  apiVersion: "NetSuite API Version",
  token: {
    consumerKey: "NetSuite Consumer Key",
    consumerSecret: "NetSuite Consumer Secret",
    tokenKey: "NetSuite Token Key",
    tokenSecret: "NetSuite Token Secret",
  },
};

// Create NetSuite client using above credentials
const client = new TypeSuiteClient(config);

API Details

Configuration

The Configuration object holds generic NetSuite configuration information, including the account ID and auth credentials, API version information, and can even contain shared query options, if desired.

const config: Configuration = {
  account: "NetSuite Account ID",
  apiVersion: "2019_2",
  token: {
    ...
  },
};

Preferences

The Configuration can optionally contain preferences, which will be passed in each request.

const client = new TypesSuiteClient({
  ...,
  preferences: {
    ignoreReadOnlyFields: true
  }
})

See here for supported preferences.

Sending per-request preferences is not currently supported.

API Version

Currently, TypeSuite only supports the 2019_2 WSDL; therefore, the only acceptable configuration option for apiVersion is "2019_2".

We aim to support additional API versions in future versions of TypeSuite, and will update the docs accordingly.

Authentication

TypeSuite uses NetSuite Token Based Auth (TBA), which requires a consumerKey, consumerSecret, tokenKey, and tokenSecret.

const config: Configuration = {
  account: "...",
  apiVersion: "...",
  token: {
    consumerKey: "NetSuite Consumer Key",
    consumerSecret: "NetSuite Consumer Secret",
    tokenKey: "NetSuite Token Key",
    tokenSecret: "NetSuite Token Secret",
  },
};

Reading from NetSuite

Searching for Records

You can search NetSuite for all records of a certain type (e.g. a _purchaseOrder), matching all other criteria (e.g. a status of "pending receipt") in a given time period:

// Add additional imports from our API version
import { SearchRequest } from "typesuite/2019_2/platform_messages";
import { TransactionSearchAdvanced } from "typesuite/2019_2/transactions_sales";

// Set up the correct time you'd like to start the search from
const dateTime = ZonedDateTime.of(
  LocalDateTime.parse("2020-01-01T00:00"),
  ZoneId.UTC
);
const isoFormatter = new DateTimeFormatterBuilder()
  .appendInstant(3)
  .toFormatter(ResolverStyle.STRICT);

// Construct the search request
const searchAdvancedRequest = new SearchRequest({
  searchRecord: new TransactionSearchAdvanced({
    columns: {
      basic: {
        internalId: [{}],
      },
      itemJoin: {
        internalId: [{}],
      },
    },
    criteria: {
      basic: {
        closed: false,
        mainLine: true,
        status: {
          operator: "anyOf",
          searchValue: ["_purchaseOrderPendingReceipt"],
        },
        type: {
          operator: "anyOf",
          searchValue: ["_purchaseOrder"],
        },
        dateCreated: {
          operator: "after",
          searchValue: dateTime.format(isoFormatter),
        },
      },
    },
  }),
});

// Perform NetSuite Search
const response: any = await client
  .search(searchAdvancedRequest)
  .catch((error: any) => {
    console.log("Error during search");
    throw error;
  });

// Do interesting things with the response
console.log("Found %d purchase orders", response.searchResult.totalRecords);

Note that this will return the record references, not the actual record. You'll need to fetch a record, as shown below, to get the full contents.

Resolving a Record

You can fetch an individual record (e.g. a particular purchase order) from NetSuite:

// Add additional imports
import { GetRequest } from "typesuite/2019_2/platform_messages";
import { PurchaseOrder } from "typesuite/2019_2/transactions_purchases";

// Create a PO GET request
const getRequest = new GetRequest({
  baseRef: new RecordRef({
    internalId: "NetSuite Document ID",
    type: "purchaseOrder",
  }),
});

// Perform the request
const response = await client.get(getRequest).catch(function (error: any) {
  console.log("Error fetching purchaseOrder");
  throw error;
});

// Cast the response record appropriately
const purchaseOrder = response.readResponse.record as PurchaseOrder;

Writing to NetSuite

While TypeSuite currently supports types that can be written back to NetSuite, we don't yet have examples. Stay tuned for more!

A note on instantiated objects vs object literals

Building requests to the NetSuite SuiteTalk API frequently involves instantiating quite a few objects. In order to minimize the amount of code required to build all the necessary objects, in many cases an object literal can be provided instead of a fully instantiated object. There are two cases where a fully instantiated object is required. The first case is the outermost object, typically the Request object, which must be created by calling the class' constructor. In the example below, a SearchRequest is explicitly instantiated via new.

const SearchRequest = new SearchRequest({
  ...
  });

The second case where a fully instantiated object is required is where you provide an object that is a subclass of type that is expected for that field. For example, SearchRequest has single field called searchRecord whose type is PlatformCore.SearchRecord. PlatformCore.SearchRecord is an abstract type that isn't meant to be used directly. Instead, you provide one of its subclasses, which includes TransactionSearchBasic. In order for the correct xml for this request to be generated, you must provide a fully instantiated TransactionSearchBasic.

const SearchRequest = new SearchRequest({
  searchRecord: new TransactionSearchBasic({
      ...
    }),
  });

In all other cases you can simply supply an object literal with the data needed for your request. For example, the status and type fields of TransactionSearchBasic have a type of PlatformCore.SearchEnumMultiSelectField, but it is not necessary to create these objects by calling new.

const searchRequest = new SearchRequest({
  searchRecord: new TransactionSearchBasic({
    status: {
      operator: "anyOf",
      searchValue: ["_purchaseOrderPendingReceipt"],
    },
    type: {
      operator: "anyOf",
      searchValue: ["_purchaseOrder"],
    },
  }),
});

Current limitations

API Version

As mentioned above, TypeSuite only supports the 2019_2 WSDL.

Date handling

Right now, you must convert Dates to a string manually. This is due to a complication with one of the underlying libraries that TypeSuite uses and will be fixed in a later release. However, it will always be possible to provide a string for any field in the NetSuite API that holds a Date.

const dateTime = ZonedDateTime.of(
  LocalDateTime.parse("2020-01-01T00:00"),
  ZoneId.UTC
);
const isoFormatter = new DateTimeFormatterBuilder()
  .appendInstant(3)
  .toFormatter(ResolverStyle.STRICT);

const searchRequest = new SearchRequest({
  searchRecord: new TransactionSearchBasic({
    dateCreated: {
      operator: "after",
      searchValue: dateTime.format(isoFormatter),
    },
  }),
});

Development

Build

To build TypeSuite, run npm run build. Source code is located in /src.

Test

To test TypeSuite, run npm run test. Tests are located in /test and use Jest.