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