netsuite-sdk 0.1.2 → 0.1.31

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/dist/index.mjs CHANGED
@@ -1,819 +1,2067 @@
1
- import axios from 'axios';
2
- import http from 'http';
3
- import https from 'https';
4
- import OAuth from 'oauth-1.0a';
5
- import { createHmac } from 'crypto';
1
+ import { randomBytes, createHmac } from 'crypto';
6
2
 
7
- // src/transport/http-transport.ts
8
- function createOAuthSigner(config) {
9
- const oauth = new OAuth({
10
- consumer: { key: config.consumerKey, secret: config.consumerSecret },
11
- signature_method: "HMAC-SHA256",
12
- hash_function: (baseString, key) => createHmac("sha256", key).update(baseString).digest("base64"),
13
- realm: config.realm
14
- });
15
- const token = { key: config.tokenKey, secret: config.tokenSecret };
16
- return (url, method) => {
17
- const requestData = { url, method };
18
- const authorization = oauth.authorize(requestData, token);
19
- return oauth.toHeader(authorization);
20
- };
21
- }
22
-
23
- // src/types/errors.ts
24
- var NetSuiteError = class _NetSuiteError extends Error {
25
- status;
26
- code;
27
- details;
28
- requestUrl;
29
- requestMethod;
30
- constructor(message, status, code, details, requestUrl, requestMethod) {
31
- super(message);
32
- this.name = "NetSuiteError";
33
- this.status = status;
34
- this.code = code;
35
- this.details = details;
36
- this.requestUrl = requestUrl;
37
- this.requestMethod = requestMethod;
38
- if (Error.captureStackTrace) {
39
- Error.captureStackTrace(this, _NetSuiteError);
40
- }
41
- }
42
- /** Whether this is a retryable error (5xx, timeout, network) */
43
- get isRetryable() {
44
- return this.status >= 500 || this.code === "TIMEOUT" || this.code === "NETWORK_ERROR";
45
- }
46
- /** Whether this is an auth error (401, 403) */
47
- get isAuthError() {
48
- return this.status === 401 || this.status === 403;
49
- }
50
- static isNetSuiteError(error) {
51
- return error instanceof _NetSuiteError;
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
15
+ var __commonJS = (cb, mod) => function __require2() {
16
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
52
23
  }
24
+ return to;
53
25
  };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
27
+ // If the importer is in node compatibility mode or this is not an ESM
28
+ // file that has been converted to a CommonJS file using a Babel-
29
+ // compatible transform (i.e. "__esModule" has not been set), then set
30
+ // "default" to the CommonJS "module.exports" for node compatibility.
31
+ !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
+ mod
33
+ ));
54
34
 
55
- // src/transport/retry.ts
56
- var DEFAULT_RETRY_CONFIG = {
57
- maxRetries: 3,
58
- initialDelay: 1e3,
59
- maxDelay: 3e4,
60
- backoffFactor: 2,
61
- shouldRetry: (error) => {
62
- if (error instanceof NetSuiteError) {
63
- return error.isRetryable;
35
+ // src/transport/oauth.js
36
+ var require_oauth = __commonJS({
37
+ "src/transport/oauth.js"(exports$1) {
38
+ Object.defineProperty(exports$1, "__esModule", { value: true });
39
+ exports$1.createOAuthSigner = createOAuthSigner;
40
+ var oauth_1_0a_1 = __require("oauth-1.0a");
41
+ var node_crypto_1 = __require("crypto");
42
+ function createOAuthSigner(config) {
43
+ var oauth = new oauth_1_0a_1.default({
44
+ consumer: { key: config.consumerKey, secret: config.consumerSecret },
45
+ signature_method: "HMAC-SHA256",
46
+ hash_function: function(baseString, key) {
47
+ return (0, node_crypto_1.createHmac)("sha256", key).update(baseString).digest("base64");
48
+ },
49
+ realm: config.realm
50
+ });
51
+ var token = { key: config.tokenKey, secret: config.tokenSecret };
52
+ return function(url, method) {
53
+ var requestData = { url, method };
54
+ var authorization = oauth.authorize(requestData, token);
55
+ return oauth.toHeader(authorization);
56
+ };
64
57
  }
65
- return true;
66
58
  }
67
- };
68
- async function withRetry(fn, config = {}) {
69
- const opts = { ...DEFAULT_RETRY_CONFIG, ...config };
70
- for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
71
- try {
72
- return await fn();
73
- } catch (error) {
74
- const isLastAttempt = attempt === opts.maxRetries;
75
- if (isLastAttempt || !opts.shouldRetry(error, attempt)) {
76
- throw error;
77
- }
78
- opts.onRetry?.(error, attempt + 1);
79
- const delay = Math.min(
80
- opts.initialDelay * Math.pow(opts.backoffFactor, attempt),
81
- opts.maxDelay
82
- );
83
- const jitter = delay * 0.25 * (Math.random() * 2 - 1);
84
- await new Promise((resolve) => setTimeout(resolve, delay + jitter));
59
+ });
60
+
61
+ // src/types/errors.js
62
+ var require_errors = __commonJS({
63
+ "src/types/errors.js"(exports$1) {
64
+ var __extends = exports$1 && exports$1.__extends || /* @__PURE__ */ (function() {
65
+ var extendStatics = function(d, b) {
66
+ extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
67
+ d2.__proto__ = b2;
68
+ } || function(d2, b2) {
69
+ for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p];
70
+ };
71
+ return extendStatics(d, b);
72
+ };
73
+ return function(d, b) {
74
+ if (typeof b !== "function" && b !== null)
75
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
76
+ extendStatics(d, b);
77
+ function __() {
78
+ this.constructor = d;
79
+ }
80
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
81
+ };
82
+ })();
83
+ Object.defineProperty(exports$1, "__esModule", { value: true });
84
+ exports$1.NetSuiteError = void 0;
85
+ var NetSuiteError2 = (
86
+ /** @class */
87
+ (function(_super) {
88
+ __extends(NetSuiteError3, _super);
89
+ function NetSuiteError3(message, status, code, details, requestUrl, requestMethod) {
90
+ var _this = _super.call(this, message) || this;
91
+ _this.name = "NetSuiteError";
92
+ _this.status = status;
93
+ _this.code = code;
94
+ _this.details = details;
95
+ _this.requestUrl = requestUrl;
96
+ _this.requestMethod = requestMethod;
97
+ if (Error.captureStackTrace) {
98
+ Error.captureStackTrace(_this, NetSuiteError3);
99
+ }
100
+ return _this;
101
+ }
102
+ Object.defineProperty(NetSuiteError3.prototype, "isRetryable", {
103
+ /** Whether this is a retryable error (5xx, timeout, network) */
104
+ get: function() {
105
+ return this.status >= 500 || this.code === "TIMEOUT" || this.code === "NETWORK_ERROR";
106
+ },
107
+ enumerable: false,
108
+ configurable: true
109
+ });
110
+ Object.defineProperty(NetSuiteError3.prototype, "isAuthError", {
111
+ /** Whether this is an auth error (401, 403) */
112
+ get: function() {
113
+ return this.status === 401 || this.status === 403;
114
+ },
115
+ enumerable: false,
116
+ configurable: true
117
+ });
118
+ NetSuiteError3.isNetSuiteError = function(error) {
119
+ return error instanceof NetSuiteError3;
120
+ };
121
+ return NetSuiteError3;
122
+ })(Error)
123
+ );
124
+ exports$1.NetSuiteError = NetSuiteError2;
125
+ }
126
+ });
127
+
128
+ // src/transport/retry.js
129
+ var require_retry = __commonJS({
130
+ "src/transport/retry.js"(exports$1) {
131
+ var __assign = exports$1 && exports$1.__assign || function() {
132
+ __assign = Object.assign || function(t) {
133
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
134
+ s = arguments[i];
135
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
136
+ t[p] = s[p];
137
+ }
138
+ return t;
139
+ };
140
+ return __assign.apply(this, arguments);
141
+ };
142
+ var __awaiter = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P, generator) {
143
+ function adopt(value) {
144
+ return value instanceof P ? value : new P(function(resolve) {
145
+ resolve(value);
146
+ });
147
+ }
148
+ return new (P || (P = Promise))(function(resolve, reject) {
149
+ function fulfilled(value) {
150
+ try {
151
+ step(generator.next(value));
152
+ } catch (e) {
153
+ reject(e);
154
+ }
155
+ }
156
+ function rejected(value) {
157
+ try {
158
+ step(generator["throw"](value));
159
+ } catch (e) {
160
+ reject(e);
161
+ }
162
+ }
163
+ function step(result) {
164
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
165
+ }
166
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
167
+ });
168
+ };
169
+ var __generator = exports$1 && exports$1.__generator || function(thisArg, body) {
170
+ var _ = { label: 0, sent: function() {
171
+ if (t[0] & 1) throw t[1];
172
+ return t[1];
173
+ }, trys: [], ops: [] }, f, y, t, g;
174
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
175
+ return this;
176
+ }), g;
177
+ function verb(n) {
178
+ return function(v) {
179
+ return step([n, v]);
180
+ };
181
+ }
182
+ function step(op) {
183
+ if (f) throw new TypeError("Generator is already executing.");
184
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
185
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
186
+ if (y = 0, t) op = [op[0] & 2, t.value];
187
+ switch (op[0]) {
188
+ case 0:
189
+ case 1:
190
+ t = op;
191
+ break;
192
+ case 4:
193
+ _.label++;
194
+ return { value: op[1], done: false };
195
+ case 5:
196
+ _.label++;
197
+ y = op[1];
198
+ op = [0];
199
+ continue;
200
+ case 7:
201
+ op = _.ops.pop();
202
+ _.trys.pop();
203
+ continue;
204
+ default:
205
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
206
+ _ = 0;
207
+ continue;
208
+ }
209
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
210
+ _.label = op[1];
211
+ break;
212
+ }
213
+ if (op[0] === 6 && _.label < t[1]) {
214
+ _.label = t[1];
215
+ t = op;
216
+ break;
217
+ }
218
+ if (t && _.label < t[2]) {
219
+ _.label = t[2];
220
+ _.ops.push(op);
221
+ break;
222
+ }
223
+ if (t[2]) _.ops.pop();
224
+ _.trys.pop();
225
+ continue;
226
+ }
227
+ op = body.call(thisArg, _);
228
+ } catch (e) {
229
+ op = [6, e];
230
+ y = 0;
231
+ } finally {
232
+ f = t = 0;
233
+ }
234
+ if (op[0] & 5) throw op[1];
235
+ return { value: op[0] ? op[1] : void 0, done: true };
236
+ }
237
+ };
238
+ Object.defineProperty(exports$1, "__esModule", { value: true });
239
+ exports$1.withRetry = withRetry;
240
+ var errors_js_1 = require_errors();
241
+ var DEFAULT_RETRY_CONFIG = {
242
+ maxRetries: 3,
243
+ initialDelay: 1e3,
244
+ maxDelay: 3e4,
245
+ backoffFactor: 2,
246
+ shouldRetry: function(error) {
247
+ if (error instanceof errors_js_1.NetSuiteError) {
248
+ return error.isRetryable;
249
+ }
250
+ return true;
251
+ }
252
+ };
253
+ function withRetry(fn_1) {
254
+ return __awaiter(this, arguments, void 0, function(fn, config) {
255
+ var opts, _loop_1, attempt, state_1;
256
+ var _a;
257
+ if (config === void 0) {
258
+ config = {};
259
+ }
260
+ return __generator(this, function(_b) {
261
+ switch (_b.label) {
262
+ case 0:
263
+ opts = __assign(__assign({}, DEFAULT_RETRY_CONFIG), config);
264
+ _loop_1 = function(attempt2) {
265
+ var _c, error_1, isLastAttempt, delay_1, jitter_1;
266
+ return __generator(this, function(_d) {
267
+ switch (_d.label) {
268
+ case 0:
269
+ _d.trys.push([0, 2, , 4]);
270
+ _c = {};
271
+ return [4, fn()];
272
+ case 1:
273
+ return [2, (_c.value = _d.sent(), _c)];
274
+ case 2:
275
+ error_1 = _d.sent();
276
+ isLastAttempt = attempt2 === opts.maxRetries;
277
+ if (isLastAttempt || !opts.shouldRetry(error_1, attempt2)) {
278
+ throw error_1;
279
+ }
280
+ (_a = opts.onRetry) === null || _a === void 0 ? void 0 : _a.call(opts, error_1, attempt2 + 1);
281
+ delay_1 = Math.min(opts.initialDelay * Math.pow(opts.backoffFactor, attempt2), opts.maxDelay);
282
+ jitter_1 = delay_1 * 0.25 * (Math.random() * 2 - 1);
283
+ return [4, new Promise(function(resolve) {
284
+ return setTimeout(resolve, delay_1 + jitter_1);
285
+ })];
286
+ case 3:
287
+ _d.sent();
288
+ return [3, 4];
289
+ case 4:
290
+ return [
291
+ 2
292
+ /*return*/
293
+ ];
294
+ }
295
+ });
296
+ };
297
+ attempt = 0;
298
+ _b.label = 1;
299
+ case 1:
300
+ if (!(attempt <= opts.maxRetries)) return [3, 4];
301
+ return [5, _loop_1(attempt)];
302
+ case 2:
303
+ state_1 = _b.sent();
304
+ if (typeof state_1 === "object")
305
+ return [2, state_1.value];
306
+ _b.label = 3;
307
+ case 3:
308
+ attempt++;
309
+ return [3, 1];
310
+ case 4:
311
+ throw new Error("Retry loop exited unexpectedly");
312
+ }
313
+ });
314
+ });
85
315
  }
86
316
  }
87
- throw new Error("Retry loop exited unexpectedly");
88
- }
317
+ });
89
318
 
90
- // src/transport/middleware-chain.ts
91
- function executeMiddlewareChain(middlewares, context, finalHandler) {
92
- let index = 0;
93
- function next() {
94
- if (index >= middlewares.length) {
95
- return finalHandler();
319
+ // src/transport/middleware-chain.js
320
+ var require_middleware_chain = __commonJS({
321
+ "src/transport/middleware-chain.js"(exports$1) {
322
+ Object.defineProperty(exports$1, "__esModule", { value: true });
323
+ exports$1.executeMiddlewareChain = executeMiddlewareChain;
324
+ function executeMiddlewareChain(middlewares, context, finalHandler) {
325
+ var index = 0;
326
+ function next() {
327
+ if (index >= middlewares.length) {
328
+ return finalHandler();
329
+ }
330
+ var middleware = middlewares[index++];
331
+ return middleware(context, next);
332
+ }
333
+ return next();
96
334
  }
97
- const middleware = middlewares[index++];
98
- return middleware(context, next);
99
335
  }
100
- return next();
101
- }
336
+ });
102
337
 
103
- // src/types/http.ts
104
- function extractHeaders(response) {
105
- const headers = {};
106
- if (response.headers) {
107
- for (const [key, value] of Object.entries(response.headers)) {
108
- if (typeof value === "string") {
109
- headers[key] = value;
338
+ // src/types/http.js
339
+ var require_http = __commonJS({
340
+ "src/types/http.js"(exports$1) {
341
+ Object.defineProperty(exports$1, "__esModule", { value: true });
342
+ exports$1.extractHeaders = extractHeaders;
343
+ function extractHeaders(response) {
344
+ var headers = {};
345
+ if (response.headers) {
346
+ for (var _i = 0, _a = Object.entries(response.headers); _i < _a.length; _i++) {
347
+ var _b = _a[_i], key = _b[0], value = _b[1];
348
+ if (typeof value === "string") {
349
+ headers[key] = value;
350
+ }
351
+ }
110
352
  }
353
+ return headers;
111
354
  }
112
355
  }
113
- return headers;
114
- }
356
+ });
115
357
 
116
- // src/transport/http-transport.ts
117
- var HttpTransport = class {
118
- sign;
119
- axiosInstance;
120
- middlewares = [];
121
- config;
122
- constructor(config) {
123
- this.config = {
124
- timeout: config.timeout ?? 3e4,
125
- maxRetries: config.maxRetries ?? 3,
126
- retryDelay: config.retryDelay ?? 1e3,
127
- defaultHeaders: config.defaultHeaders ?? {},
128
- logger: config.logger
358
+ // src/transport/http-transport.js
359
+ var require_http_transport = __commonJS({
360
+ "src/transport/http-transport.js"(exports$1) {
361
+ var __assign = exports$1 && exports$1.__assign || function() {
362
+ __assign = Object.assign || function(t) {
363
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
364
+ s = arguments[i];
365
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
366
+ t[p] = s[p];
367
+ }
368
+ return t;
369
+ };
370
+ return __assign.apply(this, arguments);
129
371
  };
130
- this.sign = createOAuthSigner(config.auth);
131
- this.axiosInstance = axios.create({
132
- timeout: this.config.timeout,
133
- headers: {
134
- "Content-Type": "application/json",
135
- "Accept-Encoding": "gzip, deflate"
136
- },
137
- httpAgent: new http.Agent({ keepAlive: true }),
138
- httpsAgent: new https.Agent({ keepAlive: true }),
139
- maxRedirects: 5,
140
- // Let us handle all status codes in our error handling
141
- validateStatus: () => true
142
- });
143
- }
144
- /** Add a middleware to the chain. Returns `this` for chaining. */
145
- use(middleware) {
146
- this.middlewares.push(middleware);
147
- return this;
148
- }
149
- /** Execute an HTTP request with OAuth signing, retry, and middleware. */
150
- async request(url, options = {}) {
151
- const method = options.method ?? "GET";
152
- const timeout = options.timeout ?? this.config.timeout;
153
- const maxRetries = options.maxRetries ?? this.config.maxRetries;
154
- return withRetry(
155
- async () => {
156
- const authHeaders = this.sign(url, method);
157
- const headers = {
158
- "Content-Type": "application/json",
159
- ...this.config.defaultHeaders,
160
- ...authHeaders,
161
- ...options.headers
162
- };
163
- const context = {
164
- url,
165
- method,
166
- headers,
167
- body: options.body,
168
- metadata: {}
169
- };
170
- const response = await executeMiddlewareChain(
171
- this.middlewares,
172
- context,
173
- () => this.executeRequest(context, timeout)
174
- );
175
- return {
176
- data: response.body,
177
- status: response.status,
178
- headers: response.headers,
179
- duration: response.duration
372
+ var __awaiter = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P, generator) {
373
+ function adopt(value) {
374
+ return value instanceof P ? value : new P(function(resolve) {
375
+ resolve(value);
376
+ });
377
+ }
378
+ return new (P || (P = Promise))(function(resolve, reject) {
379
+ function fulfilled(value) {
380
+ try {
381
+ step(generator.next(value));
382
+ } catch (e) {
383
+ reject(e);
384
+ }
385
+ }
386
+ function rejected(value) {
387
+ try {
388
+ step(generator["throw"](value));
389
+ } catch (e) {
390
+ reject(e);
391
+ }
392
+ }
393
+ function step(result) {
394
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
395
+ }
396
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
397
+ });
398
+ };
399
+ var __generator = exports$1 && exports$1.__generator || function(thisArg, body) {
400
+ var _ = { label: 0, sent: function() {
401
+ if (t[0] & 1) throw t[1];
402
+ return t[1];
403
+ }, trys: [], ops: [] }, f, y, t, g;
404
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
405
+ return this;
406
+ }), g;
407
+ function verb(n) {
408
+ return function(v) {
409
+ return step([n, v]);
180
410
  };
181
- },
182
- {
183
- maxRetries,
184
- initialDelay: this.config.retryDelay,
185
- shouldRetry: (error) => {
186
- if (error instanceof NetSuiteError) {
187
- return error.isRetryable;
188
- }
189
- return true;
190
- },
191
- onRetry: (error, attempt) => {
192
- this.config.logger?.warn(`Retry attempt ${attempt}/${maxRetries}`, {
193
- url,
194
- method,
195
- error
196
- });
411
+ }
412
+ function step(op) {
413
+ if (f) throw new TypeError("Generator is already executing.");
414
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
415
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
416
+ if (y = 0, t) op = [op[0] & 2, t.value];
417
+ switch (op[0]) {
418
+ case 0:
419
+ case 1:
420
+ t = op;
421
+ break;
422
+ case 4:
423
+ _.label++;
424
+ return { value: op[1], done: false };
425
+ case 5:
426
+ _.label++;
427
+ y = op[1];
428
+ op = [0];
429
+ continue;
430
+ case 7:
431
+ op = _.ops.pop();
432
+ _.trys.pop();
433
+ continue;
434
+ default:
435
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
436
+ _ = 0;
437
+ continue;
438
+ }
439
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
440
+ _.label = op[1];
441
+ break;
442
+ }
443
+ if (op[0] === 6 && _.label < t[1]) {
444
+ _.label = t[1];
445
+ t = op;
446
+ break;
447
+ }
448
+ if (t && _.label < t[2]) {
449
+ _.label = t[2];
450
+ _.ops.push(op);
451
+ break;
452
+ }
453
+ if (t[2]) _.ops.pop();
454
+ _.trys.pop();
455
+ continue;
456
+ }
457
+ op = body.call(thisArg, _);
458
+ } catch (e) {
459
+ op = [6, e];
460
+ y = 0;
461
+ } finally {
462
+ f = t = 0;
197
463
  }
464
+ if (op[0] & 5) throw op[1];
465
+ return { value: op[0] ? op[1] : void 0, done: true };
198
466
  }
467
+ };
468
+ Object.defineProperty(exports$1, "__esModule", { value: true });
469
+ exports$1.HttpTransport = void 0;
470
+ var axios_1 = __require("axios");
471
+ var node_http_1 = __require("http");
472
+ var node_https_1 = __require("https");
473
+ var oauth_js_1 = require_oauth();
474
+ var retry_js_1 = require_retry();
475
+ var middleware_chain_js_1 = require_middleware_chain();
476
+ var errors_js_1 = require_errors();
477
+ var http_js_1 = require_http();
478
+ var HttpTransport = (
479
+ /** @class */
480
+ (function() {
481
+ function HttpTransport2(config) {
482
+ var _a, _b, _c, _d;
483
+ this.middlewares = [];
484
+ this.config = {
485
+ timeout: (_a = config.timeout) !== null && _a !== void 0 ? _a : 3e4,
486
+ maxRetries: (_b = config.maxRetries) !== null && _b !== void 0 ? _b : 3,
487
+ retryDelay: (_c = config.retryDelay) !== null && _c !== void 0 ? _c : 1e3,
488
+ defaultHeaders: (_d = config.defaultHeaders) !== null && _d !== void 0 ? _d : {},
489
+ logger: config.logger
490
+ };
491
+ this.sign = (0, oauth_js_1.createOAuthSigner)(config.auth);
492
+ this.axiosInstance = axios_1.default.create({
493
+ timeout: this.config.timeout,
494
+ headers: {
495
+ "Content-Type": "application/json",
496
+ "Accept-Encoding": "gzip, deflate"
497
+ },
498
+ httpAgent: new node_http_1.default.Agent({ keepAlive: true }),
499
+ httpsAgent: new node_https_1.default.Agent({ keepAlive: true }),
500
+ maxRedirects: 5,
501
+ // Let us handle all status codes in our error handling
502
+ validateStatus: function() {
503
+ return true;
504
+ }
505
+ });
506
+ }
507
+ HttpTransport2.prototype.use = function(middleware) {
508
+ this.middlewares.push(middleware);
509
+ return this;
510
+ };
511
+ HttpTransport2.prototype.request = function(url_1) {
512
+ return __awaiter(this, arguments, void 0, function(url, options) {
513
+ var method, timeout, maxRetries;
514
+ var _this = this;
515
+ var _a, _b, _c;
516
+ if (options === void 0) {
517
+ options = {};
518
+ }
519
+ return __generator(this, function(_d) {
520
+ method = (_a = options.method) !== null && _a !== void 0 ? _a : "GET";
521
+ timeout = (_b = options.timeout) !== null && _b !== void 0 ? _b : this.config.timeout;
522
+ maxRetries = (_c = options.maxRetries) !== null && _c !== void 0 ? _c : this.config.maxRetries;
523
+ return [2, (0, retry_js_1.withRetry)(function() {
524
+ return __awaiter(_this, void 0, void 0, function() {
525
+ var authHeaders, headers, context, response;
526
+ var _this2 = this;
527
+ return __generator(this, function(_a2) {
528
+ switch (_a2.label) {
529
+ case 0:
530
+ authHeaders = this.sign(url, method);
531
+ headers = __assign(__assign(__assign({ "Content-Type": "application/json" }, this.config.defaultHeaders), authHeaders), options.headers);
532
+ context = {
533
+ url,
534
+ method,
535
+ headers,
536
+ body: options.body,
537
+ metadata: {}
538
+ };
539
+ return [4, (0, middleware_chain_js_1.executeMiddlewareChain)(this.middlewares, context, function() {
540
+ return _this2.executeRequest(context, timeout);
541
+ })];
542
+ case 1:
543
+ response = _a2.sent();
544
+ return [2, {
545
+ data: response.body,
546
+ status: response.status,
547
+ headers: response.headers,
548
+ duration: response.duration
549
+ }];
550
+ }
551
+ });
552
+ });
553
+ }, {
554
+ maxRetries,
555
+ initialDelay: this.config.retryDelay,
556
+ shouldRetry: function(error) {
557
+ if (error instanceof errors_js_1.NetSuiteError) {
558
+ return error.isRetryable;
559
+ }
560
+ return true;
561
+ },
562
+ onRetry: function(error, attempt) {
563
+ var _a2;
564
+ (_a2 = _this.config.logger) === null || _a2 === void 0 ? void 0 : _a2.warn("Retry attempt ".concat(attempt, "/").concat(maxRetries), {
565
+ url,
566
+ method,
567
+ error
568
+ });
569
+ }
570
+ })];
571
+ });
572
+ });
573
+ };
574
+ HttpTransport2.prototype.executeRequest = function(context, timeout) {
575
+ return __awaiter(this, void 0, void 0, function() {
576
+ var startTime, response, duration, errorBody, message, code, error_1, duration, axiosError;
577
+ var _a, _b, _c, _d, _e, _f, _g, _h;
578
+ return __generator(this, function(_j) {
579
+ switch (_j.label) {
580
+ case 0:
581
+ startTime = performance.now();
582
+ _j.label = 1;
583
+ case 1:
584
+ _j.trys.push([1, 3, , 4]);
585
+ (_a = this.config.logger) === null || _a === void 0 ? void 0 : _a.debug("".concat(context.method, " ").concat(context.url), {
586
+ headers: Object.keys(context.headers)
587
+ });
588
+ return [4, this.axiosInstance.request({
589
+ url: context.url,
590
+ method: context.method,
591
+ headers: context.headers,
592
+ data: context.body && ["POST", "PUT", "PATCH"].includes(context.method) ? context.body : void 0,
593
+ timeout
594
+ })];
595
+ case 2:
596
+ response = _j.sent();
597
+ duration = Math.round(performance.now() - startTime);
598
+ (_b = this.config.logger) === null || _b === void 0 ? void 0 : _b.info("".concat(context.method, " ").concat(context.url, " \u2192 ").concat(response.status), {
599
+ duration
600
+ });
601
+ if (response.status >= 400) {
602
+ errorBody = (_c = response.data) !== null && _c !== void 0 ? _c : {};
603
+ message = (_f = (_e = (_d = errorBody.detail) !== null && _d !== void 0 ? _d : errorBody.title) !== null && _e !== void 0 ? _e : errorBody.message) !== null && _f !== void 0 ? _f : "HTTP ".concat(response.status);
604
+ code = (_h = (_g = errorBody["o:errorCode"]) !== null && _g !== void 0 ? _g : errorBody.code) !== null && _h !== void 0 ? _h : "HTTP_".concat(response.status);
605
+ throw new errors_js_1.NetSuiteError(message, response.status, code, errorBody, context.url, context.method);
606
+ }
607
+ return [2, {
608
+ status: response.status,
609
+ headers: (0, http_js_1.extractHeaders)(response),
610
+ body: response.status === 204 ? void 0 : response.data,
611
+ duration
612
+ }];
613
+ case 3:
614
+ error_1 = _j.sent();
615
+ if (error_1 instanceof errors_js_1.NetSuiteError) {
616
+ throw error_1;
617
+ }
618
+ duration = Math.round(performance.now() - startTime);
619
+ axiosError = error_1;
620
+ if (axiosError.code === "ECONNABORTED" || axiosError.code === "ERR_CANCELED") {
621
+ throw new errors_js_1.NetSuiteError("Request timed out after ".concat(timeout, "ms"), 504, "TIMEOUT", void 0, context.url, context.method);
622
+ }
623
+ throw new errors_js_1.NetSuiteError(axiosError.message || "Network error", 0, "NETWORK_ERROR", void 0, context.url, context.method);
624
+ case 4:
625
+ return [
626
+ 2
627
+ /*return*/
628
+ ];
629
+ }
630
+ });
631
+ });
632
+ };
633
+ return HttpTransport2;
634
+ })()
199
635
  );
636
+ exports$1.HttpTransport = HttpTransport;
200
637
  }
201
- async executeRequest(context, timeout) {
202
- const startTime = performance.now();
203
- try {
204
- this.config.logger?.debug(`${context.method} ${context.url}`, {
205
- headers: Object.keys(context.headers)
206
- });
207
- const response = await this.axiosInstance.request({
208
- url: context.url,
209
- method: context.method,
210
- headers: context.headers,
211
- data: context.body && ["POST", "PUT", "PATCH"].includes(context.method) ? context.body : void 0,
212
- timeout
213
- });
214
- const duration = Math.round(performance.now() - startTime);
215
- this.config.logger?.info(`${context.method} ${context.url} \u2192 ${response.status}`, {
216
- duration
638
+ });
639
+
640
+ // src/suiteql/suiteql-client.js
641
+ var require_suiteql_client = __commonJS({
642
+ "src/suiteql/suiteql-client.js"(exports$1) {
643
+ var __assign = exports$1 && exports$1.__assign || function() {
644
+ __assign = Object.assign || function(t) {
645
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
646
+ s = arguments[i];
647
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
648
+ t[p] = s[p];
649
+ }
650
+ return t;
651
+ };
652
+ return __assign.apply(this, arguments);
653
+ };
654
+ var __awaiter = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P, generator) {
655
+ function adopt(value) {
656
+ return value instanceof P ? value : new P(function(resolve) {
657
+ resolve(value);
658
+ });
659
+ }
660
+ return new (P || (P = Promise))(function(resolve, reject) {
661
+ function fulfilled(value) {
662
+ try {
663
+ step(generator.next(value));
664
+ } catch (e) {
665
+ reject(e);
666
+ }
667
+ }
668
+ function rejected(value) {
669
+ try {
670
+ step(generator["throw"](value));
671
+ } catch (e) {
672
+ reject(e);
673
+ }
674
+ }
675
+ function step(result) {
676
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
677
+ }
678
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
217
679
  });
218
- if (response.status >= 400) {
219
- const errorBody = response.data ?? {};
220
- const message = errorBody.detail ?? errorBody.title ?? errorBody.message ?? `HTTP ${response.status}`;
221
- const code = errorBody["o:errorCode"] ?? errorBody.code ?? `HTTP_${response.status}`;
222
- throw new NetSuiteError(
223
- message,
224
- response.status,
225
- code,
226
- errorBody,
227
- context.url,
228
- context.method
229
- );
680
+ };
681
+ var __generator = exports$1 && exports$1.__generator || function(thisArg, body) {
682
+ var _ = { label: 0, sent: function() {
683
+ if (t[0] & 1) throw t[1];
684
+ return t[1];
685
+ }, trys: [], ops: [] }, f, y, t, g;
686
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
687
+ return this;
688
+ }), g;
689
+ function verb(n) {
690
+ return function(v) {
691
+ return step([n, v]);
692
+ };
230
693
  }
231
- return {
232
- status: response.status,
233
- headers: extractHeaders(response),
234
- body: response.status === 204 ? void 0 : response.data,
235
- duration
236
- };
237
- } catch (error) {
238
- if (error instanceof NetSuiteError) {
239
- throw error;
240
- }
241
- Math.round(performance.now() - startTime);
242
- const axiosError = error;
243
- if (axiosError.code === "ECONNABORTED" || axiosError.code === "ERR_CANCELED") {
244
- throw new NetSuiteError(
245
- `Request timed out after ${timeout}ms`,
246
- 504,
247
- "TIMEOUT",
248
- void 0,
249
- context.url,
250
- context.method
251
- );
252
- }
253
- throw new NetSuiteError(
254
- axiosError.message || "Network error",
255
- 0,
256
- "NETWORK_ERROR",
257
- void 0,
258
- context.url,
259
- context.method
260
- );
261
- }
694
+ function step(op) {
695
+ if (f) throw new TypeError("Generator is already executing.");
696
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
697
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
698
+ if (y = 0, t) op = [op[0] & 2, t.value];
699
+ switch (op[0]) {
700
+ case 0:
701
+ case 1:
702
+ t = op;
703
+ break;
704
+ case 4:
705
+ _.label++;
706
+ return { value: op[1], done: false };
707
+ case 5:
708
+ _.label++;
709
+ y = op[1];
710
+ op = [0];
711
+ continue;
712
+ case 7:
713
+ op = _.ops.pop();
714
+ _.trys.pop();
715
+ continue;
716
+ default:
717
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
718
+ _ = 0;
719
+ continue;
720
+ }
721
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
722
+ _.label = op[1];
723
+ break;
724
+ }
725
+ if (op[0] === 6 && _.label < t[1]) {
726
+ _.label = t[1];
727
+ t = op;
728
+ break;
729
+ }
730
+ if (t && _.label < t[2]) {
731
+ _.label = t[2];
732
+ _.ops.push(op);
733
+ break;
734
+ }
735
+ if (t[2]) _.ops.pop();
736
+ _.trys.pop();
737
+ continue;
738
+ }
739
+ op = body.call(thisArg, _);
740
+ } catch (e) {
741
+ op = [6, e];
742
+ y = 0;
743
+ } finally {
744
+ f = t = 0;
745
+ }
746
+ if (op[0] & 5) throw op[1];
747
+ return { value: op[0] ? op[1] : void 0, done: true };
748
+ }
749
+ };
750
+ var __await = exports$1 && exports$1.__await || function(v) {
751
+ return this instanceof __await ? (this.v = v, this) : new __await(v);
752
+ };
753
+ var __asyncGenerator = exports$1 && exports$1.__asyncGenerator || function(thisArg, _arguments, generator) {
754
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
755
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
756
+ return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() {
757
+ return this;
758
+ }, i;
759
+ function awaitReturn(f) {
760
+ return function(v) {
761
+ return Promise.resolve(v).then(f, reject);
762
+ };
763
+ }
764
+ function verb(n, f) {
765
+ if (g[n]) {
766
+ i[n] = function(v) {
767
+ return new Promise(function(a, b) {
768
+ q.push([n, v, a, b]) > 1 || resume(n, v);
769
+ });
770
+ };
771
+ if (f) i[n] = f(i[n]);
772
+ }
773
+ }
774
+ function resume(n, v) {
775
+ try {
776
+ step(g[n](v));
777
+ } catch (e) {
778
+ settle(q[0][3], e);
779
+ }
780
+ }
781
+ function step(r) {
782
+ r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
783
+ }
784
+ function fulfill(value) {
785
+ resume("next", value);
786
+ }
787
+ function reject(value) {
788
+ resume("throw", value);
789
+ }
790
+ function settle(f, v) {
791
+ if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
792
+ }
793
+ };
794
+ Object.defineProperty(exports$1, "__esModule", { value: true });
795
+ exports$1.SuiteQLClient = void 0;
796
+ var SuiteQLClient = (
797
+ /** @class */
798
+ (function() {
799
+ function SuiteQLClient2(transport, accountId) {
800
+ this.transport = transport;
801
+ var normalizedId = accountId.toLowerCase().replace(/_/g, "-");
802
+ this.baseUrl = "https://".concat(normalizedId, ".suitetalk.api.netsuite.com/services/rest/query/v1/suiteql");
803
+ }
804
+ SuiteQLClient2.prototype.query = function(sql_1) {
805
+ return __awaiter(this, arguments, void 0, function(sql, options) {
806
+ var _a, pageSize, _b, startOffset, _c, maxRows, timeout, allItems, currentOffset, totalResults, pagesFetched, startTime, effectiveLimit, url, response, page, hasMore;
807
+ if (options === void 0) {
808
+ options = {};
809
+ }
810
+ return __generator(this, function(_d) {
811
+ switch (_d.label) {
812
+ case 0:
813
+ _a = options.pageSize, pageSize = _a === void 0 ? 1e3 : _a, _b = options.offset, startOffset = _b === void 0 ? 0 : _b, _c = options.maxRows, maxRows = _c === void 0 ? Infinity : _c, timeout = options.timeout;
814
+ allItems = [];
815
+ currentOffset = startOffset;
816
+ totalResults = 0;
817
+ pagesFetched = 0;
818
+ startTime = performance.now();
819
+ _d.label = 1;
820
+ case 1:
821
+ effectiveLimit = Math.min(pageSize, maxRows - allItems.length);
822
+ if (effectiveLimit <= 0)
823
+ return [3, 3];
824
+ url = "".concat(this.baseUrl, "?limit=").concat(effectiveLimit, "&offset=").concat(currentOffset);
825
+ return [4, this.transport.request(url, {
826
+ method: "POST",
827
+ body: { q: sql },
828
+ headers: { Prefer: "transient" },
829
+ timeout
830
+ })];
831
+ case 2:
832
+ response = _d.sent();
833
+ page = response.data;
834
+ totalResults = page.totalResults;
835
+ pagesFetched++;
836
+ allItems.push.apply(allItems, page.items);
837
+ hasMore = page.hasMore || currentOffset + page.items.length < totalResults;
838
+ if (!hasMore || allItems.length >= maxRows || page.items.length === 0)
839
+ return [3, 3];
840
+ currentOffset += page.items.length;
841
+ return [3, 1];
842
+ case 3:
843
+ return [2, {
844
+ items: allItems,
845
+ totalResults,
846
+ pagesFetched,
847
+ hasMore: allItems.length < totalResults,
848
+ duration: Math.round(performance.now() - startTime)
849
+ }];
850
+ }
851
+ });
852
+ });
853
+ };
854
+ SuiteQLClient2.prototype.queryOne = function(sql, options) {
855
+ return __awaiter(this, void 0, void 0, function() {
856
+ var result;
857
+ var _a;
858
+ return __generator(this, function(_b) {
859
+ switch (_b.label) {
860
+ case 0:
861
+ return [4, this.query(sql, __assign(__assign({}, options), { maxRows: 1 }))];
862
+ case 1:
863
+ result = _b.sent();
864
+ return [2, (_a = result.items[0]) !== null && _a !== void 0 ? _a : null];
865
+ }
866
+ });
867
+ });
868
+ };
869
+ SuiteQLClient2.prototype.queryPages = function(sql_1) {
870
+ return __asyncGenerator(this, arguments, function queryPages_1(sql, options) {
871
+ var _a, pageSize, _b, startOffset, _c, maxRows, timeout, currentOffset, totalYielded, effectiveLimit, url, response, page, hasMore;
872
+ if (options === void 0) {
873
+ options = {};
874
+ }
875
+ return __generator(this, function(_d) {
876
+ switch (_d.label) {
877
+ case 0:
878
+ _a = options.pageSize, pageSize = _a === void 0 ? 1e3 : _a, _b = options.offset, startOffset = _b === void 0 ? 0 : _b, _c = options.maxRows, maxRows = _c === void 0 ? Infinity : _c, timeout = options.timeout;
879
+ currentOffset = startOffset;
880
+ totalYielded = 0;
881
+ _d.label = 1;
882
+ case 1:
883
+ effectiveLimit = Math.min(pageSize, maxRows - totalYielded);
884
+ if (!(effectiveLimit <= 0)) return [3, 3];
885
+ return [4, __await(void 0)];
886
+ case 2:
887
+ return [2, _d.sent()];
888
+ case 3:
889
+ url = "".concat(this.baseUrl, "?limit=").concat(effectiveLimit, "&offset=").concat(currentOffset);
890
+ return [4, __await(this.transport.request(url, {
891
+ method: "POST",
892
+ body: { q: sql },
893
+ headers: { Prefer: "transient" },
894
+ timeout
895
+ }))];
896
+ case 4:
897
+ response = _d.sent();
898
+ page = response.data;
899
+ if (!(page.items.length === 0)) return [3, 6];
900
+ return [4, __await(void 0)];
901
+ case 5:
902
+ return [2, _d.sent()];
903
+ case 6:
904
+ return [4, __await(page.items)];
905
+ case 7:
906
+ return [4, _d.sent()];
907
+ case 8:
908
+ _d.sent();
909
+ totalYielded += page.items.length;
910
+ hasMore = page.hasMore || currentOffset + page.items.length < page.totalResults;
911
+ if (!(!hasMore || totalYielded >= maxRows)) return [3, 10];
912
+ return [4, __await(void 0)];
913
+ case 9:
914
+ return [2, _d.sent()];
915
+ case 10:
916
+ currentOffset += page.items.length;
917
+ return [3, 1];
918
+ case 11:
919
+ return [
920
+ 2
921
+ /*return*/
922
+ ];
923
+ }
924
+ });
925
+ });
926
+ };
927
+ return SuiteQLClient2;
928
+ })()
929
+ );
930
+ exports$1.SuiteQLClient = SuiteQLClient;
262
931
  }
263
- };
932
+ });
264
933
 
265
- // src/suiteql/suiteql-client.ts
266
- var SuiteQLClient = class {
267
- transport;
268
- baseUrl;
269
- constructor(transport, accountId) {
270
- this.transport = transport;
271
- const normalizedId = accountId.toLowerCase().replace(/_/g, "-");
272
- this.baseUrl = `https://${normalizedId}.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql`;
273
- }
274
- /**
275
- * Execute a SuiteQL query and return all matching rows.
276
- * Automatically paginates across multiple pages.
277
- *
278
- * @example
279
- * ```ts
280
- * const result = await client.suiteql.query<Customer>(
281
- * 'SELECT id, companyname, email FROM customer WHERE isinactive = \'F\'',
282
- * { pageSize: 500 }
283
- * );
284
- * console.log(result.items); // all rows
285
- * console.log(result.totalResults); // total count from NetSuite
286
- * ```
287
- */
288
- async query(sql, options = {}) {
289
- const {
290
- pageSize = 1e3,
291
- offset: startOffset = 0,
292
- maxRows = Infinity,
293
- timeout
294
- } = options;
295
- const allItems = [];
296
- let currentOffset = startOffset;
297
- let totalResults = 0;
298
- let pagesFetched = 0;
299
- const startTime = performance.now();
300
- while (true) {
301
- const effectiveLimit = Math.min(pageSize, maxRows - allItems.length);
302
- if (effectiveLimit <= 0) break;
303
- const url = `${this.baseUrl}?limit=${effectiveLimit}&offset=${currentOffset}`;
304
- const response = await this.transport.request(url, {
305
- method: "POST",
306
- body: { q: sql },
307
- headers: { Prefer: "transient" },
308
- timeout
934
+ // src/records/record-client.js
935
+ var require_record_client = __commonJS({
936
+ "src/records/record-client.js"(exports$1) {
937
+ var __awaiter = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P, generator) {
938
+ function adopt(value) {
939
+ return value instanceof P ? value : new P(function(resolve) {
940
+ resolve(value);
941
+ });
942
+ }
943
+ return new (P || (P = Promise))(function(resolve, reject) {
944
+ function fulfilled(value) {
945
+ try {
946
+ step(generator.next(value));
947
+ } catch (e) {
948
+ reject(e);
949
+ }
950
+ }
951
+ function rejected(value) {
952
+ try {
953
+ step(generator["throw"](value));
954
+ } catch (e) {
955
+ reject(e);
956
+ }
957
+ }
958
+ function step(result) {
959
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
960
+ }
961
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
309
962
  });
310
- const page = response.data;
311
- totalResults = page.totalResults;
312
- pagesFetched++;
313
- allItems.push(...page.items);
314
- const hasMore = page.hasMore || currentOffset + page.items.length < totalResults;
315
- if (!hasMore || allItems.length >= maxRows || page.items.length === 0) break;
316
- currentOffset += page.items.length;
317
- }
318
- return {
319
- items: allItems,
320
- totalResults,
321
- pagesFetched,
322
- hasMore: allItems.length < totalResults,
323
- duration: Math.round(performance.now() - startTime)
324
963
  };
964
+ var __generator = exports$1 && exports$1.__generator || function(thisArg, body) {
965
+ var _ = { label: 0, sent: function() {
966
+ if (t[0] & 1) throw t[1];
967
+ return t[1];
968
+ }, trys: [], ops: [] }, f, y, t, g;
969
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
970
+ return this;
971
+ }), g;
972
+ function verb(n) {
973
+ return function(v) {
974
+ return step([n, v]);
975
+ };
976
+ }
977
+ function step(op) {
978
+ if (f) throw new TypeError("Generator is already executing.");
979
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
980
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
981
+ if (y = 0, t) op = [op[0] & 2, t.value];
982
+ switch (op[0]) {
983
+ case 0:
984
+ case 1:
985
+ t = op;
986
+ break;
987
+ case 4:
988
+ _.label++;
989
+ return { value: op[1], done: false };
990
+ case 5:
991
+ _.label++;
992
+ y = op[1];
993
+ op = [0];
994
+ continue;
995
+ case 7:
996
+ op = _.ops.pop();
997
+ _.trys.pop();
998
+ continue;
999
+ default:
1000
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1001
+ _ = 0;
1002
+ continue;
1003
+ }
1004
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1005
+ _.label = op[1];
1006
+ break;
1007
+ }
1008
+ if (op[0] === 6 && _.label < t[1]) {
1009
+ _.label = t[1];
1010
+ t = op;
1011
+ break;
1012
+ }
1013
+ if (t && _.label < t[2]) {
1014
+ _.label = t[2];
1015
+ _.ops.push(op);
1016
+ break;
1017
+ }
1018
+ if (t[2]) _.ops.pop();
1019
+ _.trys.pop();
1020
+ continue;
1021
+ }
1022
+ op = body.call(thisArg, _);
1023
+ } catch (e) {
1024
+ op = [6, e];
1025
+ y = 0;
1026
+ } finally {
1027
+ f = t = 0;
1028
+ }
1029
+ if (op[0] & 5) throw op[1];
1030
+ return { value: op[0] ? op[1] : void 0, done: true };
1031
+ }
1032
+ };
1033
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1034
+ exports$1.RecordClient = void 0;
1035
+ var RecordClient = (
1036
+ /** @class */
1037
+ (function() {
1038
+ function RecordClient2(transport, accountId) {
1039
+ this.transport = transport;
1040
+ var normalizedId = accountId.toLowerCase().replace(/_/g, "-");
1041
+ this.baseUrl = "https://".concat(normalizedId, ".suitetalk.api.netsuite.com/services/rest/record/v1");
1042
+ }
1043
+ RecordClient2.prototype.get = function(recordType, id, options) {
1044
+ return __awaiter(this, void 0, void 0, function() {
1045
+ var params, qs, url;
1046
+ var _a;
1047
+ return __generator(this, function(_b) {
1048
+ params = new URLSearchParams();
1049
+ if ((_a = options === null || options === void 0 ? void 0 : options.fields) === null || _a === void 0 ? void 0 : _a.length) {
1050
+ params.set("fields", options.fields.join(","));
1051
+ }
1052
+ if (options === null || options === void 0 ? void 0 : options.expandSubResources) {
1053
+ params.set("expandSubResources", "true");
1054
+ }
1055
+ qs = params.toString();
1056
+ url = "".concat(this.baseUrl, "/").concat(recordType, "/").concat(id).concat(qs ? "?".concat(qs) : "");
1057
+ return [2, this.transport.request(url)];
1058
+ });
1059
+ });
1060
+ };
1061
+ RecordClient2.prototype.list = function(recordType, options) {
1062
+ return __awaiter(this, void 0, void 0, function() {
1063
+ var params, _i, _a, _b, key, value, qs, url;
1064
+ var _c;
1065
+ return __generator(this, function(_d) {
1066
+ params = new URLSearchParams();
1067
+ if ((options === null || options === void 0 ? void 0 : options.limit) != null)
1068
+ params.set("limit", String(options.limit));
1069
+ if ((options === null || options === void 0 ? void 0 : options.offset) != null)
1070
+ params.set("offset", String(options.offset));
1071
+ if ((_c = options === null || options === void 0 ? void 0 : options.fields) === null || _c === void 0 ? void 0 : _c.length)
1072
+ params.set("fields", options.fields.join(","));
1073
+ if (options === null || options === void 0 ? void 0 : options.expandSubResources)
1074
+ params.set("expandSubResources", "true");
1075
+ if (options === null || options === void 0 ? void 0 : options.query) {
1076
+ for (_i = 0, _a = Object.entries(options.query); _i < _a.length; _i++) {
1077
+ _b = _a[_i], key = _b[0], value = _b[1];
1078
+ params.set(key, value);
1079
+ }
1080
+ }
1081
+ qs = params.toString();
1082
+ url = "".concat(this.baseUrl, "/").concat(recordType).concat(qs ? "?".concat(qs) : "");
1083
+ return [2, this.transport.request(url)];
1084
+ });
1085
+ });
1086
+ };
1087
+ RecordClient2.prototype.create = function(recordType, body) {
1088
+ return __awaiter(this, void 0, void 0, function() {
1089
+ return __generator(this, function(_a) {
1090
+ return [2, this.transport.request("".concat(this.baseUrl, "/").concat(recordType), {
1091
+ method: "POST",
1092
+ body
1093
+ })];
1094
+ });
1095
+ });
1096
+ };
1097
+ RecordClient2.prototype.update = function(recordType, id, body) {
1098
+ return __awaiter(this, void 0, void 0, function() {
1099
+ return __generator(this, function(_a) {
1100
+ return [2, this.transport.request("".concat(this.baseUrl, "/").concat(recordType, "/").concat(id), {
1101
+ method: "PATCH",
1102
+ body
1103
+ })];
1104
+ });
1105
+ });
1106
+ };
1107
+ RecordClient2.prototype.replace = function(recordType, id, body) {
1108
+ return __awaiter(this, void 0, void 0, function() {
1109
+ return __generator(this, function(_a) {
1110
+ return [2, this.transport.request("".concat(this.baseUrl, "/").concat(recordType, "/").concat(id), {
1111
+ method: "PUT",
1112
+ body
1113
+ })];
1114
+ });
1115
+ });
1116
+ };
1117
+ RecordClient2.prototype.delete = function(recordType, id) {
1118
+ return __awaiter(this, void 0, void 0, function() {
1119
+ return __generator(this, function(_a) {
1120
+ return [2, this.transport.request("".concat(this.baseUrl, "/").concat(recordType, "/").concat(id), {
1121
+ method: "DELETE"
1122
+ })];
1123
+ });
1124
+ });
1125
+ };
1126
+ RecordClient2.prototype.upsert = function(recordType, externalIdField, externalIdValue, body) {
1127
+ return __awaiter(this, void 0, void 0, function() {
1128
+ return __generator(this, function(_a) {
1129
+ return [2, this.transport.request("".concat(this.baseUrl, "/").concat(recordType, "/eid:").concat(externalIdField, "=").concat(externalIdValue), { method: "PUT", body })];
1130
+ });
1131
+ });
1132
+ };
1133
+ return RecordClient2;
1134
+ })()
1135
+ );
1136
+ exports$1.RecordClient = RecordClient;
325
1137
  }
326
- /**
327
- * Execute a query and return a single row, or null if not found.
328
- *
329
- * @example
330
- * ```ts
331
- * const customer = await client.suiteql.queryOne<Customer>(
332
- * 'SELECT id, companyname FROM customer WHERE id = 123'
333
- * );
334
- * ```
335
- */
336
- async queryOne(sql, options) {
337
- const result = await this.query(sql, { ...options, maxRows: 1 });
338
- return result.items[0] ?? null;
339
- }
340
- /**
341
- * Execute a query and yield pages as an async generator.
342
- * Useful for streaming large result sets without holding everything in memory.
343
- *
344
- * @example
345
- * ```ts
346
- * for await (const page of client.suiteql.queryPages<Transaction>(
347
- * 'SELECT id, tranid, total FROM transaction',
348
- * { pageSize: 500 }
349
- * )) {
350
- * await processBatch(page);
351
- * }
352
- * ```
353
- */
354
- async *queryPages(sql, options = {}) {
355
- const {
356
- pageSize = 1e3,
357
- offset: startOffset = 0,
358
- maxRows = Infinity,
359
- timeout
360
- } = options;
361
- let currentOffset = startOffset;
362
- let totalYielded = 0;
363
- while (true) {
364
- const effectiveLimit = Math.min(pageSize, maxRows - totalYielded);
365
- if (effectiveLimit <= 0) return;
366
- const url = `${this.baseUrl}?limit=${effectiveLimit}&offset=${currentOffset}`;
367
- const response = await this.transport.request(url, {
368
- method: "POST",
369
- body: { q: sql },
370
- headers: { Prefer: "transient" },
371
- timeout
1138
+ });
1139
+
1140
+ // src/restlets/restlet-client.js
1141
+ var require_restlet_client = __commonJS({
1142
+ "src/restlets/restlet-client.js"(exports$1) {
1143
+ var __awaiter = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P, generator) {
1144
+ function adopt(value) {
1145
+ return value instanceof P ? value : new P(function(resolve) {
1146
+ resolve(value);
1147
+ });
1148
+ }
1149
+ return new (P || (P = Promise))(function(resolve, reject) {
1150
+ function fulfilled(value) {
1151
+ try {
1152
+ step(generator.next(value));
1153
+ } catch (e) {
1154
+ reject(e);
1155
+ }
1156
+ }
1157
+ function rejected(value) {
1158
+ try {
1159
+ step(generator["throw"](value));
1160
+ } catch (e) {
1161
+ reject(e);
1162
+ }
1163
+ }
1164
+ function step(result) {
1165
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
1166
+ }
1167
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
372
1168
  });
373
- const page = response.data;
374
- if (page.items.length === 0) return;
375
- yield page.items;
376
- totalYielded += page.items.length;
377
- const hasMore = page.hasMore || currentOffset + page.items.length < page.totalResults;
378
- if (!hasMore || totalYielded >= maxRows) return;
379
- currentOffset += page.items.length;
380
- }
1169
+ };
1170
+ var __generator = exports$1 && exports$1.__generator || function(thisArg, body) {
1171
+ var _ = { label: 0, sent: function() {
1172
+ if (t[0] & 1) throw t[1];
1173
+ return t[1];
1174
+ }, trys: [], ops: [] }, f, y, t, g;
1175
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
1176
+ return this;
1177
+ }), g;
1178
+ function verb(n) {
1179
+ return function(v) {
1180
+ return step([n, v]);
1181
+ };
1182
+ }
1183
+ function step(op) {
1184
+ if (f) throw new TypeError("Generator is already executing.");
1185
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
1186
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1187
+ if (y = 0, t) op = [op[0] & 2, t.value];
1188
+ switch (op[0]) {
1189
+ case 0:
1190
+ case 1:
1191
+ t = op;
1192
+ break;
1193
+ case 4:
1194
+ _.label++;
1195
+ return { value: op[1], done: false };
1196
+ case 5:
1197
+ _.label++;
1198
+ y = op[1];
1199
+ op = [0];
1200
+ continue;
1201
+ case 7:
1202
+ op = _.ops.pop();
1203
+ _.trys.pop();
1204
+ continue;
1205
+ default:
1206
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1207
+ _ = 0;
1208
+ continue;
1209
+ }
1210
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1211
+ _.label = op[1];
1212
+ break;
1213
+ }
1214
+ if (op[0] === 6 && _.label < t[1]) {
1215
+ _.label = t[1];
1216
+ t = op;
1217
+ break;
1218
+ }
1219
+ if (t && _.label < t[2]) {
1220
+ _.label = t[2];
1221
+ _.ops.push(op);
1222
+ break;
1223
+ }
1224
+ if (t[2]) _.ops.pop();
1225
+ _.trys.pop();
1226
+ continue;
1227
+ }
1228
+ op = body.call(thisArg, _);
1229
+ } catch (e) {
1230
+ op = [6, e];
1231
+ y = 0;
1232
+ } finally {
1233
+ f = t = 0;
1234
+ }
1235
+ if (op[0] & 5) throw op[1];
1236
+ return { value: op[0] ? op[1] : void 0, done: true };
1237
+ }
1238
+ };
1239
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1240
+ exports$1.RestletClient = void 0;
1241
+ var RestletClient = (
1242
+ /** @class */
1243
+ (function() {
1244
+ function RestletClient2(transport, accountId) {
1245
+ this.transport = transport;
1246
+ var normalizedId = accountId.toLowerCase().replace(/_/g, "-");
1247
+ this.baseUrl = "https://".concat(normalizedId, ".restlets.api.netsuite.com/app/site/hosting/restlet.nl");
1248
+ }
1249
+ RestletClient2.prototype.call = function(restlet, options) {
1250
+ return __awaiter(this, void 0, void 0, function() {
1251
+ var searchParams, _i, _a, _b, key, value, url;
1252
+ return __generator(this, function(_c) {
1253
+ searchParams = new URLSearchParams({
1254
+ script: String(restlet.script),
1255
+ deploy: String(restlet.deploy)
1256
+ });
1257
+ if (restlet.params) {
1258
+ for (_i = 0, _a = Object.entries(restlet.params); _i < _a.length; _i++) {
1259
+ _b = _a[_i], key = _b[0], value = _b[1];
1260
+ searchParams.set(key, String(value));
1261
+ }
1262
+ }
1263
+ url = "".concat(this.baseUrl, "?").concat(searchParams.toString());
1264
+ return [2, this.transport.request(url, options)];
1265
+ });
1266
+ });
1267
+ };
1268
+ return RestletClient2;
1269
+ })()
1270
+ );
1271
+ exports$1.RestletClient = RestletClient;
381
1272
  }
382
- };
1273
+ });
383
1274
 
384
- // src/records/record-client.ts
385
- var RecordClient = class {
386
- transport;
387
- baseUrl;
388
- constructor(transport, accountId) {
389
- this.transport = transport;
390
- const normalizedId = accountId.toLowerCase().replace(/_/g, "-");
391
- this.baseUrl = `https://${normalizedId}.suitetalk.api.netsuite.com/services/rest/record/v1`;
392
- }
393
- /** Get a record by type and internal ID */
394
- async get(recordType, id, options) {
395
- const params = new URLSearchParams();
396
- if (options?.fields?.length) {
397
- params.set("fields", options.fields.join(","));
398
- }
399
- if (options?.expandSubResources) {
400
- params.set("expandSubResources", "true");
401
- }
402
- const qs = params.toString();
403
- const url = `${this.baseUrl}/${recordType}/${id}${qs ? `?${qs}` : ""}`;
404
- return this.transport.request(url);
405
- }
406
- /** List records of a given type */
407
- async list(recordType, options) {
408
- const params = new URLSearchParams();
409
- if (options?.limit != null) params.set("limit", String(options.limit));
410
- if (options?.offset != null) params.set("offset", String(options.offset));
411
- if (options?.fields?.length) params.set("fields", options.fields.join(","));
412
- if (options?.expandSubResources) params.set("expandSubResources", "true");
413
- if (options?.query) {
414
- for (const [key, value] of Object.entries(options.query)) {
415
- params.set(key, value);
1275
+ // src/utils/validation.js
1276
+ var require_validation = __commonJS({
1277
+ "src/utils/validation.js"(exports$1) {
1278
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1279
+ exports$1.validateConfig = validateConfig2;
1280
+ function validateConfig2(config) {
1281
+ var errors = [];
1282
+ if (!config || typeof config !== "object") {
1283
+ return ["Config must be a non-null object"];
1284
+ }
1285
+ var c = config;
1286
+ if (!c.auth || typeof c.auth !== "object") {
1287
+ errors.push("auth is required and must be an object");
1288
+ } else {
1289
+ var auth = c.auth;
1290
+ var requiredFields = ["consumerKey", "consumerSecret", "tokenKey", "tokenSecret", "realm"];
1291
+ for (var _i = 0, requiredFields_1 = requiredFields; _i < requiredFields_1.length; _i++) {
1292
+ var field = requiredFields_1[_i];
1293
+ if (!auth[field] || typeof auth[field] !== "string") {
1294
+ errors.push("auth.".concat(field, " is required and must be a non-empty string"));
1295
+ }
1296
+ }
416
1297
  }
1298
+ if (!c.accountId || typeof c.accountId !== "string") {
1299
+ errors.push("accountId is required and must be a non-empty string");
1300
+ }
1301
+ return errors;
417
1302
  }
418
- const qs = params.toString();
419
- const url = `${this.baseUrl}/${recordType}${qs ? `?${qs}` : ""}`;
420
- return this.transport.request(url);
421
- }
422
- /** Create a new record */
423
- async create(recordType, body) {
424
- return this.transport.request(`${this.baseUrl}/${recordType}`, {
425
- method: "POST",
426
- body
427
- });
428
- }
429
- /** Update an existing record (partial update via PATCH) */
430
- async update(recordType, id, body) {
431
- return this.transport.request(`${this.baseUrl}/${recordType}/${id}`, {
432
- method: "PATCH",
433
- body
434
- });
435
1303
  }
436
- /** Replace an existing record (full replace via PUT) */
437
- async replace(recordType, id, body) {
438
- return this.transport.request(`${this.baseUrl}/${recordType}/${id}`, {
439
- method: "PUT",
440
- body
441
- });
442
- }
443
- /** Delete a record */
444
- async delete(recordType, id) {
445
- return this.transport.request(`${this.baseUrl}/${recordType}/${id}`, {
446
- method: "DELETE"
447
- });
448
- }
449
- /** Upsert: create or update based on external ID */
450
- async upsert(recordType, externalIdField, externalIdValue, body) {
451
- return this.transport.request(
452
- `${this.baseUrl}/${recordType}/eid:${externalIdField}=${externalIdValue}`,
453
- { method: "PUT", body }
1304
+ });
1305
+
1306
+ // src/client.js
1307
+ var require_client = __commonJS({
1308
+ "src/client.js"(exports$1) {
1309
+ var __assign = exports$1 && exports$1.__assign || function() {
1310
+ __assign = Object.assign || function(t) {
1311
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
1312
+ s = arguments[i];
1313
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
1314
+ t[p] = s[p];
1315
+ }
1316
+ return t;
1317
+ };
1318
+ return __assign.apply(this, arguments);
1319
+ };
1320
+ var __awaiter = exports$1 && exports$1.__awaiter || function(thisArg, _arguments, P, generator) {
1321
+ function adopt(value) {
1322
+ return value instanceof P ? value : new P(function(resolve) {
1323
+ resolve(value);
1324
+ });
1325
+ }
1326
+ return new (P || (P = Promise))(function(resolve, reject) {
1327
+ function fulfilled(value) {
1328
+ try {
1329
+ step(generator.next(value));
1330
+ } catch (e) {
1331
+ reject(e);
1332
+ }
1333
+ }
1334
+ function rejected(value) {
1335
+ try {
1336
+ step(generator["throw"](value));
1337
+ } catch (e) {
1338
+ reject(e);
1339
+ }
1340
+ }
1341
+ function step(result) {
1342
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
1343
+ }
1344
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1345
+ });
1346
+ };
1347
+ var __generator = exports$1 && exports$1.__generator || function(thisArg, body) {
1348
+ var _ = { label: 0, sent: function() {
1349
+ if (t[0] & 1) throw t[1];
1350
+ return t[1];
1351
+ }, trys: [], ops: [] }, f, y, t, g;
1352
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
1353
+ return this;
1354
+ }), g;
1355
+ function verb(n) {
1356
+ return function(v) {
1357
+ return step([n, v]);
1358
+ };
1359
+ }
1360
+ function step(op) {
1361
+ if (f) throw new TypeError("Generator is already executing.");
1362
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
1363
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
1364
+ if (y = 0, t) op = [op[0] & 2, t.value];
1365
+ switch (op[0]) {
1366
+ case 0:
1367
+ case 1:
1368
+ t = op;
1369
+ break;
1370
+ case 4:
1371
+ _.label++;
1372
+ return { value: op[1], done: false };
1373
+ case 5:
1374
+ _.label++;
1375
+ y = op[1];
1376
+ op = [0];
1377
+ continue;
1378
+ case 7:
1379
+ op = _.ops.pop();
1380
+ _.trys.pop();
1381
+ continue;
1382
+ default:
1383
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
1384
+ _ = 0;
1385
+ continue;
1386
+ }
1387
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
1388
+ _.label = op[1];
1389
+ break;
1390
+ }
1391
+ if (op[0] === 6 && _.label < t[1]) {
1392
+ _.label = t[1];
1393
+ t = op;
1394
+ break;
1395
+ }
1396
+ if (t && _.label < t[2]) {
1397
+ _.label = t[2];
1398
+ _.ops.push(op);
1399
+ break;
1400
+ }
1401
+ if (t[2]) _.ops.pop();
1402
+ _.trys.pop();
1403
+ continue;
1404
+ }
1405
+ op = body.call(thisArg, _);
1406
+ } catch (e) {
1407
+ op = [6, e];
1408
+ y = 0;
1409
+ } finally {
1410
+ f = t = 0;
1411
+ }
1412
+ if (op[0] & 5) throw op[1];
1413
+ return { value: op[0] ? op[1] : void 0, done: true };
1414
+ }
1415
+ };
1416
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1417
+ exports$1.NetSuiteClient = void 0;
1418
+ var http_transport_js_1 = require_http_transport();
1419
+ var suiteql_client_js_1 = require_suiteql_client();
1420
+ var record_client_js_1 = require_record_client();
1421
+ var restlet_client_js_1 = require_restlet_client();
1422
+ var validation_js_1 = require_validation();
1423
+ var NetSuiteClient2 = (
1424
+ /** @class */
1425
+ (function() {
1426
+ function NetSuiteClient3(config) {
1427
+ var errors = (0, validation_js_1.validateConfig)(config);
1428
+ if (errors.length > 0) {
1429
+ throw new Error("Invalid NetSuite configuration:\n - ".concat(errors.join("\n - ")));
1430
+ }
1431
+ this.transport = new http_transport_js_1.HttpTransport(config);
1432
+ this.suiteql = new suiteql_client_js_1.SuiteQLClient(this.transport, config.accountId);
1433
+ this.records = new record_client_js_1.RecordClient(this.transport, config.accountId);
1434
+ this.restlets = new restlet_client_js_1.RestletClient(this.transport, config.accountId);
1435
+ }
1436
+ NetSuiteClient3.prototype.use = function(middleware) {
1437
+ this.transport.use(middleware);
1438
+ return this;
1439
+ };
1440
+ NetSuiteClient3.prototype.request = function(url, options) {
1441
+ return __awaiter(this, void 0, void 0, function() {
1442
+ return __generator(this, function(_a) {
1443
+ return [2, this.transport.request(url, options)];
1444
+ });
1445
+ });
1446
+ };
1447
+ NetSuiteClient3.prototype.get = function(url, options) {
1448
+ return __awaiter(this, void 0, void 0, function() {
1449
+ return __generator(this, function(_a) {
1450
+ return [2, this.transport.request(url, __assign(__assign({}, options), { method: "GET" }))];
1451
+ });
1452
+ });
1453
+ };
1454
+ NetSuiteClient3.prototype.post = function(url, body, options) {
1455
+ return __awaiter(this, void 0, void 0, function() {
1456
+ return __generator(this, function(_a) {
1457
+ return [2, this.transport.request(url, __assign(__assign({}, options), { method: "POST", body }))];
1458
+ });
1459
+ });
1460
+ };
1461
+ NetSuiteClient3.prototype.put = function(url, body, options) {
1462
+ return __awaiter(this, void 0, void 0, function() {
1463
+ return __generator(this, function(_a) {
1464
+ return [2, this.transport.request(url, __assign(__assign({}, options), { method: "PUT", body }))];
1465
+ });
1466
+ });
1467
+ };
1468
+ NetSuiteClient3.prototype.patch = function(url, body, options) {
1469
+ return __awaiter(this, void 0, void 0, function() {
1470
+ return __generator(this, function(_a) {
1471
+ return [2, this.transport.request(url, __assign(__assign({}, options), { method: "PATCH", body }))];
1472
+ });
1473
+ });
1474
+ };
1475
+ NetSuiteClient3.prototype.delete = function(url, options) {
1476
+ return __awaiter(this, void 0, void 0, function() {
1477
+ return __generator(this, function(_a) {
1478
+ return [2, this.transport.request(url, __assign(__assign({}, options), { method: "DELETE" }))];
1479
+ });
1480
+ });
1481
+ };
1482
+ return NetSuiteClient3;
1483
+ })()
454
1484
  );
1485
+ exports$1.NetSuiteClient = NetSuiteClient2;
455
1486
  }
456
- };
1487
+ });
457
1488
 
458
- // src/restlets/restlet-client.ts
459
- var RestletClient = class {
460
- transport;
461
- baseUrl;
462
- constructor(transport, accountId) {
463
- this.transport = transport;
464
- const normalizedId = accountId.toLowerCase().replace(/_/g, "-");
465
- this.baseUrl = `https://${normalizedId}.restlets.api.netsuite.com/app/site/hosting/restlet.nl`;
466
- }
467
- /** Execute a RESTlet call */
468
- async call(restlet, options) {
469
- const searchParams = new URLSearchParams({
470
- script: String(restlet.script),
471
- deploy: String(restlet.deploy)
472
- });
473
- if (restlet.params) {
474
- for (const [key, value] of Object.entries(restlet.params)) {
475
- searchParams.set(key, String(value));
1489
+ // src/suiteql/query-builder.js
1490
+ var require_query_builder = __commonJS({
1491
+ "src/suiteql/query-builder.js"(exports$1) {
1492
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1493
+ exports$1.SuiteQLBuilder = void 0;
1494
+ exports$1.suiteql = suiteql2;
1495
+ var SuiteQLBuilder2 = (
1496
+ /** @class */
1497
+ (function() {
1498
+ function SuiteQLBuilder3() {
1499
+ this._select = [];
1500
+ this._from = "";
1501
+ this._joins = [];
1502
+ this._where = [];
1503
+ this._groupBy = [];
1504
+ this._orderBy = [];
1505
+ this._having = [];
1506
+ }
1507
+ SuiteQLBuilder3.prototype.select = function() {
1508
+ var _a;
1509
+ var columns = [];
1510
+ for (var _i = 0; _i < arguments.length; _i++) {
1511
+ columns[_i] = arguments[_i];
1512
+ }
1513
+ (_a = this._select).push.apply(_a, columns);
1514
+ return this;
1515
+ };
1516
+ SuiteQLBuilder3.prototype.from = function(table, alias) {
1517
+ this._from = alias ? "".concat(table, " ").concat(alias) : table;
1518
+ return this;
1519
+ };
1520
+ SuiteQLBuilder3.prototype.join = function(table, condition, type) {
1521
+ if (type === void 0) {
1522
+ type = "INNER";
1523
+ }
1524
+ this._joins.push("".concat(type, " JOIN ").concat(table, " ON ").concat(condition));
1525
+ return this;
1526
+ };
1527
+ SuiteQLBuilder3.prototype.leftJoin = function(table, condition) {
1528
+ return this.join(table, condition, "LEFT");
1529
+ };
1530
+ SuiteQLBuilder3.prototype.rightJoin = function(table, condition) {
1531
+ return this.join(table, condition, "RIGHT");
1532
+ };
1533
+ SuiteQLBuilder3.prototype.where = function(condition) {
1534
+ this._where.push(condition);
1535
+ return this;
1536
+ };
1537
+ SuiteQLBuilder3.prototype.whereEquals = function(column, value) {
1538
+ this._where.push("".concat(column, " = ").concat(escapeValue(value)));
1539
+ return this;
1540
+ };
1541
+ SuiteQLBuilder3.prototype.whereNotEquals = function(column, value) {
1542
+ this._where.push("".concat(column, " != ").concat(escapeValue(value)));
1543
+ return this;
1544
+ };
1545
+ SuiteQLBuilder3.prototype.whereIn = function(column, values) {
1546
+ var escaped = values.map(escapeValue);
1547
+ this._where.push("".concat(column, " IN (").concat(escaped.join(", "), ")"));
1548
+ return this;
1549
+ };
1550
+ SuiteQLBuilder3.prototype.whereNull = function(column) {
1551
+ this._where.push("".concat(column, " IS NULL"));
1552
+ return this;
1553
+ };
1554
+ SuiteQLBuilder3.prototype.whereNotNull = function(column) {
1555
+ this._where.push("".concat(column, " IS NOT NULL"));
1556
+ return this;
1557
+ };
1558
+ SuiteQLBuilder3.prototype.whereBetween = function(column, start, end) {
1559
+ this._where.push("".concat(column, " BETWEEN ").concat(escapeValue(start), " AND ").concat(escapeValue(end)));
1560
+ return this;
1561
+ };
1562
+ SuiteQLBuilder3.prototype.whereLike = function(column, pattern) {
1563
+ this._where.push("".concat(column, " LIKE ").concat(escapeValue(pattern)));
1564
+ return this;
1565
+ };
1566
+ SuiteQLBuilder3.prototype.groupBy = function() {
1567
+ var _a;
1568
+ var columns = [];
1569
+ for (var _i = 0; _i < arguments.length; _i++) {
1570
+ columns[_i] = arguments[_i];
1571
+ }
1572
+ (_a = this._groupBy).push.apply(_a, columns);
1573
+ return this;
1574
+ };
1575
+ SuiteQLBuilder3.prototype.having = function(condition) {
1576
+ this._having.push(condition);
1577
+ return this;
1578
+ };
1579
+ SuiteQLBuilder3.prototype.orderBy = function(column, direction) {
1580
+ if (direction === void 0) {
1581
+ direction = "ASC";
1582
+ }
1583
+ this._orderBy.push("".concat(column, " ").concat(direction));
1584
+ return this;
1585
+ };
1586
+ SuiteQLBuilder3.prototype.build = function() {
1587
+ if (this._select.length === 0) {
1588
+ throw new Error("SuiteQLBuilder: SELECT clause is required");
1589
+ }
1590
+ if (!this._from) {
1591
+ throw new Error("SuiteQLBuilder: FROM clause is required");
1592
+ }
1593
+ var parts = [
1594
+ "SELECT ".concat(this._select.join(", ")),
1595
+ "FROM ".concat(this._from)
1596
+ ];
1597
+ if (this._joins.length > 0) {
1598
+ parts.push(this._joins.join(" "));
1599
+ }
1600
+ if (this._where.length > 0) {
1601
+ parts.push("WHERE ".concat(this._where.join(" AND ")));
1602
+ }
1603
+ if (this._groupBy.length > 0) {
1604
+ parts.push("GROUP BY ".concat(this._groupBy.join(", ")));
1605
+ }
1606
+ if (this._having.length > 0) {
1607
+ parts.push("HAVING ".concat(this._having.join(" AND ")));
1608
+ }
1609
+ if (this._orderBy.length > 0) {
1610
+ parts.push("ORDER BY ".concat(this._orderBy.join(", ")));
1611
+ }
1612
+ return parts.join(" ");
1613
+ };
1614
+ SuiteQLBuilder3.prototype.toString = function() {
1615
+ return this.build();
1616
+ };
1617
+ return SuiteQLBuilder3;
1618
+ })()
1619
+ );
1620
+ exports$1.SuiteQLBuilder = SuiteQLBuilder2;
1621
+ function escapeValue(value) {
1622
+ if (typeof value === "number") {
1623
+ return String(value);
1624
+ }
1625
+ if (typeof value === "boolean") {
1626
+ return value ? "'T'" : "'F'";
476
1627
  }
1628
+ var escaped = value.replace(/'/g, "''");
1629
+ return "'".concat(escaped, "'");
1630
+ }
1631
+ function suiteql2() {
1632
+ return new SuiteQLBuilder2();
477
1633
  }
478
- const url = `${this.baseUrl}?${searchParams.toString()}`;
479
- return this.transport.request(url, options);
480
1634
  }
481
- };
1635
+ });
482
1636
 
483
- // src/utils/validation.ts
484
- function validateConfig(config) {
485
- const errors = [];
486
- if (!config || typeof config !== "object") {
487
- return ["Config must be a non-null object"];
488
- }
489
- const c = config;
490
- if (!c.auth || typeof c.auth !== "object") {
491
- errors.push("auth is required and must be an object");
492
- } else {
493
- const auth = c.auth;
494
- const requiredFields = ["consumerKey", "consumerSecret", "tokenKey", "tokenSecret", "realm"];
495
- for (const field of requiredFields) {
496
- if (!auth[field] || typeof auth[field] !== "string") {
497
- errors.push(`auth.${field} is required and must be a non-empty string`);
1637
+ // src/utils/response-cache.js
1638
+ var require_response_cache = __commonJS({
1639
+ "src/utils/response-cache.js"(exports$1) {
1640
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1641
+ exports$1.ResponseCache = void 0;
1642
+ exports$1.createCacheKey = createCacheKey2;
1643
+ var ResponseCache2 = (
1644
+ /** @class */
1645
+ (function() {
1646
+ function ResponseCache3() {
1647
+ this.cache = /* @__PURE__ */ new Map();
1648
+ }
1649
+ ResponseCache3.prototype.get = function(key) {
1650
+ var entry = this.cache.get(key);
1651
+ if (!entry)
1652
+ return null;
1653
+ if (Date.now() > entry.expiresAt) {
1654
+ this.cache.delete(key);
1655
+ return null;
1656
+ }
1657
+ return entry.data;
1658
+ };
1659
+ ResponseCache3.prototype.set = function(key, data, ttlSeconds) {
1660
+ this.cache.set(key, {
1661
+ data,
1662
+ expiresAt: Date.now() + ttlSeconds * 1e3
1663
+ });
1664
+ };
1665
+ ResponseCache3.prototype.delete = function(key) {
1666
+ return this.cache.delete(key);
1667
+ };
1668
+ ResponseCache3.prototype.clear = function() {
1669
+ this.cache.clear();
1670
+ };
1671
+ Object.defineProperty(ResponseCache3.prototype, "size", {
1672
+ /** Get the number of entries (including expired). */
1673
+ get: function() {
1674
+ return this.cache.size;
1675
+ },
1676
+ enumerable: false,
1677
+ configurable: true
1678
+ });
1679
+ return ResponseCache3;
1680
+ })()
1681
+ );
1682
+ exports$1.ResponseCache = ResponseCache2;
1683
+ function createCacheKey2(url, method, params) {
1684
+ var base = "".concat(method, ":").concat(url);
1685
+ if (params) {
1686
+ return "".concat(base, ":").concat(JSON.stringify(params));
498
1687
  }
1688
+ return base;
499
1689
  }
500
1690
  }
501
- if (!c.accountId || typeof c.accountId !== "string") {
502
- errors.push("accountId is required and must be a non-empty string");
503
- }
504
- return errors;
505
- }
1691
+ });
506
1692
 
507
- // src/client.ts
508
- var NetSuiteClient = class {
509
- /** SuiteQL query execution and builder */
510
- suiteql;
511
- /** REST Record API CRUD */
512
- records;
513
- /** RESTlet caller */
514
- restlets;
515
- transport;
516
- constructor(config) {
517
- const errors = validateConfig(config);
518
- if (errors.length > 0) {
519
- throw new Error(`Invalid NetSuite configuration:
520
- - ${errors.join("\n - ")}`);
521
- }
522
- this.transport = new HttpTransport(config);
523
- this.suiteql = new SuiteQLClient(this.transport, config.accountId);
524
- this.records = new RecordClient(this.transport, config.accountId);
525
- this.restlets = new RestletClient(this.transport, config.accountId);
526
- }
527
- /** Add middleware to all requests. Returns `this` for chaining. */
528
- use(middleware) {
529
- this.transport.use(middleware);
530
- return this;
531
- }
532
- /** Make a raw HTTP request (escape hatch for custom endpoints). */
533
- async request(url, options) {
534
- return this.transport.request(url, options);
535
- }
536
- /** Convenience: GET request */
537
- async get(url, options) {
538
- return this.transport.request(url, { ...options, method: "GET" });
539
- }
540
- /** Convenience: POST request */
541
- async post(url, body, options) {
542
- return this.transport.request(url, { ...options, method: "POST", body });
543
- }
544
- /** Convenience: PUT request */
545
- async put(url, body, options) {
546
- return this.transport.request(url, { ...options, method: "PUT", body });
547
- }
548
- /** Convenience: PATCH request */
549
- async patch(url, body, options) {
550
- return this.transport.request(url, { ...options, method: "PATCH", body });
551
- }
552
- /** Convenience: DELETE request */
553
- async delete(url, options) {
554
- return this.transport.request(url, { ...options, method: "DELETE" });
1693
+ // src/utils/rate-limiter.js
1694
+ var require_rate_limiter = __commonJS({
1695
+ "src/utils/rate-limiter.js"(exports$1) {
1696
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1697
+ exports$1.RateLimiter = void 0;
1698
+ var RateLimiter2 = (
1699
+ /** @class */
1700
+ (function() {
1701
+ function RateLimiter3(maxRequests, windowMs) {
1702
+ if (maxRequests === void 0) {
1703
+ maxRequests = 100;
1704
+ }
1705
+ if (windowMs === void 0) {
1706
+ windowMs = 6e4;
1707
+ }
1708
+ this.timestamps = [];
1709
+ this.maxRequests = maxRequests;
1710
+ this.windowMs = windowMs;
1711
+ }
1712
+ RateLimiter3.prototype.canMakeRequest = function() {
1713
+ this.pruneExpired();
1714
+ return this.timestamps.length < this.maxRequests;
1715
+ };
1716
+ RateLimiter3.prototype.recordRequest = function() {
1717
+ this.pruneExpired();
1718
+ this.timestamps.push(Date.now());
1719
+ };
1720
+ RateLimiter3.prototype.getRemainingRequests = function() {
1721
+ this.pruneExpired();
1722
+ return Math.max(0, this.maxRequests - this.timestamps.length);
1723
+ };
1724
+ RateLimiter3.prototype.getTimeUntilNextSlot = function() {
1725
+ this.pruneExpired();
1726
+ if (this.timestamps.length < this.maxRequests)
1727
+ return 0;
1728
+ var oldest = this.timestamps[0];
1729
+ return Math.max(0, oldest + this.windowMs - Date.now());
1730
+ };
1731
+ RateLimiter3.prototype.pruneExpired = function() {
1732
+ var cutoff = Date.now() - this.windowMs;
1733
+ while (this.timestamps.length > 0 && this.timestamps[0] <= cutoff) {
1734
+ this.timestamps.shift();
1735
+ }
1736
+ };
1737
+ return RateLimiter3;
1738
+ })()
1739
+ );
1740
+ exports$1.RateLimiter = RateLimiter2;
555
1741
  }
556
- };
1742
+ });
557
1743
 
558
- // src/suiteql/query-builder.ts
559
- var SuiteQLBuilder = class {
560
- _select = [];
561
- _from = "";
562
- _joins = [];
563
- _where = [];
564
- _groupBy = [];
565
- _orderBy = [];
566
- _having = [];
567
- /** Add columns to SELECT clause */
568
- select(...columns) {
569
- this._select.push(...columns);
570
- return this;
571
- }
572
- /** Set the FROM table, with optional alias */
573
- from(table, alias) {
574
- this._from = alias ? `${table} ${alias}` : table;
575
- return this;
576
- }
577
- /** Add a JOIN clause */
578
- join(table, condition, type = "INNER") {
579
- this._joins.push(`${type} JOIN ${table} ON ${condition}`);
580
- return this;
581
- }
582
- /** Add a LEFT JOIN clause */
583
- leftJoin(table, condition) {
584
- return this.join(table, condition, "LEFT");
585
- }
586
- /** Add a RIGHT JOIN clause */
587
- rightJoin(table, condition) {
588
- return this.join(table, condition, "RIGHT");
589
- }
590
- /** Add a raw WHERE condition */
591
- where(condition) {
592
- this._where.push(condition);
593
- return this;
594
- }
595
- /** Add a WHERE column = value condition. Values are escaped. */
596
- whereEquals(column, value) {
597
- this._where.push(`${column} = ${escapeValue(value)}`);
598
- return this;
599
- }
600
- /** Add a WHERE column != value condition. Values are escaped. */
601
- whereNotEquals(column, value) {
602
- this._where.push(`${column} != ${escapeValue(value)}`);
603
- return this;
604
- }
605
- /** Add a WHERE column IN (...) condition. Values are escaped. */
606
- whereIn(column, values) {
607
- const escaped = values.map(escapeValue);
608
- this._where.push(`${column} IN (${escaped.join(", ")})`);
609
- return this;
610
- }
611
- /** Add a WHERE column IS NULL condition */
612
- whereNull(column) {
613
- this._where.push(`${column} IS NULL`);
614
- return this;
615
- }
616
- /** Add a WHERE column IS NOT NULL condition */
617
- whereNotNull(column) {
618
- this._where.push(`${column} IS NOT NULL`);
619
- return this;
620
- }
621
- /** Add a WHERE column BETWEEN start AND end condition. Values are escaped. */
622
- whereBetween(column, start, end) {
623
- this._where.push(`${column} BETWEEN ${escapeValue(start)} AND ${escapeValue(end)}`);
624
- return this;
625
- }
626
- /** Add a WHERE column LIKE pattern condition. Value is escaped. */
627
- whereLike(column, pattern) {
628
- this._where.push(`${column} LIKE ${escapeValue(pattern)}`);
629
- return this;
630
- }
631
- /** Add columns to GROUP BY clause */
632
- groupBy(...columns) {
633
- this._groupBy.push(...columns);
634
- return this;
635
- }
636
- /** Add a HAVING condition (used with GROUP BY) */
637
- having(condition) {
638
- this._having.push(condition);
639
- return this;
640
- }
641
- /** Add a column to ORDER BY clause */
642
- orderBy(column, direction = "ASC") {
643
- this._orderBy.push(`${column} ${direction}`);
644
- return this;
645
- }
646
- /** Build the SQL string. Throws if SELECT or FROM is missing. */
647
- build() {
648
- if (this._select.length === 0) {
649
- throw new Error("SuiteQLBuilder: SELECT clause is required");
650
- }
651
- if (!this._from) {
652
- throw new Error("SuiteQLBuilder: FROM clause is required");
653
- }
654
- const parts = [
655
- `SELECT ${this._select.join(", ")}`,
656
- `FROM ${this._from}`
657
- ];
658
- if (this._joins.length > 0) {
659
- parts.push(this._joins.join(" "));
1744
+ // src/utils/date.js
1745
+ var require_date = __commonJS({
1746
+ "src/utils/date.js"(exports$1) {
1747
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1748
+ exports$1.formatNetSuiteDate = formatNetSuiteDate2;
1749
+ exports$1.parseNetSuiteDate = parseNetSuiteDate2;
1750
+ function formatNetSuiteDate2(date) {
1751
+ var year = date.getFullYear();
1752
+ var month = String(date.getMonth() + 1).padStart(2, "0");
1753
+ var day = String(date.getDate()).padStart(2, "0");
1754
+ return "".concat(year, "-").concat(month, "-").concat(day);
660
1755
  }
661
- if (this._where.length > 0) {
662
- parts.push(`WHERE ${this._where.join(" AND ")}`);
663
- }
664
- if (this._groupBy.length > 0) {
665
- parts.push(`GROUP BY ${this._groupBy.join(", ")}`);
666
- }
667
- if (this._having.length > 0) {
668
- parts.push(`HAVING ${this._having.join(" AND ")}`);
669
- }
670
- if (this._orderBy.length > 0) {
671
- parts.push(`ORDER BY ${this._orderBy.join(", ")}`);
1756
+ function parseNetSuiteDate2(dateString) {
1757
+ if (dateString.includes("/")) {
1758
+ var _a = dateString.split("/"), month_1 = _a[0], day_1 = _a[1], year_1 = _a[2];
1759
+ return new Date(Number(year_1), Number(month_1) - 1, Number(day_1));
1760
+ }
1761
+ var _b = dateString.split("-"), year = _b[0], month = _b[1], day = _b[2];
1762
+ return new Date(Number(year), Number(month) - 1, Number(day));
672
1763
  }
673
- return parts.join(" ");
674
- }
675
- /** Alias for build() */
676
- toString() {
677
- return this.build();
678
- }
679
- };
680
- function escapeValue(value) {
681
- if (typeof value === "number") {
682
- return String(value);
683
- }
684
- if (typeof value === "boolean") {
685
- return value ? "'T'" : "'F'";
686
1764
  }
687
- const escaped = value.replace(/'/g, "''");
688
- return `'${escaped}'`;
689
- }
690
- function suiteql() {
691
- return new SuiteQLBuilder();
692
- }
1765
+ });
693
1766
 
694
- // src/utils/response-cache.ts
695
- var ResponseCache = class {
696
- cache = /* @__PURE__ */ new Map();
697
- /** Get a cached value, or null if not found or expired. */
698
- get(key) {
699
- const entry = this.cache.get(key);
700
- if (!entry) return null;
701
- if (Date.now() > entry.expiresAt) {
702
- this.cache.delete(key);
703
- return null;
1767
+ // src/utils/error-parser.js
1768
+ var require_error_parser = __commonJS({
1769
+ "src/utils/error-parser.js"(exports$1) {
1770
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1771
+ exports$1.parseNetSuiteError = parseNetSuiteError2;
1772
+ function parseNetSuiteError2(error) {
1773
+ var _a, _b;
1774
+ if (!error || typeof error !== "object") {
1775
+ return { message: String(error) };
1776
+ }
1777
+ var e = error;
1778
+ if (e.title || e.detail) {
1779
+ return {
1780
+ message: String((_b = (_a = e.detail) !== null && _a !== void 0 ? _a : e.title) !== null && _b !== void 0 ? _b : "Unknown error"),
1781
+ code: e["o:errorCode"],
1782
+ details: e
1783
+ };
1784
+ }
1785
+ if (e.message) {
1786
+ return {
1787
+ message: String(e.message),
1788
+ code: e.code
1789
+ };
1790
+ }
1791
+ return { message: JSON.stringify(error) };
704
1792
  }
705
- return entry.data;
706
- }
707
- /** Set a cached value with a TTL in seconds. */
708
- set(key, data, ttlSeconds) {
709
- this.cache.set(key, {
710
- data,
711
- expiresAt: Date.now() + ttlSeconds * 1e3
712
- });
713
- }
714
- /** Delete a specific cache entry. */
715
- delete(key) {
716
- return this.cache.delete(key);
717
- }
718
- /** Clear all cached entries. */
719
- clear() {
720
- this.cache.clear();
721
- }
722
- /** Get the number of entries (including expired). */
723
- get size() {
724
- return this.cache.size;
725
- }
726
- };
727
- function createCacheKey(url, method, params) {
728
- const base = `${method}:${url}`;
729
- if (params) {
730
- return `${base}:${JSON.stringify(params)}`;
731
1793
  }
732
- return base;
733
- }
1794
+ });
734
1795
 
735
- // src/utils/rate-limiter.ts
736
- var RateLimiter = class {
737
- timestamps = [];
738
- maxRequests;
739
- windowMs;
740
- constructor(maxRequests = 100, windowMs = 6e4) {
741
- this.maxRequests = maxRequests;
742
- this.windowMs = windowMs;
743
- }
744
- /** Check if a request can be made without exceeding the limit. */
745
- canMakeRequest() {
746
- this.pruneExpired();
747
- return this.timestamps.length < this.maxRequests;
748
- }
749
- /** Record that a request was made. */
750
- recordRequest() {
751
- this.pruneExpired();
752
- this.timestamps.push(Date.now());
753
- }
754
- /** Get the number of remaining requests in the current window. */
755
- getRemainingRequests() {
756
- this.pruneExpired();
757
- return Math.max(0, this.maxRequests - this.timestamps.length);
758
- }
759
- /** Get ms until the next request slot opens. Returns 0 if a slot is available. */
760
- getTimeUntilNextSlot() {
761
- this.pruneExpired();
762
- if (this.timestamps.length < this.maxRequests) return 0;
763
- const oldest = this.timestamps[0];
764
- return Math.max(0, oldest + this.windowMs - Date.now());
765
- }
766
- pruneExpired() {
767
- const cutoff = Date.now() - this.windowMs;
768
- while (this.timestamps.length > 0 && this.timestamps[0] <= cutoff) {
769
- this.timestamps.shift();
1796
+ // src/utils/url-builder.js
1797
+ var require_url_builder = __commonJS({
1798
+ "src/utils/url-builder.js"(exports$1) {
1799
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1800
+ exports$1.normalizeAccountId = normalizeAccountId2;
1801
+ exports$1.buildSuiteTalkUrl = buildSuiteTalkUrl;
1802
+ exports$1.buildRestletUrl = buildRestletUrl;
1803
+ function normalizeAccountId2(accountId) {
1804
+ return accountId.toLowerCase().replace(/_/g, "-");
1805
+ }
1806
+ function buildSuiteTalkUrl(accountId) {
1807
+ return "https://".concat(normalizeAccountId2(accountId), ".suitetalk.api.netsuite.com");
1808
+ }
1809
+ function buildRestletUrl(accountId) {
1810
+ return "https://".concat(normalizeAccountId2(accountId), ".restlets.api.netsuite.com");
770
1811
  }
771
1812
  }
772
- };
1813
+ });
773
1814
 
774
- // src/utils/date.ts
775
- function formatNetSuiteDate(date) {
776
- const year = date.getFullYear();
777
- const month = String(date.getMonth() + 1).padStart(2, "0");
778
- const day = String(date.getDate()).padStart(2, "0");
779
- return `${year}-${month}-${day}`;
780
- }
781
- function parseNetSuiteDate(dateString) {
782
- if (dateString.includes("/")) {
783
- const [month2, day2, year2] = dateString.split("/");
784
- return new Date(Number(year2), Number(month2) - 1, Number(day2));
1815
+ // src/index.ts
1816
+ var import_client = __toESM(require_client());
1817
+ var import_query_builder = __toESM(require_query_builder());
1818
+ var import_errors = __toESM(require_errors());
1819
+ var SOAP_ONLY_FIELDS = {
1820
+ assemblyItem: ["taxSchedule"],
1821
+ inventoryItem: ["taxSchedule"],
1822
+ nonInventoryItem: ["taxSchedule"],
1823
+ kitItem: ["taxSchedule"],
1824
+ serviceItem: ["taxSchedule"],
1825
+ otherChargeItem: ["taxSchedule"],
1826
+ lotNumberedInventoryItem: ["taxSchedule"],
1827
+ serializedInventoryItem: ["taxSchedule"]
1828
+ };
1829
+ var SOAP_RECORD_TYPES = {
1830
+ assemblyItem: { type: "AssemblyItem", namespace: "listAcct" },
1831
+ inventoryItem: { type: "InventoryItem", namespace: "listAcct" },
1832
+ nonInventoryItem: { type: "NonInventorySaleItem", namespace: "listAcct" },
1833
+ kitItem: { type: "KitItem", namespace: "listAcct" },
1834
+ serviceItem: { type: "ServiceSaleItem", namespace: "listAcct" },
1835
+ otherChargeItem: { type: "OtherChargeSaleItem", namespace: "listAcct" },
1836
+ lotNumberedInventoryItem: { type: "LotNumberedInventoryItem", namespace: "listAcct" },
1837
+ serializedInventoryItem: { type: "SerializedInventoryItem", namespace: "listAcct" },
1838
+ customer: { type: "Customer", namespace: "listRel" },
1839
+ vendor: { type: "Vendor", namespace: "listRel" },
1840
+ salesOrder: { type: "SalesOrder", namespace: "tranSales" },
1841
+ purchaseOrder: { type: "PurchaseOrder", namespace: "tranPurch" },
1842
+ invoice: { type: "Invoice", namespace: "tranSales" }
1843
+ };
1844
+ var NS_NAMESPACES = {
1845
+ listAcct: "urn:accounting_2024_1.lists.webservices.netsuite.com",
1846
+ listRel: "urn:relationships_2024_1.lists.webservices.netsuite.com",
1847
+ tranSales: "urn:sales_2024_1.transactions.webservices.netsuite.com",
1848
+ tranPurch: "urn:purchases_2024_1.transactions.webservices.netsuite.com",
1849
+ core: "urn:core_2024_1.platform.webservices.netsuite.com",
1850
+ messages: "urn:messages_2024_1.platform.webservices.netsuite.com"
1851
+ };
1852
+ function extractSoapOnlyFields(recordType, body) {
1853
+ const knownSoapFields = SOAP_ONLY_FIELDS[recordType] ?? [];
1854
+ const soapFields = {};
1855
+ const restBody = {};
1856
+ for (const [key, value] of Object.entries(body)) {
1857
+ if (knownSoapFields.includes(key)) {
1858
+ soapFields[key] = value;
1859
+ } else {
1860
+ restBody[key] = value;
1861
+ }
785
1862
  }
786
- const [year, month, day] = dateString.split("-");
787
- return new Date(Number(year), Number(month) - 1, Number(day));
1863
+ return { soapFields, restBody };
788
1864
  }
789
-
790
- // src/utils/error-parser.ts
791
- function parseNetSuiteError(error) {
792
- if (!error || typeof error !== "object") {
793
- return { message: String(error) };
1865
+ var SoapFieldClient = class {
1866
+ auth;
1867
+ accountId;
1868
+ constructor(auth, accountId) {
1869
+ this.auth = auth;
1870
+ this.accountId = accountId;
794
1871
  }
795
- const e = error;
796
- if (e.title || e.detail) {
1872
+ /**
1873
+ * Update SOAP-only fields on an existing record.
1874
+ */
1875
+ async updateFields(recordType, internalId, fields) {
1876
+ const soapType = SOAP_RECORD_TYPES[recordType];
1877
+ if (!soapType) {
1878
+ return {
1879
+ success: false,
1880
+ error: `Unsupported SOAP record type: ${recordType}`
1881
+ };
1882
+ }
1883
+ const fieldXml = this.buildFieldXml(fields, soapType.namespace);
1884
+ const envelope = this.buildUpdateEnvelope(soapType, internalId, fieldXml);
1885
+ const normalizedId = this.accountId.toLowerCase().replace(/_/g, "-");
1886
+ const soapUrl = `https://${normalizedId}.suitetalk.api.netsuite.com/services/NetSuitePort_2024_1`;
1887
+ const response = await fetch(soapUrl, {
1888
+ method: "POST",
1889
+ headers: {
1890
+ "Content-Type": "text/xml; charset=utf-8",
1891
+ SOAPAction: "update"
1892
+ },
1893
+ body: envelope
1894
+ });
1895
+ const responseText = await response.text();
1896
+ if (!response.ok) {
1897
+ const errorMatch = responseText.match(/<faultstring>(.*?)<\/faultstring>/s);
1898
+ return {
1899
+ success: false,
1900
+ error: errorMatch?.[1] ?? `SOAP HTTP ${response.status}: ${response.statusText}`
1901
+ };
1902
+ }
1903
+ const successMatch = responseText.match(/isSuccess="true"/);
1904
+ if (successMatch) {
1905
+ return { success: true, internalId };
1906
+ }
1907
+ const detailMatch = responseText.match(/<platformCore:message>(.*?)<\/platformCore:message>/s);
797
1908
  return {
798
- message: String(e.detail ?? e.title ?? "Unknown error"),
799
- code: e["o:errorCode"],
800
- details: e
1909
+ success: false,
1910
+ internalId,
1911
+ error: detailMatch?.[1] ?? "SOAP update returned without success flag"
801
1912
  };
802
1913
  }
803
- if (e.message) {
1914
+ /**
1915
+ * Create a record via SOAP (full creation, not just field update).
1916
+ */
1917
+ async addRecord(recordType, fields) {
1918
+ const soapType = SOAP_RECORD_TYPES[recordType];
1919
+ if (!soapType) {
1920
+ return {
1921
+ success: false,
1922
+ error: `Unsupported SOAP record type: ${recordType}`
1923
+ };
1924
+ }
1925
+ const fieldXml = this.buildFieldXml(fields, soapType.namespace);
1926
+ const envelope = this.buildAddEnvelope(soapType, fieldXml);
1927
+ const normalizedId = this.accountId.toLowerCase().replace(/_/g, "-");
1928
+ const soapUrl = `https://${normalizedId}.suitetalk.api.netsuite.com/services/NetSuitePort_2024_1`;
1929
+ const response = await fetch(soapUrl, {
1930
+ method: "POST",
1931
+ headers: {
1932
+ "Content-Type": "text/xml; charset=utf-8",
1933
+ SOAPAction: "add"
1934
+ },
1935
+ body: envelope
1936
+ });
1937
+ const responseText = await response.text();
1938
+ if (!response.ok) {
1939
+ const errorMatch = responseText.match(/<faultstring>(.*?)<\/faultstring>/s);
1940
+ return {
1941
+ success: false,
1942
+ error: errorMatch?.[1] ?? `SOAP HTTP ${response.status}: ${response.statusText}`
1943
+ };
1944
+ }
1945
+ const successMatch = responseText.match(/isSuccess="true"/);
1946
+ const idMatch = responseText.match(/internalId="(\d+)"/);
1947
+ if (successMatch) {
1948
+ return { success: true, internalId: idMatch?.[1] };
1949
+ }
1950
+ const detailMatch = responseText.match(/<platformCore:message>(.*?)<\/platformCore:message>/s);
804
1951
  return {
805
- message: String(e.message),
806
- code: e.code
1952
+ success: false,
1953
+ error: detailMatch?.[1] ?? "SOAP add returned without success flag"
807
1954
  };
808
1955
  }
809
- return { message: JSON.stringify(error) };
810
- }
1956
+ // ─── Private helpers ──────────────────────────────────────────────────────
1957
+ buildFieldXml(fields, ns) {
1958
+ const prefix = ns;
1959
+ const parts = [];
1960
+ for (const [key, value] of Object.entries(fields)) {
1961
+ if (value === null || value === void 0) continue;
1962
+ if (typeof value === "object" && value !== null && "id" in value) {
1963
+ parts.push(`<${prefix}:${key} internalId="${value.id}"/>`);
1964
+ } else if (typeof value === "object" && value !== null && "items" in value) {
1965
+ const items = value.items;
1966
+ const listParts = [];
1967
+ for (const item of items) {
1968
+ Object.entries(item).map(([k, v]) => {
1969
+ if (typeof v === "object" && v !== null && "id" in v) {
1970
+ return `<${prefix}:${k} internalId="${v.id}"/>`;
1971
+ }
1972
+ return `<${prefix}:${k}>${String(v)}</${prefix}:${k}>`;
1973
+ }).join("\n ");
1974
+ listParts.push(`<core:recordRef internalId="${item.id ?? ""}"/>`);
1975
+ }
1976
+ parts.push(`<${prefix}:${key}List>
1977
+ ${listParts.join("\n ")}
1978
+ </${prefix}:${key}List>`);
1979
+ } else if (typeof value === "boolean") {
1980
+ parts.push(`<${prefix}:${key}>${value}</${prefix}:${key}>`);
1981
+ } else {
1982
+ parts.push(`<${prefix}:${key}>${String(value)}</${prefix}:${key}>`);
1983
+ }
1984
+ }
1985
+ return parts.join("\n ");
1986
+ }
1987
+ buildTokenPassport() {
1988
+ const nonce = randomBytes(16).toString("hex");
1989
+ const timestamp = Math.floor(Date.now() / 1e3).toString();
1990
+ const baseString = `${this.accountId}&${this.auth.consumerKey}&${this.auth.tokenKey}&${nonce}&${timestamp}`;
1991
+ const signingKey = `${this.auth.consumerSecret}&${this.auth.tokenSecret}`;
1992
+ const signature = createHmac("sha256", signingKey).update(baseString).digest("base64");
1993
+ return `
1994
+ <urn:tokenPassport>
1995
+ <core:account>${this.accountId}</core:account>
1996
+ <core:consumerKey>${this.auth.consumerKey}</core:consumerKey>
1997
+ <core:token>${this.auth.tokenKey}</core:token>
1998
+ <core:nonce>${nonce}</core:nonce>
1999
+ <core:timestamp>${timestamp}</core:timestamp>
2000
+ <core:signature algorithm="HMAC-SHA256">${signature}</core:signature>
2001
+ </urn:tokenPassport>`;
2002
+ }
2003
+ buildUpdateEnvelope(soapType, internalId, fieldXml) {
2004
+ const nsUri = NS_NAMESPACES[soapType.namespace];
2005
+ return `<?xml version="1.0" encoding="UTF-8"?>
2006
+ <soapenv:Envelope
2007
+ xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
2008
+ xmlns:urn="${NS_NAMESPACES.messages}"
2009
+ xmlns:core="${NS_NAMESPACES.core}"
2010
+ xmlns:${soapType.namespace}="${nsUri}"
2011
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2012
+ <soapenv:Header>${this.buildTokenPassport()}
2013
+ </soapenv:Header>
2014
+ <soapenv:Body>
2015
+ <urn:update>
2016
+ <urn:record xsi:type="${soapType.namespace}:${soapType.type}" internalId="${internalId}">
2017
+ ${fieldXml}
2018
+ </urn:record>
2019
+ </urn:update>
2020
+ </soapenv:Body>
2021
+ </soapenv:Envelope>`;
2022
+ }
2023
+ buildAddEnvelope(soapType, fieldXml) {
2024
+ const nsUri = NS_NAMESPACES[soapType.namespace];
2025
+ return `<?xml version="1.0" encoding="UTF-8"?>
2026
+ <soapenv:Envelope
2027
+ xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
2028
+ xmlns:urn="${NS_NAMESPACES.messages}"
2029
+ xmlns:core="${NS_NAMESPACES.core}"
2030
+ xmlns:${soapType.namespace}="${nsUri}"
2031
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2032
+ <soapenv:Header>${this.buildTokenPassport()}
2033
+ </soapenv:Header>
2034
+ <soapenv:Body>
2035
+ <urn:add>
2036
+ <urn:record xsi:type="${soapType.namespace}:${soapType.type}">
2037
+ ${fieldXml}
2038
+ </urn:record>
2039
+ </urn:add>
2040
+ </soapenv:Body>
2041
+ </soapenv:Envelope>`;
2042
+ }
2043
+ };
811
2044
 
812
- // src/utils/url-builder.ts
813
- function normalizeAccountId(accountId) {
814
- return accountId.toLowerCase().replace(/_/g, "-");
815
- }
2045
+ // src/index.ts
2046
+ var import_response_cache = __toESM(require_response_cache());
2047
+ var import_rate_limiter = __toESM(require_rate_limiter());
2048
+ var import_validation = __toESM(require_validation());
2049
+ var import_date = __toESM(require_date());
2050
+ var import_error_parser = __toESM(require_error_parser());
2051
+ var import_url_builder = __toESM(require_url_builder());
2052
+ var export_NetSuiteClient = import_client.NetSuiteClient;
2053
+ var export_NetSuiteError = import_errors.NetSuiteError;
2054
+ var export_RateLimiter = import_rate_limiter.RateLimiter;
2055
+ var export_ResponseCache = import_response_cache.ResponseCache;
2056
+ var export_SuiteQLBuilder = import_query_builder.SuiteQLBuilder;
2057
+ var export_createCacheKey = import_response_cache.createCacheKey;
2058
+ var export_formatNetSuiteDate = import_date.formatNetSuiteDate;
2059
+ var export_normalizeAccountId = import_url_builder.normalizeAccountId;
2060
+ var export_parseNetSuiteDate = import_date.parseNetSuiteDate;
2061
+ var export_parseNetSuiteError = import_error_parser.parseNetSuiteError;
2062
+ var export_suiteql = import_query_builder.suiteql;
2063
+ var export_validateConfig = import_validation.validateConfig;
816
2064
 
817
- export { NetSuiteClient, NetSuiteError, RateLimiter, ResponseCache, SuiteQLBuilder, createCacheKey, formatNetSuiteDate, normalizeAccountId, parseNetSuiteDate, parseNetSuiteError, suiteql, validateConfig };
2065
+ export { export_NetSuiteClient as NetSuiteClient, export_NetSuiteError as NetSuiteError, export_RateLimiter as RateLimiter, export_ResponseCache as ResponseCache, SOAP_ONLY_FIELDS, SoapFieldClient, export_SuiteQLBuilder as SuiteQLBuilder, export_createCacheKey as createCacheKey, extractSoapOnlyFields, export_formatNetSuiteDate as formatNetSuiteDate, export_normalizeAccountId as normalizeAccountId, export_parseNetSuiteDate as parseNetSuiteDate, export_parseNetSuiteError as parseNetSuiteError, export_suiteql as suiteql, export_validateConfig as validateConfig };
818
2066
  //# sourceMappingURL=index.mjs.map
819
2067
  //# sourceMappingURL=index.mjs.map