Epicor Rest Helper for Node (npm) V2.0


Update 2.0.0 Epicor Rest Helper for Node (npm) V2.0 - #21 by josecgomez

Update 1.3.0 Epicor Rest Helper for Node (npm) V2.0 - #20 by josecgomez


Update 1.2.8 Epicor Rest Helper for Node (npm) V2.0 - #19 by josecgomez


Update: 1.2.3 Epicor Rest Helper for Node (npm) V2.0 - #16 by josecgomez


@jgiese.wci and I just published a similar helper library to the
C# Nuget or
Angular NPM package

It can be found here
https://www.npmjs.com/package/epicor-rest-node

This library helps make Epicor calls from a node application.

All the documentation for it is in the NPM Site.

Let us know if you run into issues

7 Likes

Added ability to create bearer tokens to the NPM.

1 Like

The link to the github repo appears to be incorrect

Looks cool, the npm page description for epicor-rest-node says for Angular but this should work independent of a framework, right?

There’s an angular specific one (link above) and this one is just for node (server side)

The angular package above is implemented as an angular service and has the service life cycle and singleton pattern so that one may be more useful if you are doing angular specifically

the description issue is a copy and paste blunder ill fix it

1 Like

GitHub link is fine but it’s private

2 Likes

Are you guys planning to make the repo public in the future?

We weren’t planning on it since the NPM packages allow everyone to use it and frankly… its JS the code is there in the NPM package anyways. Any particular reason why you want it in github?

To do pull requests or report issues mostly

1 Like

Got it I can give you access to this repo if you want to do pull requests I’m all for that. Ping me with your github username and I’ll invite you to this repo.

2 Likes
npm audit
# npm audit report

axios  
Severity: moderate
Axios Cross-Site Request Forgery Vulnerability - https://github.com/advisories/GHSA-wf5p-g6vw-rhxx
No fix available
node_modules/axios
  epicor-rest-node  
  Depends on vulnerable versions of axios
  node_modules/epicor-rest-node

2 moderate severity vulnerabilities

Some issues need review, and may require choosing
a different dependency.

I assume this is because Epicor is on TLS 1.2 and the up to date stuff is TLS 1.3. Is this repo still being maintained?
I’m still working on this issue Epicor REST nodejs error EPROTO

Yes it is still being maintained. I’ll poke at and upgrade the axios library when I get a chance.

1 Like

Version 1.1.14 has been published

You can grab it with

npm i epicor-rest-node@latest 

Thanks for the heads up upgraded axios from version 0.21.1 to 1.6.7 also bumped node and typescript to latest.

2 Likes

npm audit now shows 0 vulnerabilities. Thank you so much!

Version 1.1.16 has been published

You can grab it with

npm i epicor-rest-node@latest 

This release has added support for CallContext. Our documentation has also been updated to demonstrate the use of CallContext. Call context can be passed as a param in our standard functions. The param is an object of type CallContext. The model has been added to our module for your use. You can also convert a partial context to the full object for consumption by passing it as a generic object.

Rough Example

// Build our partial generic
var cc = {
    "Context": {
      "BpmData": [
        {
          "Character01": "FOO",
          "Character02": "BAR",
          "Checkbox01": true,
          "Date01": "2024-12-27"
        }
      ]
    }
  }

// Setup call params
var library = "SomeLibrary";
var function = "SomeFunction";
var useStaging = false;
var params = {
    "iValueOne": "FooBar"
};
var requestCC = new CallContext(cc.Context); // Get our partial generic to the type of CallContext

// Make our call to Epicor using the module
const { data, context } = await EpicorRest.EfxPost(library , function , params, useStaging , requestCC ).then((res) => {
        var responseData = res.Data;
        var responseCC = new CallContext(JSON.parse(res.headers['contextheader']).Context); // Capture the callcontext from response headers

        // Do something with response call context or pass it back up the chain for use elsewhere
        return { data: responseData, context: responseCC };
      ​});
4 Likes

Version 1.2.3
feat: Enhance EpicorRestService with error handling and new environment retrieval

  • Updated EpicorRestService methods (BoGet, BoPost, BoPatch, BoDelete, BaqGet, BaqPatch, EfxPost) to return typed responses or EpicorError instances.

  • Added GetEnvironment method to retrieve environment details.

  • Introduced EpicorError class for structured error handling.

  • Created EpicorEnvironment interface to define environment structure.

  • Updated TypeScript definitions and JavaScript implementations accordingly.

Most signficant update here is the introduction of Error class and specific async / await handling within the implementation (for error checking)

Also we added GetEnvironment() which returns a Typed EpicorEnvironment object

See Read Me for all details:

6 Likes

Update 1.2.5

Summary of Features Added Today

1. Get Function Library List [GetFunctionLibraryList]

  • Purpose: Discover all available EFX function libraries in an Epicor environment
  • Endpoint: https://{host}/{instance}/api/v2/efx/{company}/
  • Returns: Array of EpicorFunctionLibrary objects with [LibraryId]

2. Get Function Library Specification [GetFunctionLibrarySpec](

  • Purpose: Get detailed OpenAPI 3.0.1 specification for a specific function library
  • Endpoint: https://{host}/{instance}/api/swagger/v2/efx/{library}/{company}.json
  • Returns: Complete OpenAPI spec with function definitions, parameters, and schemas

3. BAQ Metadata Enhancement [BaqMetaData]:star:

  • Enhancement: Added automatic Accept: application/json header handling
  • Purpose: Get BAQ schema/metadata information in JSON format

4. Additional Headers Functionality :star:

  • Enhancement: Added [additionalHeaders] parameter to ALL public methods
  • Type: EpicorHttpHeaders | null = null
  • Purpose: Allow custom headers to be passed and merged with standard Epicor headers
  • Behavior: Additional headers can override default headers
  • Methods Enhanced:
    • [BoGet], [BoPost], [BoPatch], [BoDelete]
    • [BaqGet], BaqPatch, [BaqMetaData]
    • [EfxPost]
    • [GetEnvironment]
    • [GetFunctionLibraryList], [GetFunctionLibrarySpec]

5. EpicorHttpHeaders Type Interface :star:

export interface EpicorHttpHeaders {

[key: string]: string;

}
  • Purpose: Type-safe header definitions
  • Usage: Ensures all header values are strings
  • Exported: Available for external use
4 Likes

Version 1.2.7

:tada: New Features

Response Headers Capture

Added the ability to capture HTTP response headers from all API calls using the new [CapturedResponseHeaders] class.

What’s New:

  • New Class: [CapturedResponseHeaders] - A utility class for capturing and managing HTTP response headers
  • Enhanced API Methods: All API methods now accept an optional capturedResponseHeaders parameter as the last argument
  • Header Access Methods:
    • getHeader(name)- Get specific headers (case-insensitive)
    • hasHeader(name) - Check if a header exists
    • getHeaderNames()- Get all header names
    • headers property - Access all headers as an object
    • clear() - Clear captured headers

Supported Methods:

  • [BoGet], [BoPost], [BoPatch], [BoDelete]
  • [BaqGet], [BaqPatch], [BaqMetaData]
  • [EfxPost]
  • [GetFunctionLibraryList], [GetFunctionLibrarySpec]
  • [GetEnvironment]

Example Usage:

import { CapturedResponseHeaders } from 'epicor-rest-node';

const capturedHeaders = new CapturedResponseHeaders();

const result = await service.GetEnvironment(null, null, capturedHeaders);

// Access headers

console.log('Content-Type:', capturedHeaders.getHeader('content-type'));

console.log('All headers:', capturedHeaders.headers);

:wrench: Technical Changes

  • Import Updates: Added [CapturedResponseHeaders] to exports in main module
  • Type Safety: Full TypeScript support with proper typing for all new functionality
  • Backward Compatibility: All existing code continues to work without changes - the new parameter is optional
  • Error Handling: Response headers are captured even when API calls return errors (when response object is available)

:light_bulb: Use Cases

The new response headers capture feature enables:

  • Debugging: Examine server response headers for troubleshooting
  • Rate Limiting: Access rate limiting information and quotas
  • Custom Logic: Extract custom Epicor headers with business information
  • Performance Monitoring: Monitor server performance metrics
  • Caching: Implement caching strategies based on cache-control headers
  • Security: Security auditing and compliance logging
  • Tracing: Epicor supports passing in addtional trace headers to a call. You can now do this using the additionalHeaders and the capture headers thanks @Olga for the suggestion

IE: You can pass in an optional header as such to enable server side tracing. See Performance Tunning Guide for a complete list of trace flags.

const capturedHeaders = new CapturedResponseHeaders();
const optionalHeaders = {"TraceFlags":"{\"FlagList\":[\"trace:\/\/system\/fw\/trigger\",\"trace:\/\/system\/db\/hits\",\"trace:\/\/ice\/fw\/BPM\",\"trace:\/\/ice\/fw\/DynamicQuery\"],\"UseServerTiming\":false}"};  
var map = new Map<string, string>();
map.set('whereClause', '');
map.set('pageSize', '0'); // Limit results for testing
map.set('absolutePage', '0');
result = await this.service.BoGet("Erp.BO.CompanySvc","GetList",map,null, optionalHeaders, capturedHeaders);

//the capturedHeaders object will contain the aformentioned headers including the new callertrace

Which will then Return the following as Part of the capture response headers.

{"callertrace": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTE2Ij8+DQo8T3AgVXRjPSI yMDI1LTA4LTEzVDE4OjQ2OjAxLjYzNjI3ODFaIi
BhY3Q9IkVycDpCTzpDb21wYW55L0NvbXBhbnlTdmNDb250cmFjdC9HZXRMaXN0IiBjb3JyZWxhdGlvbklkPSJjNTM2ZTdmOC1kOWMyLTQ3ZjQtODEwYy0yMDdhMGE4ZTE0ZDUiIGR1cj0iNC4xMjYxIiBjbGk9IjEwLjI1NC4xLjIwMDo1MDQwNiIgdXNyPSJqY2dvbWV6IiBtYWNoaW5lPSJBWi1FUElDT1ItREVWMDEiIHBpZD0iMTEzNTgwIiB0aWQ9IjMyIj4NCiAgPFNxbCBxdWVyaWVzPSIxIiBjYWNoZUhpdHM9IjAiIHRpbWU9IjAuNjQxOCIgcXJ5VHlwZUNvdW50PSIxIiAvPg0KPC9PcD4="}

Which you if you haven’t guessed by now is a base64 encoded string which contains… you guessed it a Tracecall

<?xml version="1.0" encoding="utf-16"?>
<Op Utc="2025-08-13T18:46:01.6362781Z" act="Erp:BO:Company/CompanySvcContract/GetList" correlationId="c536e7f8-d9c2-47f4-810c-207a0a8e14d5" dur="4.1261" cli="10.254.1.200:50406" usr="jcgomez" machine="AZ-EPICOR-DEV01" pid="113580" tid="32">
  <Sql queries="1" cacheHits="0" time="0.6418" qryTypeCount="1" />
</Op>
5 Likes

EpicorRestNode v1.2.8 Release Notes

:rocket: New Features

GetBaqSwagger Method

Added a new method to retrieve OpenAPI 3.0.1 swagger documentation for Business Activity Queries (BAQs).

public async GetBaqSwagger<T = any>(

iBaqID: string,

iCallContext?: CallContext | null,

additionalHeaders?: EpicorHttpHeaders | null,

capturedResponseHeaders?: CapturedResponseHeaders | null

): Promise<T | EpicorError>

Endpoint Pattern:

https://{host}/{instance}/api/swagger/v2/baq/{company}/{baqId}.json

:clipboard: What’s New

Enhanced BAQ Documentation Support

  • Complete OpenAPI Specification: Get full swagger documentation for any BAQ including available endpoints, schemas, and field definitions
  • Schema Discovery: Understand BAQ return types, field descriptions, and data types programmatically
  • API Documentation: Access comprehensive endpoint information for /Data, /$metadata, and service document endpoints
  • Dynamic Integration: Build dynamic UIs and validation based on BAQ field definitions

Comprehensive Test Coverage

  • Added automated tests for the new [GetBaqSwagger] functionality
  • Test validates OpenAPI document structure, endpoint availability, and schema parsing
  • Integrated into the existing test suite with detailed output and error handling

:bullseye: Use Cases

The new [GetBaqSwagger] method enables:

  • Dynamic UI Generation: Build forms and interfaces based on BAQ field definitions
  • API Documentation: Generate client documentation for BAQ endpoints
  • Schema Validation: Validate data types and required fields before BAQ execution
  • Integration Planning: Understand BAQ capabilities for system integration
  • Code Generation: Generate typed interfaces for BAQ results
  • Field Discovery: Programmatically discover available fields and their descriptions

:open_book: Usage Example

import { EpicorRestService, EpicorError } from 'epicor-rest-node';

const epicorService = new EpicorRestService();

// ... configure service properties ...

// Get swagger documentation for BAQ

const swaggerDoc = await epicorService.GetBaqSwagger('zCustomer01');

if (!EpicorError.isError(swaggerDoc)) {

console.log('BAQ Title:', swaggerDoc.info.title);

console.log('Available Endpoints:', Object.keys(swaggerDoc.paths));

// Extract field information

const queryItemSchema = swaggerDoc.components?.schemas?.['Epicor.QueryItem'];

if (queryItemSchema?.properties) {

const fields = Object.keys(queryItemSchema.properties);

console.log('Available Fields:', fields);

}

} else {

console.error('Error:', swaggerDoc.message);

}

:wrench: Technical Details

  • OpenAPI Version: Supports OpenAPI 3.0.1 specification
  • Type Safety: Fully typed with TypeScript generics
  • Error Handling: Consistent error handling using [EpicorError] class
  • Response Headers: Support for capturing response headers
  • Call Context: Support for Epicor call context and additional headers

:test_tube: Testing

  • New Test Suite: [testGetBaqSwagger()] added to test runner
  • Full Integration: Test validates real-world BAQ swagger retrieval
  • Detailed Output: Test provides comprehensive feedback on swagger document structure
  • CI/CD Ready: Integrated with existing test automation

:building_construction: Backward Compatibility

This release is fully backward compatible. All existing functionality remains unchanged, and the new [GetBaqSwagger] method is an additive enhancement.

5 Likes

EpicorRestNode v1.3.0 Release Notes

:rocket: New Features

Session Management Methods

Added comprehensive session management methods to control Epicor session context after establishing a connection.

public async SetEmployee(employeeID: string): Promise<boolean>
public async SetPlant(newSite: string): Promise<boolean>
public async SetWorkstation(newWorkstationID: string): Promise<boolean>
public async SetClientData(
  clientUserName: string,
  clientComputerName: string,
  clientDateFormat?: string,
  appserver?: string,
  clientTerminalID?: number
): Promise<boolean>
public async GetSessionInfo(): Promise<any>
public async GetThemeInfo(): Promise<any>

Important: All session management methods require an active session created with CreateSession(). They will throw an error if called without a valid session.

EFX Staging Retry Flag

Added a new development-only flag to automatically retry Epicor Function calls with the staging endpoint when encountering 404 errors.

EpicorRest.EfxAttemptStagingRetry = true; // Development mode only

Endpoint Pattern:

  • Standard: https://{host}/{instance}/api/v2/efx/{company}/{library}/{function}
  • Staging: https://{host}/{instance}/api/v2/efx/staging/{company}/{library}/{function}

:clipboard: What’s New

Advanced Session Control

  • Employee Context: Switch to a different employee for labor tracking or permissions
  • Plant Management: Change the manufacturing site context for operations
  • Workstation Control: Set the workstation for production or quality operations
  • Client Synchronization: Sync client machine information with the server session
  • Session Information: Retrieve current session state, user info, and Epicor version
  • Theme Preferences: Get user preferences and theme settings for UI customization

Development Workflow Enhancement

  • Staging Retry: Automatically retry EFX function calls with staging endpoint on 404
  • Seamless Testing: Test functions in staging before publishing to production
  • Smart Fallback: Only retries when initial call returns 404 status

Method Standardization

  • Deprecated Createsession(): Use CreateSession() (capital ‘S’) instead
  • Consistent Naming: All methods now follow proper PascalCase conventions
  • Backward Compatible: Deprecated method still works but will be removed in future versions

Comprehensive Test Coverage

  • Added automated tests for all new session management methods
  • Test validates SetEmployee, SetPlant, SetWorkstation, and SetClientData functionality
  • Integrated EfxAttemptStagingRetry testing with detailed output
  • GetSessionInfo and GetThemeInfo validation included

:bullseye: Use Cases

The new session management methods enable:

  • Multi-User Scenarios: Switch employee context for labor tracking without creating new sessions
  • Multi-Site Operations: Change plant context for cross-facility workflows
  • Production Tracking: Set workstation context for manufacturing operations
  • Session Diagnostics: Retrieve session information for debugging and auditing
  • UI Customization: Adapt interfaces based on user theme preferences
  • Client Integration: Synchronize client machine details with Epicor server

The EfxAttemptStagingRetry flag enables:

  • Function Development: Test new EFX functions in staging before production deployment
  • Rapid Iteration: Automatically fall back to staging during development
  • Seamless Workflow: Reduce manual endpoint switching during testing

:open_book: Usage Examples

Session Management

import { EpicorRestService, EpicorError } from 'epicor-rest-node';

const epicorService = new EpicorRestService();
// ... configure service properties ...

// Create a session first
const sessionCreated = await epicorService.CreateSession();

if (sessionCreated) {
  try {
    // Switch employee context
    const employeeSet = await epicorService.SetEmployee('EMP123');
    if (employeeSet) {
      console.log('Employee context updated');
    }

    // Change plant/site
    const plantSet = await epicorService.SetPlant('MfgSys');
    if (plantSet) {
      console.log('Plant context updated');
    }

    // Set workstation
    const workstationSet = await epicorService.SetWorkstation('WKST001');
    if (workstationSet) {
      console.log('Workstation context updated');
    }

    // Synchronize client data
    const clientDataSet = await epicorService.SetClientData(
      'john.doe',
      'DESKTOP-ABC123',
      'M/d/yyyy'
    );
    if (clientDataSet) {
      console.log('Client data synchronized');
    }

    // Get session information
    const sessionInfo = await epicorService.GetSessionInfo();
    console.log('Current User:', sessionInfo.UserID);
    console.log('Company:', sessionInfo.CompanyID);
    console.log('Plant:', sessionInfo.PlantID);

    // Get theme information
    const themeInfo = await epicorService.GetThemeInfo();
    console.log('User Theme:', themeInfo.Theme);

  } finally {
    await epicorService.DestroySession();
  }
}

EFX Staging Retry (Development Only)

import { EpicorRestService } from 'epicor-rest-node';

const epicorService = new EpicorRestService();
// ... configure service properties ...

// Enable staging retry for development
epicorService.EfxAttemptStagingRetry = true;

// Call EFX function - will automatically retry with staging endpoint on 404
const result = await epicorService.EfxPost(
  'MyLibrary',
  'MyNewFunction',
  { param1: 'value1' }
);

// Remember to disable for production!
epicorService.EfxAttemptStagingRetry = false;

:wrench: Technical Details

Session Management

  • Session Required: All Set* methods require an active session or will throw an error
  • Type Safety: Fully typed with boolean return values for success/failure
  • Error Handling: Consistent error handling using EpicorError class
  • Session Info: Returns detailed user, company, plant, and version information
  • Theme Info: Returns user preferences and shell layout options

EFX Staging Retry

  • Development Only: Should only be enabled during development/testing
  • Smart Retry: Only retries when initial call returns 404 status
  • Transparent: Works seamlessly with existing EfxPost calls
  • Configurable: Simple boolean flag to enable/disable

Breaking Changes

  • None: All changes are backward compatible
  • Deprecation: Createsession() deprecated in favor of CreateSession()

:test_tube: Testing

  • New Test Methods:

    • testSetEmployee() - Validates employee context switching
    • testSetPlant() - Validates plant context switching
    • testSetWorkstation() - Validates workstation context switching
    • testSetClientData() - Validates client data synchronization
    • testGetSessionInfo() - Validates session information retrieval
    • testGetThemeInfo() - Validates theme information retrieval
    • testEfxAttemptStagingRetry() - Validates staging retry functionality
  • Full Integration: Tests validate real-world session management scenarios

  • Detailed Output: Tests provide comprehensive feedback on session state changes

  • CI/CD Ready: Integrated with existing test automation

  • Optional Configuration: Tests skip gracefully if optional parameters not configured

:building_construction: Backward Compatibility

This release is fully backward compatible. All existing functionality remains unchanged, and the new session management methods are additive enhancements. The deprecated Createsession() method continues to work but will be removed in a future major version.

:warning: Important Notes

  • Session Management: All Set* methods require an active session created with CreateSession()
  • Staging Retry: The EfxAttemptStagingRetry flag should only be used during development
  • Deprecation Warning: Update Createsession() calls to CreateSession() to prepare for future versions
  • Production Use: Disable EfxAttemptStagingRetry in production environments
3 Likes