fireberry-api-client 1.0.0-beta.1
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 +441 -0
- package/dist/excludedFields-CGXgZN8Y.d.cts +278 -0
- package/dist/excludedFields-CGXgZN8Y.d.ts +278 -0
- package/dist/fieldTypes-BLzJTzpI.d.cts +67 -0
- package/dist/fieldTypes-BLzJTzpI.d.ts +67 -0
- package/dist/index.cjs +1597 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +871 -0
- package/dist/index.d.ts +871 -0
- package/dist/index.js +1586 -0
- package/dist/index.js.map +1 -0
- package/dist/sdk/index.cjs +1041 -0
- package/dist/sdk/index.cjs.map +1 -0
- package/dist/sdk/index.d.cts +372 -0
- package/dist/sdk/index.d.ts +372 -0
- package/dist/sdk/index.js +1022 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/utils/index.cjs +796 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +73 -0
- package/dist/utils/index.d.ts +73 -0
- package/dist/utils/index.js +767 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
# fireberry-api-client
|
|
2
|
+
|
|
3
|
+
A standalone, framework-agnostic TypeScript/JavaScript client for the Fireberry CRM API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Full TypeScript support with comprehensive type definitions
|
|
8
|
+
- Zero runtime dependencies (uses native `fetch`)
|
|
9
|
+
- Supports both ESM and CommonJS
|
|
10
|
+
- Automatic retry on rate limits (429)
|
|
11
|
+
- Optional metadata caching
|
|
12
|
+
- Fluent QueryBuilder API
|
|
13
|
+
- Batch operations with auto-chunking
|
|
14
|
+
- AbortController support for cancellation
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install fireberry-api-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Requirements:** Node.js 18+
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { FireberryClient } from 'fireberry-api-client';
|
|
28
|
+
|
|
29
|
+
const client = new FireberryClient({
|
|
30
|
+
apiKey: 'your-api-key',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Query records
|
|
34
|
+
const accounts = await client.query({
|
|
35
|
+
objectType: '1', // Account
|
|
36
|
+
fields: ['accountid', 'accountname', 'statuscode'],
|
|
37
|
+
limit: 10,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
console.log(accounts.records);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API Reference
|
|
44
|
+
|
|
45
|
+
### Client Configuration
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const client = new FireberryClient({
|
|
49
|
+
apiKey: 'your-api-key', // Required
|
|
50
|
+
baseUrl: 'https://api.fireberry.com', // Optional, default shown
|
|
51
|
+
timeout: 30000, // Optional, request timeout in ms
|
|
52
|
+
retryOn429: true, // Optional, auto-retry on rate limit
|
|
53
|
+
maxRetries: 120, // Optional, max retry attempts
|
|
54
|
+
retryDelay: 1000, // Optional, delay between retries in ms
|
|
55
|
+
cacheMetadata: false, // Optional, enable metadata caching
|
|
56
|
+
cacheTTL: 300000, // Optional, cache TTL in ms (5 min default)
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Query Records
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// Simple query - fields as array
|
|
64
|
+
const result = await client.query({
|
|
65
|
+
objectType: '1',
|
|
66
|
+
fields: ['accountid', 'accountname'],
|
|
67
|
+
query: '(statuscode = 1)',
|
|
68
|
+
sortBy: 'modifiedon',
|
|
69
|
+
sortType: 'desc',
|
|
70
|
+
limit: 100,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Fields as comma-separated string
|
|
74
|
+
const result = await client.query({
|
|
75
|
+
objectType: '1',
|
|
76
|
+
fields: 'accountid,accountname,statuscode',
|
|
77
|
+
limit: 100,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Query all records (auto-pagination enabled by default)
|
|
81
|
+
const result = await client.query({
|
|
82
|
+
objectType: '1',
|
|
83
|
+
fields: '*',
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Manual pagination (disable auto-pagination)
|
|
87
|
+
const page1 = await client.query({
|
|
88
|
+
objectType: '1',
|
|
89
|
+
fields: '*',
|
|
90
|
+
autoPage: false,
|
|
91
|
+
page: 1,
|
|
92
|
+
pageSize: 500, // default: 500, max: 500
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### QueryBuilder (Fluent API)
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const result = await client.queryBuilder()
|
|
100
|
+
.objectType('1')
|
|
101
|
+
.select('accountid', 'accountname', 'emailaddress1')
|
|
102
|
+
.where('statuscode').equals('1')
|
|
103
|
+
.and()
|
|
104
|
+
.where('accountname').contains('Acme')
|
|
105
|
+
.sortBy('modifiedon', 'desc')
|
|
106
|
+
.limit(50)
|
|
107
|
+
.execute();
|
|
108
|
+
|
|
109
|
+
// Available conditions:
|
|
110
|
+
// .equals(value) - Exact match
|
|
111
|
+
// .notEquals(value) - Not equal
|
|
112
|
+
// .lessThan(value) - Less than
|
|
113
|
+
// .greaterThan(value) - Greater than
|
|
114
|
+
// .lessThanOrEqual(value) - Less than or equal (numbers only)
|
|
115
|
+
// .greaterThanOrEqual(value) - Greater than or equal (numbers only)
|
|
116
|
+
// .contains(value) - Contains (translates to start-with %value)
|
|
117
|
+
// .notContains(value) - Does not contain
|
|
118
|
+
// .startsWith(value) - Starts with
|
|
119
|
+
// .notStartsWith(value) - Does not start with
|
|
120
|
+
// .isNull() - Field is null
|
|
121
|
+
// .isNotNull() - Field is not null
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### CRUD Operations
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// Create
|
|
128
|
+
const created = await client.records.create('1', {
|
|
129
|
+
accountname: 'New Account',
|
|
130
|
+
emailaddress1: 'contact@example.com',
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Update
|
|
134
|
+
const updated = await client.records.update('1', 'record-id', {
|
|
135
|
+
accountname: 'Updated Name',
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Delete
|
|
139
|
+
await client.records.delete('1', 'record-id');
|
|
140
|
+
|
|
141
|
+
// Upsert (create if not exists, update if exists)
|
|
142
|
+
const result = await client.records.upsert('1', ['emailaddress1'], {
|
|
143
|
+
accountname: 'Acme Corp',
|
|
144
|
+
emailaddress1: 'contact@acme.com',
|
|
145
|
+
});
|
|
146
|
+
console.log(result.operationType); // 'create' or 'update'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Batch Operations
|
|
150
|
+
|
|
151
|
+
Batch operations automatically chunk large datasets into API-compatible batches of 20.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// Batch create
|
|
155
|
+
const result = await client.batch.create('1', [
|
|
156
|
+
{ accountname: 'Account 1' },
|
|
157
|
+
{ accountname: 'Account 2' },
|
|
158
|
+
{ accountname: 'Account 3' },
|
|
159
|
+
]);
|
|
160
|
+
|
|
161
|
+
// Batch update
|
|
162
|
+
await client.batch.update('1', [
|
|
163
|
+
{ id: 'id-1', record: { accountname: 'Updated 1' } },
|
|
164
|
+
{ id: 'id-2', record: { accountname: 'Updated 2' } },
|
|
165
|
+
]);
|
|
166
|
+
|
|
167
|
+
// Batch delete
|
|
168
|
+
await client.batch.delete('1', ['id-1', 'id-2', 'id-3']);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Metadata
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
// Get all objects
|
|
175
|
+
const objects = await client.metadata.getObjects();
|
|
176
|
+
|
|
177
|
+
// Get fields for an object
|
|
178
|
+
const fields = await client.metadata.getFields('1');
|
|
179
|
+
|
|
180
|
+
// Get dropdown values
|
|
181
|
+
const values = await client.metadata.getFieldValues('1', 'statuscode');
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Metadata Caching
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const client = new FireberryClient({
|
|
188
|
+
apiKey: 'your-api-key',
|
|
189
|
+
cacheMetadata: true,
|
|
190
|
+
cacheTTL: 300000, // 5 minutes
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Metadata calls are cached
|
|
194
|
+
await client.metadata.getFields('1'); // Hits API
|
|
195
|
+
await client.metadata.getFields('1'); // Uses cache
|
|
196
|
+
|
|
197
|
+
// Manual cache control
|
|
198
|
+
client.cache.clear(); // Clear all cache
|
|
199
|
+
client.cache.clearFields('1'); // Clear fields for object 1
|
|
200
|
+
client.cache.clearFieldValues('1', 'statuscode'); // Clear specific field values
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Custom API Calls
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const response = await client.request({
|
|
207
|
+
method: 'POST',
|
|
208
|
+
endpoint: '/api/custom',
|
|
209
|
+
body: { data: 'value' },
|
|
210
|
+
headers: { 'X-Custom': 'header' },
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### AbortController Support
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const controller = new AbortController();
|
|
218
|
+
|
|
219
|
+
// Start query
|
|
220
|
+
const promise = client.query({
|
|
221
|
+
objectType: '1',
|
|
222
|
+
fields: '*',
|
|
223
|
+
signal: controller.signal,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Cancel if needed
|
|
227
|
+
controller.abort();
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## SDK Adapter (for @fireberry/sdk)
|
|
231
|
+
|
|
232
|
+
If you're building embedded Fireberry widgets/plugins using `@fireberry/sdk`, you can use this library's utilities with the SDK adapter:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import FireberryClientSDK from '@fireberry/sdk/client';
|
|
236
|
+
import { createSDKQueryBuilder, EnhancedSDK } from 'fireberry-api-client/sdk';
|
|
237
|
+
|
|
238
|
+
// Initialize Fireberry SDK (runs in iframe)
|
|
239
|
+
const sdk = new FireberryClientSDK();
|
|
240
|
+
await sdk.initializeContext();
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Option 1: Query Builder Factory
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { createSDKQueryBuilder } from 'fireberry-api-client/sdk';
|
|
247
|
+
|
|
248
|
+
const queryBuilder = createSDKQueryBuilder(sdk);
|
|
249
|
+
|
|
250
|
+
// Build and execute queries with fluent API
|
|
251
|
+
const results = await queryBuilder(1) // 1 = Account
|
|
252
|
+
.select('accountid', 'accountname', 'statuscode')
|
|
253
|
+
.selectWithLabels('ownerid') // Auto-adds 'ownername'
|
|
254
|
+
.where('statuscode').equals('1')
|
|
255
|
+
.pageSize(50)
|
|
256
|
+
.execute();
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Option 2: Enhanced SDK Wrapper
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import { EnhancedSDK } from 'fireberry-api-client/sdk';
|
|
263
|
+
|
|
264
|
+
const enhanced = EnhancedSDK.create(sdk);
|
|
265
|
+
|
|
266
|
+
// Access context easily
|
|
267
|
+
console.log('Current user:', enhanced.userId, enhanced.userFullName);
|
|
268
|
+
console.log('Current record:', enhanced.recordId, enhanced.recordType);
|
|
269
|
+
|
|
270
|
+
// Query with utilities
|
|
271
|
+
const results = await enhanced
|
|
272
|
+
.query(1)
|
|
273
|
+
.select('accountid', 'accountname')
|
|
274
|
+
.where('ownerid').equals(enhanced.userId!)
|
|
275
|
+
.execute();
|
|
276
|
+
|
|
277
|
+
// Use field utilities
|
|
278
|
+
const idField = enhanced.getIdField(1); // 'accountid'
|
|
279
|
+
const nameField = enhanced.getNameField(2); // 'fullname'
|
|
280
|
+
const labelField = enhanced.getLabelField('statuscode', 1); // 'status'
|
|
281
|
+
|
|
282
|
+
// Expand fields with their labels
|
|
283
|
+
const fields = enhanced.expandFieldsWithLabels(['statuscode', 'ownerid'], 1);
|
|
284
|
+
// ['statuscode', 'status', 'ownerid', 'ownername']
|
|
285
|
+
|
|
286
|
+
// CRUD operations
|
|
287
|
+
await enhanced.create(1, { accountname: 'New Account' });
|
|
288
|
+
await enhanced.update(1, 'record-id', { accountname: 'Updated' });
|
|
289
|
+
await enhanced.delete(1, 'record-id');
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Option 3: Use QueryBuilder Directly
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
import { QueryBuilder } from 'fireberry-api-client';
|
|
296
|
+
|
|
297
|
+
// Build query and convert to SDK-compatible payload
|
|
298
|
+
const payload = new QueryBuilder()
|
|
299
|
+
.select('accountid', 'accountname')
|
|
300
|
+
.where('statuscode').equals('1')
|
|
301
|
+
.limit(50)
|
|
302
|
+
.toSDKPayload();
|
|
303
|
+
|
|
304
|
+
// Execute with SDK
|
|
305
|
+
const results = await sdk.api.query(1, payload);
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Utility Functions
|
|
309
|
+
|
|
310
|
+
Utility functions are available as a separate export:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
import {
|
|
314
|
+
getObjectIdFieldName,
|
|
315
|
+
getNameFieldByObjectType,
|
|
316
|
+
getLabelFieldForField,
|
|
317
|
+
isDropdownField,
|
|
318
|
+
isLookupField,
|
|
319
|
+
chunkArray,
|
|
320
|
+
normalizeFields,
|
|
321
|
+
} from 'fireberry-api-client/utils';
|
|
322
|
+
|
|
323
|
+
// Get primary key field name
|
|
324
|
+
getObjectIdFieldName('1'); // 'accountid'
|
|
325
|
+
getObjectIdFieldName('1000'); // 'customobject1000id'
|
|
326
|
+
|
|
327
|
+
// Get display name field
|
|
328
|
+
getNameFieldByObjectType('1'); // 'accountname'
|
|
329
|
+
getNameFieldByObjectType('2'); // 'fullname' (Contact)
|
|
330
|
+
getNameFieldByObjectType('14'); // 'productname' (Product)
|
|
331
|
+
|
|
332
|
+
// Get label field for a lookup/dropdown field
|
|
333
|
+
getLabelFieldForField('accountid', '1'); // 'accountname'
|
|
334
|
+
getLabelFieldForField('statuscode', '1'); // 'status'
|
|
335
|
+
|
|
336
|
+
// Field type detection
|
|
337
|
+
isDropdownField('5'); // true
|
|
338
|
+
isLookupField('6'); // true
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Object Type Reference
|
|
342
|
+
|
|
343
|
+
| ID | Object | ID Field | Name Field |
|
|
344
|
+
|----|--------|----------|------------|
|
|
345
|
+
| 1 | Account | accountid | accountname |
|
|
346
|
+
| 2 | Contact | contactid | fullname |
|
|
347
|
+
| 3 | Lead | leadid | fullname |
|
|
348
|
+
| 4 | Opportunity | opportunityid | name |
|
|
349
|
+
| 5 | Case | casesid | title |
|
|
350
|
+
| 6 | Activity | activityid | subject |
|
|
351
|
+
| 7 | Note | noteid | subject |
|
|
352
|
+
| 10 | Task | taskid | subject |
|
|
353
|
+
| 13 | CRM Order | crmorderid | name |
|
|
354
|
+
| 14 | Product | productid | productname |
|
|
355
|
+
| 1000+ | Custom Objects | customobject{N}id | name |
|
|
356
|
+
|
|
357
|
+
## Error Handling
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
import { FireberryError, FireberryErrorCode } from 'fireberry-api-client';
|
|
361
|
+
|
|
362
|
+
try {
|
|
363
|
+
await client.query({ objectType: '1', fields: '*' });
|
|
364
|
+
} catch (error) {
|
|
365
|
+
if (error instanceof FireberryError) {
|
|
366
|
+
console.log(error.code); // e.g., 'RATE_LIMITED'
|
|
367
|
+
console.log(error.statusCode); // e.g., 429
|
|
368
|
+
console.log(error.message); // Human-readable message
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Error codes:
|
|
373
|
+
// - UNKNOWN
|
|
374
|
+
// - NETWORK_ERROR
|
|
375
|
+
// - TIMEOUT
|
|
376
|
+
// - AUTHENTICATION_FAILED
|
|
377
|
+
// - AUTHORIZATION_FAILED
|
|
378
|
+
// - NOT_FOUND
|
|
379
|
+
// - RATE_LIMITED
|
|
380
|
+
// - INVALID_REQUEST
|
|
381
|
+
// - SERVER_ERROR
|
|
382
|
+
// - ABORTED
|
|
383
|
+
// - INVALID_RESPONSE
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## Query Syntax
|
|
387
|
+
|
|
388
|
+
Fireberry uses a custom query syntax:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// Operators
|
|
392
|
+
'(field = value)' // Equals
|
|
393
|
+
'(field != value)' // Not equals
|
|
394
|
+
'(field < value)' // Less than
|
|
395
|
+
'(field > value)' // Greater than
|
|
396
|
+
'(field <= value)' // Less than or equal (numbers only)
|
|
397
|
+
'(field >= value)' // Greater than or equal (numbers only)
|
|
398
|
+
'(field start-with value)' // Starts with
|
|
399
|
+
'(field start-with %value)' // Contains (% is wildcard)
|
|
400
|
+
'(field is-null)' // Is null
|
|
401
|
+
'(field is-not-null)' // Is not null
|
|
402
|
+
|
|
403
|
+
// Combining conditions
|
|
404
|
+
'(statuscode = 1) and (name start-with %Acme)'
|
|
405
|
+
'(statuscode = 1) or (statuscode = 2)'
|
|
406
|
+
|
|
407
|
+
// Nested field search (lookup fields)
|
|
408
|
+
'(accountid_fullname start-with %Acme)' // Search Contact by Account name
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Important:** Dropdown fields use IDs, not labels. Use `showRealValue: true` to get labels in responses.
|
|
412
|
+
|
|
413
|
+
## Development
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
# Install dependencies
|
|
417
|
+
npm install
|
|
418
|
+
|
|
419
|
+
# Build
|
|
420
|
+
npm run build
|
|
421
|
+
|
|
422
|
+
# Run tests
|
|
423
|
+
npm run test
|
|
424
|
+
|
|
425
|
+
# Run tests once
|
|
426
|
+
npm run test:run
|
|
427
|
+
|
|
428
|
+
# Lint
|
|
429
|
+
npm run lint
|
|
430
|
+
|
|
431
|
+
# Type check
|
|
432
|
+
npm run typecheck
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## Author
|
|
436
|
+
|
|
437
|
+
Created by **[Ido Kraicer](https://www.linkedin.com/in/ido-kraicer/)** - An open-source client library built for the Fireberry community.
|
|
438
|
+
|
|
439
|
+
## License
|
|
440
|
+
|
|
441
|
+
MIT
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escapes special characters in query values to prevent query injection.
|
|
3
|
+
* This is a security measure to ensure user-provided values cannot modify
|
|
4
|
+
* the query structure or inject additional query logic.
|
|
5
|
+
*
|
|
6
|
+
* @param value - The value to escape
|
|
7
|
+
* @returns Escaped value safe for use in Fireberry queries
|
|
8
|
+
*/
|
|
9
|
+
declare function escapeQueryValue(value: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Sanitizes a query string to ensure proper syntax for the Fireberry API
|
|
12
|
+
* Handles common syntax issues and removes extraneous elements
|
|
13
|
+
*
|
|
14
|
+
* @param query - Query string to sanitize
|
|
15
|
+
* @returns Sanitized query string
|
|
16
|
+
*/
|
|
17
|
+
declare function sanitizeQuery(query: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Condition builder for fluent query construction
|
|
20
|
+
*/
|
|
21
|
+
interface ConditionBuilder {
|
|
22
|
+
/** Equals comparison (=) */
|
|
23
|
+
equals(value: string | number): QueryBuilder;
|
|
24
|
+
/** Not equals comparison (!=) */
|
|
25
|
+
notEquals(value: string | number): QueryBuilder;
|
|
26
|
+
/** Less than comparison (<) - works with numbers and dates */
|
|
27
|
+
lessThan(value: string | number): QueryBuilder;
|
|
28
|
+
/** Greater than comparison (>) - works with numbers and dates */
|
|
29
|
+
greaterThan(value: string | number): QueryBuilder;
|
|
30
|
+
/** Less than or equal (<=) - works with numbers ONLY (not dates!) */
|
|
31
|
+
lessThanOrEqual(value: string | number): QueryBuilder;
|
|
32
|
+
/** Greater than or equal (>=) - works with numbers ONLY (not dates!) */
|
|
33
|
+
greaterThanOrEqual(value: string | number): QueryBuilder;
|
|
34
|
+
/** Contains value (translates to start-with %value) */
|
|
35
|
+
contains(value: string): QueryBuilder;
|
|
36
|
+
/** Does not contain value (translates to not-start-with %value) */
|
|
37
|
+
notContains(value: string): QueryBuilder;
|
|
38
|
+
/** Starts with value (start-with) */
|
|
39
|
+
startsWith(value: string): QueryBuilder;
|
|
40
|
+
/** Does not start with value (not-start-with) */
|
|
41
|
+
notStartsWith(value: string): QueryBuilder;
|
|
42
|
+
/** Field is null (is-null) */
|
|
43
|
+
isNull(): QueryBuilder;
|
|
44
|
+
/** Field is not null (is-not-null) */
|
|
45
|
+
isNotNull(): QueryBuilder;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Fluent query builder for constructing Fireberry queries
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* // Build a query string
|
|
53
|
+
* const query = new QueryBuilder()
|
|
54
|
+
* .where('statuscode').equals('1')
|
|
55
|
+
* .and()
|
|
56
|
+
* .where('emailaddress1').contains('@example.com')
|
|
57
|
+
* .build();
|
|
58
|
+
* // Output: "(statuscode = 1) and (emailaddress1 start-with %@example.com)"
|
|
59
|
+
*
|
|
60
|
+
* // With select and execute (requires client)
|
|
61
|
+
* const result = await new QueryBuilder(client)
|
|
62
|
+
* .objectType('1')
|
|
63
|
+
* .select('accountid', 'name', 'emailaddress1')
|
|
64
|
+
* .where('statuscode').equals('1')
|
|
65
|
+
* .limit(100)
|
|
66
|
+
* .execute();
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* Client interface for query execution
|
|
71
|
+
*/
|
|
72
|
+
interface QueryClient {
|
|
73
|
+
query(options: {
|
|
74
|
+
objectType: string;
|
|
75
|
+
fields: string[];
|
|
76
|
+
query: string;
|
|
77
|
+
showRealValue: boolean;
|
|
78
|
+
sortBy?: string;
|
|
79
|
+
sortType?: 'asc' | 'desc';
|
|
80
|
+
limit?: number;
|
|
81
|
+
page?: number;
|
|
82
|
+
signal?: AbortSignal;
|
|
83
|
+
}): Promise<QueryResult>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Query result type
|
|
87
|
+
*/
|
|
88
|
+
interface QueryResult {
|
|
89
|
+
records: Record<string, unknown>[];
|
|
90
|
+
total: number;
|
|
91
|
+
success: boolean;
|
|
92
|
+
}
|
|
93
|
+
declare class QueryBuilder {
|
|
94
|
+
private conditions;
|
|
95
|
+
private joinOperators;
|
|
96
|
+
private currentField;
|
|
97
|
+
private selectedFields;
|
|
98
|
+
private objectTypeId;
|
|
99
|
+
private sortByField;
|
|
100
|
+
private sortDirection;
|
|
101
|
+
private limitValue;
|
|
102
|
+
private pageNumber;
|
|
103
|
+
private showRealValueFlag;
|
|
104
|
+
private client;
|
|
105
|
+
/**
|
|
106
|
+
* Creates a new QueryBuilder
|
|
107
|
+
* @param client - Optional FireberryClient for executing queries
|
|
108
|
+
*/
|
|
109
|
+
constructor(client?: QueryClient);
|
|
110
|
+
/**
|
|
111
|
+
* Sets the object type for the query
|
|
112
|
+
* @param objectType - Object type ID (e.g., '1' for Account)
|
|
113
|
+
*/
|
|
114
|
+
objectType(objectType: string | number): this;
|
|
115
|
+
/**
|
|
116
|
+
* Adds fields to select
|
|
117
|
+
* @param fields - Field names to select
|
|
118
|
+
*/
|
|
119
|
+
select(...fields: string[]): this;
|
|
120
|
+
/**
|
|
121
|
+
* Starts a new WHERE condition
|
|
122
|
+
* @param field - Field name to filter on
|
|
123
|
+
*/
|
|
124
|
+
where(field: string): ConditionBuilder;
|
|
125
|
+
/**
|
|
126
|
+
* Adds an AND logical operator
|
|
127
|
+
*/
|
|
128
|
+
and(): this;
|
|
129
|
+
/**
|
|
130
|
+
* Adds an OR logical operator
|
|
131
|
+
*/
|
|
132
|
+
or(): this;
|
|
133
|
+
/**
|
|
134
|
+
* Sets the sort field and direction
|
|
135
|
+
* @param field - Field to sort by
|
|
136
|
+
* @param direction - Sort direction ('asc' or 'desc')
|
|
137
|
+
*/
|
|
138
|
+
sortBy(field: string, direction?: 'asc' | 'desc'): this;
|
|
139
|
+
/**
|
|
140
|
+
* Sets the maximum number of records to return
|
|
141
|
+
* @param count - Maximum record count
|
|
142
|
+
*/
|
|
143
|
+
limit(count: number): this;
|
|
144
|
+
/**
|
|
145
|
+
* Sets the page number for pagination
|
|
146
|
+
* @param page - Page number (1-based)
|
|
147
|
+
*/
|
|
148
|
+
page(page: number): this;
|
|
149
|
+
/**
|
|
150
|
+
* Controls whether to show real values (labels) for dropdown fields
|
|
151
|
+
* @param show - Whether to show real values (default: true)
|
|
152
|
+
*/
|
|
153
|
+
showRealValue(show: boolean): this;
|
|
154
|
+
/**
|
|
155
|
+
* Builds the query string from conditions
|
|
156
|
+
* @returns The built query string
|
|
157
|
+
*/
|
|
158
|
+
build(): string;
|
|
159
|
+
/**
|
|
160
|
+
* Returns the selected fields array
|
|
161
|
+
* Useful for inspecting the query configuration
|
|
162
|
+
*/
|
|
163
|
+
getFields(): string[];
|
|
164
|
+
/**
|
|
165
|
+
* Converts the query builder state to a payload compatible with @fireberry/sdk
|
|
166
|
+
*
|
|
167
|
+
* @returns Object with `fields` (comma-separated string) and `query` (filter string)
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* import FireberryClientSDK from '@fireberry/sdk/client';
|
|
172
|
+
* import { QueryBuilder } from 'fireberry-api-client';
|
|
173
|
+
*
|
|
174
|
+
* const sdk = new FireberryClientSDK();
|
|
175
|
+
* await sdk.initializeContext();
|
|
176
|
+
*
|
|
177
|
+
* const payload = new QueryBuilder()
|
|
178
|
+
* .select('accountid', 'accountname')
|
|
179
|
+
* .where('statuscode').equals('1')
|
|
180
|
+
* .toSDKPayload();
|
|
181
|
+
*
|
|
182
|
+
* // Use with SDK
|
|
183
|
+
* const results = await sdk.api.query(1, payload);
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
toSDKPayload(): {
|
|
187
|
+
fields: string;
|
|
188
|
+
query: string;
|
|
189
|
+
page_size?: number;
|
|
190
|
+
page_number?: number;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Executes the query (requires client to be set)
|
|
194
|
+
* @param signal - Optional AbortSignal for cancellation
|
|
195
|
+
* @returns Query results
|
|
196
|
+
*/
|
|
197
|
+
execute(signal?: AbortSignal): Promise<QueryResult>;
|
|
198
|
+
/**
|
|
199
|
+
* Creates a condition builder for the current field
|
|
200
|
+
*/
|
|
201
|
+
private createConditionBuilder;
|
|
202
|
+
/**
|
|
203
|
+
* Adds a condition to the query
|
|
204
|
+
*/
|
|
205
|
+
private addCondition;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Field Type System IDs from Fireberry CRM
|
|
210
|
+
* These UUIDs identify different field types in the metadata API
|
|
211
|
+
*/
|
|
212
|
+
declare const FIELD_TYPE_IDS: {
|
|
213
|
+
readonly DROPDOWN: "b4919f2e-2996-48e4-a03c-ba39fb64386c";
|
|
214
|
+
readonly LOOKUP: "a8fcdf65-91bc-46fd-82f6-1234758345a1";
|
|
215
|
+
readonly EMAIL: "c713d2f7-8fa9-43c3-8062-f07486eaf567";
|
|
216
|
+
readonly TEXT: "a1e7ed6f-5083-477b-b44c-9943a6181359";
|
|
217
|
+
readonly URL: "c820d32f-44df-4c2a-9c1e-18734e864fd5";
|
|
218
|
+
readonly LONG_TEXT: "80108f9d-1e75-40fa-9fa9-02be4ddc1da1";
|
|
219
|
+
readonly DATETIME: "ce972d02-5013-46d4-9d1d-f09df1ac346a";
|
|
220
|
+
readonly DATE: "83bf530c-e04c-462b-9ffc-a46f750fc072";
|
|
221
|
+
readonly HTML: "ed2ad39d-32fc-4585-8f5b-2e93463f050a";
|
|
222
|
+
readonly TELEPHONE: "3f62f67a-1cee-403a-bec6-aa02a9804edb";
|
|
223
|
+
readonly NUMERIC: "6a34bfe3-fece-4da1-9136-a7b1e5ae3319";
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Human-readable mappings for field types
|
|
227
|
+
* Used for display purposes
|
|
228
|
+
*/
|
|
229
|
+
declare const FIELD_TYPE_MAPPINGS: Record<string, string>;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Object Type ID to Primary Key Field Mapping
|
|
233
|
+
* Maps Fireberry object type IDs to their primary key field names
|
|
234
|
+
*/
|
|
235
|
+
declare const OBJECT_ID_MAP: Record<number, string>;
|
|
236
|
+
/**
|
|
237
|
+
* Gets the primary key field name for a given object type
|
|
238
|
+
*
|
|
239
|
+
* @param objectTypeId - The numeric object type ID
|
|
240
|
+
* @returns The correct ID field name for the object type
|
|
241
|
+
*/
|
|
242
|
+
declare function getObjectIdFieldName(objectTypeId: string | number): string;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Object Type ID to Name Field Mapping
|
|
246
|
+
* Maps Fireberry object type IDs to their display name field
|
|
247
|
+
*/
|
|
248
|
+
declare const OBJECT_NAME_MAP: Record<number, string>;
|
|
249
|
+
/**
|
|
250
|
+
* Gets the display name field for a given object type
|
|
251
|
+
*
|
|
252
|
+
* @param objectTypeId - The numeric object type ID
|
|
253
|
+
* @returns The name field for the object type
|
|
254
|
+
*/
|
|
255
|
+
declare function getNameFieldByObjectType(objectTypeId: string | number): string;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Fields to exclude from queries when using '*' (all fields) for specific object types
|
|
259
|
+
* These fields cause API errors when queried
|
|
260
|
+
*/
|
|
261
|
+
declare const EXCLUDED_FIELDS_FOR_STAR_QUERY: Record<string, string[]>;
|
|
262
|
+
/**
|
|
263
|
+
* Checks if a field should be excluded from star queries for a given object type
|
|
264
|
+
*
|
|
265
|
+
* @param objectType - The object type ID
|
|
266
|
+
* @param fieldName - The field name to check
|
|
267
|
+
* @returns True if the field should be excluded
|
|
268
|
+
*/
|
|
269
|
+
declare function isExcludedFromStarQuery(objectType: string | number, fieldName: string): boolean;
|
|
270
|
+
/**
|
|
271
|
+
* Gets the list of excluded fields for a given object type
|
|
272
|
+
*
|
|
273
|
+
* @param objectType - The object type ID
|
|
274
|
+
* @returns Array of field names to exclude, or empty array if none
|
|
275
|
+
*/
|
|
276
|
+
declare function getExcludedFieldsForStarQuery(objectType: string | number): string[];
|
|
277
|
+
|
|
278
|
+
export { type ConditionBuilder as C, EXCLUDED_FIELDS_FOR_STAR_QUERY as E, FIELD_TYPE_IDS as F, OBJECT_ID_MAP as O, QueryBuilder as Q, FIELD_TYPE_MAPPINGS as a, OBJECT_NAME_MAP as b, getNameFieldByObjectType as c, getExcludedFieldsForStarQuery as d, escapeQueryValue as e, getObjectIdFieldName as g, isExcludedFromStarQuery as i, sanitizeQuery as s };
|