-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
145 lines (126 loc) · 44.4 KB
/
index.html
File metadata and controls
145 lines (126 loc) · 44.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<!DOCTYPE html><html class="default" lang="en" data-base="./"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>@theredspace/spp-client</title><meta name="description" content="Documentation for @theredspace/spp-client"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script><script async src="assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="index.html" class="title">@theredspace/spp-client</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>@theredspace/spp-client</h1></div><div class="tsd-panel tsd-typography"><h1 id="theredspacespp-client-api-module" class="tsd-anchor-link">@theredspace/spp-client API Module<a href="#theredspacespp-client-api-module" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p><a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache-2.0"></a></p>
<p>A TypeScript client library for interacting with the OpenAir SuiteProjects Pro (SPP) XML API. This package provides a core <code>SPPClient</code> for making direct API calls and pre-built, type-safe BuisinessObject Services for all SuiteProjects Pro objects.</p>
<h2 id="features" class="tsd-anchor-link">Features<a href="#features" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
<li>Modern ECMAScript Module (ESM) and TypeScript-first design.</li>
<li>Core <code>SPPClient</code> for flexible PI communication via OpenAir/SPP XML API.</li>
<li>Type-safe services for all SPP objects (e.g., Invoices, Projects, Users, etc.).</li>
<li>Handles OAuth 2.0 authentication, including automatic token refresh.</li>
<li>Callbacks for <code>onRefresh</code> (to persist new tokens) and <code>onError</code> (for critical client errors).</li>
<li>Automatic parsing of XML responses to JavaScript objects.</li>
<li>Comprehensive error handling with custom, typed errors (<code>SPPAuthError</code>, <code>SPPBusinessError</code>, etc.).</li>
<li>Extensive list of <code>SPPStatus</code> codes and <code>SPPStatusInfo</code> for easy error identification and handling.</li>
</ul>
<h1 id="documentation" class="tsd-anchor-link">Documentation<a href="#documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><ul>
<li><a href="https://theredspace.github.io/spp-client-docs/">SPP Client Documentation</a></li>
<li>Made with <a href="https://typedoc.org/">https://typedoc.org/</a>, hosted on github pages</li>
</ul>
<h2 id="installation" class="tsd-anchor-link">Installation<a href="#installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>To use <code>@theredspace/spp-api-client</code>, configure your package manager to fetch packages from GitHub Packages under the <code>@theredspace</code> scope.</p>
<p><strong>1. Configure <code>.npmrc</code></strong></p>
<ul>
<li>
<p><strong>Option A: Edit <code>.npmrc</code> file directly (Recommended)</strong></p>
<pre><code><span class="hl-0">@</span><span class="hl-1">theredspace</span><span class="hl-0">:</span><span class="hl-1">registry</span><span class="hl-0">=</span><span class="hl-1">https</span><span class="hl-0">:</span><span class="hl-2">//npm.pkg.github.com</span>
</code><button>Copy</button></pre>
<p>For private packages or CI/CD, add:</p>
<pre><code><span class="hl-2">//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN</span>
</code><button>Copy</button></pre>
<p>Replace <code>YOUR_GITHUB_TOKEN</code> with a <a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens">GitHub Personal Access Token (PAT)</a> with <code>read:packages</code> scope.</p>
</li>
<li>
<p><strong>Option B: <code>npm login</code> (for local development)</strong></p>
<pre><code class="bash"><span class="hl-3">npm</span><span class="hl-0"> </span><span class="hl-4">login</span><span class="hl-0"> </span><span class="hl-5">--registry=https://npm.pkg.github.com</span><span class="hl-0"> </span><span class="hl-5">--scope=@theredspace</span>
</code><button type="button">Copy</button></pre>
</li>
</ul>
<p><strong>2. Install the Package</strong></p>
<pre><code class="bash"><span class="hl-3">npm</span><span class="hl-0"> </span><span class="hl-4">install</span><span class="hl-0"> </span><span class="hl-4">@theredspace/spp-client@latest</span><br/><span class="hl-2"># or</span><br/><span class="hl-3">yarn</span><span class="hl-0"> </span><span class="hl-4">add</span><span class="hl-0"> </span><span class="hl-4">@theredspace/spp-client@latest</span>
</code><button type="button">Copy</button></pre>
<h2 id="authentication" class="tsd-anchor-link">Authentication<a href="#authentication" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Before making API calls, you need OAuth tokens. Follow these steps:</p>
<ol>
<li><strong>Get the authorization URL and redirect the user</strong><pre><code class="ts"><span class="hl-6">import</span><span class="hl-0"> { </span><span class="hl-1">SPPClient</span><span class="hl-0"> } </span><span class="hl-6">from</span><span class="hl-0"> </span><span class="hl-4">"@theredspace/spp-api-client"</span><span class="hl-0">;</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">authClient</span><span class="hl-0"> = </span><span class="hl-5">new</span><span class="hl-0"> </span><span class="hl-3">SPPClient</span><span class="hl-0">({</span><br/><span class="hl-0"> </span><span class="hl-1">sppUrl:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_URL</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">clientId:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CLIENT_ID</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">clientSecret:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CLIENT_SECRET</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">callbackUrl:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CALLBACK_URL</span><span class="hl-0">,</span><br/><span class="hl-0">});</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">authorizationUrl</span><span class="hl-0"> = </span><span class="hl-1">authClient</span><span class="hl-0">.</span><span class="hl-3">getAuthUrl</span><span class="hl-0">();</span><br/><span class="hl-1">console</span><span class="hl-0">.</span><span class="hl-3">log</span><span class="hl-0">(</span><span class="hl-4">"Visit this URL to authorize:"</span><span class="hl-0">, </span><span class="hl-1">authorizationUrl</span><span class="hl-0">);</span>
</code><button type="button">Copy</button></pre>
</li>
<li><strong>Exchange the authorization code for tokens</strong>
After the user grants access, your app receives a <code>code</code> query parameter at your callback URL. Exchange it for tokens:<pre><code class="bash"><span class="hl-3">curl</span><span class="hl-0"> </span><span class="hl-5">-X</span><span class="hl-0"> </span><span class="hl-4">POST</span><span class="hl-0"> </span><span class="hl-4">"${</span><span class="hl-1">SPP_URL</span><span class="hl-4">}/login/oauth2/v1/token"</span><span class="hl-0"> </span><span class="hl-8">\</span><br/><span class="hl-0"> </span><span class="hl-5">-u</span><span class="hl-0"> </span><span class="hl-4">"${</span><span class="hl-1">CLIENT_ID</span><span class="hl-4">}:${</span><span class="hl-1">CLIENT_SECRET</span><span class="hl-4">}"</span><span class="hl-0"> </span><span class="hl-8">\</span><br/><span class="hl-0"> </span><span class="hl-5">-d</span><span class="hl-0"> </span><span class="hl-4">"grant_type=authorization_code&code=AUTH_CODE&redirect_uri=${</span><span class="hl-1">CALLBACK_URL</span><span class="hl-4">}"</span>
</code><button type="button">Copy</button></pre>
Response:<pre><code class="json"><span class="hl-0">{</span><br/><span class="hl-0"> </span><span class="hl-9">"access_token"</span><span class="hl-0">: </span><span class="hl-4">"<ACCESS_TOKEN>"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-9">"refresh_token"</span><span class="hl-0">: </span><span class="hl-4">"<REFRESH_TOKEN>"</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
</li>
<li><strong>Initialize client with tokens</strong><pre><code class="ts"><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">client</span><span class="hl-0"> = </span><span class="hl-5">new</span><span class="hl-0"> </span><span class="hl-3">SPPClient</span><span class="hl-0">({</span><br/><span class="hl-0"> </span><span class="hl-1">sppUrl:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_URL</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">clientId:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CLIENT_ID</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">clientSecret:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CLIENT_SECRET</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">callbackUrl:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CALLBACK_URL</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">accessToken:</span><span class="hl-0"> </span><span class="hl-4">"<ACCESS_TOKEN>"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">refreshToken:</span><span class="hl-0"> </span><span class="hl-4">"<REFRESH_TOKEN>"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">onRefresh</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-5">async</span><span class="hl-0"> ({ </span><span class="hl-1">access_token</span><span class="hl-0">, </span><span class="hl-1">refresh_token</span><span class="hl-0"> }) </span><span class="hl-5">=></span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-2">// persist new tokens</span><br/><span class="hl-0"> },</span><br/><span class="hl-0">});</span>
</code><button type="button">Copy</button></pre>
</li>
</ol>
<h2 id="quick-start" class="tsd-anchor-link">Quick Start<a href="#quick-start" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ol>
<li><strong>Configure environment</strong> (either via constructor or env vars):<pre><code class="bash"><span class="hl-5">export</span><span class="hl-0"> </span><span class="hl-1">SPP_URL</span><span class="hl-0">=</span><span class="hl-4">"https://your.openair.com/suiteprojects/etc/etc/"</span><br/><span class="hl-5">export</span><span class="hl-0"> </span><span class="hl-1">SPP_CLIENT_ID</span><span class="hl-0">=</span><span class="hl-4">"<your_client_id>"</span><br/><span class="hl-5">export</span><span class="hl-0"> </span><span class="hl-1">SPP_CLIENT_SECRET</span><span class="hl-0">=</span><span class="hl-4">"<your_client_secret>"</span><br/><span class="hl-5">export</span><span class="hl-0"> </span><span class="hl-1">SPP_CALLBACK_URL</span><span class="hl-0">=</span><span class="hl-4">"<your_callback_url>"</span>
</code><button type="button">Copy</button></pre>
</li>
<li><strong>Initialize client</strong>:<pre><code class="ts"><span class="hl-6">import</span><span class="hl-0"> { </span><span class="hl-1">SPPClient</span><span class="hl-0"> } </span><span class="hl-6">from</span><span class="hl-0"> </span><span class="hl-4">"@theredspace/spp-api-client"</span><span class="hl-0">;</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">client</span><span class="hl-0"> = </span><span class="hl-5">new</span><span class="hl-0"> </span><span class="hl-3">SPPClient</span><span class="hl-0">({</span><br/><span class="hl-0"> </span><span class="hl-1">sppUrl:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_URL</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">clientId:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CLIENT_ID</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">clientSecret:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CLIENT_SECRET</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">callbackUrl:</span><span class="hl-0"> </span><span class="hl-1">process</span><span class="hl-0">.</span><span class="hl-1">env</span><span class="hl-0">.</span><span class="hl-7">SPP_CALLBACK_URL</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-3">onRefresh</span><span class="hl-1">:</span><span class="hl-0"> </span><span class="hl-5">async</span><span class="hl-0"> ({ </span><span class="hl-1">access_token</span><span class="hl-0">, </span><span class="hl-1">refresh_token</span><span class="hl-0"> }) </span><span class="hl-5">=></span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-2">// persist tokens securely</span><br/><span class="hl-0"> },</span><br/><span class="hl-0">});</span>
</code><button type="button">Copy</button></pre>
</li>
</ol>
<h2 id="logging" class="tsd-anchor-link">Logging<a href="#logging" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The SPP Client includes a built-in logger that prefixes all output with <code>[RSSPPC]</code> to easily identify library logs. By default, logging is <strong>disabled</strong>.</p>
<h3 id="enabling-logging" class="tsd-anchor-link">Enabling Logging<a href="#enabling-logging" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p><strong>Simple enable</strong> - Enable logging with default 'log' level:</p>
<pre><code class="ts"><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">client</span><span class="hl-0"> = </span><span class="hl-5">new</span><span class="hl-0"> </span><span class="hl-3">SPPClient</span><span class="hl-0">({</span><br/><span class="hl-0"> </span><span class="hl-2">// ... other options</span><br/><span class="hl-0"> </span><span class="hl-1">logging:</span><span class="hl-0"> </span><span class="hl-5">true</span><span class="hl-0"> </span><span class="hl-2">// Shows log, warn, and error messages</span><br/><span class="hl-0">});</span>
</code><button type="button">Copy</button></pre>
<p><strong>Advanced configuration</strong> - Full control over log levels:</p>
<pre><code class="ts"><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">client</span><span class="hl-0"> = </span><span class="hl-5">new</span><span class="hl-0"> </span><span class="hl-3">SPPClient</span><span class="hl-0">({</span><br/><span class="hl-0"> </span><span class="hl-2">// ... other options</span><br/><span class="hl-0"> </span><span class="hl-1">logging:</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-1">enabled:</span><span class="hl-0"> </span><span class="hl-5">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">level:</span><span class="hl-0"> </span><span class="hl-4">'debug'</span><span class="hl-0"> </span><span class="hl-2">// Options: 'debug' | 'info' | 'log' | 'warn' | 'error' | 'none'</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">});</span>
</code><button type="button">Copy</button></pre>
<h3 id="controlling-logging-at-runtime" class="tsd-anchor-link">Controlling Logging at Runtime<a href="#controlling-logging-at-runtime" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Use static methods to control logging globally after client initialization:</p>
<pre><code class="ts"><span class="hl-2">// Enable/disable logging</span><br/><span class="hl-1">SPPClient</span><span class="hl-0">.</span><span class="hl-3">enableLogging</span><span class="hl-0">();</span><br/><span class="hl-1">SPPClient</span><span class="hl-0">.</span><span class="hl-3">disableLogging</span><span class="hl-0">();</span><br/><br/><span class="hl-2">// Set log level</span><br/><span class="hl-1">SPPClient</span><span class="hl-0">.</span><span class="hl-3">setLogLevel</span><span class="hl-0">(</span><span class="hl-4">'error'</span><span class="hl-0">); </span><span class="hl-2">// Only show errors</span><br/><span class="hl-1">SPPClient</span><span class="hl-0">.</span><span class="hl-3">setLogLevel</span><span class="hl-0">(</span><span class="hl-4">'warn'</span><span class="hl-0">); </span><span class="hl-2">// Show warnings and errors</span><br/><span class="hl-1">SPPClient</span><span class="hl-0">.</span><span class="hl-3">setLogLevel</span><span class="hl-0">(</span><span class="hl-4">'debug'</span><span class="hl-0">); </span><span class="hl-2">// Show everything</span><br/><br/><span class="hl-2">// Or use full configuration</span><br/><span class="hl-1">SPPClient</span><span class="hl-0">.</span><span class="hl-3">configureLogging</span><span class="hl-0">({</span><br/><span class="hl-0"> </span><span class="hl-1">enabled:</span><span class="hl-0"> </span><span class="hl-5">true</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">level:</span><span class="hl-0"> </span><span class="hl-4">'info'</span><br/><span class="hl-0">});</span>
</code><button type="button">Copy</button></pre>
<h3 id="log-levels" class="tsd-anchor-link">Log Levels<a href="#log-levels" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
<li><strong>debug</strong> - All logs including debug information (most verbose)</li>
<li><strong>info</strong> - Informational messages and above</li>
<li><strong>log</strong> - Standard logs, warnings, and errors (default when <code>logging: true</code>)</li>
<li><strong>warn</strong> - Warnings and errors only</li>
<li><strong>error</strong> - Errors only (least verbose)</li>
<li><strong>none</strong> - No logs at all</li>
</ul>
<p>All log messages are prefixed with <code>[RSSPPC]</code> and include a namespace (e.g., <code>[RSSPPC] [SPPClient] Making API call...</code>).</p>
<h2 id="using-core-methods-listaddupdatedelete" class="tsd-anchor-link">Using Core Methods (List,Add,Update,Delete)<a href="#using-core-methods-listaddupdatedelete" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><strong>List Method Examples</strong></p>
<pre><code class="typescript"><span class="hl-2">// Fetch all records for an object</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">users</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">list</span><span class="hl-0">(</span><span class="hl-4">"User"</span><span class="hl-0">);</span><br/><br/><span class="hl-2">// Fetch one record with a filter</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">customers</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">list</span><span class="hl-0">(</span><span class="hl-4">"Customer"</span><span class="hl-0">, { </span><span class="hl-1">country:</span><span class="hl-0"> </span><span class="hl-4">"US"</span><span class="hl-0"> });</span><br/><br/><span class="hl-2">// Fetch many records with an array of ids using batchList</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">items</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">batchList</span><span class="hl-0">(</span><br/><span class="hl-0"> </span><span class="hl-4">"Schedulerequest_item"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">itemIds</span><span class="hl-0">.</span><span class="hl-3">map</span><span class="hl-0">((</span><span class="hl-1">id</span><span class="hl-0">) </span><span class="hl-5">=></span><span class="hl-0"> ({ </span><span class="hl-1">id:</span><span class="hl-0"> </span><span class="hl-3">String</span><span class="hl-0">(</span><span class="hl-1">id</span><span class="hl-0">) }))</span><br/><span class="hl-0">);</span>
</code><button type="button">Copy</button></pre>
<p><strong>Add Method Examples</strong></p>
<pre><code class="typescript"><span class="hl-2">// Add a single object</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">invoice</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">add</span><span class="hl-0">(</span><span class="hl-4">"Invoice"</span><span class="hl-0">, {</span><br/><span class="hl-0"> </span><span class="hl-1">customerid:</span><span class="hl-0"> </span><span class="hl-10">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">total:</span><span class="hl-0"> </span><span class="hl-10">100</span><span class="hl-0">,</span><br/><span class="hl-0">});</span><br/><br/><span class="hl-2">// Add object with Date property</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">request</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">add</span><span class="hl-0">(</span><span class="hl-4">"Schedulerequest"</span><span class="hl-0">, {</span><br/><span class="hl-0"> </span><span class="hl-1">startdate:</span><span class="hl-0"> </span><span class="hl-4">"2024-06-01"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">enddate:</span><span class="hl-0"> </span><span class="hl-4">"2024-06-05"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">userid:</span><span class="hl-0"> </span><span class="hl-10">42</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">externalid:</span><span class="hl-0"> </span><span class="hl-4">"external-123"</span><span class="hl-0">,</span><br/><span class="hl-0">});</span><br/><br/><span class="hl-2">// Add multiple new objects at once</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">newProjects</span><span class="hl-0"> = [</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-1">name:</span><span class="hl-0"> </span><span class="hl-4">"Website Redesign"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">customerid:</span><span class="hl-0"> </span><span class="hl-10">1</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">externalid:</span><span class="hl-0"> </span><span class="hl-4">"proj-001"</span><span class="hl-0">,</span><br/><span class="hl-0"> },</span><br/><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-1">name:</span><span class="hl-0"> </span><span class="hl-4">"Mobile App Launch"</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">customerid:</span><span class="hl-0"> </span><span class="hl-10">2</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">externalid:</span><span class="hl-0"> </span><span class="hl-4">"proj-002"</span><span class="hl-0">,</span><br/><span class="hl-0"> },</span><br/><span class="hl-0">];</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">createdProjects</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">add</span><span class="hl-0">(</span><span class="hl-4">"Project"</span><span class="hl-0">, </span><span class="hl-1">newProjects</span><span class="hl-0">);</span>
</code><button type="button">Copy</button></pre>
<p><strong>Update Method Examples</strong></p>
<pre><code class="typescript"><span class="hl-2">// Update one Object by id, passing in change object.</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">updatedUser</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">update</span><span class="hl-0">(</span><span class="hl-4">"User"</span><span class="hl-0">, </span><span class="hl-10">16</span><span class="hl-0">, {</span><br/><span class="hl-0"> </span><span class="hl-1">nickname:</span><span class="hl-0"> </span><span class="hl-4">"janedoe@example.com"</span><span class="hl-0">,</span><br/><span class="hl-0">});</span><br/><br/><span class="hl-2">// Update many Objects by passing in an array of change objects.</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">updates</span><span class="hl-0"> = [</span><br/><span class="hl-0"> { </span><span class="hl-1">id:</span><span class="hl-0"> </span><span class="hl-10">101</span><span class="hl-0">, </span><span class="hl-1">changes:</span><span class="hl-0"> { </span><span class="hl-1">status:</span><span class="hl-0"> </span><span class="hl-4">"Active"</span><span class="hl-0"> } },</span><br/><span class="hl-0"> { </span><span class="hl-1">id:</span><span class="hl-0"> </span><span class="hl-10">102</span><span class="hl-0">, </span><span class="hl-1">changes:</span><span class="hl-0"> { </span><span class="hl-1">status:</span><span class="hl-0"> </span><span class="hl-4">"Completed"</span><span class="hl-0"> } },</span><br/><span class="hl-0"> { </span><span class="hl-1">id:</span><span class="hl-0"> </span><span class="hl-10">103</span><span class="hl-0">, </span><span class="hl-1">changes:</span><span class="hl-0"> { </span><span class="hl-1">status:</span><span class="hl-0"> </span><span class="hl-4">"On Hold"</span><span class="hl-0"> } },</span><br/><span class="hl-0">];</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">updatedProjects</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">update</span><span class="hl-0">(</span><span class="hl-4">"Project"</span><span class="hl-0">, </span><span class="hl-1">updates</span><span class="hl-0">);</span>
</code><button type="button">Copy</button></pre>
<p><strong>Delete Method Examples</strong>:</p>
<pre><code class="typescript"><span class="hl-2">// Delete one Object by id. Returns an array of Results</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">deletedInvoice</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">delete</span><span class="hl-0">(</span><span class="hl-4">"Invoice"</span><span class="hl-0">, </span><span class="hl-10">123</span><span class="hl-0">);</span><br/><br/><span class="hl-2">// Delete many Objects by an array of ids</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">deletedInvoices</span><span class="hl-0"> = </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">delete</span><span class="hl-0">(</span><span class="hl-4">"Invoice"</span><span class="hl-0">, [</span><span class="hl-10">123</span><span class="hl-0">, </span><span class="hl-10">456</span><span class="hl-0">]);</span>
</code><button type="button">Copy</button></pre>
<h2 id="api-rate-limiting--request-limits" class="tsd-anchor-link">API Rate Limiting & Request Limits<a href="#api-rate-limiting--request-limits" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><strong>Important:</strong><br>
The SuiteProjects API enforces rate limits based on your organizations' account. If you exceed this limit, your requests may be throttled or rejected.</p>
<ul>
<li><strong>Best Practices:</strong>
<ul>
<li>Batch your requests by passing arrays to <code>add</code>, <code>update</code>, or <code>delete</code>.</li>
<li>Use pagination for large data sets.</li>
<li>Implement retry logic with exponential backoff for 429 (Too Many Requests) errors.</li>
<li>Monitor your request volume and avoid sending bursts of requests.</li>
</ul>
</li>
</ul>
<p>If you need to process more records, consider spreading your requests over time or paginating your requests.</p>
<h2 id="error-handling--error-codes" class="tsd-anchor-link">Error Handling & Error Codes<a href="#error-handling--error-codes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>All methods throw <strong>typed errors</strong> that extend JavaScript's <code>Error</code> class. You can catch and handle these using <code>try/catch</code> blocks. The main error types are:</p>
<ul>
<li><code>SPPAuthError</code> – Authentication or token issues</li>
<li><code>SPPRequestError</code> – Network or HTTP-level failures (e.g., no response)</li>
<li><code>SPPResponseError</code> – Malformed or unexpected API responses</li>
<li><code>SPPBusinessError</code> – API-level business logic errors (non-zero SPP status codes)</li>
</ul>
<p>Each error includes a <code>.detail</code> property with a <code>code</code> and <code>message</code> for debugging.</p>
<h3 id="example" class="tsd-anchor-link">Example<a href="#example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-6">import</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-1">SPPAuthError</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">SPPBusinessError</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">SPPStatus</span><span class="hl-0">,</span><br/><span class="hl-0"> </span><span class="hl-1">SPPStatusInfo</span><span class="hl-0">,</span><br/><span class="hl-0">} </span><span class="hl-6">from</span><span class="hl-0"> </span><span class="hl-4">"@thespace/spp-api-client"</span><span class="hl-0">;</span><br/><br/><span class="hl-6">try</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-6">await</span><span class="hl-0"> </span><span class="hl-1">client</span><span class="hl-0">.</span><span class="hl-3">add</span><span class="hl-0">(</span><span class="hl-4">"User"</span><span class="hl-0">, { </span><span class="hl-1">name:</span><span class="hl-0"> </span><span class="hl-4">"Test"</span><span class="hl-0">, </span><span class="hl-1">externalid:</span><span class="hl-0"> </span><span class="hl-4">"test-001"</span><span class="hl-0"> });</span><br/><span class="hl-0">} </span><span class="hl-6">catch</span><span class="hl-0"> (</span><span class="hl-1">err</span><span class="hl-0">) {</span><br/><span class="hl-0"> </span><span class="hl-6">if</span><span class="hl-0"> (</span><span class="hl-1">err</span><span class="hl-0"> </span><span class="hl-5">instanceof</span><span class="hl-0"> </span><span class="hl-11">SPPAuthError</span><span class="hl-0">) {</span><br/><span class="hl-0"> </span><span class="hl-1">console</span><span class="hl-0">.</span><span class="hl-3">error</span><span class="hl-0">(</span><span class="hl-4">"Authentication error:"</span><span class="hl-0">, </span><span class="hl-1">err</span><span class="hl-0">.</span><span class="hl-1">detail</span><span class="hl-0">.</span><span class="hl-1">message</span><span class="hl-0">);</span><br/><span class="hl-0"> } </span><span class="hl-6">else</span><span class="hl-0"> </span><span class="hl-6">if</span><span class="hl-0"> (</span><span class="hl-1">err</span><span class="hl-0"> </span><span class="hl-5">instanceof</span><span class="hl-0"> </span><span class="hl-11">SPPBusinessError</span><span class="hl-0">) {</span><br/><span class="hl-0"> </span><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">code</span><span class="hl-0"> = </span><span class="hl-1">err</span><span class="hl-0">.</span><span class="hl-1">detail</span><span class="hl-0">.</span><span class="hl-1">code</span><span class="hl-0">;</span><br/><span class="hl-0"> </span><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">info</span><span class="hl-0"> = </span><span class="hl-1">SPPStatusInfo</span><span class="hl-0">[</span><span class="hl-1">code</span><span class="hl-0"> </span><span class="hl-6">as</span><span class="hl-0"> </span><span class="hl-11">SPPStatus</span><span class="hl-0">];</span><br/><span class="hl-0"> </span><span class="hl-1">console</span><span class="hl-0">.</span><span class="hl-3">error</span><span class="hl-0">(</span><br/><span class="hl-0"> </span><span class="hl-4">`Business error: </span><span class="hl-5">${</span><span class="hl-1">info</span><span class="hl-12">?.</span><span class="hl-1">name</span><span class="hl-12"> </span><span class="hl-0">||</span><span class="hl-12"> </span><span class="hl-1">code</span><span class="hl-5">}</span><span class="hl-4"> - </span><span class="hl-5">${</span><br/><span class="hl-12"> </span><span class="hl-1">info</span><span class="hl-12">?.</span><span class="hl-1">description</span><span class="hl-12"> </span><span class="hl-0">||</span><span class="hl-12"> </span><span class="hl-1">err</span><span class="hl-12">.</span><span class="hl-1">detail</span><span class="hl-12">.</span><span class="hl-1">message</span><br/><span class="hl-12"> </span><span class="hl-5">}</span><span class="hl-4">`</span><br/><span class="hl-0"> );</span><br/><span class="hl-0"> } </span><span class="hl-6">else</span><span class="hl-0"> {</span><br/><span class="hl-0"> </span><span class="hl-1">console</span><span class="hl-0">.</span><span class="hl-3">error</span><span class="hl-0">(</span><span class="hl-4">"Unexpected error:"</span><span class="hl-0">, </span><span class="hl-1">err</span><span class="hl-0">);</span><br/><span class="hl-0"> }</span><br/><span class="hl-0">}</span>
</code><button type="button">Copy</button></pre>
<h2 id="spp-status-codes" class="tsd-anchor-link">SPP Status Codes<a href="#spp-status-codes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
<li>All business/API errors include a numeric or string <code>code</code> (see <code>SPPStatus</code> enum).</li>
<li>You can look up human-friendly names and descriptions using <code>SPPStatusInfo</code>.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="typescript"><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">code</span><span class="hl-0"> = </span><span class="hl-10">202</span><span class="hl-0">; </span><span class="hl-2">// e.g., from err.detail.code</span><br/><span class="hl-5">const</span><span class="hl-0"> </span><span class="hl-7">info</span><span class="hl-0"> = </span><span class="hl-1">SPPStatusInfo</span><span class="hl-0">[</span><span class="hl-1">code</span><span class="hl-0">];</span><br/><span class="hl-1">console</span><span class="hl-0">.</span><span class="hl-3">log</span><span class="hl-0">(</span><span class="hl-1">info</span><span class="hl-0">.</span><span class="hl-1">name</span><span class="hl-0">); </span><span class="hl-2">// "UserDuplicateNickname"</span><br/><span class="hl-1">console</span><span class="hl-0">.</span><span class="hl-3">log</span><span class="hl-0">(</span><span class="hl-1">info</span><span class="hl-0">.</span><span class="hl-1">description</span><span class="hl-0">); </span><span class="hl-2">// "There is already a user with the same User ID (nickname)"</span>
</code><button type="button">Copy</button></pre>
<p>For a full list of status codes and their meanings, see <a href="utils/errorCodes.ts"><code>src/utils/errorCodes.ts</code></a>.</p>
<hr>
<p><strong>Tip:</strong><br>
Always wrap API calls in <code>try/catch</code> and use the error classes and status info to provide clear feedback to users and for debugging.</p>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#theredspacespp-client-api-module"><span>@theredspace/spp-<wbr/>client <wbr/>API <wbr/>Module</span></a><ul><li><a href="#features"><span>Features</span></a></li></ul><a href="#documentation"><span>Documentation</span></a><ul><li><a href="#installation"><span>Installation</span></a></li><li><a href="#authentication"><span>Authentication</span></a></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><a href="#logging"><span>Logging</span></a></li><li><ul><li><a href="#enabling-logging"><span>Enabling <wbr/>Logging</span></a></li><li><a href="#controlling-logging-at-runtime"><span>Controlling <wbr/>Logging at <wbr/>Runtime</span></a></li><li><a href="#log-levels"><span>Log <wbr/>Levels</span></a></li></ul></li><li><a href="#using-core-methods-listaddupdatedelete"><span>Using <wbr/>Core <wbr/>Methods (<wbr/>List,<wbr/>Add,<wbr/>Update,<wbr/>Delete)</span></a></li><li><a href="#api-rate-limiting--request-limits"><span>API <wbr/>Rate <wbr/>Limiting & <wbr/>Request <wbr/>Limits</span></a></li><li><a href="#error-handling--error-codes"><span>Error <wbr/>Handling & <wbr/>Error <wbr/>Codes</span></a></li><li><ul><li><a href="#example"><span>Example</span></a></li></ul></li><li><a href="#spp-status-codes"><span>SPP <wbr/>Status <wbr/>Codes</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">@theredspace/spp-client</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>