fireberry-api-client 1.0.0-beta.2 → 1.0.0-beta.2.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 CHANGED
@@ -9,6 +9,7 @@ A standalone, framework-agnostic TypeScript/JavaScript client for the Fireberry
9
9
  - Supports both ESM and CommonJS
10
10
  - Automatic retry on rate limits (429)
11
11
  - Optional metadata caching
12
+ - Lookup field relationship detection
12
13
  - Fluent QueryBuilder API
13
14
  - Batch operations with auto-chunking
14
15
  - AbortController support for cancellation
@@ -190,6 +191,15 @@ const objects = await client.metadata.getObjects();
190
191
  // Get fields for an object
191
192
  const fields = await client.metadata.getFields('1');
192
193
 
194
+ // Get fields with lookup relationships (shows which object each lookup field references)
195
+ const fieldsWithRelations = await client.metadata.getFields('1', {
196
+ includeLookupRelations: true
197
+ });
198
+
199
+ // Example: Find related object for a lookup field
200
+ const primaryContact = fieldsWithRelations.fields.find(f => f.fieldName === 'primarycontactid');
201
+ console.log(primaryContact?.relatedObjectType); // 2 (Contact)
202
+
193
203
  // Get dropdown values
194
204
  const values = await client.metadata.getFieldValues('1', 'statuscode');
195
205
  ```
package/dist/index.cjs CHANGED
@@ -14,6 +14,7 @@ var __export = (target, all) => {
14
14
  var excludedFields_exports = {};
15
15
  __export(excludedFields_exports, {
16
16
  EXCLUDED_FIELDS_FOR_STAR_QUERY: () => exports.EXCLUDED_FIELDS_FOR_STAR_QUERY,
17
+ EXCLUDED_LOOKUP_FIELDS: () => EXCLUDED_LOOKUP_FIELDS,
17
18
  getExcludedFieldsForStarQuery: () => getExcludedFieldsForStarQuery,
18
19
  isExcludedFromStarQuery: () => isExcludedFromStarQuery
19
20
  });
@@ -26,7 +27,7 @@ function getExcludedFieldsForStarQuery(objectType) {
26
27
  const objectTypeStr = String(objectType);
27
28
  return exports.EXCLUDED_FIELDS_FOR_STAR_QUERY[objectTypeStr] || [];
28
29
  }
29
- exports.EXCLUDED_FIELDS_FOR_STAR_QUERY = void 0;
30
+ exports.EXCLUDED_FIELDS_FOR_STAR_QUERY = void 0; var EXCLUDED_LOOKUP_FIELDS;
30
31
  var init_excludedFields = __esm({
31
32
  "src/constants/excludedFields.ts"() {
32
33
  exports.EXCLUDED_FIELDS_FOR_STAR_QUERY = {
@@ -43,6 +44,7 @@ var init_excludedFields = __esm({
43
44
  "117": ["deletedon", "deletedby"]
44
45
  // Landing Page
45
46
  };
47
+ EXCLUDED_LOOKUP_FIELDS = ["deletedby", "deletedon"];
46
48
  }
47
49
  });
48
50
 
@@ -522,6 +524,13 @@ var FIELD_TYPE_MAPPINGS = {
522
524
  };
523
525
 
524
526
  // src/api/metadata.ts
527
+ init_excludedFields();
528
+ var ENDPOINTS = {
529
+ OBJECTS: "/metadata/records",
530
+ FIELDS: (objectType) => `/metadata/records/${objectType}/fields`,
531
+ FIELD_VALUES: (objectType, fieldName) => `/metadata/records/${objectType}/fields/${fieldName}/values`,
532
+ QUERY: "/api/query"
533
+ };
525
534
  var MetadataAPI = class {
526
535
  constructor(client) {
527
536
  this.client = client;
@@ -545,7 +554,7 @@ var MetadataAPI = class {
545
554
  }
546
555
  const response = await this.client.request({
547
556
  method: "GET",
548
- endpoint: "/metadata/records",
557
+ endpoint: ENDPOINTS.OBJECTS,
549
558
  signal
550
559
  });
551
560
  const result = {
@@ -560,30 +569,55 @@ var MetadataAPI = class {
560
569
  * Gets all fields for a specific object type
561
570
  *
562
571
  * @param objectType - The object type ID (e.g., '1' for Account)
563
- * @param signal - Optional AbortSignal for cancellation
572
+ * @param options - Optional settings
573
+ * @param options.includeLookupRelations - If true, fetches related object types for lookup fields (requires additional API call)
574
+ * @param options.signal - Optional AbortSignal for cancellation
564
575
  * @returns List of fields with metadata
565
576
  *
566
577
  * @example
567
578
  * ```typescript
568
579
  * const result = await client.metadata.getFields('1');
569
580
  * console.log(result.fields); // [{ fieldName: 'accountid', label: 'Account ID', ... }, ...]
581
+ *
582
+ * // With lookup relations
583
+ * const result = await client.metadata.getFields('1', { includeLookupRelations: true });
584
+ * console.log(result.fields.find(f => f.fieldName === 'primarycontactid')?.relatedObjectType); // 2
570
585
  * ```
571
586
  */
572
- async getFields(objectType, signal) {
587
+ async getFields(objectType, options) {
573
588
  const objectTypeStr = String(objectType);
574
- const cached = this.client.getCached("fields", objectTypeStr);
575
- if (cached) {
576
- return cached;
589
+ const opts = options instanceof AbortSignal ? { signal: options, includeLookupRelations: false } : { signal: options?.signal, includeLookupRelations: options?.includeLookupRelations };
590
+ if (!opts.includeLookupRelations) {
591
+ const cached = this.client.getCached("fields", objectTypeStr);
592
+ if (cached) {
593
+ return cached;
594
+ }
577
595
  }
578
596
  const response = await this.client.request({
579
597
  method: "GET",
580
- endpoint: `/metadata/records/${objectTypeStr}/fields`,
581
- signal
598
+ endpoint: ENDPOINTS.FIELDS(objectTypeStr),
599
+ signal: opts.signal
582
600
  });
583
- const fields = (response.data || []).map((field) => ({
601
+ let fields = (response.data || []).map((field) => ({
584
602
  ...field,
585
603
  fieldType: FIELD_TYPE_MAPPINGS[field.systemFieldTypeId] || field.systemFieldTypeId
586
604
  }));
605
+ if (opts.includeLookupRelations) {
606
+ const lookupFields = fields.filter(
607
+ (field) => field.systemFieldTypeId === FIELD_TYPE_IDS.LOOKUP
608
+ );
609
+ if (lookupFields.length > 0) {
610
+ const lookupRelations = await this.fetchLookupRelations(
611
+ objectTypeStr,
612
+ lookupFields.map((f) => f.fieldName),
613
+ opts.signal
614
+ );
615
+ fields = fields.map((field) => ({
616
+ ...field,
617
+ relatedObjectType: lookupRelations.get(field.fieldName)
618
+ }));
619
+ }
620
+ }
587
621
  const result = {
588
622
  objectTypeId: objectTypeStr,
589
623
  fields,
@@ -593,6 +627,40 @@ var MetadataAPI = class {
593
627
  this.client.setCache("fields", objectTypeStr, result);
594
628
  return result;
595
629
  }
630
+ /**
631
+ * Fetches related object types for lookup fields using the query endpoint.
632
+ * The query endpoint returns Columns metadata with fieldobjecttype even without records.
633
+ * Excludes fields that cause API errors (e.g., deletedby, deletedon).
634
+ */
635
+ async fetchLookupRelations(objectType, lookupFieldNames, signal) {
636
+ const relations = /* @__PURE__ */ new Map();
637
+ const queryableFields = lookupFieldNames.filter(
638
+ (fieldName) => !EXCLUDED_LOOKUP_FIELDS.includes(fieldName)
639
+ );
640
+ if (queryableFields.length === 0) {
641
+ return relations;
642
+ }
643
+ const response = await this.client.request({
644
+ method: "POST",
645
+ endpoint: ENDPOINTS.QUERY,
646
+ body: {
647
+ objecttype: objectType,
648
+ fields: queryableFields.join(","),
649
+ query: "",
650
+ page_size: 1,
651
+ page_number: 1,
652
+ show_real_value: 0
653
+ },
654
+ signal
655
+ });
656
+ const columns = response.data?.Columns || [];
657
+ for (const column of columns) {
658
+ if (column.fieldobjecttype !== null && column.fieldobjecttype !== void 0) {
659
+ relations.set(column.fieldname, column.fieldobjecttype);
660
+ }
661
+ }
662
+ return relations;
663
+ }
596
664
  /**
597
665
  * Gets all possible values for a dropdown field
598
666
  *
@@ -619,7 +687,7 @@ var MetadataAPI = class {
619
687
  }
620
688
  const response = await this.client.request({
621
689
  method: "GET",
622
- endpoint: `/metadata/records/${objectTypeStr}/fields/${fieldName}/values`,
690
+ endpoint: ENDPOINTS.FIELD_VALUES(objectTypeStr, fieldName),
623
691
  signal
624
692
  });
625
693
  const result = {