netsuite-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +258 -0
- package/dist/index.d.mts +457 -0
- package/dist/index.d.ts +457 -0
- package/dist/index.js +839 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +819 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +67 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
interface Logger {
|
|
2
|
+
debug(message: string, meta?: unknown): void;
|
|
3
|
+
info(message: string, meta?: unknown): void;
|
|
4
|
+
warn(message: string, meta?: unknown): void;
|
|
5
|
+
error(message: string, meta?: unknown): void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface OAuthConfig {
|
|
9
|
+
consumerKey: string;
|
|
10
|
+
consumerSecret: string;
|
|
11
|
+
tokenKey: string;
|
|
12
|
+
tokenSecret: string;
|
|
13
|
+
realm: string;
|
|
14
|
+
}
|
|
15
|
+
interface NetSuiteConfig {
|
|
16
|
+
/** OAuth 1.0a (TBA) credentials */
|
|
17
|
+
auth: OAuthConfig;
|
|
18
|
+
/** NetSuite account ID (e.g., "1234567" or "1234567_SB1" for sandbox) */
|
|
19
|
+
accountId: string;
|
|
20
|
+
/** Request timeout in ms. Default: 30000 */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
/** Max retry attempts for transient errors. Default: 3 */
|
|
23
|
+
maxRetries?: number;
|
|
24
|
+
/** Initial retry delay in ms. Default: 1000 */
|
|
25
|
+
retryDelay?: number;
|
|
26
|
+
/** Default headers added to every request */
|
|
27
|
+
defaultHeaders?: Record<string, string>;
|
|
28
|
+
/** Optional logger */
|
|
29
|
+
logger?: Logger;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
33
|
+
interface RequestOptions {
|
|
34
|
+
method?: HttpMethod;
|
|
35
|
+
headers?: Record<string, string>;
|
|
36
|
+
body?: unknown;
|
|
37
|
+
/** Override timeout for this request */
|
|
38
|
+
timeout?: number;
|
|
39
|
+
/** Override retry count for this request */
|
|
40
|
+
maxRetries?: number;
|
|
41
|
+
}
|
|
42
|
+
interface NetSuiteResponse<T = unknown> {
|
|
43
|
+
data: T;
|
|
44
|
+
status: number;
|
|
45
|
+
headers: Record<string, string>;
|
|
46
|
+
duration: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface RequestContext {
|
|
50
|
+
url: string;
|
|
51
|
+
method: HttpMethod;
|
|
52
|
+
headers: Record<string, string>;
|
|
53
|
+
body?: unknown;
|
|
54
|
+
metadata: Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
interface ResponseContext {
|
|
57
|
+
status: number;
|
|
58
|
+
headers: Record<string, string>;
|
|
59
|
+
body: unknown;
|
|
60
|
+
duration: number;
|
|
61
|
+
}
|
|
62
|
+
type Middleware = (context: RequestContext, next: () => Promise<ResponseContext>) => Promise<ResponseContext>;
|
|
63
|
+
|
|
64
|
+
declare class HttpTransport {
|
|
65
|
+
private sign;
|
|
66
|
+
private axiosInstance;
|
|
67
|
+
private middlewares;
|
|
68
|
+
private config;
|
|
69
|
+
constructor(config: NetSuiteConfig);
|
|
70
|
+
/** Add a middleware to the chain. Returns `this` for chaining. */
|
|
71
|
+
use(middleware: Middleware): this;
|
|
72
|
+
/** Execute an HTTP request with OAuth signing, retry, and middleware. */
|
|
73
|
+
request<T = unknown>(url: string, options?: RequestOptions): Promise<NetSuiteResponse<T>>;
|
|
74
|
+
private executeRequest;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Raw SuiteQL API response envelope */
|
|
78
|
+
interface SuiteQLRawResponse<T = Record<string, unknown>> {
|
|
79
|
+
links: Array<{
|
|
80
|
+
rel: string;
|
|
81
|
+
href: string;
|
|
82
|
+
}>;
|
|
83
|
+
count: number;
|
|
84
|
+
hasMore: boolean;
|
|
85
|
+
offset: number;
|
|
86
|
+
totalResults: number;
|
|
87
|
+
items: T[];
|
|
88
|
+
}
|
|
89
|
+
/** Options for a SuiteQL query execution */
|
|
90
|
+
interface SuiteQLOptions {
|
|
91
|
+
/** Maximum rows to fetch per page. Default: 1000, Max: 1000 */
|
|
92
|
+
pageSize?: number;
|
|
93
|
+
/** Starting offset. Default: 0 */
|
|
94
|
+
offset?: number;
|
|
95
|
+
/** Maximum total rows to fetch across all pages. Default: Infinity */
|
|
96
|
+
maxRows?: number;
|
|
97
|
+
/** Override timeout for this query */
|
|
98
|
+
timeout?: number;
|
|
99
|
+
}
|
|
100
|
+
/** Result of a SuiteQL query with metadata */
|
|
101
|
+
interface SuiteQLResult<T = Record<string, unknown>> {
|
|
102
|
+
/** All fetched rows */
|
|
103
|
+
items: T[];
|
|
104
|
+
/** Total results reported by NetSuite */
|
|
105
|
+
totalResults: number;
|
|
106
|
+
/** Number of pages fetched */
|
|
107
|
+
pagesFetched: number;
|
|
108
|
+
/** Whether more results exist beyond what was fetched */
|
|
109
|
+
hasMore: boolean;
|
|
110
|
+
/** Total execution time in ms */
|
|
111
|
+
duration: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* SuiteQL client for executing queries against the NetSuite SuiteQL REST endpoint.
|
|
116
|
+
*
|
|
117
|
+
* Handles the `Prefer: transient` header requirement and automatic pagination.
|
|
118
|
+
*/
|
|
119
|
+
declare class SuiteQLClient {
|
|
120
|
+
private transport;
|
|
121
|
+
private baseUrl;
|
|
122
|
+
constructor(transport: HttpTransport, accountId: string);
|
|
123
|
+
/**
|
|
124
|
+
* Execute a SuiteQL query and return all matching rows.
|
|
125
|
+
* Automatically paginates across multiple pages.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const result = await client.suiteql.query<Customer>(
|
|
130
|
+
* 'SELECT id, companyname, email FROM customer WHERE isinactive = \'F\'',
|
|
131
|
+
* { pageSize: 500 }
|
|
132
|
+
* );
|
|
133
|
+
* console.log(result.items); // all rows
|
|
134
|
+
* console.log(result.totalResults); // total count from NetSuite
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
query<T = Record<string, unknown>>(sql: string, options?: SuiteQLOptions): Promise<SuiteQLResult<T>>;
|
|
138
|
+
/**
|
|
139
|
+
* Execute a query and return a single row, or null if not found.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* const customer = await client.suiteql.queryOne<Customer>(
|
|
144
|
+
* 'SELECT id, companyname FROM customer WHERE id = 123'
|
|
145
|
+
* );
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
queryOne<T = Record<string, unknown>>(sql: string, options?: Omit<SuiteQLOptions, 'maxRows'>): Promise<T | null>;
|
|
149
|
+
/**
|
|
150
|
+
* Execute a query and yield pages as an async generator.
|
|
151
|
+
* Useful for streaming large result sets without holding everything in memory.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* for await (const page of client.suiteql.queryPages<Transaction>(
|
|
156
|
+
* 'SELECT id, tranid, total FROM transaction',
|
|
157
|
+
* { pageSize: 500 }
|
|
158
|
+
* )) {
|
|
159
|
+
* await processBatch(page);
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
queryPages<T = Record<string, unknown>>(sql: string, options?: SuiteQLOptions): AsyncGenerator<T[], void, undefined>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Options for listing records */
|
|
167
|
+
interface RecordListOptions {
|
|
168
|
+
limit?: number;
|
|
169
|
+
offset?: number;
|
|
170
|
+
fields?: string[];
|
|
171
|
+
/** URL query params for filtering */
|
|
172
|
+
query?: Record<string, string>;
|
|
173
|
+
expandSubResources?: boolean;
|
|
174
|
+
}
|
|
175
|
+
/** Response from listing records */
|
|
176
|
+
interface RecordListResponse<T = Record<string, unknown>> {
|
|
177
|
+
links: Array<{
|
|
178
|
+
rel: string;
|
|
179
|
+
href: string;
|
|
180
|
+
}>;
|
|
181
|
+
count: number;
|
|
182
|
+
hasMore: boolean;
|
|
183
|
+
offset: number;
|
|
184
|
+
totalResults: number;
|
|
185
|
+
items: T[];
|
|
186
|
+
}
|
|
187
|
+
/** Options for getting a single record */
|
|
188
|
+
interface RecordGetOptions {
|
|
189
|
+
fields?: string[];
|
|
190
|
+
expandSubResources?: boolean;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Common NetSuite record types with autocomplete support.
|
|
194
|
+
* Any string is accepted for custom/unlisted record types.
|
|
195
|
+
*/
|
|
196
|
+
type RecordType = 'customer' | 'vendor' | 'employee' | 'salesOrder' | 'purchaseOrder' | 'invoice' | 'item' | 'contact' | 'opportunity' | 'journalEntry' | 'creditMemo' | 'inventoryItem' | 'nonInventoryItem' | 'serviceItem' | (string & {});
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Client for NetSuite REST Record API v1.
|
|
200
|
+
* Provides CRUD operations on NetSuite records.
|
|
201
|
+
*/
|
|
202
|
+
declare class RecordClient {
|
|
203
|
+
private transport;
|
|
204
|
+
private baseUrl;
|
|
205
|
+
constructor(transport: HttpTransport, accountId: string);
|
|
206
|
+
/** Get a record by type and internal ID */
|
|
207
|
+
get<T = Record<string, unknown>>(recordType: RecordType, id: string | number, options?: RecordGetOptions): Promise<NetSuiteResponse<T>>;
|
|
208
|
+
/** List records of a given type */
|
|
209
|
+
list<T = Record<string, unknown>>(recordType: RecordType, options?: RecordListOptions): Promise<NetSuiteResponse<RecordListResponse<T>>>;
|
|
210
|
+
/** Create a new record */
|
|
211
|
+
create<T = Record<string, unknown>>(recordType: RecordType, body: Record<string, unknown>): Promise<NetSuiteResponse<T>>;
|
|
212
|
+
/** Update an existing record (partial update via PATCH) */
|
|
213
|
+
update<T = Record<string, unknown>>(recordType: RecordType, id: string | number, body: Record<string, unknown>): Promise<NetSuiteResponse<T>>;
|
|
214
|
+
/** Replace an existing record (full replace via PUT) */
|
|
215
|
+
replace<T = Record<string, unknown>>(recordType: RecordType, id: string | number, body: Record<string, unknown>): Promise<NetSuiteResponse<T>>;
|
|
216
|
+
/** Delete a record */
|
|
217
|
+
delete(recordType: RecordType, id: string | number): Promise<NetSuiteResponse<void>>;
|
|
218
|
+
/** Upsert: create or update based on external ID */
|
|
219
|
+
upsert<T = Record<string, unknown>>(recordType: RecordType, externalIdField: string, externalIdValue: string, body: Record<string, unknown>): Promise<NetSuiteResponse<T>>;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
interface RestletParams {
|
|
223
|
+
/** Script ID of the RESTlet */
|
|
224
|
+
script: string | number;
|
|
225
|
+
/** Deploy ID of the RESTlet */
|
|
226
|
+
deploy: string | number;
|
|
227
|
+
/** Additional query parameters */
|
|
228
|
+
params?: Record<string, string | number | boolean>;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Client for calling NetSuite RESTlets.
|
|
232
|
+
* Auto-builds the RESTlet URL from account ID, script, and deploy IDs.
|
|
233
|
+
*/
|
|
234
|
+
declare class RestletClient {
|
|
235
|
+
private transport;
|
|
236
|
+
private baseUrl;
|
|
237
|
+
constructor(transport: HttpTransport, accountId: string);
|
|
238
|
+
/** Execute a RESTlet call */
|
|
239
|
+
call<T = unknown>(restlet: RestletParams, options?: RequestOptions): Promise<NetSuiteResponse<T>>;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Main NetSuite API client.
|
|
244
|
+
*
|
|
245
|
+
* Provides namespaced access to SuiteQL, Record, and RESTlet APIs,
|
|
246
|
+
* plus raw HTTP methods as an escape hatch.
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```ts
|
|
250
|
+
* import { NetSuiteClient } from 'netsuite-sdk';
|
|
251
|
+
*
|
|
252
|
+
* const client = new NetSuiteClient({
|
|
253
|
+
* auth: {
|
|
254
|
+
* consumerKey: '...',
|
|
255
|
+
* consumerSecret: '...',
|
|
256
|
+
* tokenKey: '...',
|
|
257
|
+
* tokenSecret: '...',
|
|
258
|
+
* realm: '1234567',
|
|
259
|
+
* },
|
|
260
|
+
* accountId: '1234567',
|
|
261
|
+
* });
|
|
262
|
+
*
|
|
263
|
+
* // SuiteQL
|
|
264
|
+
* const result = await client.suiteql.query('SELECT id, companyname FROM customer');
|
|
265
|
+
*
|
|
266
|
+
* // Records
|
|
267
|
+
* const customer = await client.records.get('customer', 123);
|
|
268
|
+
*
|
|
269
|
+
* // RESTlets
|
|
270
|
+
* const data = await client.restlets.call({ script: '1', deploy: '1' });
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare class NetSuiteClient {
|
|
274
|
+
/** SuiteQL query execution and builder */
|
|
275
|
+
readonly suiteql: SuiteQLClient;
|
|
276
|
+
/** REST Record API CRUD */
|
|
277
|
+
readonly records: RecordClient;
|
|
278
|
+
/** RESTlet caller */
|
|
279
|
+
readonly restlets: RestletClient;
|
|
280
|
+
private readonly transport;
|
|
281
|
+
constructor(config: NetSuiteConfig);
|
|
282
|
+
/** Add middleware to all requests. Returns `this` for chaining. */
|
|
283
|
+
use(middleware: Middleware): this;
|
|
284
|
+
/** Make a raw HTTP request (escape hatch for custom endpoints). */
|
|
285
|
+
request<T = unknown>(url: string, options?: RequestOptions): Promise<NetSuiteResponse<T>>;
|
|
286
|
+
/** Convenience: GET request */
|
|
287
|
+
get<T = unknown>(url: string, options?: Omit<RequestOptions, 'method'>): Promise<NetSuiteResponse<T>>;
|
|
288
|
+
/** Convenience: POST request */
|
|
289
|
+
post<T = unknown>(url: string, body?: unknown, options?: Omit<RequestOptions, 'method' | 'body'>): Promise<NetSuiteResponse<T>>;
|
|
290
|
+
/** Convenience: PUT request */
|
|
291
|
+
put<T = unknown>(url: string, body?: unknown, options?: Omit<RequestOptions, 'method' | 'body'>): Promise<NetSuiteResponse<T>>;
|
|
292
|
+
/** Convenience: PATCH request */
|
|
293
|
+
patch<T = unknown>(url: string, body?: unknown, options?: Omit<RequestOptions, 'method' | 'body'>): Promise<NetSuiteResponse<T>>;
|
|
294
|
+
/** Convenience: DELETE request */
|
|
295
|
+
delete<T = unknown>(url: string, options?: Omit<RequestOptions, 'method'>): Promise<NetSuiteResponse<T>>;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Fluent builder for constructing SuiteQL queries with basic value escaping.
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts
|
|
303
|
+
* import { suiteql } from 'netsuite-sdk';
|
|
304
|
+
*
|
|
305
|
+
* const sql = suiteql()
|
|
306
|
+
* .select('c.id', 'c.companyname', 'c.email')
|
|
307
|
+
* .from('customer', 'c')
|
|
308
|
+
* .leftJoin('transaction t', 'c.id = t.entity')
|
|
309
|
+
* .whereEquals('c.isinactive', 'F')
|
|
310
|
+
* .whereNotNull('c.email')
|
|
311
|
+
* .groupBy('c.id', 'c.companyname', 'c.email')
|
|
312
|
+
* .orderBy('c.companyname', 'ASC')
|
|
313
|
+
* .build();
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
declare class SuiteQLBuilder {
|
|
317
|
+
private _select;
|
|
318
|
+
private _from;
|
|
319
|
+
private _joins;
|
|
320
|
+
private _where;
|
|
321
|
+
private _groupBy;
|
|
322
|
+
private _orderBy;
|
|
323
|
+
private _having;
|
|
324
|
+
/** Add columns to SELECT clause */
|
|
325
|
+
select(...columns: string[]): this;
|
|
326
|
+
/** Set the FROM table, with optional alias */
|
|
327
|
+
from(table: string, alias?: string): this;
|
|
328
|
+
/** Add a JOIN clause */
|
|
329
|
+
join(table: string, condition: string, type?: 'INNER' | 'LEFT' | 'RIGHT'): this;
|
|
330
|
+
/** Add a LEFT JOIN clause */
|
|
331
|
+
leftJoin(table: string, condition: string): this;
|
|
332
|
+
/** Add a RIGHT JOIN clause */
|
|
333
|
+
rightJoin(table: string, condition: string): this;
|
|
334
|
+
/** Add a raw WHERE condition */
|
|
335
|
+
where(condition: string): this;
|
|
336
|
+
/** Add a WHERE column = value condition. Values are escaped. */
|
|
337
|
+
whereEquals(column: string, value: string | number | boolean): this;
|
|
338
|
+
/** Add a WHERE column != value condition. Values are escaped. */
|
|
339
|
+
whereNotEquals(column: string, value: string | number | boolean): this;
|
|
340
|
+
/** Add a WHERE column IN (...) condition. Values are escaped. */
|
|
341
|
+
whereIn(column: string, values: (string | number)[]): this;
|
|
342
|
+
/** Add a WHERE column IS NULL condition */
|
|
343
|
+
whereNull(column: string): this;
|
|
344
|
+
/** Add a WHERE column IS NOT NULL condition */
|
|
345
|
+
whereNotNull(column: string): this;
|
|
346
|
+
/** Add a WHERE column BETWEEN start AND end condition. Values are escaped. */
|
|
347
|
+
whereBetween(column: string, start: string | number, end: string | number): this;
|
|
348
|
+
/** Add a WHERE column LIKE pattern condition. Value is escaped. */
|
|
349
|
+
whereLike(column: string, pattern: string): this;
|
|
350
|
+
/** Add columns to GROUP BY clause */
|
|
351
|
+
groupBy(...columns: string[]): this;
|
|
352
|
+
/** Add a HAVING condition (used with GROUP BY) */
|
|
353
|
+
having(condition: string): this;
|
|
354
|
+
/** Add a column to ORDER BY clause */
|
|
355
|
+
orderBy(column: string, direction?: 'ASC' | 'DESC'): this;
|
|
356
|
+
/** Build the SQL string. Throws if SELECT or FROM is missing. */
|
|
357
|
+
build(): string;
|
|
358
|
+
/** Alias for build() */
|
|
359
|
+
toString(): string;
|
|
360
|
+
}
|
|
361
|
+
/** Factory function for creating a new SuiteQL query builder */
|
|
362
|
+
declare function suiteql(): SuiteQLBuilder;
|
|
363
|
+
|
|
364
|
+
interface NetSuiteErrorDetail {
|
|
365
|
+
type?: string;
|
|
366
|
+
title?: string;
|
|
367
|
+
status?: number;
|
|
368
|
+
detail?: string;
|
|
369
|
+
'o:errorCode'?: string;
|
|
370
|
+
'o:errorDetails'?: Array<{
|
|
371
|
+
detail?: string;
|
|
372
|
+
'o:errorCode'?: string;
|
|
373
|
+
'o:errorPath'?: string;
|
|
374
|
+
}>;
|
|
375
|
+
}
|
|
376
|
+
declare class NetSuiteError extends Error {
|
|
377
|
+
readonly status: number;
|
|
378
|
+
readonly code: string;
|
|
379
|
+
readonly details?: NetSuiteErrorDetail;
|
|
380
|
+
readonly requestUrl?: string;
|
|
381
|
+
readonly requestMethod?: HttpMethod;
|
|
382
|
+
constructor(message: string, status: number, code: string, details?: NetSuiteErrorDetail, requestUrl?: string, requestMethod?: HttpMethod);
|
|
383
|
+
/** Whether this is a retryable error (5xx, timeout, network) */
|
|
384
|
+
get isRetryable(): boolean;
|
|
385
|
+
/** Whether this is an auth error (401, 403) */
|
|
386
|
+
get isAuthError(): boolean;
|
|
387
|
+
static isNetSuiteError(error: unknown): error is NetSuiteError;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Simple in-memory TTL-based cache for API responses.
|
|
392
|
+
*/
|
|
393
|
+
declare class ResponseCache {
|
|
394
|
+
private cache;
|
|
395
|
+
/** Get a cached value, or null if not found or expired. */
|
|
396
|
+
get<T>(key: string): T | null;
|
|
397
|
+
/** Set a cached value with a TTL in seconds. */
|
|
398
|
+
set(key: string, data: unknown, ttlSeconds: number): void;
|
|
399
|
+
/** Delete a specific cache entry. */
|
|
400
|
+
delete(key: string): boolean;
|
|
401
|
+
/** Clear all cached entries. */
|
|
402
|
+
clear(): void;
|
|
403
|
+
/** Get the number of entries (including expired). */
|
|
404
|
+
get size(): number;
|
|
405
|
+
}
|
|
406
|
+
/** Create a cache key from request parameters. */
|
|
407
|
+
declare function createCacheKey(url: string, method: string, params?: unknown): string;
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Sliding-window rate limiter.
|
|
411
|
+
* Tracks requests within a time window and prevents exceeding the limit.
|
|
412
|
+
*/
|
|
413
|
+
declare class RateLimiter {
|
|
414
|
+
private timestamps;
|
|
415
|
+
private maxRequests;
|
|
416
|
+
private windowMs;
|
|
417
|
+
constructor(maxRequests?: number, windowMs?: number);
|
|
418
|
+
/** Check if a request can be made without exceeding the limit. */
|
|
419
|
+
canMakeRequest(): boolean;
|
|
420
|
+
/** Record that a request was made. */
|
|
421
|
+
recordRequest(): void;
|
|
422
|
+
/** Get the number of remaining requests in the current window. */
|
|
423
|
+
getRemainingRequests(): number;
|
|
424
|
+
/** Get ms until the next request slot opens. Returns 0 if a slot is available. */
|
|
425
|
+
getTimeUntilNextSlot(): number;
|
|
426
|
+
private pruneExpired;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/** Validate a NetSuiteConfig and return an array of error messages (empty = valid). */
|
|
430
|
+
declare function validateConfig(config: unknown): string[];
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Format a Date as a NetSuite date string (YYYY-MM-DD).
|
|
434
|
+
*/
|
|
435
|
+
declare function formatNetSuiteDate(date: Date): string;
|
|
436
|
+
/**
|
|
437
|
+
* Parse a NetSuite date string (YYYY-MM-DD or MM/DD/YYYY) into a Date.
|
|
438
|
+
*/
|
|
439
|
+
declare function parseNetSuiteDate(dateString: string): Date;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Parse a NetSuite error response body into a structured format.
|
|
443
|
+
*/
|
|
444
|
+
declare function parseNetSuiteError(error: unknown): {
|
|
445
|
+
message: string;
|
|
446
|
+
code?: string;
|
|
447
|
+
details?: NetSuiteErrorDetail;
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Normalize a NetSuite account ID for use in API URLs.
|
|
452
|
+
* Sandbox accounts use underscore format (e.g., "1234567_SB1")
|
|
453
|
+
* but URLs require hyphens (e.g., "1234567-sb1").
|
|
454
|
+
*/
|
|
455
|
+
declare function normalizeAccountId(accountId: string): string;
|
|
456
|
+
|
|
457
|
+
export { type HttpMethod, type Logger, type Middleware, NetSuiteClient, type NetSuiteConfig, NetSuiteError, type NetSuiteErrorDetail, type NetSuiteResponse, type OAuthConfig, RateLimiter, type RecordGetOptions, type RecordListOptions, type RecordListResponse, type RecordType, type RequestContext, type RequestOptions, ResponseCache, type ResponseContext, type RestletParams, SuiteQLBuilder, type SuiteQLOptions, type SuiteQLRawResponse, type SuiteQLResult, createCacheKey, formatNetSuiteDate, normalizeAccountId, parseNetSuiteDate, parseNetSuiteError, suiteql, validateConfig };
|