fireberry-api-client 1.0.2-beta.1.0 → 1.0.2-beta.1.2
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/README.md +97 -10
- package/dist/{excludedFields-CuQ8Dp-N.d.cts → excludedFields-Dk-ILROQ.d.cts} +95 -1
- package/dist/{excludedFields-CuQ8Dp-N.d.ts → excludedFields-Dk-ILROQ.d.ts} +95 -1
- package/dist/index.cjs +721 -294
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +720 -295
- package/dist/index.js.map +1 -1
- package/dist/{relatedFieldMapping-Plja-OuE.d.ts → relatedFieldMapping-6o0SKPT2.d.ts} +311 -118
- package/dist/{relatedFieldMapping-jprv6Lhg.d.cts → relatedFieldMapping-uUVpIJk9.d.cts} +311 -118
- package/dist/sdk/index.d.cts +3 -96
- package/dist/sdk/index.d.ts +3 -96
- package/dist/utils/index.d.cts +3 -3
- package/dist/utils/index.d.ts +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -172,20 +172,6 @@ function createNetworkError(error) {
|
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
// src/utils/helpers.ts
|
|
176
|
-
function wait(ms) {
|
|
177
|
-
return new Promise((resolve) => {
|
|
178
|
-
setTimeout(resolve, ms);
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
function chunkArray(array, size) {
|
|
182
|
-
const result = [];
|
|
183
|
-
for (let i = 0; i < array.length; i += size) {
|
|
184
|
-
result.push(array.slice(i, i + size));
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
175
|
// src/constants/objectIds.ts
|
|
190
176
|
var OBJECT_ID_MAP = {
|
|
191
177
|
1: "accountid",
|
|
@@ -1071,6 +1057,584 @@ var QueryBuilder = class {
|
|
|
1071
1057
|
}
|
|
1072
1058
|
};
|
|
1073
1059
|
|
|
1060
|
+
// src/utils/helpers.ts
|
|
1061
|
+
function wait(ms) {
|
|
1062
|
+
return new Promise((resolve) => {
|
|
1063
|
+
setTimeout(resolve, ms);
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
function chunkArray(array, size) {
|
|
1067
|
+
const result = [];
|
|
1068
|
+
for (let i = 0; i < array.length; i += size) {
|
|
1069
|
+
result.push(array.slice(i, i + size));
|
|
1070
|
+
}
|
|
1071
|
+
return result;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// src/transport/http.ts
|
|
1075
|
+
var HTTPTransport = class {
|
|
1076
|
+
config;
|
|
1077
|
+
constructor(config) {
|
|
1078
|
+
this.config = {
|
|
1079
|
+
apiKey: config.apiKey,
|
|
1080
|
+
baseUrl: config.baseUrl || "https://api.fireberry.com",
|
|
1081
|
+
timeout: config.timeout || 3e4,
|
|
1082
|
+
retryOn429: config.retryOn429 ?? true,
|
|
1083
|
+
maxRetries: config.maxRetries || 120,
|
|
1084
|
+
retryDelay: config.retryDelay || 1e3
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
getType() {
|
|
1088
|
+
return "http";
|
|
1089
|
+
}
|
|
1090
|
+
async request(options) {
|
|
1091
|
+
const { method, endpoint, query: queryParams, body, headers: customHeaders, signal } = options;
|
|
1092
|
+
let url = `${this.config.baseUrl}${endpoint}`;
|
|
1093
|
+
if (queryParams && Object.keys(queryParams).length > 0) {
|
|
1094
|
+
const params = new URLSearchParams();
|
|
1095
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
1096
|
+
if (value !== void 0 && value !== null) {
|
|
1097
|
+
params.set(key, String(value));
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
url += `?${params.toString()}`;
|
|
1101
|
+
}
|
|
1102
|
+
const headers = {
|
|
1103
|
+
Accept: "application/json",
|
|
1104
|
+
tokenid: this.config.apiKey,
|
|
1105
|
+
...customHeaders
|
|
1106
|
+
};
|
|
1107
|
+
if (body) {
|
|
1108
|
+
headers["Content-Type"] = "application/json";
|
|
1109
|
+
}
|
|
1110
|
+
const fetchOptions = {
|
|
1111
|
+
method,
|
|
1112
|
+
headers,
|
|
1113
|
+
signal
|
|
1114
|
+
};
|
|
1115
|
+
if (body) {
|
|
1116
|
+
fetchOptions.body = JSON.stringify(body);
|
|
1117
|
+
}
|
|
1118
|
+
return this.executeWithRetry(url, fetchOptions);
|
|
1119
|
+
}
|
|
1120
|
+
async query(options) {
|
|
1121
|
+
const {
|
|
1122
|
+
objectType,
|
|
1123
|
+
fields,
|
|
1124
|
+
query,
|
|
1125
|
+
sortBy = "modifiedon",
|
|
1126
|
+
sortType = "desc",
|
|
1127
|
+
limit,
|
|
1128
|
+
page = 1,
|
|
1129
|
+
pageSize = 500,
|
|
1130
|
+
showRealValue = true,
|
|
1131
|
+
autoPage = true,
|
|
1132
|
+
signal
|
|
1133
|
+
} = options;
|
|
1134
|
+
let fieldsStr;
|
|
1135
|
+
if (Array.isArray(fields)) {
|
|
1136
|
+
fieldsStr = fields.join(",");
|
|
1137
|
+
} else if (typeof fields === "string") {
|
|
1138
|
+
fieldsStr = fields;
|
|
1139
|
+
} else {
|
|
1140
|
+
fieldsStr = "*";
|
|
1141
|
+
}
|
|
1142
|
+
if (autoPage) {
|
|
1143
|
+
return this.queryAllPages({
|
|
1144
|
+
objectType,
|
|
1145
|
+
fields: fieldsStr,
|
|
1146
|
+
query,
|
|
1147
|
+
sortBy,
|
|
1148
|
+
sortType,
|
|
1149
|
+
showRealValue,
|
|
1150
|
+
limit,
|
|
1151
|
+
signal
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
const body = {
|
|
1155
|
+
objecttype: objectType,
|
|
1156
|
+
fields: fieldsStr,
|
|
1157
|
+
query: query || "",
|
|
1158
|
+
sort_by: sortBy,
|
|
1159
|
+
sort_type: sortType,
|
|
1160
|
+
page_size: Math.min(pageSize, limit || 500),
|
|
1161
|
+
page_number: page,
|
|
1162
|
+
show_real_value: showRealValue ? 1 : 0
|
|
1163
|
+
};
|
|
1164
|
+
const response = await this.request({
|
|
1165
|
+
method: "POST",
|
|
1166
|
+
endpoint: "/api/query",
|
|
1167
|
+
body,
|
|
1168
|
+
signal
|
|
1169
|
+
});
|
|
1170
|
+
const records = response.data?.Data || [];
|
|
1171
|
+
return {
|
|
1172
|
+
records,
|
|
1173
|
+
total: records.length,
|
|
1174
|
+
success: true
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
async createRecord(objectType, data, signal) {
|
|
1178
|
+
const response = await this.request({
|
|
1179
|
+
method: "POST",
|
|
1180
|
+
endpoint: `/api/v2/record/${objectType}`,
|
|
1181
|
+
body: data,
|
|
1182
|
+
signal
|
|
1183
|
+
});
|
|
1184
|
+
return response.record;
|
|
1185
|
+
}
|
|
1186
|
+
async updateRecord(objectType, recordId, data, signal) {
|
|
1187
|
+
const response = await this.request({
|
|
1188
|
+
method: "PUT",
|
|
1189
|
+
endpoint: `/api/v2/record/${objectType}/${recordId}`,
|
|
1190
|
+
body: data,
|
|
1191
|
+
signal
|
|
1192
|
+
});
|
|
1193
|
+
return response.record;
|
|
1194
|
+
}
|
|
1195
|
+
async deleteRecord(objectType, recordId, signal) {
|
|
1196
|
+
await this.request({
|
|
1197
|
+
method: "DELETE",
|
|
1198
|
+
endpoint: `/api/record/${objectType}/${recordId}`,
|
|
1199
|
+
signal
|
|
1200
|
+
});
|
|
1201
|
+
return {
|
|
1202
|
+
success: true,
|
|
1203
|
+
id: recordId
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
async batchCreate(objectType, records, signal) {
|
|
1207
|
+
const response = await this.request({
|
|
1208
|
+
method: "POST",
|
|
1209
|
+
endpoint: `/api/v3/record/${objectType}/batch/create`,
|
|
1210
|
+
body: { data: records },
|
|
1211
|
+
signal
|
|
1212
|
+
});
|
|
1213
|
+
const data = response.data || [];
|
|
1214
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
|
1215
|
+
return {
|
|
1216
|
+
success: true,
|
|
1217
|
+
data: dataArray,
|
|
1218
|
+
count: dataArray.length
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1221
|
+
async batchUpdate(objectType, records, signal) {
|
|
1222
|
+
const response = await this.request({
|
|
1223
|
+
method: "POST",
|
|
1224
|
+
endpoint: `/api/v3/record/${objectType}/batch/update`,
|
|
1225
|
+
body: { data: records },
|
|
1226
|
+
signal
|
|
1227
|
+
});
|
|
1228
|
+
const data = response.data || [];
|
|
1229
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
|
1230
|
+
return {
|
|
1231
|
+
success: true,
|
|
1232
|
+
data: dataArray,
|
|
1233
|
+
count: dataArray.length
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
async batchDelete(objectType, recordIds, signal) {
|
|
1237
|
+
await this.request({
|
|
1238
|
+
method: "POST",
|
|
1239
|
+
endpoint: `/api/v3/record/${objectType}/batch/delete`,
|
|
1240
|
+
body: { data: recordIds },
|
|
1241
|
+
signal
|
|
1242
|
+
});
|
|
1243
|
+
return {
|
|
1244
|
+
success: true,
|
|
1245
|
+
ids: recordIds,
|
|
1246
|
+
count: recordIds.length
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Fetches all pages of a query
|
|
1251
|
+
*/
|
|
1252
|
+
async queryAllPages(options) {
|
|
1253
|
+
const { objectType, fields, query, sortBy, sortType, showRealValue, limit, signal } = options;
|
|
1254
|
+
const maxPageSize = 500;
|
|
1255
|
+
const allRecords = [];
|
|
1256
|
+
let currentPage = 1;
|
|
1257
|
+
let hasMore = true;
|
|
1258
|
+
while (hasMore) {
|
|
1259
|
+
if (signal?.aborted) {
|
|
1260
|
+
break;
|
|
1261
|
+
}
|
|
1262
|
+
const body = {
|
|
1263
|
+
objecttype: objectType,
|
|
1264
|
+
fields,
|
|
1265
|
+
query: query || "",
|
|
1266
|
+
sort_by: sortBy,
|
|
1267
|
+
sort_type: sortType,
|
|
1268
|
+
page_size: maxPageSize,
|
|
1269
|
+
page_number: currentPage,
|
|
1270
|
+
show_real_value: showRealValue ? 1 : 0
|
|
1271
|
+
};
|
|
1272
|
+
const response = await this.request({
|
|
1273
|
+
method: "POST",
|
|
1274
|
+
endpoint: "/api/query",
|
|
1275
|
+
body,
|
|
1276
|
+
signal
|
|
1277
|
+
});
|
|
1278
|
+
const pageData = response.data?.Data || [];
|
|
1279
|
+
allRecords.push(...pageData);
|
|
1280
|
+
if (limit && allRecords.length >= limit) {
|
|
1281
|
+
allRecords.splice(limit);
|
|
1282
|
+
break;
|
|
1283
|
+
}
|
|
1284
|
+
if (pageData.length < maxPageSize) {
|
|
1285
|
+
hasMore = false;
|
|
1286
|
+
} else {
|
|
1287
|
+
currentPage++;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
return {
|
|
1291
|
+
records: allRecords,
|
|
1292
|
+
total: allRecords.length,
|
|
1293
|
+
success: true
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Executes a fetch request with retry logic for 429 errors
|
|
1298
|
+
*/
|
|
1299
|
+
async executeWithRetry(url, options, retryCount = 0) {
|
|
1300
|
+
try {
|
|
1301
|
+
const timeoutController = new AbortController();
|
|
1302
|
+
const timeoutId = setTimeout(() => {
|
|
1303
|
+
timeoutController.abort();
|
|
1304
|
+
}, this.config.timeout);
|
|
1305
|
+
const combinedSignal = options.signal ? this.combineSignals([options.signal, timeoutController.signal]) : timeoutController.signal;
|
|
1306
|
+
const response = await fetch(url, {
|
|
1307
|
+
...options,
|
|
1308
|
+
signal: combinedSignal
|
|
1309
|
+
});
|
|
1310
|
+
clearTimeout(timeoutId);
|
|
1311
|
+
if (response.status === 429 && this.config.retryOn429) {
|
|
1312
|
+
if (retryCount < this.config.maxRetries) {
|
|
1313
|
+
await wait(this.config.retryDelay);
|
|
1314
|
+
return this.executeWithRetry(url, options, retryCount + 1);
|
|
1315
|
+
}
|
|
1316
|
+
throw new FireberryError("Rate limit exceeded after max retries", {
|
|
1317
|
+
code: "RATE_LIMITED" /* RATE_LIMITED */,
|
|
1318
|
+
statusCode: 429,
|
|
1319
|
+
context: { retryCount }
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
let body;
|
|
1323
|
+
const contentType = response.headers.get("content-type");
|
|
1324
|
+
if (contentType?.includes("application/json")) {
|
|
1325
|
+
body = await response.json();
|
|
1326
|
+
} else {
|
|
1327
|
+
body = await response.text();
|
|
1328
|
+
}
|
|
1329
|
+
if (!response.ok) {
|
|
1330
|
+
throw createErrorFromResponse(response, body);
|
|
1331
|
+
}
|
|
1332
|
+
return body;
|
|
1333
|
+
} catch (error) {
|
|
1334
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1335
|
+
throw createNetworkError(error);
|
|
1336
|
+
}
|
|
1337
|
+
if (error instanceof FireberryError) {
|
|
1338
|
+
throw error;
|
|
1339
|
+
}
|
|
1340
|
+
throw createNetworkError(error);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Combines multiple abort signals into one
|
|
1345
|
+
*/
|
|
1346
|
+
combineSignals(signals) {
|
|
1347
|
+
const controller = new AbortController();
|
|
1348
|
+
for (const signal of signals) {
|
|
1349
|
+
if (signal.aborted) {
|
|
1350
|
+
controller.abort();
|
|
1351
|
+
break;
|
|
1352
|
+
}
|
|
1353
|
+
signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
1354
|
+
}
|
|
1355
|
+
return controller.signal;
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
// src/transport/sdk.ts
|
|
1360
|
+
var BATCH_SIZE = 20;
|
|
1361
|
+
var SDKTransport = class {
|
|
1362
|
+
sdk;
|
|
1363
|
+
constructor(config) {
|
|
1364
|
+
this.sdk = config.sdk;
|
|
1365
|
+
}
|
|
1366
|
+
getType() {
|
|
1367
|
+
return "sdk";
|
|
1368
|
+
}
|
|
1369
|
+
async request(_options) {
|
|
1370
|
+
throw new FireberryError(
|
|
1371
|
+
"Raw request() is not supported in SDK mode. Use specific methods like query(), createRecord(), etc.",
|
|
1372
|
+
{
|
|
1373
|
+
code: "INVALID_REQUEST" /* INVALID_REQUEST */
|
|
1374
|
+
}
|
|
1375
|
+
);
|
|
1376
|
+
}
|
|
1377
|
+
async query(options) {
|
|
1378
|
+
const {
|
|
1379
|
+
objectType,
|
|
1380
|
+
fields,
|
|
1381
|
+
query,
|
|
1382
|
+
limit,
|
|
1383
|
+
page = 1,
|
|
1384
|
+
pageSize = 500,
|
|
1385
|
+
autoPage = true,
|
|
1386
|
+
signal
|
|
1387
|
+
} = options;
|
|
1388
|
+
let fieldsStr;
|
|
1389
|
+
if (Array.isArray(fields)) {
|
|
1390
|
+
fieldsStr = fields.join(",");
|
|
1391
|
+
} else if (typeof fields === "string") {
|
|
1392
|
+
fieldsStr = fields;
|
|
1393
|
+
} else {
|
|
1394
|
+
fieldsStr = "*";
|
|
1395
|
+
}
|
|
1396
|
+
if (autoPage) {
|
|
1397
|
+
return this.queryAllPages({
|
|
1398
|
+
objectType,
|
|
1399
|
+
fields: fieldsStr,
|
|
1400
|
+
query,
|
|
1401
|
+
limit,
|
|
1402
|
+
pageSize,
|
|
1403
|
+
signal
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
const payload = {
|
|
1407
|
+
fields: fieldsStr,
|
|
1408
|
+
query: query || "",
|
|
1409
|
+
page_size: Math.min(pageSize, limit || 500),
|
|
1410
|
+
page_number: page
|
|
1411
|
+
};
|
|
1412
|
+
const response = await this.sdk.api.query(objectType, payload);
|
|
1413
|
+
if (!response.success && response.error) {
|
|
1414
|
+
throw new FireberryError(
|
|
1415
|
+
response.error.data?.Message || response.error.statusText || "SDK query failed",
|
|
1416
|
+
{
|
|
1417
|
+
code: "SERVER_ERROR" /* SERVER_ERROR */,
|
|
1418
|
+
statusCode: response.error.status,
|
|
1419
|
+
context: { response }
|
|
1420
|
+
}
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
const pageData = Array.isArray(response.data) ? response.data : [response.data];
|
|
1424
|
+
const records = pageData.filter(
|
|
1425
|
+
(record) => record && typeof record === "object"
|
|
1426
|
+
);
|
|
1427
|
+
return {
|
|
1428
|
+
records,
|
|
1429
|
+
total: records.length,
|
|
1430
|
+
success: true
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
async createRecord(objectType, data, signal) {
|
|
1434
|
+
if (signal?.aborted) {
|
|
1435
|
+
throw new FireberryError("Request aborted", {
|
|
1436
|
+
code: "NETWORK_ERROR" /* NETWORK_ERROR */
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
const response = await this.sdk.api.create(objectType, data);
|
|
1440
|
+
if (!response.success && response.error) {
|
|
1441
|
+
throw new FireberryError(
|
|
1442
|
+
response.error.data?.Message || response.error.statusText || "SDK create failed",
|
|
1443
|
+
{
|
|
1444
|
+
code: "SERVER_ERROR" /* SERVER_ERROR */,
|
|
1445
|
+
statusCode: response.error.status,
|
|
1446
|
+
context: { response }
|
|
1447
|
+
}
|
|
1448
|
+
);
|
|
1449
|
+
}
|
|
1450
|
+
return response.data;
|
|
1451
|
+
}
|
|
1452
|
+
async updateRecord(objectType, recordId, data, signal) {
|
|
1453
|
+
if (signal?.aborted) {
|
|
1454
|
+
throw new FireberryError("Request aborted", {
|
|
1455
|
+
code: "NETWORK_ERROR" /* NETWORK_ERROR */
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1458
|
+
const response = await this.sdk.api.update(objectType, recordId, data);
|
|
1459
|
+
if (!response.success && response.error) {
|
|
1460
|
+
throw new FireberryError(
|
|
1461
|
+
response.error.data?.Message || response.error.statusText || "SDK update failed",
|
|
1462
|
+
{
|
|
1463
|
+
code: "SERVER_ERROR" /* SERVER_ERROR */,
|
|
1464
|
+
statusCode: response.error.status,
|
|
1465
|
+
context: { response }
|
|
1466
|
+
}
|
|
1467
|
+
);
|
|
1468
|
+
}
|
|
1469
|
+
return response.data;
|
|
1470
|
+
}
|
|
1471
|
+
async deleteRecord(objectType, recordId, signal) {
|
|
1472
|
+
if (signal?.aborted) {
|
|
1473
|
+
throw new FireberryError("Request aborted", {
|
|
1474
|
+
code: "NETWORK_ERROR" /* NETWORK_ERROR */
|
|
1475
|
+
});
|
|
1476
|
+
}
|
|
1477
|
+
const response = await this.sdk.api.delete(objectType, recordId);
|
|
1478
|
+
if (!response.success && response.error) {
|
|
1479
|
+
throw new FireberryError(
|
|
1480
|
+
response.error.data?.Message || response.error.statusText || "SDK delete failed",
|
|
1481
|
+
{
|
|
1482
|
+
code: "SERVER_ERROR" /* SERVER_ERROR */,
|
|
1483
|
+
statusCode: response.error.status,
|
|
1484
|
+
context: { response }
|
|
1485
|
+
}
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
return {
|
|
1489
|
+
success: true,
|
|
1490
|
+
id: recordId
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
async batchCreate(objectType, records, signal) {
|
|
1494
|
+
const batches = chunkArray(records, BATCH_SIZE);
|
|
1495
|
+
const allResponses = [];
|
|
1496
|
+
for (const batch of batches) {
|
|
1497
|
+
if (signal?.aborted) {
|
|
1498
|
+
break;
|
|
1499
|
+
}
|
|
1500
|
+
const batchPromises = batch.map((record) => this.createRecord(objectType, record, signal));
|
|
1501
|
+
const batchResults = await Promise.all(batchPromises);
|
|
1502
|
+
allResponses.push(...batchResults);
|
|
1503
|
+
}
|
|
1504
|
+
return {
|
|
1505
|
+
success: true,
|
|
1506
|
+
data: allResponses,
|
|
1507
|
+
count: allResponses.length
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
async batchUpdate(objectType, records, signal) {
|
|
1511
|
+
const batches = chunkArray(records, BATCH_SIZE);
|
|
1512
|
+
const allResponses = [];
|
|
1513
|
+
for (const batch of batches) {
|
|
1514
|
+
if (signal?.aborted) {
|
|
1515
|
+
break;
|
|
1516
|
+
}
|
|
1517
|
+
const batchPromises = batch.map(
|
|
1518
|
+
(item) => this.updateRecord(objectType, item.id, item.record, signal)
|
|
1519
|
+
);
|
|
1520
|
+
const batchResults = await Promise.all(batchPromises);
|
|
1521
|
+
allResponses.push(...batchResults);
|
|
1522
|
+
}
|
|
1523
|
+
return {
|
|
1524
|
+
success: true,
|
|
1525
|
+
data: allResponses,
|
|
1526
|
+
count: allResponses.length
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
async batchDelete(objectType, recordIds, signal) {
|
|
1530
|
+
const batches = chunkArray(recordIds, BATCH_SIZE);
|
|
1531
|
+
const allDeletedIds = [];
|
|
1532
|
+
for (const batch of batches) {
|
|
1533
|
+
if (signal?.aborted) {
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
const batchPromises = batch.map((id) => this.deleteRecord(objectType, id, signal));
|
|
1537
|
+
await Promise.all(batchPromises);
|
|
1538
|
+
allDeletedIds.push(...batch);
|
|
1539
|
+
}
|
|
1540
|
+
return {
|
|
1541
|
+
success: true,
|
|
1542
|
+
ids: allDeletedIds,
|
|
1543
|
+
count: allDeletedIds.length
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Fetches all pages of a query using SDK
|
|
1548
|
+
*/
|
|
1549
|
+
async queryAllPages(options) {
|
|
1550
|
+
const { objectType, fields, query, limit, pageSize = 500, signal } = options;
|
|
1551
|
+
const maxPageSize = 500;
|
|
1552
|
+
const allRecords = [];
|
|
1553
|
+
let currentPage = 1;
|
|
1554
|
+
let hasMore = true;
|
|
1555
|
+
while (hasMore) {
|
|
1556
|
+
if (signal?.aborted) {
|
|
1557
|
+
break;
|
|
1558
|
+
}
|
|
1559
|
+
const payload = {
|
|
1560
|
+
fields,
|
|
1561
|
+
query: query || "",
|
|
1562
|
+
page_size: Math.min(maxPageSize, pageSize),
|
|
1563
|
+
page_number: currentPage
|
|
1564
|
+
};
|
|
1565
|
+
const response = await this.sdk.api.query(objectType, payload);
|
|
1566
|
+
if (!response.success && response.error) {
|
|
1567
|
+
throw new FireberryError(
|
|
1568
|
+
response.error.data?.Message || response.error.statusText || "SDK query failed",
|
|
1569
|
+
{
|
|
1570
|
+
code: "SERVER_ERROR" /* SERVER_ERROR */,
|
|
1571
|
+
statusCode: response.error.status,
|
|
1572
|
+
context: { response }
|
|
1573
|
+
}
|
|
1574
|
+
);
|
|
1575
|
+
}
|
|
1576
|
+
const pageData = Array.isArray(response.data) ? response.data : [response.data];
|
|
1577
|
+
const validRecords = pageData.filter(
|
|
1578
|
+
(record) => record && typeof record === "object"
|
|
1579
|
+
);
|
|
1580
|
+
allRecords.push(...validRecords);
|
|
1581
|
+
if (limit && allRecords.length >= limit) {
|
|
1582
|
+
allRecords.splice(limit);
|
|
1583
|
+
break;
|
|
1584
|
+
}
|
|
1585
|
+
if (validRecords.length < maxPageSize) {
|
|
1586
|
+
hasMore = false;
|
|
1587
|
+
} else {
|
|
1588
|
+
currentPage++;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
return {
|
|
1592
|
+
records: allRecords,
|
|
1593
|
+
total: allRecords.length,
|
|
1594
|
+
success: true
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
// src/utils/transport.ts
|
|
1600
|
+
function createTransport(config) {
|
|
1601
|
+
if (config.sdk) {
|
|
1602
|
+
return new SDKTransport({ sdk: config.sdk });
|
|
1603
|
+
}
|
|
1604
|
+
if (config.apiKey) {
|
|
1605
|
+
return new HTTPTransport({
|
|
1606
|
+
apiKey: config.apiKey,
|
|
1607
|
+
baseUrl: config.baseUrl,
|
|
1608
|
+
timeout: config.timeout,
|
|
1609
|
+
retryOn429: config.retryOn429,
|
|
1610
|
+
maxRetries: config.maxRetries,
|
|
1611
|
+
retryDelay: config.retryDelay
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
throw new FireberryError(
|
|
1615
|
+
"Either apiKey or sdk must be provided in FireberryClientConfig",
|
|
1616
|
+
{
|
|
1617
|
+
code: "INVALID_REQUEST" /* INVALID_REQUEST */
|
|
1618
|
+
}
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
function createMetadataTransport(config) {
|
|
1622
|
+
if (!config.apiKey) {
|
|
1623
|
+
return null;
|
|
1624
|
+
}
|
|
1625
|
+
return new HTTPTransport({
|
|
1626
|
+
apiKey: config.apiKey,
|
|
1627
|
+
baseUrl: config.baseUrl,
|
|
1628
|
+
timeout: config.timeout,
|
|
1629
|
+
retryOn429: config.retryOn429,
|
|
1630
|
+
maxRetries: config.maxRetries,
|
|
1631
|
+
retryDelay: config.retryDelay
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
function isMetadataAvailable(config) {
|
|
1635
|
+
return Boolean(config.apiKey);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1074
1638
|
// src/constants/fieldTypes.ts
|
|
1075
1639
|
var FIELD_TYPE_IDS = {
|
|
1076
1640
|
DROPDOWN: "b4919f2e-2996-48e4-a03c-ba39fb64386c",
|
|
@@ -1111,6 +1675,23 @@ var MetadataAPI = class {
|
|
|
1111
1675
|
constructor(client) {
|
|
1112
1676
|
this.client = client;
|
|
1113
1677
|
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Checks if metadata operations are available and throws error if not
|
|
1680
|
+
* @private
|
|
1681
|
+
*/
|
|
1682
|
+
ensureMetadataAvailable() {
|
|
1683
|
+
if (!this.client.isMetadataAvailable()) {
|
|
1684
|
+
throw new FireberryError(
|
|
1685
|
+
"Metadata operations are not available in SDK-only mode. Please provide an API key in the FireberryClient configuration to use metadata features.",
|
|
1686
|
+
{
|
|
1687
|
+
code: "INVALID_REQUEST" /* INVALID_REQUEST */,
|
|
1688
|
+
context: {
|
|
1689
|
+
hint: "Fireberry SDK does not yet support metadata operations. Use API key mode or hybrid mode (both SDK + API key) to access metadata."
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1114
1695
|
/**
|
|
1115
1696
|
* Gets all available objects/entity types from Fireberry
|
|
1116
1697
|
*
|
|
@@ -1124,6 +1705,7 @@ var MetadataAPI = class {
|
|
|
1124
1705
|
* ```
|
|
1125
1706
|
*/
|
|
1126
1707
|
async getObjects(signal) {
|
|
1708
|
+
this.ensureMetadataAvailable();
|
|
1127
1709
|
const cached = this.client.getCached("objects");
|
|
1128
1710
|
if (cached) {
|
|
1129
1711
|
return cached;
|
|
@@ -1161,6 +1743,7 @@ var MetadataAPI = class {
|
|
|
1161
1743
|
* ```
|
|
1162
1744
|
*/
|
|
1163
1745
|
async getFields(objectType, options) {
|
|
1746
|
+
this.ensureMetadataAvailable();
|
|
1164
1747
|
const objectTypeStr = String(objectType);
|
|
1165
1748
|
const opts = options instanceof AbortSignal ? { signal: options, includeLookupRelations: true } : { signal: options?.signal, includeLookupRelations: options?.includeLookupRelations ?? true };
|
|
1166
1749
|
const cached = this.client.getCached("fields", objectTypeStr);
|
|
@@ -1217,24 +1800,27 @@ var MetadataAPI = class {
|
|
|
1217
1800
|
if (queryableFields.length === 0) {
|
|
1218
1801
|
return relations;
|
|
1219
1802
|
}
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1803
|
+
try {
|
|
1804
|
+
const response = await this.client.request({
|
|
1805
|
+
method: "POST",
|
|
1806
|
+
endpoint: ENDPOINTS.QUERY,
|
|
1807
|
+
body: {
|
|
1808
|
+
objecttype: objectType,
|
|
1809
|
+
fields: queryableFields.join(","),
|
|
1810
|
+
query: "",
|
|
1811
|
+
page_size: 1,
|
|
1812
|
+
page_number: 1,
|
|
1813
|
+
show_real_value: 0
|
|
1814
|
+
},
|
|
1815
|
+
signal
|
|
1816
|
+
});
|
|
1817
|
+
const columns = response.data?.Columns || [];
|
|
1818
|
+
for (const column of columns) {
|
|
1819
|
+
if (column.fieldobjecttype !== null && column.fieldobjecttype !== void 0) {
|
|
1820
|
+
relations.set(column.fieldname, column.fieldobjecttype);
|
|
1821
|
+
}
|
|
1237
1822
|
}
|
|
1823
|
+
} catch (error) {
|
|
1238
1824
|
}
|
|
1239
1825
|
return relations;
|
|
1240
1826
|
}
|
|
@@ -1253,6 +1839,7 @@ var MetadataAPI = class {
|
|
|
1253
1839
|
* ```
|
|
1254
1840
|
*/
|
|
1255
1841
|
async getFieldValues(objectType, fieldName, signal) {
|
|
1842
|
+
this.ensureMetadataAvailable();
|
|
1256
1843
|
const objectTypeStr = String(objectType);
|
|
1257
1844
|
const cached = this.client.getCached(
|
|
1258
1845
|
"fieldValues",
|
|
@@ -1302,14 +1889,10 @@ var RecordsAPI = class {
|
|
|
1302
1889
|
*/
|
|
1303
1890
|
async create(objectType, data, options) {
|
|
1304
1891
|
const objectTypeStr = String(objectType);
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1307
|
-
endpoint: `/api/v2/record/${objectTypeStr}`,
|
|
1308
|
-
body: data,
|
|
1309
|
-
signal: options?.signal
|
|
1310
|
-
});
|
|
1892
|
+
const transport = this.client.getTransport();
|
|
1893
|
+
const record = await transport.createRecord(objectTypeStr, data, options?.signal);
|
|
1311
1894
|
this.client.invalidateCacheForMutation(objectTypeStr);
|
|
1312
|
-
return
|
|
1895
|
+
return record;
|
|
1313
1896
|
}
|
|
1314
1897
|
/**
|
|
1315
1898
|
* Updates an existing record in Fireberry
|
|
@@ -1329,14 +1912,10 @@ var RecordsAPI = class {
|
|
|
1329
1912
|
*/
|
|
1330
1913
|
async update(objectType, recordId, data, options) {
|
|
1331
1914
|
const objectTypeStr = String(objectType);
|
|
1332
|
-
const
|
|
1333
|
-
|
|
1334
|
-
endpoint: `/api/v2/record/${objectTypeStr}/${recordId}`,
|
|
1335
|
-
body: data,
|
|
1336
|
-
signal: options?.signal
|
|
1337
|
-
});
|
|
1915
|
+
const transport = this.client.getTransport();
|
|
1916
|
+
const record = await transport.updateRecord(objectTypeStr, recordId, data, options?.signal);
|
|
1338
1917
|
this.client.invalidateCacheForMutation(objectTypeStr);
|
|
1339
|
-
return
|
|
1918
|
+
return record;
|
|
1340
1919
|
}
|
|
1341
1920
|
/**
|
|
1342
1921
|
* Deletes a record from Fireberry
|
|
@@ -1353,16 +1932,10 @@ var RecordsAPI = class {
|
|
|
1353
1932
|
*/
|
|
1354
1933
|
async delete(objectType, recordId, options) {
|
|
1355
1934
|
const objectTypeStr = String(objectType);
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
endpoint: `/api/record/${objectTypeStr}/${recordId}`,
|
|
1359
|
-
signal: options?.signal
|
|
1360
|
-
});
|
|
1935
|
+
const transport = this.client.getTransport();
|
|
1936
|
+
const result = await transport.deleteRecord(objectTypeStr, recordId, options?.signal);
|
|
1361
1937
|
this.client.invalidateCacheForMutation(objectTypeStr);
|
|
1362
|
-
return
|
|
1363
|
-
success: true,
|
|
1364
|
-
id: recordId
|
|
1365
|
-
};
|
|
1938
|
+
return result;
|
|
1366
1939
|
}
|
|
1367
1940
|
/**
|
|
1368
1941
|
* Upserts a record (creates if not exists, updates if exists)
|
|
@@ -1430,7 +2003,7 @@ var RecordsAPI = class {
|
|
|
1430
2003
|
};
|
|
1431
2004
|
|
|
1432
2005
|
// src/api/batch.ts
|
|
1433
|
-
var
|
|
2006
|
+
var BATCH_SIZE2 = 20;
|
|
1434
2007
|
var BatchAPI = class {
|
|
1435
2008
|
constructor(client) {
|
|
1436
2009
|
this.client = client;
|
|
@@ -1455,25 +2028,15 @@ var BatchAPI = class {
|
|
|
1455
2028
|
*/
|
|
1456
2029
|
async create(objectType, records, options) {
|
|
1457
2030
|
const objectTypeStr = String(objectType);
|
|
1458
|
-
const
|
|
2031
|
+
const transport = this.client.getTransport();
|
|
2032
|
+
const batches = chunkArray(records, BATCH_SIZE2);
|
|
1459
2033
|
const allResponses = [];
|
|
1460
2034
|
for (const batch of batches) {
|
|
1461
2035
|
if (options?.signal?.aborted) {
|
|
1462
2036
|
break;
|
|
1463
2037
|
}
|
|
1464
|
-
const
|
|
1465
|
-
|
|
1466
|
-
endpoint: `/api/v3/record/${objectTypeStr}/batch/create`,
|
|
1467
|
-
body: { data: batch },
|
|
1468
|
-
signal: options?.signal
|
|
1469
|
-
});
|
|
1470
|
-
if (response.data) {
|
|
1471
|
-
if (Array.isArray(response.data)) {
|
|
1472
|
-
allResponses.push(...response.data);
|
|
1473
|
-
} else {
|
|
1474
|
-
allResponses.push(response.data);
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
2038
|
+
const result = await transport.batchCreate(objectTypeStr, batch, options?.signal);
|
|
2039
|
+
allResponses.push(...result.data);
|
|
1477
2040
|
}
|
|
1478
2041
|
this.client.invalidateCacheForMutation(objectTypeStr);
|
|
1479
2042
|
return {
|
|
@@ -1501,25 +2064,15 @@ var BatchAPI = class {
|
|
|
1501
2064
|
*/
|
|
1502
2065
|
async update(objectType, records, options) {
|
|
1503
2066
|
const objectTypeStr = String(objectType);
|
|
1504
|
-
const
|
|
2067
|
+
const transport = this.client.getTransport();
|
|
2068
|
+
const batches = chunkArray(records, BATCH_SIZE2);
|
|
1505
2069
|
const allResponses = [];
|
|
1506
2070
|
for (const batch of batches) {
|
|
1507
2071
|
if (options?.signal?.aborted) {
|
|
1508
2072
|
break;
|
|
1509
2073
|
}
|
|
1510
|
-
const
|
|
1511
|
-
|
|
1512
|
-
endpoint: `/api/v3/record/${objectTypeStr}/batch/update`,
|
|
1513
|
-
body: { data: batch },
|
|
1514
|
-
signal: options?.signal
|
|
1515
|
-
});
|
|
1516
|
-
if (response.data) {
|
|
1517
|
-
if (Array.isArray(response.data)) {
|
|
1518
|
-
allResponses.push(...response.data);
|
|
1519
|
-
} else {
|
|
1520
|
-
allResponses.push(response.data);
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
2074
|
+
const result = await transport.batchUpdate(objectTypeStr, batch, options?.signal);
|
|
2075
|
+
allResponses.push(...result.data);
|
|
1523
2076
|
}
|
|
1524
2077
|
this.client.invalidateCacheForMutation(objectTypeStr);
|
|
1525
2078
|
return {
|
|
@@ -1545,19 +2098,15 @@ var BatchAPI = class {
|
|
|
1545
2098
|
*/
|
|
1546
2099
|
async delete(objectType, recordIds, options) {
|
|
1547
2100
|
const objectTypeStr = String(objectType);
|
|
1548
|
-
const
|
|
2101
|
+
const transport = this.client.getTransport();
|
|
2102
|
+
const batches = chunkArray(recordIds, BATCH_SIZE2);
|
|
1549
2103
|
const allDeletedIds = [];
|
|
1550
2104
|
for (const batch of batches) {
|
|
1551
2105
|
if (options?.signal?.aborted) {
|
|
1552
2106
|
break;
|
|
1553
2107
|
}
|
|
1554
|
-
await
|
|
1555
|
-
|
|
1556
|
-
endpoint: `/api/v3/record/${objectTypeStr}/batch/delete`,
|
|
1557
|
-
body: { data: batch },
|
|
1558
|
-
signal: options?.signal
|
|
1559
|
-
});
|
|
1560
|
-
allDeletedIds.push(...batch);
|
|
2108
|
+
const result = await transport.batchDelete(objectTypeStr, batch, options?.signal);
|
|
2109
|
+
allDeletedIds.push(...result.ids);
|
|
1561
2110
|
}
|
|
1562
2111
|
this.client.invalidateCacheForMutation(objectTypeStr);
|
|
1563
2112
|
return {
|
|
@@ -1735,7 +2284,15 @@ var FilesAPI = class {
|
|
|
1735
2284
|
const objectTypeStr = String(objectType);
|
|
1736
2285
|
const { buffer, filename, mimeType } = options;
|
|
1737
2286
|
const config = this.client.getConfig();
|
|
1738
|
-
|
|
2287
|
+
if (!config.apiKey) {
|
|
2288
|
+
throw new FireberryError(
|
|
2289
|
+
"File upload requires an API key. SDK mode does not support file uploads.",
|
|
2290
|
+
{
|
|
2291
|
+
code: "INVALID_REQUEST" /* INVALID_REQUEST */
|
|
2292
|
+
}
|
|
2293
|
+
);
|
|
2294
|
+
}
|
|
2295
|
+
const url = `${config.baseUrl || "https://api.fireberry.com"}/api/v2/record/${objectTypeStr}/${recordId}/files`;
|
|
1739
2296
|
const boundary = `----FormBoundary${Date.now()}`;
|
|
1740
2297
|
const formParts = [];
|
|
1741
2298
|
const fileHeader = [
|
|
@@ -1808,9 +2365,12 @@ function generateQueryCacheKey(options) {
|
|
|
1808
2365
|
}
|
|
1809
2366
|
var FireberryClient = class {
|
|
1810
2367
|
config;
|
|
2368
|
+
normalizedConfig;
|
|
1811
2369
|
cacheStore;
|
|
1812
2370
|
inFlightQueries = /* @__PURE__ */ new Map();
|
|
1813
2371
|
queryCache = /* @__PURE__ */ new Map();
|
|
2372
|
+
transport;
|
|
2373
|
+
metadataTransport;
|
|
1814
2374
|
/** Metadata API operations */
|
|
1815
2375
|
metadata;
|
|
1816
2376
|
/** Records CRUD operations */
|
|
@@ -1825,8 +2385,8 @@ var FireberryClient = class {
|
|
|
1825
2385
|
* Creates a new FireberryClient instance
|
|
1826
2386
|
*/
|
|
1827
2387
|
constructor(config) {
|
|
1828
|
-
this.config =
|
|
1829
|
-
|
|
2388
|
+
this.config = config;
|
|
2389
|
+
this.normalizedConfig = {
|
|
1830
2390
|
baseUrl: config.baseUrl || "https://api.fireberry.com",
|
|
1831
2391
|
timeout: config.timeout || 3e4,
|
|
1832
2392
|
retryOn429: config.retryOn429 ?? true,
|
|
@@ -1845,6 +2405,8 @@ var FireberryClient = class {
|
|
|
1845
2405
|
fields: /* @__PURE__ */ new Map(),
|
|
1846
2406
|
fieldValues: /* @__PURE__ */ new Map()
|
|
1847
2407
|
};
|
|
2408
|
+
this.transport = createTransport(config);
|
|
2409
|
+
this.metadataTransport = createMetadataTransport(config);
|
|
1848
2410
|
this.metadata = new MetadataAPI(this);
|
|
1849
2411
|
this.records = new RecordsAPI(this);
|
|
1850
2412
|
this.batch = new BatchAPI(this);
|
|
@@ -1852,10 +2414,34 @@ var FireberryClient = class {
|
|
|
1852
2414
|
this.files = new FilesAPI(this);
|
|
1853
2415
|
}
|
|
1854
2416
|
/**
|
|
1855
|
-
* Gets the client configuration
|
|
2417
|
+
* Gets the client configuration with all defaults applied
|
|
1856
2418
|
*/
|
|
1857
2419
|
getConfig() {
|
|
1858
|
-
return
|
|
2420
|
+
return {
|
|
2421
|
+
...this.config,
|
|
2422
|
+
...this.normalizedConfig
|
|
2423
|
+
};
|
|
2424
|
+
}
|
|
2425
|
+
/**
|
|
2426
|
+
* Gets the transport instance (for internal use by API modules)
|
|
2427
|
+
* @internal
|
|
2428
|
+
*/
|
|
2429
|
+
getTransport() {
|
|
2430
|
+
return this.transport;
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Gets the metadata transport instance (for internal use by MetadataAPI)
|
|
2434
|
+
* Returns null if metadata is not available (SDK-only mode without API key)
|
|
2435
|
+
* @internal
|
|
2436
|
+
*/
|
|
2437
|
+
getMetadataTransport() {
|
|
2438
|
+
return this.metadataTransport;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* Checks if metadata operations are available
|
|
2442
|
+
*/
|
|
2443
|
+
isMetadataAvailable() {
|
|
2444
|
+
return isMetadataAvailable(this.config);
|
|
1859
2445
|
}
|
|
1860
2446
|
/**
|
|
1861
2447
|
* Cache control methods
|
|
@@ -1904,7 +2490,7 @@ var FireberryClient = class {
|
|
|
1904
2490
|
* @internal
|
|
1905
2491
|
*/
|
|
1906
2492
|
invalidateCacheForMutation(objectType) {
|
|
1907
|
-
if (this.
|
|
2493
|
+
if (this.normalizedConfig.invalidateCacheOnMutation) {
|
|
1908
2494
|
this.cache.clearQueryResultsForObject(objectType);
|
|
1909
2495
|
}
|
|
1910
2496
|
}
|
|
@@ -1913,55 +2499,55 @@ var FireberryClient = class {
|
|
|
1913
2499
|
*/
|
|
1914
2500
|
cleanupExpiredCacheEntries() {
|
|
1915
2501
|
const now = Date.now();
|
|
1916
|
-
if (this.
|
|
2502
|
+
if (this.normalizedConfig.cacheQueryResults) {
|
|
1917
2503
|
for (const [key, entry] of this.queryCache) {
|
|
1918
|
-
if (now - entry.timestamp >= this.
|
|
2504
|
+
if (now - entry.timestamp >= this.normalizedConfig.queryResultCacheTTL) {
|
|
1919
2505
|
this.queryCache.delete(key);
|
|
1920
2506
|
}
|
|
1921
2507
|
}
|
|
1922
2508
|
}
|
|
1923
|
-
if (this.
|
|
1924
|
-
if (this.cacheStore.objects && now - this.cacheStore.objects.timestamp >= this.
|
|
2509
|
+
if (this.normalizedConfig.cacheMetadata) {
|
|
2510
|
+
if (this.cacheStore.objects && now - this.cacheStore.objects.timestamp >= this.normalizedConfig.cacheTTL) {
|
|
1925
2511
|
this.cacheStore.objects = void 0;
|
|
1926
2512
|
}
|
|
1927
2513
|
for (const [key, entry] of this.cacheStore.fields) {
|
|
1928
|
-
if (now - entry.timestamp >= this.
|
|
2514
|
+
if (now - entry.timestamp >= this.normalizedConfig.cacheTTL) {
|
|
1929
2515
|
this.cacheStore.fields.delete(key);
|
|
1930
2516
|
}
|
|
1931
2517
|
}
|
|
1932
2518
|
for (const [key, entry] of this.cacheStore.fieldValues) {
|
|
1933
|
-
if (now - entry.timestamp >= this.
|
|
2519
|
+
if (now - entry.timestamp >= this.normalizedConfig.cacheTTL) {
|
|
1934
2520
|
this.cacheStore.fieldValues.delete(key);
|
|
1935
2521
|
}
|
|
1936
2522
|
}
|
|
1937
2523
|
}
|
|
1938
2524
|
}
|
|
1939
2525
|
getCached(type, objectType, fieldName) {
|
|
1940
|
-
if (!this.
|
|
2526
|
+
if (!this.normalizedConfig.cacheMetadata) {
|
|
1941
2527
|
return void 0;
|
|
1942
2528
|
}
|
|
1943
2529
|
const now = Date.now();
|
|
1944
2530
|
if (type === "objects") {
|
|
1945
2531
|
const cached = this.cacheStore.objects;
|
|
1946
|
-
if (cached && now - cached.timestamp < this.
|
|
2532
|
+
if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {
|
|
1947
2533
|
return cached.data;
|
|
1948
2534
|
}
|
|
1949
2535
|
} else if (type === "fields" && objectType) {
|
|
1950
2536
|
const cached = this.cacheStore.fields.get(objectType);
|
|
1951
|
-
if (cached && now - cached.timestamp < this.
|
|
2537
|
+
if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {
|
|
1952
2538
|
return cached.data;
|
|
1953
2539
|
}
|
|
1954
2540
|
} else if (type === "fieldValues" && objectType && fieldName) {
|
|
1955
2541
|
const key = `${objectType}:${fieldName}`;
|
|
1956
2542
|
const cached = this.cacheStore.fieldValues.get(key);
|
|
1957
|
-
if (cached && now - cached.timestamp < this.
|
|
2543
|
+
if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {
|
|
1958
2544
|
return cached.data;
|
|
1959
2545
|
}
|
|
1960
2546
|
}
|
|
1961
2547
|
return void 0;
|
|
1962
2548
|
}
|
|
1963
2549
|
setCache(type, objectTypeOrData, fieldNameOrData, data) {
|
|
1964
|
-
if (!this.
|
|
2550
|
+
if (!this.normalizedConfig.cacheMetadata) {
|
|
1965
2551
|
return;
|
|
1966
2552
|
}
|
|
1967
2553
|
this.cleanupExpiredCacheEntries();
|
|
@@ -2114,9 +2700,9 @@ var FireberryClient = class {
|
|
|
2114
2700
|
*/
|
|
2115
2701
|
async query(options) {
|
|
2116
2702
|
const cacheKey = generateQueryCacheKey(options);
|
|
2117
|
-
if (this.
|
|
2703
|
+
if (this.normalizedConfig.cacheQueryResults) {
|
|
2118
2704
|
const cached = this.queryCache.get(cacheKey);
|
|
2119
|
-
if (cached && Date.now() - cached.timestamp < this.
|
|
2705
|
+
if (cached && Date.now() - cached.timestamp < this.normalizedConfig.queryResultCacheTTL) {
|
|
2120
2706
|
return cached.data;
|
|
2121
2707
|
}
|
|
2122
2708
|
}
|
|
@@ -2128,7 +2714,7 @@ var FireberryClient = class {
|
|
|
2128
2714
|
this.inFlightQueries.set(cacheKey, queryPromise);
|
|
2129
2715
|
try {
|
|
2130
2716
|
const result = await queryPromise;
|
|
2131
|
-
if (this.
|
|
2717
|
+
if (this.normalizedConfig.cacheQueryResults) {
|
|
2132
2718
|
this.cleanupExpiredCacheEntries();
|
|
2133
2719
|
this.queryCache.set(cacheKey, {
|
|
2134
2720
|
data: result,
|
|
@@ -2147,14 +2733,6 @@ var FireberryClient = class {
|
|
|
2147
2733
|
const {
|
|
2148
2734
|
objectType,
|
|
2149
2735
|
fields,
|
|
2150
|
-
query,
|
|
2151
|
-
sortBy = "modifiedon",
|
|
2152
|
-
sortType = "desc",
|
|
2153
|
-
limit,
|
|
2154
|
-
page = 1,
|
|
2155
|
-
pageSize = 500,
|
|
2156
|
-
showRealValue = true,
|
|
2157
|
-
autoPage = true,
|
|
2158
2736
|
signal
|
|
2159
2737
|
} = options;
|
|
2160
2738
|
let fieldsStr;
|
|
@@ -2168,87 +2746,10 @@ var FireberryClient = class {
|
|
|
2168
2746
|
if (fieldsStr === "*") {
|
|
2169
2747
|
fieldsStr = await this.expandStarFields(objectType, signal);
|
|
2170
2748
|
}
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
fields: fieldsStr,
|
|
2175
|
-
query,
|
|
2176
|
-
sortBy,
|
|
2177
|
-
sortType,
|
|
2178
|
-
showRealValue,
|
|
2179
|
-
limit,
|
|
2180
|
-
signal
|
|
2181
|
-
});
|
|
2182
|
-
}
|
|
2183
|
-
const body = {
|
|
2184
|
-
objecttype: objectType,
|
|
2185
|
-
fields: fieldsStr,
|
|
2186
|
-
query: query || "",
|
|
2187
|
-
sort_by: sortBy,
|
|
2188
|
-
sort_type: sortType,
|
|
2189
|
-
page_size: Math.min(pageSize, limit || 500),
|
|
2190
|
-
page_number: page,
|
|
2191
|
-
show_real_value: showRealValue ? 1 : 0
|
|
2192
|
-
};
|
|
2193
|
-
const response = await this.request({
|
|
2194
|
-
method: "POST",
|
|
2195
|
-
endpoint: "/api/query",
|
|
2196
|
-
body,
|
|
2197
|
-
signal
|
|
2749
|
+
return this.transport.query({
|
|
2750
|
+
...options,
|
|
2751
|
+
fields: fieldsStr
|
|
2198
2752
|
});
|
|
2199
|
-
const records = response.data?.Data || [];
|
|
2200
|
-
return {
|
|
2201
|
-
records,
|
|
2202
|
-
total: records.length,
|
|
2203
|
-
success: true
|
|
2204
|
-
};
|
|
2205
|
-
}
|
|
2206
|
-
/**
|
|
2207
|
-
* Fetches all pages of a query
|
|
2208
|
-
*/
|
|
2209
|
-
async queryAllPages(options) {
|
|
2210
|
-
const { objectType, fields, query, sortBy, sortType, showRealValue, limit, signal } = options;
|
|
2211
|
-
const maxPageSize = 500;
|
|
2212
|
-
const allRecords = [];
|
|
2213
|
-
let currentPage = 1;
|
|
2214
|
-
let hasMore = true;
|
|
2215
|
-
while (hasMore) {
|
|
2216
|
-
if (signal?.aborted) {
|
|
2217
|
-
break;
|
|
2218
|
-
}
|
|
2219
|
-
const body = {
|
|
2220
|
-
objecttype: objectType,
|
|
2221
|
-
fields,
|
|
2222
|
-
query: query || "",
|
|
2223
|
-
sort_by: sortBy,
|
|
2224
|
-
sort_type: sortType,
|
|
2225
|
-
page_size: maxPageSize,
|
|
2226
|
-
page_number: currentPage,
|
|
2227
|
-
show_real_value: showRealValue ? 1 : 0
|
|
2228
|
-
};
|
|
2229
|
-
const response = await this.request({
|
|
2230
|
-
method: "POST",
|
|
2231
|
-
endpoint: "/api/query",
|
|
2232
|
-
body,
|
|
2233
|
-
signal
|
|
2234
|
-
});
|
|
2235
|
-
const pageData = response.data?.Data || [];
|
|
2236
|
-
allRecords.push(...pageData);
|
|
2237
|
-
if (limit && allRecords.length >= limit) {
|
|
2238
|
-
allRecords.splice(limit);
|
|
2239
|
-
break;
|
|
2240
|
-
}
|
|
2241
|
-
if (pageData.length < maxPageSize) {
|
|
2242
|
-
hasMore = false;
|
|
2243
|
-
} else {
|
|
2244
|
-
currentPage++;
|
|
2245
|
-
}
|
|
2246
|
-
}
|
|
2247
|
-
return {
|
|
2248
|
-
records: allRecords,
|
|
2249
|
-
total: allRecords.length,
|
|
2250
|
-
success: true
|
|
2251
|
-
};
|
|
2252
2753
|
}
|
|
2253
2754
|
/**
|
|
2254
2755
|
* Expands '*' fields to actual field names, excluding problematic fields for specific object types
|
|
@@ -2268,104 +2769,20 @@ var FireberryClient = class {
|
|
|
2268
2769
|
}
|
|
2269
2770
|
/**
|
|
2270
2771
|
* Makes a raw API request to the Fireberry API
|
|
2772
|
+
* @deprecated Use getTransport() or getMetadataTransport() for new code
|
|
2773
|
+
* @internal This method is kept for backwards compatibility with API modules
|
|
2271
2774
|
*/
|
|
2272
2775
|
async request(options) {
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
let url = `${this.config.baseUrl}${endpoint}`;
|
|
2282
|
-
if (queryParams && Object.keys(queryParams).length > 0) {
|
|
2283
|
-
const params = new URLSearchParams();
|
|
2284
|
-
for (const [key, value] of Object.entries(queryParams)) {
|
|
2285
|
-
if (value !== void 0 && value !== null) {
|
|
2286
|
-
params.set(key, String(value));
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
url += `?${params.toString()}`;
|
|
2290
|
-
}
|
|
2291
|
-
const headers = {
|
|
2292
|
-
Accept: "application/json",
|
|
2293
|
-
tokenid: this.config.apiKey,
|
|
2294
|
-
...customHeaders
|
|
2295
|
-
};
|
|
2296
|
-
if (body) {
|
|
2297
|
-
headers["Content-Type"] = "application/json";
|
|
2298
|
-
}
|
|
2299
|
-
const fetchOptions = {
|
|
2300
|
-
method,
|
|
2301
|
-
headers,
|
|
2302
|
-
signal
|
|
2303
|
-
};
|
|
2304
|
-
if (body) {
|
|
2305
|
-
fetchOptions.body = JSON.stringify(body);
|
|
2306
|
-
}
|
|
2307
|
-
return this.executeWithRetry(url, fetchOptions);
|
|
2308
|
-
}
|
|
2309
|
-
/**
|
|
2310
|
-
* Executes a fetch request with retry logic for 429 errors
|
|
2311
|
-
*/
|
|
2312
|
-
async executeWithRetry(url, options, retryCount = 0) {
|
|
2313
|
-
try {
|
|
2314
|
-
const timeoutController = new AbortController();
|
|
2315
|
-
const timeoutId = setTimeout(() => {
|
|
2316
|
-
timeoutController.abort();
|
|
2317
|
-
}, this.config.timeout);
|
|
2318
|
-
const combinedSignal = options.signal ? this.combineSignals([options.signal, timeoutController.signal]) : timeoutController.signal;
|
|
2319
|
-
const response = await fetch(url, {
|
|
2320
|
-
...options,
|
|
2321
|
-
signal: combinedSignal
|
|
2322
|
-
});
|
|
2323
|
-
clearTimeout(timeoutId);
|
|
2324
|
-
if (response.status === 429 && this.config.retryOn429) {
|
|
2325
|
-
if (retryCount < this.config.maxRetries) {
|
|
2326
|
-
await wait(this.config.retryDelay);
|
|
2327
|
-
return this.executeWithRetry(url, options, retryCount + 1);
|
|
2328
|
-
}
|
|
2329
|
-
throw new FireberryError("Rate limit exceeded after max retries", {
|
|
2330
|
-
code: "RATE_LIMITED" /* RATE_LIMITED */,
|
|
2331
|
-
statusCode: 429,
|
|
2332
|
-
context: { retryCount }
|
|
2333
|
-
});
|
|
2334
|
-
}
|
|
2335
|
-
let body;
|
|
2336
|
-
const contentType = response.headers.get("content-type");
|
|
2337
|
-
if (contentType?.includes("application/json")) {
|
|
2338
|
-
body = await response.json();
|
|
2339
|
-
} else {
|
|
2340
|
-
body = await response.text();
|
|
2341
|
-
}
|
|
2342
|
-
if (!response.ok) {
|
|
2343
|
-
throw createErrorFromResponse(response, body);
|
|
2344
|
-
}
|
|
2345
|
-
return body;
|
|
2346
|
-
} catch (error) {
|
|
2347
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
2348
|
-
throw createNetworkError(error);
|
|
2349
|
-
}
|
|
2350
|
-
if (error instanceof FireberryError) {
|
|
2351
|
-
throw error;
|
|
2352
|
-
}
|
|
2353
|
-
throw createNetworkError(error);
|
|
2354
|
-
}
|
|
2355
|
-
}
|
|
2356
|
-
/**
|
|
2357
|
-
* Combines multiple abort signals into one
|
|
2358
|
-
*/
|
|
2359
|
-
combineSignals(signals) {
|
|
2360
|
-
const controller = new AbortController();
|
|
2361
|
-
for (const signal of signals) {
|
|
2362
|
-
if (signal.aborted) {
|
|
2363
|
-
controller.abort();
|
|
2364
|
-
break;
|
|
2776
|
+
const transport = this.metadataTransport || this.transport;
|
|
2777
|
+
if (transport instanceof HTTPTransport) {
|
|
2778
|
+
return transport.request(options);
|
|
2779
|
+
}
|
|
2780
|
+
throw new FireberryError(
|
|
2781
|
+
"Raw request() is not supported in SDK mode. Use specific methods like query(), createRecord(), etc.",
|
|
2782
|
+
{
|
|
2783
|
+
code: "INVALID_REQUEST" /* INVALID_REQUEST */
|
|
2365
2784
|
}
|
|
2366
|
-
|
|
2367
|
-
}
|
|
2368
|
-
return controller.signal;
|
|
2785
|
+
);
|
|
2369
2786
|
}
|
|
2370
2787
|
};
|
|
2371
2788
|
|
|
@@ -2850,6 +3267,14 @@ function getRelatedFieldInfo(fieldName) {
|
|
|
2850
3267
|
return { ...parsed, ...resolved };
|
|
2851
3268
|
}
|
|
2852
3269
|
|
|
3270
|
+
// src/types/transport.ts
|
|
3271
|
+
function isHTTPTransportConfig(config) {
|
|
3272
|
+
return "apiKey" in config;
|
|
3273
|
+
}
|
|
3274
|
+
function isSDKTransportConfig(config) {
|
|
3275
|
+
return "sdk" in config;
|
|
3276
|
+
}
|
|
3277
|
+
|
|
2853
3278
|
// src/constants/objectNames.ts
|
|
2854
3279
|
var OBJECT_NAME_MAP = {
|
|
2855
3280
|
1: "accountname",
|
|
@@ -2965,6 +3390,6 @@ var OBJECT_NAME_MAP = {
|
|
|
2965
3390
|
// src/constants/index.ts
|
|
2966
3391
|
init_excludedFields();
|
|
2967
3392
|
|
|
2968
|
-
export { EXCLUDED_FIELDS_FOR_STAR_QUERY, FIELD_TYPE_IDS, FIELD_TYPE_MAPPINGS, FireberryClient, FireberryError, FireberryErrorCode, ID_FIELD_TO_OBJECT_TYPE, OBJECT_ID_MAP, OBJECT_NAME_MAP, QueryBuilder, RelatedFieldResolver, escapeQueryValue, expandRelatedFields, getObjectTypeFromReferenceField, getRelatedFieldInfo, parseRelatedField, resolveRelatedField, sanitizeQuery };
|
|
3393
|
+
export { EXCLUDED_FIELDS_FOR_STAR_QUERY, FIELD_TYPE_IDS, FIELD_TYPE_MAPPINGS, FireberryClient, FireberryError, FireberryErrorCode, ID_FIELD_TO_OBJECT_TYPE, OBJECT_ID_MAP, OBJECT_NAME_MAP, QueryBuilder, RelatedFieldResolver, escapeQueryValue, expandRelatedFields, getObjectTypeFromReferenceField, getRelatedFieldInfo, isHTTPTransportConfig, isSDKTransportConfig, parseRelatedField, resolveRelatedField, sanitizeQuery };
|
|
2969
3394
|
//# sourceMappingURL=index.js.map
|
|
2970
3395
|
//# sourceMappingURL=index.js.map
|