fireberry-api-client 1.0.2-beta.2.2 → 1.0.2-beta.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{fieldTypes-BLzJTzpI.d.cts → fieldTypes-DZpAev83.d.cts} +21 -1
- package/dist/{fieldTypes-BLzJTzpI.d.ts → fieldTypes-DZpAev83.d.ts} +21 -1
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/sdk/index.cjs +4 -0
- package/dist/sdk/index.cjs.map +1 -1
- package/dist/sdk/index.d.cts +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +4 -0
- package/dist/sdk/index.js.map +1 -1
- package/dist/utils/index.cjs +21 -0
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +20 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +7 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants/excludedFields.ts","../src/errors.ts","../src/constants/objectIds.ts","../src/utils/queryBuilder.ts","../src/utils/helpers.ts","../src/transport/http.ts","../src/transport/sdk.ts","../src/utils/transport.ts","../src/constants/fieldTypes.ts","../src/api/metadata.ts","../src/api/records.ts","../src/api/batch.ts","../src/api/fields.ts","../src/api/files.ts","../src/client.ts","../src/utils/fieldMapping.ts","../src/utils/relatedFieldMapping.ts","../src/types/transport.ts","../src/constants/objectNames.ts","../src/constants/index.ts"],"names":["EXCLUDED_FIELDS_FOR_STAR_QUERY","FireberryErrorCode","BATCH_SIZE","getExcludedFieldsForStarQuery","codeFieldMeta"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Fields to exclude from queries when using '*' (all fields) for specific object types\r\n * These fields cause API errors when queried\r\n */\r\nexport const EXCLUDED_FIELDS_FOR_STAR_QUERY: Record<string, string[]> = {\r\n '7': ['deletedon', 'deletedby'], // Note\r\n '8': ['deletedon', 'deletedby', 's', 'w', 'o', 't', 'description'], // Competitor\r\n '114': ['deletedon', 'deletedby'], // Calendar Resource\r\n '115': ['deletedon', 'deletedby'], // Customer Journey\r\n '116': ['deletedon', 'deletedby'], // Profile\r\n '117': ['deletedon', 'deletedby'], // Landing Page\r\n};\r\n\r\n/**\r\n * Fields to exclude from lookup relation queries across ALL object types\r\n * These fields cause API errors when queried for lookup relationships\r\n */\r\nexport const EXCLUDED_LOOKUP_FIELDS: string[] = ['deletedby', 'deletedon'];\r\n\r\n/**\r\n * Checks if a field should be excluded from star queries for a given object type\r\n *\r\n * @param objectType - The object type ID\r\n * @param fieldName - The field name to check\r\n * @returns True if the field should be excluded\r\n */\r\nexport function isExcludedFromStarQuery(objectType: string | number, fieldName: string): boolean {\r\n const objectTypeStr = String(objectType);\r\n const excludedFields = EXCLUDED_FIELDS_FOR_STAR_QUERY[objectTypeStr];\r\n return excludedFields ? excludedFields.includes(fieldName) : false;\r\n}\r\n\r\n/**\r\n * Gets the list of excluded fields for a given object type\r\n *\r\n * @param objectType - The object type ID\r\n * @returns Array of field names to exclude, or empty array if none\r\n */\r\nexport function getExcludedFieldsForStarQuery(objectType: string | number): string[] {\r\n const objectTypeStr = String(objectType);\r\n return EXCLUDED_FIELDS_FOR_STAR_QUERY[objectTypeStr] || [];\r\n}\r\n","/**\r\n * Error codes for Fireberry API errors\r\n */\r\nexport enum FireberryErrorCode {\r\n /** Unknown or unexpected error */\r\n UNKNOWN = 'UNKNOWN',\r\n /** Network error (connection failed, DNS, etc.) */\r\n NETWORK_ERROR = 'NETWORK_ERROR',\r\n /** Request timeout */\r\n TIMEOUT = 'TIMEOUT',\r\n /** Authentication failed (invalid API key) */\r\n AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED',\r\n /** Authorization failed (missing permissions) */\r\n AUTHORIZATION_FAILED = 'AUTHORIZATION_FAILED',\r\n /** Resource not found */\r\n NOT_FOUND = 'NOT_FOUND',\r\n /** Rate limit exceeded (429) */\r\n RATE_LIMITED = 'RATE_LIMITED',\r\n /** Invalid request parameters */\r\n INVALID_REQUEST = 'INVALID_REQUEST',\r\n /** Server error (5xx) */\r\n SERVER_ERROR = 'SERVER_ERROR',\r\n /** Request was aborted */\r\n ABORTED = 'ABORTED',\r\n /** Invalid response from API */\r\n INVALID_RESPONSE = 'INVALID_RESPONSE',\r\n}\r\n\r\n/**\r\n * Options for creating a FireberryError\r\n */\r\nexport interface FireberryErrorOptions {\r\n /** Error code */\r\n code: FireberryErrorCode;\r\n /** HTTP status code if applicable */\r\n statusCode?: number;\r\n /** Original error that caused this error */\r\n cause?: Error;\r\n /** Additional context data */\r\n context?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Custom error class for Fireberry API errors\r\n */\r\nexport class FireberryError extends Error {\r\n /** Error code */\r\n readonly code: FireberryErrorCode;\r\n /** HTTP status code if applicable */\r\n readonly statusCode?: number;\r\n /** Original error that caused this error */\r\n readonly cause?: Error;\r\n /** Additional context data */\r\n readonly context?: Record<string, unknown>;\r\n\r\n constructor(message: string, options: FireberryErrorOptions) {\r\n super(message);\r\n this.name = 'FireberryError';\r\n this.code = options.code;\r\n this.statusCode = options.statusCode;\r\n this.cause = options.cause;\r\n this.context = options.context;\r\n\r\n // Maintains proper stack trace in V8 environments\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, FireberryError);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a string representation of the error\r\n */\r\n toString(): string {\r\n let str = `${this.name} [${this.code}]: ${this.message}`;\r\n if (this.statusCode) {\r\n str += ` (HTTP ${this.statusCode})`;\r\n }\r\n return str;\r\n }\r\n\r\n /**\r\n * Converts the error to a plain object for logging/serialization\r\n */\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n code: this.code,\r\n statusCode: this.statusCode,\r\n context: this.context,\r\n stack: this.stack,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Creates an error from an HTTP response\r\n */\r\nexport function createErrorFromResponse(\r\n response: Response,\r\n body?: unknown,\r\n): FireberryError {\r\n const status = response.status;\r\n let code: FireberryErrorCode;\r\n let message: string;\r\n\r\n switch (status) {\r\n case 400:\r\n code = FireberryErrorCode.INVALID_REQUEST;\r\n message = 'Invalid request parameters';\r\n break;\r\n case 401:\r\n code = FireberryErrorCode.AUTHENTICATION_FAILED;\r\n message = 'Authentication failed - invalid or missing API key';\r\n break;\r\n case 403:\r\n code = FireberryErrorCode.AUTHORIZATION_FAILED;\r\n message = 'Authorization failed - insufficient permissions';\r\n break;\r\n case 404:\r\n code = FireberryErrorCode.NOT_FOUND;\r\n message = 'Resource not found';\r\n break;\r\n case 429:\r\n code = FireberryErrorCode.RATE_LIMITED;\r\n message = 'Rate limit exceeded - too many requests';\r\n break;\r\n default:\r\n if (status >= 500) {\r\n code = FireberryErrorCode.SERVER_ERROR;\r\n message = `Server error (${status})`;\r\n } else {\r\n code = FireberryErrorCode.UNKNOWN;\r\n message = `HTTP error ${status}`;\r\n }\r\n }\r\n\r\n // Try to extract error message from response body\r\n if (body && typeof body === 'object') {\r\n const bodyObj = body as Record<string, unknown>;\r\n if (typeof bodyObj.message === 'string') {\r\n message = bodyObj.message;\r\n } else if (typeof bodyObj.error === 'string') {\r\n message = bodyObj.error;\r\n }\r\n }\r\n\r\n return new FireberryError(message, {\r\n code,\r\n statusCode: status,\r\n context: { body },\r\n });\r\n}\r\n\r\n/**\r\n * Creates an error from a network/fetch error\r\n */\r\nexport function createNetworkError(error: Error): FireberryError {\r\n // Check for abort\r\n if (error.name === 'AbortError') {\r\n return new FireberryError('Request was aborted', {\r\n code: FireberryErrorCode.ABORTED,\r\n cause: error,\r\n });\r\n }\r\n\r\n // Check for timeout\r\n if (error.name === 'TimeoutError' || error.message.includes('timeout')) {\r\n return new FireberryError('Request timed out', {\r\n code: FireberryErrorCode.TIMEOUT,\r\n cause: error,\r\n });\r\n }\r\n\r\n return new FireberryError(`Network error: ${error.message}`, {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n cause: error,\r\n });\r\n}\r\n","/**\r\n * Object Type ID to Primary Key Field Mapping\r\n * Maps Fireberry object type IDs to their primary key field names\r\n * Generated from actual API responses\r\n */\r\nexport const OBJECT_ID_MAP: Record<number, string> = {\r\n 1: 'accountid', // Account\r\n 2: 'contactid', // Contact\r\n 3: 'leadid', // Lead\r\n 4: 'opportunityid', // Opportunity\r\n 5: 'casesid', // Cases\r\n 6: 'activityid', // Activity\r\n 7: 'noteid', // Note\r\n 8: 'competitorid', // Competitor\r\n 9: 'crmuserid', // CrmUser\r\n 10: 'taskid', // Task\r\n 12: 'quoteid', // Quote\r\n 13: 'crmorderid', // CrmOrder\r\n 14: 'productid', // Product\r\n 17: 'crmorderitemid', // CrmOrderItem\r\n 20: 'emailtemplateid', // EmailTemplate\r\n 23: 'businessunitid', // BusinessUnit\r\n 25: 'orgid', // Org\r\n 27: 'printtemplateid', // PrintTemplate\r\n 28: 'contractid', // Contract\r\n 33: 'accountproductid', // AccountProduct\r\n 46: 'projectid', // Project\r\n 55: 'wfruleid', // WFRule\r\n 58: 'mdobjectid', // MDObject\r\n 64: 'roleid', // Role\r\n 67: 'campaignid', // Campaign\r\n 70: 'crmuserloginid', // CrmUserLogin\r\n 73: 'systemfieldid', // SystemField\r\n 76: 'articleid', // Article\r\n 77: 'linkid', // Link\r\n 78: 'invoiceid', // Invoice\r\n 80: 'invoicereceiptitemid', // InvoiceReceiptItem\r\n 81: 'invoiceid', // InvoiceNo\r\n 82: 'invoiceid', // InvoiceDraft\r\n 83: 'invoiceid', // InvoiceReceipt\r\n 84: 'invoiceid', // InvoiceReno\r\n 85: 'invoiceid', // InvoiceCredit\r\n 86: 'invoiceid', // InvoiceDelivery\r\n 89: 'iprestrictionid', // IpRestriction\r\n 90: 'transactionitemid', // TransactionItem\r\n 93: 'chargeid', // Charge\r\n 100: 'calllogid', // calllog\r\n 101: 'attendanceclockid', // AttendanceClock\r\n 102: 'activitylogid', // ActivityLog\r\n 104: 'conversationid', // Conversation\r\n 105: 'teaminboxid', // TeamInbox\r\n 106: 'texttemplateid', // TextTemplate\r\n 107: 'facebookconnectionid', // FacebookConnection\r\n 109: 'auditlogid', // AuditLog\r\n 110: 'smstemplateid', // SMSTemplate\r\n 111: 'providerverificationid', // ProviderVerification\r\n 114: 'calendarresourceid', // CalendarResource\r\n 115: 'journeyid', // Journey\r\n 116: 'profileid', // Profile\r\n 117: 'landingpageid', // LandingPage\r\n};\r\n\r\n/**\r\n * Gets the primary key field name for a given object type\r\n *\r\n * @param objectTypeId - The numeric object type ID\r\n * @returns The correct ID field name for the object type\r\n */\r\nexport function getObjectIdFieldName(objectTypeId: string | number): string {\r\n const objectTypeNum =\r\n typeof objectTypeId === 'string' ? parseInt(objectTypeId, 10) : objectTypeId;\r\n\r\n // Check if it's a mapped base object\r\n if (OBJECT_ID_MAP[objectTypeNum]) {\r\n return OBJECT_ID_MAP[objectTypeNum];\r\n }\r\n\r\n // For custom objects (1000 and up), use the pattern customobjectXid\r\n if (objectTypeNum >= 1000) {\r\n return `customobject${objectTypeNum}id`;\r\n }\r\n\r\n // Fallback to generic 'id' for unmapped objects\r\n return 'id';\r\n}\r\n","import type { QueryOperator, QueryMetadata, QueryResultWithMetadata, QueryExplainResult } from '../types/query';\r\nimport { getObjectIdFieldName } from '../constants/objectIds';\r\n\r\n/**\r\n * Regular expression to match pure date format (YYYY-MM-DD).\r\n * Does not match datetime formats like YYYY-MM-DDTHH:MM:SS or YYYY-MM-DD HH:MM:SS.\r\n */\r\nconst PURE_DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n\r\n/**\r\n * Checks if a value is a pure date string (YYYY-MM-DD format).\r\n * Returns false for datetime formats that include time components.\r\n *\r\n * @param value - The value to check\r\n * @returns True if the value is a pure date string\r\n *\r\n * @example\r\n * isPureDate('2024-01-15') // true\r\n * isPureDate('2024-01-15T10:30:00') // false\r\n * isPureDate('2024-01-15 10:30:00') // false\r\n * isPureDate('123') // false\r\n */\r\nexport function isPureDate(value: string): boolean {\r\n return PURE_DATE_REGEX.test(value);\r\n}\r\n\r\n/**\r\n * Adds a specified number of days to a date string.\r\n * Works with both pure dates (YYYY-MM-DD) and datetime formats.\r\n *\r\n * @param dateStr - The date string to modify\r\n * @param days - Number of days to add (can be negative)\r\n * @returns The modified date in YYYY-MM-DD format\r\n *\r\n * @example\r\n * addDays('2024-01-15', 1) // '2024-01-16'\r\n * addDays('2024-01-31', 1) // '2024-02-01'\r\n * addDays('2024-03-01', -1) // '2024-02-29' (leap year)\r\n */\r\nexport function addDays(dateStr: string, days: number): string {\r\n // Extract just the date part if datetime format\r\n const datePart = dateStr.split(/[T\\s]/)[0];\r\n const date = new Date(datePart + 'T00:00:00');\r\n date.setDate(date.getDate() + days);\r\n\r\n const year = date.getFullYear();\r\n const month = String(date.getMonth() + 1).padStart(2, '0');\r\n const day = String(date.getDate()).padStart(2, '0');\r\n\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Escapes special characters in query values to prevent query injection.\r\n * This is a security measure to ensure user-provided values cannot modify\r\n * the query structure or inject additional query logic.\r\n *\r\n * @param value - The value to escape\r\n * @returns Escaped value safe for use in Fireberry queries\r\n */\r\nexport function escapeQueryValue(value: string): string {\r\n if (!value) {\r\n return '';\r\n }\r\n // Escape backslashes first to avoid double-escaping\r\n let escaped = value.replace(/\\\\/g, '\\\\\\\\');\r\n // Escape parentheses which could break out of conditions\r\n escaped = escaped.replace(/\\(/g, '\\\\(');\r\n escaped = escaped.replace(/\\)/g, '\\\\)');\r\n // Escape logical operators that could inject additional conditions\r\n // Using word boundaries to only match standalone operators\r\n escaped = escaped.replace(/\\bor\\b/gi, '\\\\or');\r\n escaped = escaped.replace(/\\band\\b/gi, '\\\\and');\r\n return escaped;\r\n}\r\n\r\n/**\r\n * Sanitizes a query string to ensure proper syntax for the Fireberry API\r\n * Handles common syntax issues and removes extraneous elements\r\n *\r\n * @param query - Query string to sanitize\r\n * @returns Sanitized query string\r\n */\r\nexport function sanitizeQuery(query: string): string {\r\n if (!query) {\r\n return '';\r\n }\r\n\r\n // First, protect special operators from being modified\r\n // Temporarily mark is-null and is-not-null operators\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+)\\s+(is-null|is-not-null)\\s*\\)/g,\r\n '($1 __SPECIAL_OPERATOR__$2)',\r\n );\r\n\r\n // Also protect text operators like start-with, not-start-with\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+)\\s+(start-with|not-start-with)\\s+([^)]+)\\s*\\)/g,\r\n '($1 __TEXT_OPERATOR__$2 $3)',\r\n );\r\n\r\n // Fix missing operators: (field value) -> (field = value)\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+(?:field|Field|system|System)[0-9]*)\\s+(?!__SPECIAL_OPERATOR__|__TEXT_OPERATOR__)([^()<>=!]+)\\s*\\)/g,\r\n '($1 = $2)',\r\n );\r\n\r\n // Fix with a more general pattern for any field-value pair without operator\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+)\\s+(?!__SPECIAL_OPERATOR__|__TEXT_OPERATOR__|<=|>=|!=|<|>|=\\s)([^()<>]+)\\s*\\)/g,\r\n '($1 = $2)',\r\n );\r\n\r\n // Restore special operators\r\n query = query.replace(/__SPECIAL_OPERATOR__/g, '');\r\n query = query.replace(/__TEXT_OPERATOR__/g, '');\r\n\r\n // Remove parentheses containing only a comparison operator\r\n query = query.replace(/\\(\\s*(?:<=|>=|!=|<|>|=)\\s*\\)/g, '');\r\n // Remove parentheses containing only text operators\r\n query = query.replace(/\\(\\s*(?:start-with|not-start-with)\\s*\\)/gi, '');\r\n // Remove parentheses containing only logical operators (AND/OR)\r\n query = query.replace(/\\(\\s*(?:and|or)\\s*\\)/gi, '');\r\n // Remove empty parentheses\r\n query = query.replace(/\\(\\s*\\)/g, '');\r\n // Remove logical operators without operands at start/end\r\n query = query.replace(/^\\s*(and|or)\\s*/gi, '');\r\n query = query.replace(/\\s*(and|or)\\s*$/gi, '');\r\n // Remove redundant nested parentheses: ((x)) -> (x)\r\n const nestedPattern = /\\(\\s*\\(([^()]+)\\)\\s*\\)/g;\r\n while (nestedPattern.test(query)) {\r\n query = query.replace(nestedPattern, '($1)');\r\n }\r\n // Collapse multiple spaces\r\n query = query.replace(/\\s+/g, ' ');\r\n return query.trim();\r\n}\r\n\r\n/**\r\n * Gets today's date in YYYY-MM-DD format\r\n */\r\nexport function getToday(): string {\r\n const now = new Date();\r\n const year = now.getFullYear();\r\n const month = String(now.getMonth() + 1).padStart(2, '0');\r\n const day = String(now.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Gets the start of current week (Monday) in YYYY-MM-DD format\r\n */\r\nexport function getStartOfWeek(): string {\r\n const now = new Date();\r\n const day = now.getDay();\r\n // Adjust so Monday is first day (day 0 = Sunday, so Monday = 1)\r\n const diff = now.getDate() - day + (day === 0 ? -6 : 1);\r\n const monday = new Date(now);\r\n monday.setDate(diff);\r\n const year = monday.getFullYear();\r\n const month = String(monday.getMonth() + 1).padStart(2, '0');\r\n const dayStr = String(monday.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${dayStr}`;\r\n}\r\n\r\n/**\r\n * Gets the start of current month in YYYY-MM-DD format\r\n */\r\nexport function getStartOfMonth(): string {\r\n const now = new Date();\r\n const year = now.getFullYear();\r\n const month = String(now.getMonth() + 1).padStart(2, '0');\r\n return `${year}-${month}-01`;\r\n}\r\n\r\n/**\r\n * Date condition builder for fluent date query construction\r\n */\r\nexport interface DateConditionBuilder {\r\n /** Records from today */\r\n today(): QueryBuilder;\r\n /** Records from this week (Monday to now) */\r\n thisWeek(): QueryBuilder;\r\n /** Records from this month */\r\n thisMonth(): QueryBuilder;\r\n /** Records between two dates (inclusive) */\r\n between(startDate: string, endDate: string): QueryBuilder;\r\n /** Records from the last N days (including today) */\r\n daysAgo(days: number): QueryBuilder;\r\n /** Records before date */\r\n before(date: string): QueryBuilder;\r\n /** Records after date */\r\n after(date: string): QueryBuilder;\r\n /** Records on or before date */\r\n onOrBefore(date: string): QueryBuilder;\r\n /** Records on or after date */\r\n onOrAfter(date: string): QueryBuilder;\r\n}\r\n\r\n/**\r\n * Condition builder for fluent query construction\r\n */\r\nexport interface ConditionBuilder {\r\n /** Equals comparison (=) */\r\n equals(value: string | number): QueryBuilder;\r\n /** Not equals comparison (!=) */\r\n notEquals(value: string | number): QueryBuilder;\r\n /** IN comparison - matches any of the provided values (joined with OR) */\r\n in(values: (string | number)[]): QueryBuilder;\r\n /** Less than comparison (<) - works with numbers and dates */\r\n lessThan(value: string | number): QueryBuilder;\r\n /** Greater than comparison (>) - works with numbers and dates */\r\n greaterThan(value: string | number): QueryBuilder;\r\n /** Less than or equal (<=) - auto-converts pure dates (YYYY-MM-DD) to < nextDay */\r\n lessThanOrEqual(value: string | number): QueryBuilder;\r\n /** Greater than or equal (>=) - works with numbers and dates */\r\n greaterThanOrEqual(value: string | number): QueryBuilder;\r\n /** Contains value (translates to start-with %value) */\r\n contains(value: string): QueryBuilder;\r\n /** Does not contain value (translates to not-start-with %value) */\r\n notContains(value: string): QueryBuilder;\r\n /** Starts with value (start-with) */\r\n startsWith(value: string): QueryBuilder;\r\n /** Does not start with value (not-start-with) */\r\n notStartsWith(value: string): QueryBuilder;\r\n /** Field is null (is-null) */\r\n isNull(): QueryBuilder;\r\n /** Field is not null (is-not-null) */\r\n isNotNull(): QueryBuilder;\r\n}\r\n\r\n/**\r\n * Internal representation of a query condition\r\n */\r\ninterface QueryCondition {\r\n field: string;\r\n operator: QueryOperator;\r\n value?: string;\r\n}\r\n\r\n/**\r\n * Fluent query builder for constructing Fireberry queries\r\n *\r\n * @example\r\n * ```typescript\r\n * // Build a query string\r\n * const query = new QueryBuilder()\r\n * .where('statuscode').equals('1')\r\n * .and()\r\n * .where('emailaddress1').contains('@example.com')\r\n * .build();\r\n * // Output: \"(statuscode = 1) and (emailaddress1 start-with %@example.com)\"\r\n *\r\n * // With select and execute (requires client)\r\n * const result = await new QueryBuilder(client)\r\n * .objectType('1')\r\n * .select('accountid', 'name', 'emailaddress1')\r\n * .where('statuscode').equals('1')\r\n * .limit(100)\r\n * .execute();\r\n * ```\r\n */\r\n/**\r\n * Client interface for query execution\r\n */\r\ninterface QueryClient {\r\n query(options: {\r\n objectType: string;\r\n fields: string[];\r\n query: string;\r\n showRealValue: boolean;\r\n sortBy?: string;\r\n sortType?: 'asc' | 'desc';\r\n limit?: number;\r\n page?: number;\r\n signal?: AbortSignal;\r\n }): Promise<QueryResult>;\r\n}\r\n\r\n/**\r\n * Query result type\r\n */\r\ninterface QueryResult {\r\n records: Record<string, unknown>[];\r\n total: number;\r\n success: boolean;\r\n}\r\n\r\nexport class QueryBuilder {\r\n private conditions: QueryCondition[] = [];\r\n private joinOperators: ('and' | 'or')[] = [];\r\n private currentField: string | null = null;\r\n private selectedFields: string[] = [];\r\n private objectTypeId: string | null = null;\r\n private sortByField: string | null = null;\r\n private sortDirection: 'asc' | 'desc' = 'desc';\r\n private limitValue: number | null = null;\r\n private pageNumber: number = 1;\r\n private showRealValueFlag: boolean = true;\r\n private client: QueryClient | null = null;\r\n\r\n /**\r\n * Creates a new QueryBuilder\r\n * @param client - Optional FireberryClient for executing queries\r\n */\r\n constructor(client?: QueryClient) {\r\n this.client = client ?? null;\r\n }\r\n\r\n /**\r\n * Sets the object type for the query\r\n * @param objectType - Object type ID (e.g., '1' for Account)\r\n */\r\n objectType(objectType: string | number): this {\r\n this.objectTypeId = String(objectType);\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds fields to select\r\n * @param fields - Field names to select\r\n */\r\n select(...fields: string[]): this {\r\n this.selectedFields.push(...fields);\r\n return this;\r\n }\r\n\r\n /**\r\n * Starts a new WHERE condition\r\n * @param field - Field name to filter on\r\n */\r\n where(field: string): ConditionBuilder {\r\n this.currentField = field;\r\n return this.createConditionBuilder();\r\n }\r\n\r\n /**\r\n * Starts a new WHERE condition for a date field with date-specific helpers\r\n * @param field - Date field name to filter on\r\n *\r\n * @example\r\n * ```typescript\r\n * // Records created today\r\n * qb.whereDate('createdon').today()\r\n *\r\n * // Records from this week\r\n * qb.whereDate('createdon').thisWeek()\r\n *\r\n * // Records from the last 30 days\r\n * qb.whereDate('createdon').daysAgo(30)\r\n *\r\n * // Records between two dates\r\n * qb.whereDate('createdon').between('2024-01-01', '2024-12-31')\r\n * ```\r\n */\r\n whereDate(field: string): DateConditionBuilder {\r\n return this.createDateConditionBuilder(field);\r\n }\r\n\r\n /**\r\n * Adds a WHERE condition for the primary ID field, automatically mapped based on object type\r\n * @param value - The ID value to match\r\n * @throws Error if objectType is not set\r\n *\r\n * @example\r\n * ```typescript\r\n * // Instead of knowing the exact field name:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereId('abc123') // Automatically uses 'accountid' for object type 1\r\n * .execute();\r\n *\r\n * // Equivalent to:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .where('accountid').equals('abc123')\r\n * .execute();\r\n * ```\r\n */\r\n whereId(value: string | number): this {\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type must be set before using whereId(). Call .objectType() first.');\r\n }\r\n const idField = getObjectIdFieldName(this.objectTypeId);\r\n this.addCondition(idField, '=', String(value));\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds WHERE conditions for multiple primary ID values, joined with OR\r\n * @param values - Array of ID values to match\r\n * @throws Error if objectType is not set\r\n * @throws Error if values array is empty\r\n *\r\n * @example\r\n * ```typescript\r\n * // Query multiple accounts by ID:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereIds(['id1', 'id2', 'id3'])\r\n * .execute();\r\n *\r\n * // Generates: (accountid = id1) or (accountid = id2) or (accountid = id3)\r\n *\r\n * // Can be combined with other conditions:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereIds(['id1', 'id2'])\r\n * .and()\r\n * .where('statuscode').equals('1')\r\n * .execute();\r\n * ```\r\n */\r\n whereIds(values: (string | number)[]): this {\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type must be set before using whereIds(). Call .objectType() first.');\r\n }\r\n if (!values || values.length === 0) {\r\n throw new Error('whereIds() requires at least one ID value.');\r\n }\r\n const idField = getObjectIdFieldName(this.objectTypeId);\r\n\r\n // Add first condition\r\n this.addCondition(idField, '=', String(values[0]));\r\n\r\n // Add remaining conditions with OR\r\n for (let i = 1; i < values.length; i++) {\r\n this.joinOperators.push('or');\r\n this.addCondition(idField, '=', String(values[i]));\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a WHERE IN condition for a field with multiple values, joined with OR\r\n * @param field - Field name to filter on\r\n * @param values - Array of values to match\r\n * @throws Error if values array is empty\r\n *\r\n * @example\r\n * ```typescript\r\n * // Query accounts with specific status codes:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereIn('statuscode', [1, 2, 3])\r\n * .execute();\r\n *\r\n * // Generates: (statuscode = 1) or (statuscode = 2) or (statuscode = 3)\r\n * ```\r\n */\r\n whereIn(field: string, values: (string | number)[]): this {\r\n if (!values || values.length === 0) {\r\n throw new Error('whereIn() requires at least one value.');\r\n }\r\n // Add first condition\r\n this.addCondition(field, '=', String(values[0]));\r\n // Add remaining conditions with OR\r\n for (let i = 1; i < values.length; i++) {\r\n this.joinOperators.push('or');\r\n this.addCondition(field, '=', String(values[i]));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds an AND logical operator\r\n */\r\n and(): this {\r\n if (this.conditions.length > 0) {\r\n this.joinOperators.push('and');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds an OR logical operator\r\n */\r\n or(): this {\r\n if (this.conditions.length > 0) {\r\n this.joinOperators.push('or');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the sort field and direction\r\n * @param field - Field to sort by\r\n * @param direction - Sort direction ('asc' or 'desc')\r\n */\r\n sortBy(field: string, direction: 'asc' | 'desc' = 'desc'): this {\r\n this.sortByField = field;\r\n this.sortDirection = direction;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the maximum number of records to return\r\n * @param count - Maximum record count\r\n */\r\n limit(count: number): this {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the page number for pagination\r\n * @param page - Page number (1-based)\r\n */\r\n page(page: number): this {\r\n this.pageNumber = page;\r\n return this;\r\n }\r\n\r\n /**\r\n * Controls whether to show real values (labels) for dropdown fields\r\n * @param show - Whether to show real values (default: true)\r\n */\r\n showRealValue(show: boolean): this {\r\n this.showRealValueFlag = show;\r\n return this;\r\n }\r\n\r\n /**\r\n * Builds the query string from conditions\r\n * @returns The built query string\r\n */\r\n build(): string {\r\n if (this.conditions.length === 0) {\r\n return '';\r\n }\r\n\r\n const parts: string[] = [];\r\n\r\n for (let i = 0; i < this.conditions.length; i++) {\r\n const condition = this.conditions[i];\r\n let conditionStr: string;\r\n\r\n if (condition.operator === 'is-null' || condition.operator === 'is-not-null') {\r\n conditionStr = `(${condition.field} ${condition.operator})`;\r\n } else {\r\n const escapedValue = escapeQueryValue(condition.value || '');\r\n conditionStr = `(${condition.field} ${condition.operator} ${escapedValue})`;\r\n }\r\n\r\n parts.push(conditionStr);\r\n\r\n // Add join operator if there's a next condition\r\n if (i < this.joinOperators.length) {\r\n parts.push(this.joinOperators[i]);\r\n }\r\n }\r\n\r\n return parts.join(' ');\r\n }\r\n\r\n /**\r\n * Returns the selected fields array\r\n * Useful for inspecting the query configuration\r\n */\r\n getFields(): string[] {\r\n return [...this.selectedFields];\r\n }\r\n\r\n /**\r\n * Converts the query builder state to a payload compatible with @fireberry/sdk\r\n *\r\n * @returns Object with `fields` (comma-separated string) and `query` (filter string)\r\n *\r\n * @example\r\n * ```typescript\r\n * import FireberryClientSDK from '@fireberry/sdk/client';\r\n * import { QueryBuilder } from 'fireberry-api-client';\r\n *\r\n * const sdk = new FireberryClientSDK();\r\n * await sdk.initializeContext();\r\n *\r\n * const payload = new QueryBuilder()\r\n * .select('accountid', 'accountname')\r\n * .where('statuscode').equals('1')\r\n * .toSDKPayload();\r\n *\r\n * // Use with SDK\r\n * const results = await sdk.api.query(1, payload);\r\n * ```\r\n */\r\n toSDKPayload(): { fields: string; query: string; page_size?: number; page_number?: number } {\r\n const payload: { fields: string; query: string; page_size?: number; page_number?: number } = {\r\n fields: this.selectedFields.length > 0 ? this.selectedFields.join(',') : '*',\r\n query: this.build(),\r\n };\r\n\r\n if (this.limitValue !== null) {\r\n payload.page_size = this.limitValue;\r\n }\r\n\r\n if (this.pageNumber > 1) {\r\n payload.page_number = this.pageNumber;\r\n }\r\n\r\n return payload;\r\n }\r\n\r\n /**\r\n * Executes the query and returns the count of matching records\r\n * Uses minimal field selection (ID only) for efficiency\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Number of matching records\r\n *\r\n * @example\r\n * ```typescript\r\n * const activeCount = await client.queryBuilder()\r\n * .objectType(1)\r\n * .where('statuscode').equals('1')\r\n * .count();\r\n *\r\n * console.log(`Found ${activeCount} active accounts`);\r\n * ```\r\n */\r\n async count(signal?: AbortSignal): Promise<number> {\r\n if (!this.client) {\r\n throw new Error('QueryBuilder requires a client to execute queries. Pass a FireberryClient to the constructor.');\r\n }\r\n\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type is required. Use .objectType() before executing.');\r\n }\r\n\r\n // Use minimal fields for efficiency - just get the ID field\r\n const idField = getObjectIdFieldName(this.objectTypeId);\r\n\r\n const result = await this.client.query({\r\n objectType: this.objectTypeId,\r\n fields: [idField],\r\n query: this.build(),\r\n showRealValue: false, // No need for labels\r\n signal,\r\n });\r\n\r\n return result.total;\r\n }\r\n\r\n /**\r\n * Executes the query and returns the first record or null\r\n * Automatically sets limit to 1 for efficiency\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns First record or null if no records found\r\n *\r\n * @example\r\n * ```typescript\r\n * const account = await client.queryBuilder()\r\n * .objectType(1)\r\n * .where('accountname').equals('Acme Corp')\r\n * .first();\r\n *\r\n * if (account) {\r\n * console.log(account.accountid);\r\n * }\r\n * ```\r\n */\r\n async first(signal?: AbortSignal): Promise<Record<string, unknown> | null> {\r\n // Temporarily set limit to 1 for efficiency\r\n const originalLimit = this.limitValue;\r\n this.limitValue = 1;\r\n\r\n try {\r\n const result = await this.execute(signal);\r\n return result.records[0] ?? null;\r\n } finally {\r\n // Restore original limit\r\n this.limitValue = originalLimit;\r\n }\r\n }\r\n\r\n /**\r\n * Executes the query (requires client to be set)\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Query results\r\n */\r\n async execute(signal?: AbortSignal): Promise<QueryResult> {\r\n if (!this.client) {\r\n throw new Error('QueryBuilder requires a client to execute queries. Pass a FireberryClient to the constructor.');\r\n }\r\n\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type is required. Use .objectType() before executing.');\r\n }\r\n\r\n const queryOptions: Parameters<QueryClient['query']>[0] = {\r\n objectType: this.objectTypeId,\r\n fields: this.selectedFields.length > 0 ? this.selectedFields : ['*'],\r\n query: this.build(),\r\n showRealValue: this.showRealValueFlag,\r\n };\r\n\r\n if (this.sortByField) {\r\n queryOptions.sortBy = this.sortByField;\r\n queryOptions.sortType = this.sortDirection;\r\n }\r\n\r\n if (this.limitValue !== null) {\r\n queryOptions.limit = this.limitValue;\r\n }\r\n\r\n if (this.pageNumber > 1) {\r\n queryOptions.page = this.pageNumber;\r\n }\r\n\r\n if (signal) {\r\n queryOptions.signal = signal;\r\n }\r\n\r\n return this.client.query(queryOptions);\r\n }\r\n\r\n /**\r\n * Executes the query and returns results with debugging metadata\r\n * Includes query string, fields, pagination info, and execution time\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Query results with metadata\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.queryBuilder()\r\n * .objectType(1)\r\n * .select('accountid', 'accountname')\r\n * .where('statuscode').equals('1')\r\n * .executeWithDebug();\r\n *\r\n * console.log('Query:', result.metadata.queryString);\r\n * console.log('Fields:', result.metadata.fields);\r\n * console.log('Execution time:', result.metadata.executionTimeMs, 'ms');\r\n * console.log('Records:', result.records.length);\r\n * ```\r\n */\r\n async executeWithDebug(signal?: AbortSignal): Promise<QueryResultWithMetadata> {\r\n if (!this.client) {\r\n throw new Error('QueryBuilder requires a client to execute queries. Pass a FireberryClient to the constructor.');\r\n }\r\n\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type is required. Use .objectType() before executing.');\r\n }\r\n\r\n const startTime = Date.now();\r\n const fields = this.selectedFields.length > 0 ? this.selectedFields : ['*'];\r\n const queryString = this.build();\r\n\r\n const queryOptions: Parameters<QueryClient['query']>[0] = {\r\n objectType: this.objectTypeId,\r\n fields,\r\n query: queryString,\r\n showRealValue: this.showRealValueFlag,\r\n };\r\n\r\n if (this.sortByField) {\r\n queryOptions.sortBy = this.sortByField;\r\n queryOptions.sortType = this.sortDirection;\r\n }\r\n\r\n if (this.limitValue !== null) {\r\n queryOptions.limit = this.limitValue;\r\n }\r\n\r\n if (this.pageNumber > 1) {\r\n queryOptions.page = this.pageNumber;\r\n }\r\n\r\n if (signal) {\r\n queryOptions.signal = signal;\r\n }\r\n\r\n const result = await this.client.query(queryOptions);\r\n const executionTimeMs = Date.now() - startTime;\r\n\r\n const metadata: QueryMetadata = {\r\n objectType: this.objectTypeId,\r\n fields,\r\n queryString,\r\n pageNumber: this.pageNumber,\r\n pageSize: this.limitValue ?? 500,\r\n autoPage: true, // Default behavior\r\n executionTimeMs,\r\n };\r\n\r\n if (this.sortByField) {\r\n metadata.sortBy = this.sortByField;\r\n metadata.sortType = this.sortDirection;\r\n }\r\n\r\n if (this.limitValue !== null) {\r\n metadata.limit = this.limitValue;\r\n }\r\n\r\n return {\r\n ...result,\r\n metadata,\r\n };\r\n }\r\n\r\n /**\r\n * Analyzes the query without executing it (dry run)\r\n * Returns information about what the query will do, potential issues, and optimization suggestions\r\n *\r\n * @returns Query analysis with warnings and suggestions\r\n *\r\n * @example\r\n * ```typescript\r\n * const analysis = client.queryBuilder()\r\n * .objectType('1')\r\n * .select('*')\r\n * .where('statuscode').equals('1')\r\n * .explain();\r\n *\r\n * console.log('Query:', analysis.query);\r\n * console.log('Warnings:', analysis.warnings);\r\n * console.log('Suggestions:', analysis.suggestions);\r\n * console.log('Estimated API calls:', analysis.estimatedApiCalls);\r\n * ```\r\n */\r\n explain(): QueryExplainResult {\r\n const warnings: string[] = [];\r\n const suggestions: string[] = [];\r\n\r\n // Check object type\r\n if (!this.objectTypeId) {\r\n warnings.push('Object type is not set. Call .objectType() before executing.');\r\n }\r\n\r\n // Analyze fields\r\n const fields = this.selectedFields.length > 0 ? this.selectedFields : ['*'];\r\n const usesWildcard = fields.includes('*') || fields.length === 0;\r\n\r\n if (usesWildcard) {\r\n warnings.push('Using wildcard (*) fields may include unnecessary data and slow down queries.');\r\n suggestions.push('Consider selecting only the specific fields you need with .select()');\r\n }\r\n\r\n // Analyze query\r\n const queryString = this.build();\r\n const conditionCount = this.conditions.length;\r\n\r\n if (conditionCount === 0 && !this.limitValue) {\r\n warnings.push('No query conditions or limit set. This may return a large number of records.');\r\n suggestions.push('Add filters with .where() or set a .limit() to control result size.');\r\n }\r\n\r\n // Check for potential performance issues\r\n const hasContainsOperator = this.conditions.some(\r\n (c) => c.operator === 'start-with' && c.value?.startsWith('%'),\r\n );\r\n if (hasContainsOperator) {\r\n warnings.push('Contains queries (using % prefix) may be slower than exact matches.');\r\n }\r\n\r\n // Check for OR conditions (may affect performance)\r\n const hasOrConditions = this.joinOperators.some((op) => op === 'or');\r\n if (hasOrConditions && conditionCount > 5) {\r\n warnings.push('Multiple OR conditions may affect query performance.');\r\n suggestions.push('Consider breaking into separate queries if possible.');\r\n }\r\n\r\n // Sorting analysis\r\n const sortField = this.sortByField || 'modifiedon';\r\n const sortDirection = this.sortDirection;\r\n\r\n // Estimate API calls\r\n let estimatedApiCalls = 1;\r\n const pageSize = 500; // Default page size\r\n const willAutoPage = this.limitValue === null; // Auto-page when no limit\r\n\r\n if (willAutoPage && conditionCount === 0) {\r\n // Without conditions, could be many pages\r\n estimatedApiCalls = -1; // Unknown/many\r\n warnings.push('Without filters, query may require many API calls for pagination.');\r\n } else if (this.limitValue !== null) {\r\n estimatedApiCalls = Math.ceil(this.limitValue / pageSize);\r\n }\r\n\r\n // Check for missing index hints\r\n if (!this.sortByField && conditionCount > 0) {\r\n suggestions.push('Consider adding .sortBy() to control result ordering.');\r\n }\r\n\r\n // Check showRealValue impact\r\n if (this.showRealValueFlag) {\r\n suggestions.push('showRealValue is enabled (default). Set .showRealValue(false) if you only need IDs.');\r\n }\r\n\r\n return {\r\n objectType: this.objectTypeId || '(not set)',\r\n query: queryString || '(no conditions)',\r\n fields,\r\n usesWildcard,\r\n willAutoPage,\r\n limit: this.limitValue,\r\n pageSize,\r\n sorting: {\r\n field: sortField,\r\n direction: sortDirection,\r\n },\r\n estimatedApiCalls,\r\n warnings,\r\n suggestions,\r\n conditionCount,\r\n showRealValue: this.showRealValueFlag,\r\n };\r\n }\r\n\r\n /**\r\n * Creates a condition builder for the current field\r\n */\r\n private createConditionBuilder(): ConditionBuilder {\r\n const field = this.currentField!;\r\n\r\n return {\r\n equals: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '=', String(value));\r\n return this;\r\n },\r\n notEquals: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '!=', String(value));\r\n return this;\r\n },\r\n in: (values: (string | number)[]): QueryBuilder => {\r\n if (!values || values.length === 0) {\r\n throw new Error('in() requires at least one value.');\r\n }\r\n // Add first condition\r\n this.addCondition(field, '=', String(values[0]));\r\n // Add remaining conditions with OR\r\n for (let i = 1; i < values.length; i++) {\r\n this.joinOperators.push('or');\r\n this.addCondition(field, '=', String(values[i]));\r\n }\r\n return this;\r\n },\r\n lessThan: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '<', String(value));\r\n return this;\r\n },\r\n greaterThan: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '>', String(value));\r\n return this;\r\n },\r\n lessThanOrEqual: (value: string | number): QueryBuilder => {\r\n const strValue = String(value);\r\n // Fireberry API bug: <= with pure dates (YYYY-MM-DD) behaves like <\r\n // because it interprets the date as midnight (00:00:00).\r\n // Auto-convert to < nextDay for correct \"on or before\" behavior.\r\n if (isPureDate(strValue)) {\r\n const nextDay = addDays(strValue, 1);\r\n this.addCondition(field, '<', nextDay);\r\n } else {\r\n this.addCondition(field, '<=', strValue);\r\n }\r\n return this;\r\n },\r\n greaterThanOrEqual: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '>=', String(value));\r\n return this;\r\n },\r\n contains: (value: string): QueryBuilder => {\r\n // Contains translates to \"start-with %value\"\r\n this.addCondition(field, 'start-with', `%${value}`);\r\n return this;\r\n },\r\n notContains: (value: string): QueryBuilder => {\r\n // Not contains translates to \"not-start-with %value\"\r\n this.addCondition(field, 'not-start-with', `%${value}`);\r\n return this;\r\n },\r\n startsWith: (value: string): QueryBuilder => {\r\n this.addCondition(field, 'start-with', value);\r\n return this;\r\n },\r\n notStartsWith: (value: string): QueryBuilder => {\r\n this.addCondition(field, 'not-start-with', value);\r\n return this;\r\n },\r\n isNull: (): QueryBuilder => {\r\n this.addCondition(field, 'is-null');\r\n return this;\r\n },\r\n isNotNull: (): QueryBuilder => {\r\n this.addCondition(field, 'is-not-null');\r\n return this;\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Creates a date condition builder for the specified field\r\n */\r\n private createDateConditionBuilder(field: string): DateConditionBuilder {\r\n return {\r\n today: (): QueryBuilder => {\r\n const today = getToday();\r\n // Records from today: >= today AND < tomorrow\r\n this.addCondition(field, '>=', today);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', addDays(today, 1));\r\n return this;\r\n },\r\n thisWeek: (): QueryBuilder => {\r\n const startOfWeek = getStartOfWeek();\r\n const tomorrow = addDays(getToday(), 1);\r\n // Records from start of week to now: >= monday AND < tomorrow\r\n this.addCondition(field, '>=', startOfWeek);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', tomorrow);\r\n return this;\r\n },\r\n thisMonth: (): QueryBuilder => {\r\n const startOfMonth = getStartOfMonth();\r\n const tomorrow = addDays(getToday(), 1);\r\n // Records from start of month to now: >= first day AND < tomorrow\r\n this.addCondition(field, '>=', startOfMonth);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', tomorrow);\r\n return this;\r\n },\r\n between: (startDate: string, endDate: string): QueryBuilder => {\r\n // Records between dates (inclusive): >= start AND < day after end\r\n this.addCondition(field, '>=', startDate);\r\n this.joinOperators.push('and');\r\n // Use < next day for inclusive end date (handles API quirk)\r\n const dayAfterEnd = isPureDate(endDate) ? addDays(endDate, 1) : endDate;\r\n this.addCondition(field, '<', dayAfterEnd);\r\n return this;\r\n },\r\n daysAgo: (days: number): QueryBuilder => {\r\n const today = getToday();\r\n const startDate = addDays(today, -days);\r\n const tomorrow = addDays(today, 1);\r\n // Records from N days ago to now: >= (today - N) AND < tomorrow\r\n this.addCondition(field, '>=', startDate);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', tomorrow);\r\n return this;\r\n },\r\n before: (date: string): QueryBuilder => {\r\n this.addCondition(field, '<', date);\r\n return this;\r\n },\r\n after: (date: string): QueryBuilder => {\r\n // After a date means > end of that day\r\n // For pure dates, use > date (API treats as > midnight, so actually > end of previous day)\r\n // We need >= next day for \"after\" to work correctly\r\n const nextDay = isPureDate(date) ? addDays(date, 1) : date;\r\n this.addCondition(field, '>=', nextDay);\r\n return this;\r\n },\r\n onOrBefore: (date: string): QueryBuilder => {\r\n // Use < next day for inclusive (handles API quirk with <=)\r\n const nextDay = isPureDate(date) ? addDays(date, 1) : date;\r\n this.addCondition(field, '<', nextDay);\r\n return this;\r\n },\r\n onOrAfter: (date: string): QueryBuilder => {\r\n this.addCondition(field, '>=', date);\r\n return this;\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Adds a condition to the query\r\n */\r\n private addCondition(field: string, operator: QueryOperator, value?: string): void {\r\n this.conditions.push({ field, operator, value });\r\n this.currentField = null;\r\n }\r\n}\r\n","/**\r\n * Waits for the specified number of milliseconds\r\n * Used for rate limit handling and retry logic\r\n *\r\n * @param ms - Time to wait in milliseconds\r\n * @returns Promise that resolves after the specified time\r\n */\r\nexport function wait(ms: number): Promise<void> {\r\n return new Promise<void>((resolve) => {\r\n setTimeout(resolve, ms);\r\n });\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of specified size\r\n * Used for processing large batches in Fireberry-compatible pieces (max 20 items)\r\n *\r\n * @param array - Array to split\r\n * @param size - Maximum chunk size\r\n * @returns Array of chunks\r\n */\r\nexport function chunkArray<T>(array: T[], size: number): T[][] {\r\n const result: T[][] = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely converts a value to a string for API usage\r\n * Handles null, undefined, numbers, and other types\r\n *\r\n * @param value - The value to convert\r\n * @returns String representation of the value\r\n */\r\nexport function safeStringValue(value: unknown): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n if (typeof value === 'string') {\r\n return value;\r\n }\r\n if (typeof value === 'number' || typeof value === 'boolean') {\r\n return String(value);\r\n }\r\n if (typeof value === 'object') {\r\n return JSON.stringify(value);\r\n }\r\n return String(value);\r\n}\r\n\r\n/**\r\n * Normalizes fields input to an array\r\n * Accepts both array of strings and comma-separated string\r\n *\r\n * @param fields - Fields as array or comma-separated string\r\n * @returns Array of field names\r\n *\r\n * @example\r\n * normalizeFields('a,b,c') // ['a', 'b', 'c']\r\n * normalizeFields(['a', 'b']) // ['a', 'b']\r\n * normalizeFields('*') // ['*']\r\n */\r\nexport function normalizeFields(fields: string | string[]): string[] {\r\n if (Array.isArray(fields)) {\r\n return fields;\r\n }\r\n if (typeof fields === 'string') {\r\n // Handle empty string\r\n if (!fields.trim()) {\r\n return [];\r\n }\r\n // Split by comma and trim whitespace\r\n return fields.split(',').map((f) => f.trim()).filter((f) => f.length > 0);\r\n }\r\n return [];\r\n}\r\n\r\n/**\r\n * Joins fields array into a comma-separated string\r\n * Useful for API requests that expect fields as a string\r\n *\r\n * @param fields - Array of field names\r\n * @returns Comma-separated string of fields\r\n */\r\nexport function joinFields(fields: string[]): string {\r\n return fields.join(',');\r\n}\r\n\r\n/**\r\n * Checks if a fields input represents \"select all\"\r\n *\r\n * @param fields - Fields input (string or array)\r\n * @returns True if fields is '*' or ['*'] or empty\r\n */\r\nexport function isSelectAll(fields: string | string[]): boolean {\r\n if (Array.isArray(fields)) {\r\n return fields.length === 0 || (fields.length === 1 && fields[0] === '*');\r\n }\r\n return !fields || fields === '*';\r\n}\r\n\r\n/**\r\n * Deep clones an object\r\n * Used for safely copying configuration objects\r\n *\r\n * @param obj - Object to clone\r\n * @returns Deep cloned copy of the object\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n/**\r\n * Checks if a value is a plain object (not array, null, etc.)\r\n *\r\n * @param value - Value to check\r\n * @returns True if value is a plain object\r\n */\r\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value);\r\n}\r\n","/**\r\n * HTTP Transport implementation for Fireberry API\r\n * Uses direct HTTP requests with API key authentication\r\n */\r\n\r\nimport type {\r\n Transport,\r\n TransportRequestOptions,\r\n HTTPTransportConfig,\r\n} from '../types/transport';\r\nimport type { QueryOptions, QueryResult } from '../types/query';\r\nimport type { FireberryRecord } from '../types/records';\r\nimport {\r\n FireberryError,\r\n FireberryErrorCode,\r\n createErrorFromResponse,\r\n createNetworkError,\r\n} from '../errors';\r\nimport { wait } from '../utils/helpers';\r\n\r\n/**\r\n * HTTP transport for API key-based communication\r\n */\r\nexport class HTTPTransport implements Transport {\r\n private readonly config: Required<HTTPTransportConfig>;\r\n\r\n constructor(config: HTTPTransportConfig) {\r\n this.config = {\r\n apiKey: config.apiKey,\r\n baseUrl: config.baseUrl || 'https://api.fireberry.com',\r\n timeout: config.timeout || 30000,\r\n retryOn429: config.retryOn429 ?? true,\r\n maxRetries: config.maxRetries || 120,\r\n retryDelay: config.retryDelay || 1000,\r\n };\r\n }\r\n\r\n getType(): 'http' {\r\n return 'http';\r\n }\r\n\r\n async request<T = unknown>(options: TransportRequestOptions): Promise<T> {\r\n const { method, endpoint, query: queryParams, body, headers: customHeaders, signal } = options;\r\n\r\n // Build URL\r\n let url = `${this.config.baseUrl}${endpoint}`;\r\n\r\n // Add query parameters if any\r\n if (queryParams && Object.keys(queryParams).length > 0) {\r\n const params = new URLSearchParams();\r\n for (const [key, value] of Object.entries(queryParams)) {\r\n if (value !== undefined && value !== null) {\r\n params.set(key, String(value));\r\n }\r\n }\r\n url += `?${params.toString()}`;\r\n }\r\n\r\n // Build headers\r\n const headers: Record<string, string> = {\r\n Accept: 'application/json',\r\n tokenid: this.config.apiKey,\r\n ...customHeaders,\r\n };\r\n\r\n if (body) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n // Build fetch options\r\n const fetchOptions: RequestInit = {\r\n method,\r\n headers,\r\n signal,\r\n };\r\n\r\n if (body) {\r\n fetchOptions.body = JSON.stringify(body);\r\n }\r\n\r\n // Execute with retry logic\r\n return this.executeWithRetry<T>(url, fetchOptions);\r\n }\r\n\r\n async query(options: QueryOptions): Promise<QueryResult> {\r\n const {\r\n objectType,\r\n fields,\r\n query,\r\n sortBy = 'modifiedon',\r\n sortType = 'desc',\r\n limit,\r\n page = 1,\r\n pageSize = 500,\r\n showRealValue = true,\r\n autoPage = true,\r\n signal,\r\n } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // If autoPage is true, fetch all pages\r\n if (autoPage) {\r\n return this.queryAllPages({\r\n objectType,\r\n fields: fieldsStr,\r\n query,\r\n sortBy,\r\n sortType,\r\n showRealValue,\r\n limit,\r\n signal,\r\n });\r\n }\r\n\r\n // Single page query\r\n const body = {\r\n objecttype: objectType,\r\n fields: fieldsStr,\r\n query: query || '',\r\n sort_by: sortBy,\r\n sort_type: sortType,\r\n page_size: Math.min(pageSize, limit || 500),\r\n page_number: page,\r\n show_real_value: showRealValue ? 1 : 0,\r\n };\r\n\r\n const response = await this.request<{ data?: { Data?: Record<string, unknown>[] } }>({\r\n method: 'POST',\r\n endpoint: '/api/query',\r\n body,\r\n signal,\r\n });\r\n\r\n const records = response.data?.Data || [];\r\n\r\n return {\r\n records,\r\n total: records.length,\r\n success: true,\r\n };\r\n }\r\n\r\n async createRecord(\r\n objectType: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n const response = await this.request<{\r\n success: boolean;\r\n record: FireberryRecord;\r\n _id?: string;\r\n }>({\r\n method: 'POST',\r\n endpoint: `/api/v2/record/${objectType}`,\r\n body: data,\r\n signal,\r\n });\r\n\r\n return response.record;\r\n }\r\n\r\n async updateRecord(\r\n objectType: string,\r\n recordId: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n const response = await this.request<{\r\n success: boolean;\r\n record: FireberryRecord;\r\n _id?: string;\r\n }>({\r\n method: 'PUT',\r\n endpoint: `/api/v2/record/${objectType}/${recordId}`,\r\n body: data,\r\n signal,\r\n });\r\n\r\n return response.record;\r\n }\r\n\r\n async deleteRecord(\r\n objectType: string,\r\n recordId: string,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; id: string }> {\r\n // Note: Delete uses /api/record (not /api/v2/record)\r\n await this.request({\r\n method: 'DELETE',\r\n endpoint: `/api/record/${objectType}/${recordId}`,\r\n signal,\r\n });\r\n\r\n return {\r\n success: true,\r\n id: recordId,\r\n };\r\n }\r\n\r\n async batchCreate(\r\n objectType: string,\r\n records: FireberryRecord[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const response = await this.request<{ data?: unknown[] }>({\r\n method: 'POST',\r\n endpoint: `/api/v3/record/${objectType}/batch/create`,\r\n body: { data: records },\r\n signal,\r\n });\r\n\r\n const data = response.data || [];\r\n const dataArray = Array.isArray(data) ? data : [data];\r\n\r\n return {\r\n success: true,\r\n data: dataArray,\r\n count: dataArray.length,\r\n };\r\n }\r\n\r\n async batchUpdate(\r\n objectType: string,\r\n records: Array<{ id: string; record: FireberryRecord }>,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const response = await this.request<{ data?: unknown[] }>({\r\n method: 'POST',\r\n endpoint: `/api/v3/record/${objectType}/batch/update`,\r\n body: { data: records },\r\n signal,\r\n });\r\n\r\n const data = response.data || [];\r\n const dataArray = Array.isArray(data) ? data : [data];\r\n\r\n return {\r\n success: true,\r\n data: dataArray,\r\n count: dataArray.length,\r\n };\r\n }\r\n\r\n async batchDelete(\r\n objectType: string,\r\n recordIds: string[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; ids: string[]; count: number }> {\r\n await this.request({\r\n method: 'POST',\r\n endpoint: `/api/v3/record/${objectType}/batch/delete`,\r\n body: { data: recordIds },\r\n signal,\r\n });\r\n\r\n return {\r\n success: true,\r\n ids: recordIds,\r\n count: recordIds.length,\r\n };\r\n }\r\n\r\n /**\r\n * Fetches all pages of a query\r\n */\r\n private async queryAllPages(options: {\r\n objectType: string;\r\n fields: string;\r\n query?: string;\r\n sortBy: string;\r\n sortType: string;\r\n showRealValue: boolean;\r\n limit?: number;\r\n signal?: AbortSignal;\r\n }): Promise<QueryResult> {\r\n const { objectType, fields, query, sortBy, sortType, showRealValue, limit, signal } = options;\r\n const maxPageSize = 500;\r\n const allRecords: Record<string, unknown>[] = [];\r\n let currentPage = 1;\r\n let hasMore = true;\r\n\r\n while (hasMore) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n const body = {\r\n objecttype: objectType,\r\n fields,\r\n query: query || '',\r\n sort_by: sortBy,\r\n sort_type: sortType,\r\n page_size: maxPageSize,\r\n page_number: currentPage,\r\n show_real_value: showRealValue ? 1 : 0,\r\n };\r\n\r\n const response = await this.request<{ data?: { Data?: Record<string, unknown>[] } }>({\r\n method: 'POST',\r\n endpoint: '/api/query',\r\n body,\r\n signal,\r\n });\r\n\r\n const pageData = response.data?.Data || [];\r\n allRecords.push(...pageData);\r\n\r\n // Check if we've reached the limit\r\n if (limit && allRecords.length >= limit) {\r\n allRecords.splice(limit);\r\n break;\r\n }\r\n\r\n // Check if there are more pages\r\n if (pageData.length < maxPageSize) {\r\n hasMore = false;\r\n } else {\r\n currentPage++;\r\n }\r\n }\r\n\r\n return {\r\n records: allRecords,\r\n total: allRecords.length,\r\n success: true,\r\n };\r\n }\r\n\r\n /**\r\n * Executes a fetch request with retry logic for 429 errors and timeouts\r\n * Implements exponential backoff for timeout duration\r\n */\r\n private async executeWithRetry<T>(\r\n url: string,\r\n options: RequestInit,\r\n retryCount = 0\r\n ): Promise<T> {\r\n try {\r\n // Calculate timeout with exponential backoff\r\n // Start with base timeout, double on each retry, cap at 5 minutes (300000ms)\r\n const maxTimeout = 300000; // 5 minutes\r\n const currentTimeout = Math.min(\r\n this.config.timeout * Math.pow(2, retryCount),\r\n maxTimeout\r\n );\r\n\r\n // Create timeout controller\r\n const timeoutController = new AbortController();\r\n const timeoutId = setTimeout(() => {\r\n timeoutController.abort();\r\n }, currentTimeout);\r\n\r\n // Combine signals if external signal provided\r\n const combinedSignal = options.signal\r\n ? this.combineSignals([options.signal, timeoutController.signal])\r\n : timeoutController.signal;\r\n\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: combinedSignal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n // Handle rate limiting\r\n if (response.status === 429 && this.config.retryOn429) {\r\n if (retryCount < this.config.maxRetries) {\r\n // Wait before retrying\r\n await wait(this.config.retryDelay);\r\n return this.executeWithRetry<T>(url, options, retryCount + 1);\r\n }\r\n throw new FireberryError('Rate limit exceeded after max retries', {\r\n code: FireberryErrorCode.RATE_LIMITED,\r\n statusCode: 429,\r\n context: { retryCount },\r\n });\r\n }\r\n\r\n // Parse response\r\n let body: unknown;\r\n const contentType = response.headers.get('content-type');\r\n if (contentType?.includes('application/json')) {\r\n body = await response.json();\r\n } else {\r\n body = await response.text();\r\n }\r\n\r\n // Handle errors\r\n if (!response.ok) {\r\n throw createErrorFromResponse(response, body);\r\n }\r\n\r\n return body as T;\r\n } catch (error) {\r\n // Handle abort/timeout\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n // Check if this was caused by external abort signal (user cancellation)\r\n if (options.signal?.aborted) {\r\n throw createNetworkError(error);\r\n }\r\n\r\n // Otherwise it's a timeout - treat as rate limit and retry if enabled\r\n if (this.config.retryOn429 && retryCount < this.config.maxRetries) {\r\n // Wait before retrying\r\n await wait(this.config.retryDelay);\r\n return this.executeWithRetry<T>(url, options, retryCount + 1);\r\n }\r\n\r\n throw new FireberryError('Request timeout after max retries', {\r\n code: FireberryErrorCode.TIMEOUT,\r\n context: { retryCount },\r\n });\r\n }\r\n\r\n // Re-throw FireberryError\r\n if (error instanceof FireberryError) {\r\n throw error;\r\n }\r\n\r\n // Wrap other errors\r\n throw createNetworkError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Combines multiple abort signals into one\r\n */\r\n private combineSignals(signals: AbortSignal[]): AbortSignal {\r\n const controller = new AbortController();\r\n\r\n for (const signal of signals) {\r\n if (signal.aborted) {\r\n controller.abort();\r\n break;\r\n }\r\n signal.addEventListener('abort', () => controller.abort(), { once: true });\r\n }\r\n\r\n return controller.signal;\r\n }\r\n}\r\n","/**\r\n * SDK Transport implementation for Fireberry SDK\r\n * Uses iframe messaging through the @fireberry/sdk package\r\n */\r\n\r\nimport type {\r\n Transport,\r\n TransportRequestOptions,\r\n SDKTransportConfig,\r\n} from '../types/transport';\r\nimport type { QueryOptions, QueryResult } from '../types/query';\r\nimport type { FireberryRecord } from '../types/records';\r\nimport type { FireberrySDKClient, SDKQueryPayload } from '../types/sdk';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\nimport { chunkArray } from '../utils/helpers';\r\n\r\n/** Maximum records per batch operation */\r\nconst BATCH_SIZE = 20;\r\n\r\n/**\r\n * SDK transport for iframe messaging-based communication\r\n */\r\nexport class SDKTransport implements Transport {\r\n private readonly sdk: FireberrySDKClient;\r\n\r\n constructor(config: SDKTransportConfig) {\r\n this.sdk = config.sdk;\r\n }\r\n\r\n getType(): 'sdk' {\r\n return 'sdk';\r\n }\r\n\r\n async request<T = unknown>(_options: TransportRequestOptions): Promise<T> {\r\n throw new FireberryError(\r\n 'Raw request() is not supported in SDK mode. Use specific methods like query(), createRecord(), etc.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n }\r\n\r\n async query(options: QueryOptions): Promise<QueryResult> {\r\n const {\r\n objectType,\r\n fields,\r\n query,\r\n limit,\r\n page = 1,\r\n pageSize = 500,\r\n autoPage = true,\r\n signal,\r\n } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // If autoPage is true, fetch all pages\r\n if (autoPage) {\r\n return this.queryAllPages({\r\n objectType,\r\n fields: fieldsStr,\r\n query,\r\n limit,\r\n pageSize,\r\n signal,\r\n });\r\n }\r\n\r\n // Single page query\r\n const payload: SDKQueryPayload = {\r\n fields: fieldsStr,\r\n query: query || '',\r\n page_size: Math.min(pageSize, limit || 500),\r\n page_number: page,\r\n };\r\n\r\n const response = await this.sdk.api.query(objectType, payload);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK query failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n // SDK returns data differently than HTTP API\r\n // We need to normalize the response structure\r\n // The SDK response can be:\r\n // 1. {Columns: [...], Data: [...]} - query response with metadata\r\n // 2. An array of records\r\n // 3. A single record object\r\n let records: Record<string, unknown>[] = [];\r\n\r\n if (response.data && typeof response.data === 'object') {\r\n // Check if it's a query response with Data property\r\n if ('Data' in response.data && Array.isArray(response.data.Data)) {\r\n records = response.data.Data as Record<string, unknown>[];\r\n }\r\n // Check if data itself is an array\r\n else if (Array.isArray(response.data)) {\r\n records = response.data.filter(\r\n (record) => record && typeof record === 'object'\r\n ) as Record<string, unknown>[];\r\n }\r\n // Otherwise treat as a single record (but this shouldn't happen for queries)\r\n else if (!('Columns' in response.data)) {\r\n records = [response.data as Record<string, unknown>];\r\n }\r\n }\r\n\r\n return {\r\n records,\r\n total: records.length,\r\n success: true,\r\n };\r\n }\r\n\r\n async createRecord(\r\n objectType: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Request aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const response = await this.sdk.api.create(objectType, data);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK create failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n return response.data as FireberryRecord;\r\n }\r\n\r\n async updateRecord(\r\n objectType: string,\r\n recordId: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Request aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const response = await this.sdk.api.update(objectType, recordId, data);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK update failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n return response.data as FireberryRecord;\r\n }\r\n\r\n async deleteRecord(\r\n objectType: string,\r\n recordId: string,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; id: string }> {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Request aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const response = await this.sdk.api.delete(objectType, recordId);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK delete failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n return {\r\n success: true,\r\n id: recordId,\r\n };\r\n }\r\n\r\n async batchCreate(\r\n objectType: string,\r\n records: FireberryRecord[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n // SDK doesn't have native batch operations, so we create records one by one\r\n // This is less efficient but maintains consistency\r\n const batchPromises = batch.map((record) => this.createRecord(objectType, record, signal));\r\n const batchResults = await Promise.all(batchPromises);\r\n allResponses.push(...batchResults);\r\n }\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n async batchUpdate(\r\n objectType: string,\r\n records: Array<{ id: string; record: FireberryRecord }>,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n // SDK doesn't have native batch operations, so we update records one by one\r\n const batchPromises = batch.map((item) =>\r\n this.updateRecord(objectType, item.id, item.record, signal)\r\n );\r\n const batchResults = await Promise.all(batchPromises);\r\n allResponses.push(...batchResults);\r\n }\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n async batchDelete(\r\n objectType: string,\r\n recordIds: string[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; ids: string[]; count: number }> {\r\n const batches = chunkArray(recordIds, BATCH_SIZE);\r\n const allDeletedIds: string[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n // SDK doesn't have native batch operations, so we delete records one by one\r\n const batchPromises = batch.map((id) => this.deleteRecord(objectType, id, signal));\r\n await Promise.all(batchPromises);\r\n allDeletedIds.push(...batch);\r\n }\r\n\r\n return {\r\n success: true,\r\n ids: allDeletedIds,\r\n count: allDeletedIds.length,\r\n };\r\n }\r\n\r\n /**\r\n * Fetches all pages of a query using SDK\r\n */\r\n private async queryAllPages(options: {\r\n objectType: string;\r\n fields: string;\r\n query?: string;\r\n limit?: number;\r\n pageSize?: number;\r\n signal?: AbortSignal;\r\n }): Promise<QueryResult> {\r\n const { objectType, fields, query, limit, pageSize = 500, signal } = options;\r\n const maxPageSize = 500;\r\n const allRecords: Record<string, unknown>[] = [];\r\n let currentPage = 1;\r\n let hasMore = true;\r\n\r\n while (hasMore) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n const payload: SDKQueryPayload = {\r\n fields,\r\n query: query || '',\r\n page_size: Math.min(maxPageSize, pageSize),\r\n page_number: currentPage,\r\n };\r\n\r\n const response = await this.sdk.api.query(objectType, payload);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK query failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n // Normalize SDK response structure (same logic as single page query)\r\n let validRecords: Record<string, unknown>[] = [];\r\n\r\n if (response.data && typeof response.data === 'object') {\r\n // Check if it's a query response with Data property\r\n if ('Data' in response.data && Array.isArray(response.data.Data)) {\r\n validRecords = response.data.Data as Record<string, unknown>[];\r\n }\r\n // Check if data itself is an array\r\n else if (Array.isArray(response.data)) {\r\n validRecords = response.data.filter(\r\n (record) => record && typeof record === 'object'\r\n ) as Record<string, unknown>[];\r\n }\r\n // Otherwise treat as a single record (but this shouldn't happen for queries)\r\n else if (!('Columns' in response.data)) {\r\n validRecords = [response.data as Record<string, unknown>];\r\n }\r\n }\r\n\r\n allRecords.push(...validRecords);\r\n\r\n // Check if we've reached the limit\r\n if (limit && allRecords.length >= limit) {\r\n allRecords.splice(limit);\r\n break;\r\n }\r\n\r\n // Check if there are more pages\r\n if (validRecords.length < maxPageSize) {\r\n hasMore = false;\r\n } else {\r\n currentPage++;\r\n }\r\n }\r\n\r\n return {\r\n records: allRecords,\r\n total: allRecords.length,\r\n success: true,\r\n };\r\n }\r\n}\r\n","/**\r\n * Utility functions for creating and managing transport instances\r\n */\r\n\r\nimport type { FireberryClientConfig } from '../types/client';\r\nimport type { Transport } from '../types/transport';\r\nimport { HTTPTransport } from '../transport/http';\r\nimport { SDKTransport } from '../transport/sdk';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\n\r\n/**\r\n * Creates the appropriate transport based on client configuration\r\n * Priority: SDK > HTTP\r\n * If both are provided, SDK is used for CRUD operations\r\n */\r\nexport function createTransport(config: FireberryClientConfig): Transport {\r\n // SDK mode (with or without API key)\r\n if (config.sdk) {\r\n return new SDKTransport({ sdk: config.sdk });\r\n }\r\n\r\n // API key mode\r\n if (config.apiKey) {\r\n return new HTTPTransport({\r\n apiKey: config.apiKey,\r\n baseUrl: config.baseUrl,\r\n timeout: config.timeout,\r\n retryOn429: config.retryOn429,\r\n maxRetries: config.maxRetries,\r\n retryDelay: config.retryDelay,\r\n });\r\n }\r\n\r\n // Neither provided\r\n throw new FireberryError(\r\n 'Either apiKey or sdk must be provided in FireberryClientConfig',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Creates HTTP transport for metadata operations when using SDK mode\r\n * Returns null if no API key is available\r\n */\r\nexport function createMetadataTransport(config: FireberryClientConfig): HTTPTransport | null {\r\n if (!config.apiKey) {\r\n return null;\r\n }\r\n\r\n return new HTTPTransport({\r\n apiKey: config.apiKey,\r\n baseUrl: config.baseUrl,\r\n timeout: config.timeout,\r\n retryOn429: config.retryOn429,\r\n maxRetries: config.maxRetries,\r\n retryDelay: config.retryDelay,\r\n });\r\n}\r\n\r\n/**\r\n * Checks if metadata operations are available\r\n */\r\nexport function isMetadataAvailable(config: FireberryClientConfig): boolean {\r\n // Metadata requires HTTP transport (API key)\r\n return Boolean(config.apiKey);\r\n}\r\n\r\n/**\r\n * Gets the connection mode based on configuration\r\n */\r\nexport function getConnectionMode(config: FireberryClientConfig): 'sdk' | 'api' | 'hybrid' {\r\n if (config.sdk && config.apiKey) {\r\n return 'hybrid';\r\n }\r\n if (config.sdk) {\r\n return 'sdk';\r\n }\r\n return 'api';\r\n}\r\n","/**\r\n * Field Type System IDs from Fireberry CRM\r\n * These UUIDs identify different field types in the metadata API\r\n */\r\nexport const FIELD_TYPE_IDS = {\r\n DROPDOWN: 'b4919f2e-2996-48e4-a03c-ba39fb64386c',\r\n LOOKUP: 'a8fcdf65-91bc-46fd-82f6-1234758345a1',\r\n EMAIL: 'c713d2f7-8fa9-43c3-8062-f07486eaf567',\r\n TEXT: 'a1e7ed6f-5083-477b-b44c-9943a6181359',\r\n URL: 'c820d32f-44df-4c2a-9c1e-18734e864fd5',\r\n LONG_TEXT: '80108f9d-1e75-40fa-9fa9-02be4ddc1da1',\r\n DATETIME: 'ce972d02-5013-46d4-9d1d-f09df1ac346a',\r\n DATE: '83bf530c-e04c-462b-9ffc-a46f750fc072',\r\n HTML: 'ed2ad39d-32fc-4585-8f5b-2e93463f050a',\r\n TELEPHONE: '3f62f67a-1cee-403a-bec6-aa02a9804edb',\r\n NUMERIC: '6a34bfe3-fece-4da1-9136-a7b1e5ae3319',\r\n} as const;\r\n\r\n/**\r\n * Human-readable mappings for field types\r\n * Used for display purposes\r\n */\r\nexport const FIELD_TYPE_MAPPINGS: Record<string, string> = {\r\n [FIELD_TYPE_IDS.DROPDOWN]: 'Dropdown',\r\n [FIELD_TYPE_IDS.EMAIL]: 'Email',\r\n [FIELD_TYPE_IDS.TEXT]: 'Text',\r\n [FIELD_TYPE_IDS.LOOKUP]: 'Lookup',\r\n [FIELD_TYPE_IDS.URL]: 'URL',\r\n [FIELD_TYPE_IDS.LONG_TEXT]: 'Long Text',\r\n [FIELD_TYPE_IDS.DATETIME]: 'DateTime',\r\n [FIELD_TYPE_IDS.DATE]: 'Date',\r\n [FIELD_TYPE_IDS.HTML]: 'HTML',\r\n [FIELD_TYPE_IDS.TELEPHONE]: 'Telephone',\r\n [FIELD_TYPE_IDS.NUMERIC]: 'Number',\r\n};\r\n","import type { FireberryClient } from '../client';\r\nimport type {\r\n GetObjectsResult,\r\n GetFieldsResult,\r\n GetFieldValuesResult,\r\n FireberryObject,\r\n FireberryField,\r\n FieldValue,\r\n} from '../types/metadata';\r\nimport { FIELD_TYPE_MAPPINGS, FIELD_TYPE_IDS } from '../constants/fieldTypes';\r\nimport { EXCLUDED_LOOKUP_FIELDS } from '../constants/excludedFields';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\n\r\n/** API endpoints used by MetadataAPI */\r\nconst ENDPOINTS = {\r\n OBJECTS: '/metadata/records',\r\n FIELDS: (objectType: string) => `/metadata/records/${objectType}/fields`,\r\n FIELD_VALUES: (objectType: string, fieldName: string) =>\r\n `/metadata/records/${objectType}/fields/${fieldName}/values`,\r\n QUERY: '/api/query',\r\n} as const;\r\n\r\n/**\r\n * Metadata API for retrieving Fireberry schema information\r\n */\r\nexport class MetadataAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Checks if metadata operations are available and throws error if not\r\n * @private\r\n */\r\n private ensureMetadataAvailable(): void {\r\n if (!this.client.isMetadataAvailable()) {\r\n throw new FireberryError(\r\n 'Metadata operations are not available in SDK-only mode. Please provide an API key in the FireberryClient configuration to use metadata features.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n context: {\r\n hint: 'Fireberry SDK does not yet support metadata operations. Use API key mode or hybrid mode (both SDK + API key) to access metadata.',\r\n },\r\n }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Gets all available objects/entity types from Fireberry\r\n *\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns List of all objects\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.metadata.getObjects();\r\n * console.log(result.objects); // [{ objectType: 1, name: 'Account', ... }, ...]\r\n * ```\r\n */\r\n async getObjects(signal?: AbortSignal): Promise<GetObjectsResult> {\r\n // Ensure metadata is available\r\n this.ensureMetadataAvailable();\r\n\r\n // Check cache first\r\n const cached = this.client.getCached<GetObjectsResult>('objects');\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: FireberryObject[];\r\n }>({\r\n method: 'GET',\r\n endpoint: ENDPOINTS.OBJECTS,\r\n signal,\r\n });\r\n\r\n const result: GetObjectsResult = {\r\n objects: response.data || [],\r\n total: response.data?.length || 0,\r\n success: true,\r\n };\r\n\r\n // Cache the result\r\n this.client.setCache('objects', result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets all fields for a specific object type\r\n *\r\n * @param objectType - The object type ID (e.g., '1' for Account)\r\n * @param options - Optional settings\r\n * @param options.includeLookupRelations - Fetches related object types for lookup fields (default: true)\r\n * @param options.signal - Optional AbortSignal for cancellation\r\n * @returns List of fields with metadata\r\n *\r\n * @example\r\n * ```typescript\r\n * // Lookup relations are included by default\r\n * const result = await client.metadata.getFields('1');\r\n * console.log(result.fields.find(f => f.fieldName === 'primarycontactid')?.relatedObjectType); // 2\r\n *\r\n * // Disable lookup relations for faster response\r\n * const result = await client.metadata.getFields('1', { includeLookupRelations: false });\r\n * ```\r\n */\r\n async getFields(\r\n objectType: string | number,\r\n options?: { includeLookupRelations?: boolean; signal?: AbortSignal } | AbortSignal,\r\n ): Promise<GetFieldsResult> {\r\n // Ensure metadata is available\r\n this.ensureMetadataAvailable();\r\n\r\n const objectTypeStr = String(objectType);\r\n\r\n // Handle both old signature (signal only) and new signature (options object)\r\n // Default includeLookupRelations to true\r\n const opts =\r\n options instanceof AbortSignal\r\n ? { signal: options, includeLookupRelations: true }\r\n : { signal: options?.signal, includeLookupRelations: options?.includeLookupRelations ?? true };\r\n\r\n // Check cache first\r\n const cached = this.client.getCached<GetFieldsResult>('fields', objectTypeStr);\r\n if (cached) {\r\n // If user wants lookup relations and cache has them (or doesn't need them), return cached\r\n // Since default is includeLookupRelations: true, cached results typically have relations\r\n const cachedHasRelations = cached.fields.some((f) => f.relatedObjectType !== undefined);\r\n if (!opts.includeLookupRelations || cachedHasRelations) {\r\n return cached;\r\n }\r\n // If user wants relations but cache doesn't have them, continue to fetch\r\n }\r\n\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: Array<{\r\n fieldName: string;\r\n label: string;\r\n systemFieldTypeId: string;\r\n required?: boolean;\r\n defaultValue?: unknown;\r\n maxLength?: number;\r\n precision?: number;\r\n }>;\r\n }>({\r\n method: 'GET',\r\n endpoint: ENDPOINTS.FIELDS(objectTypeStr),\r\n signal: opts.signal,\r\n });\r\n\r\n // Enhance fields with readable field types\r\n let fields: FireberryField[] = (response.data || []).map((field) => ({\r\n ...field,\r\n fieldType: FIELD_TYPE_MAPPINGS[field.systemFieldTypeId] || field.systemFieldTypeId,\r\n }));\r\n\r\n // If requested, fetch related object types for lookup fields\r\n if (opts.includeLookupRelations) {\r\n const lookupFields = fields.filter(\r\n (field) => field.systemFieldTypeId === FIELD_TYPE_IDS.LOOKUP,\r\n );\r\n\r\n if (lookupFields.length > 0) {\r\n const lookupRelations = await this.fetchLookupRelations(\r\n objectTypeStr,\r\n lookupFields.map((f) => f.fieldName),\r\n opts.signal,\r\n );\r\n\r\n // Merge lookup relations into fields\r\n fields = fields.map((field) => ({\r\n ...field,\r\n relatedObjectType: lookupRelations.get(field.fieldName),\r\n }));\r\n }\r\n }\r\n\r\n const result: GetFieldsResult = {\r\n objectTypeId: objectTypeStr,\r\n fields,\r\n total: fields.length,\r\n success: true,\r\n };\r\n\r\n // Cache the result\r\n this.client.setCache('fields', objectTypeStr, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Fetches related object types for lookup fields using the query endpoint.\r\n * The query endpoint returns Columns metadata with fieldobjecttype even without records.\r\n * Excludes fields that cause API errors (e.g., deletedby, deletedon).\r\n */\r\n private async fetchLookupRelations(\r\n objectType: string,\r\n lookupFieldNames: string[],\r\n signal?: AbortSignal,\r\n ): Promise<Map<string, number>> {\r\n const relations = new Map<string, number>();\r\n\r\n // Filter out excluded fields that cause API errors\r\n const queryableFields = lookupFieldNames.filter(\r\n (fieldName) => !EXCLUDED_LOOKUP_FIELDS.includes(fieldName),\r\n );\r\n\r\n if (queryableFields.length === 0) {\r\n return relations;\r\n }\r\n\r\n try {\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: {\r\n Columns?: Array<{\r\n fieldname: string;\r\n fieldobjecttype: number | null;\r\n }>;\r\n };\r\n }>({\r\n method: 'POST',\r\n endpoint: ENDPOINTS.QUERY,\r\n body: {\r\n objecttype: objectType,\r\n fields: queryableFields.join(','),\r\n query: '',\r\n page_size: 1,\r\n page_number: 1,\r\n show_real_value: 0,\r\n },\r\n signal,\r\n });\r\n\r\n // Extract fieldobjecttype from Columns metadata\r\n const columns = response.data?.Columns || [];\r\n for (const column of columns) {\r\n if (column.fieldobjecttype !== null && column.fieldobjecttype !== undefined) {\r\n relations.set(column.fieldname, column.fieldobjecttype);\r\n }\r\n }\r\n } catch (error) {\r\n // If fetching lookup relations fails, return empty map\r\n // This allows tests and edge cases to work without complete mocking\r\n // Lookup fields will still be returned, just without relatedObjectType\r\n }\r\n\r\n return relations;\r\n }\r\n\r\n /**\r\n * Gets all possible values for a dropdown field\r\n *\r\n * @param objectType - The object type ID\r\n * @param fieldName - The field name\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns List of dropdown values\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.metadata.getFieldValues('1', 'statuscode');\r\n * console.log(result.values); // [{ name: 'Active', value: '1' }, { name: 'Inactive', value: '2' }]\r\n * ```\r\n */\r\n async getFieldValues(\r\n objectType: string | number,\r\n fieldName: string,\r\n signal?: AbortSignal,\r\n ): Promise<GetFieldValuesResult> {\r\n // Ensure metadata is available\r\n this.ensureMetadataAvailable();\r\n\r\n const objectTypeStr = String(objectType);\r\n\r\n // Check cache first\r\n const cached = this.client.getCached<GetFieldValuesResult>(\r\n 'fieldValues',\r\n objectTypeStr,\r\n fieldName,\r\n );\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: {\r\n values?: FieldValue[];\r\n };\r\n }>({\r\n method: 'GET',\r\n endpoint: ENDPOINTS.FIELD_VALUES(objectTypeStr, fieldName),\r\n signal,\r\n });\r\n\r\n const result: GetFieldValuesResult = {\r\n objectTypeId: objectTypeStr,\r\n fieldName,\r\n values: response.data?.values || [],\r\n total: response.data?.values?.length || 0,\r\n success: true,\r\n };\r\n\r\n // Cache the result\r\n this.client.setCache('fieldValues', objectTypeStr, fieldName, result);\r\n\r\n return result;\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport type {\r\n FireberryRecord,\r\n CreateOptions,\r\n UpdateOptions,\r\n DeleteOptions,\r\n UpsertOptions,\r\n UpsertResult,\r\n} from '../types/records';\r\nimport { getObjectIdFieldName } from '../constants/objectIds';\r\n\r\n/**\r\n * Records API for CRUD operations on Fireberry records\r\n */\r\nexport class RecordsAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Creates a new record in Fireberry\r\n *\r\n * @param objectType - The object type ID (e.g., '1' for Account)\r\n * @param data - Record data to create\r\n * @param options - Optional settings\r\n * @returns Created record data\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.records.create('1', {\r\n * accountname: 'New Account',\r\n * emailaddress1: 'contact@example.com',\r\n * });\r\n * ```\r\n */\r\n async create(\r\n objectType: string | number,\r\n data: FireberryRecord,\r\n options?: CreateOptions,\r\n ): Promise<FireberryRecord> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n\r\n const record = await transport.createRecord(objectTypeStr, data, options?.signal);\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return record;\r\n }\r\n\r\n /**\r\n * Updates an existing record in Fireberry\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordId - The record ID to update\r\n * @param data - Record data to update\r\n * @param options - Optional settings\r\n * @returns Updated record data\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.records.update('1', 'abc123', {\r\n * accountname: 'Updated Account Name',\r\n * });\r\n * ```\r\n */\r\n async update(\r\n objectType: string | number,\r\n recordId: string,\r\n data: FireberryRecord,\r\n options?: UpdateOptions,\r\n ): Promise<FireberryRecord> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n\r\n const record = await transport.updateRecord(objectTypeStr, recordId, data, options?.signal);\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return record;\r\n }\r\n\r\n /**\r\n * Deletes a record from Fireberry\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordId - The record ID to delete\r\n * @param options - Optional settings\r\n * @returns Success status\r\n *\r\n * @example\r\n * ```typescript\r\n * await client.records.delete('1', 'abc123');\r\n * ```\r\n */\r\n async delete(\r\n objectType: string | number,\r\n recordId: string,\r\n options?: DeleteOptions,\r\n ): Promise<{ success: boolean; id: string }> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n\r\n const result = await transport.deleteRecord(objectTypeStr, recordId, options?.signal);\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Upserts a record (creates if not exists, updates if exists)\r\n *\r\n * @param objectType - The object type ID\r\n * @param keyFields - Fields to use for matching existing records\r\n * @param data - Record data to upsert\r\n * @param options - Optional settings\r\n * @returns Upsert result with operation type and record data\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.records.upsert('1', ['emailaddress1'], {\r\n * accountname: 'Acme Corp',\r\n * emailaddress1: 'contact@acme.com',\r\n * });\r\n * console.log(result.operationType); // 'create' or 'update'\r\n * ```\r\n */\r\n async upsert(\r\n objectType: string | number,\r\n keyFields: string[],\r\n data: FireberryRecord,\r\n options?: UpsertOptions,\r\n ): Promise<UpsertResult> {\r\n const objectTypeStr = String(objectType);\r\n\r\n // Build key values from data\r\n const upsertKeyValues: Record<string, unknown> = {};\r\n for (const key of keyFields) {\r\n if (!(key in data)) {\r\n throw new Error(`Missing value for upsert key field: ${key}`);\r\n }\r\n upsertKeyValues[key] = data[key];\r\n }\r\n\r\n // Build query to check if record exists\r\n const queryConditions = keyFields.map((key) => `(${key} = ${data[key]})`);\r\n const queryString = queryConditions.join(' and ');\r\n\r\n // Query for existing record\r\n const queryResult = await this.client.query({\r\n objectType: objectTypeStr,\r\n fields: '*',\r\n query: queryString,\r\n limit: 1,\r\n showRealValue: true,\r\n signal: options?.signal,\r\n });\r\n\r\n const existingRecords = queryResult.records as FireberryRecord[];\r\n\r\n if (existingRecords.length > 0) {\r\n // Record exists - UPDATE\r\n const existingRecord = existingRecords[0];\r\n const idFieldName = getObjectIdFieldName(objectTypeStr);\r\n\r\n // Try to get the ID field value with exact casing first\r\n let recordId = existingRecord[idFieldName];\r\n\r\n // If not found, try case-insensitive lookup (for SDK compatibility)\r\n if (recordId === undefined || recordId === null) {\r\n const actualIdField = Object.keys(existingRecord).find(\r\n (key) => key.toLowerCase() === idFieldName.toLowerCase(),\r\n );\r\n\r\n if (actualIdField) {\r\n recordId = existingRecord[actualIdField];\r\n }\r\n }\r\n\r\n // If still not found, throw descriptive error\r\n if (recordId === undefined || recordId === null) {\r\n throw new Error(\r\n `Could not find ID field \"${idFieldName}\" in existing record. ` +\r\n `Available fields: ${Object.keys(existingRecord).join(', ')}`,\r\n );\r\n }\r\n\r\n const updatedRecord = await this.update(objectTypeStr, String(recordId), data, options);\r\n\r\n return {\r\n success: true,\r\n operationType: 'update',\r\n upsertKeys: keyFields,\r\n upsertKeyValues,\r\n oldRecord: existingRecord,\r\n newRecord: updatedRecord,\r\n };\r\n } else {\r\n // Record doesn't exist - CREATE\r\n const createdRecord = await this.create(objectTypeStr, data, options);\r\n\r\n return {\r\n success: true,\r\n operationType: 'create',\r\n upsertKeys: keyFields,\r\n upsertKeyValues,\r\n oldRecord: null,\r\n newRecord: createdRecord,\r\n };\r\n }\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport type {\r\n FireberryRecord,\r\n BatchCreateOptions,\r\n BatchUpdateOptions,\r\n BatchUpdateRecord,\r\n BatchDeleteOptions,\r\n BatchResult,\r\n BatchDeleteResult,\r\n} from '../types/records';\r\nimport { chunkArray } from '../utils/helpers';\r\n\r\n/** Maximum records per batch API call */\r\nconst BATCH_SIZE = 20;\r\n\r\n/**\r\n * Batch API for bulk operations on Fireberry records\r\n * Automatically chunks large datasets into API-compatible batches of 20\r\n */\r\nexport class BatchAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Creates multiple records in batch\r\n * Automatically chunks into batches of 20 records\r\n *\r\n * @param objectType - The object type ID\r\n * @param records - Array of records to create\r\n * @param options - Optional settings\r\n * @returns Batch result with all created records\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.batch.create('1', [\r\n * { accountname: 'Account 1' },\r\n * { accountname: 'Account 2' },\r\n * ]);\r\n * console.log(result.count); // 2\r\n * ```\r\n */\r\n async create(\r\n objectType: string | number,\r\n records: FireberryRecord[],\r\n options?: BatchCreateOptions,\r\n ): Promise<BatchResult> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (options?.signal?.aborted) {\r\n break;\r\n }\r\n\r\n const result = await transport.batchCreate(objectTypeStr, batch, options?.signal);\r\n allResponses.push(...result.data);\r\n }\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n /**\r\n * Updates multiple records in batch\r\n * Automatically chunks into batches of 20 records\r\n *\r\n * @param objectType - The object type ID\r\n * @param records - Array of records with ID and data to update\r\n * @param options - Optional settings\r\n * @returns Batch result with all updated records\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.batch.update('1', [\r\n * { id: 'abc123', record: { accountname: 'Updated 1' } },\r\n * { id: 'def456', record: { accountname: 'Updated 2' } },\r\n * ]);\r\n * ```\r\n */\r\n async update(\r\n objectType: string | number,\r\n records: BatchUpdateRecord[],\r\n options?: BatchUpdateOptions,\r\n ): Promise<BatchResult> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (options?.signal?.aborted) {\r\n break;\r\n }\r\n\r\n const result = await transport.batchUpdate(objectTypeStr, batch, options?.signal);\r\n allResponses.push(...result.data);\r\n }\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n /**\r\n * Deletes multiple records in batch\r\n * Automatically chunks into batches of 20 records\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordIds - Array of record IDs to delete\r\n * @param options - Optional settings\r\n * @returns Batch delete result with deleted IDs\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.batch.delete('1', ['abc123', 'def456']);\r\n * console.log(result.ids); // ['abc123', 'def456']\r\n * ```\r\n */\r\n async delete(\r\n objectType: string | number,\r\n recordIds: string[],\r\n options?: BatchDeleteOptions,\r\n ): Promise<BatchDeleteResult> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n const batches = chunkArray(recordIds, BATCH_SIZE);\r\n const allDeletedIds: string[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (options?.signal?.aborted) {\r\n break;\r\n }\r\n\r\n const result = await transport.batchDelete(objectTypeStr, batch, options?.signal);\r\n allDeletedIds.push(...result.ids);\r\n }\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return {\r\n success: true,\r\n ids: allDeletedIds,\r\n count: allDeletedIds.length,\r\n };\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport type { CreateFieldOptions, CreateFieldResult } from '../types/fields';\r\n\r\n/**\r\n * Field type to API endpoint mapping\r\n */\r\nconst FIELD_TYPE_ENDPOINTS: Record<string, string> = {\r\n text: 'text',\r\n email: 'email',\r\n url: 'url',\r\n phone: 'phone',\r\n number: 'number',\r\n textarea: 'textarea',\r\n html: 'html',\r\n date: 'date',\r\n datetime: 'datetime',\r\n lookup: 'lookup',\r\n summary: 'summary',\r\n formula: 'formula',\r\n picklist: 'picklist',\r\n};\r\n\r\n/**\r\n * Fields API for creating custom fields in Fireberry\r\n */\r\nexport class FieldsAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Creates a new custom field in a Fireberry object\r\n *\r\n * @param objectType - The object type ID\r\n * @param options - Field creation options\r\n * @returns Created field result\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a text field\r\n * const result = await client.fields.create('1', {\r\n * type: 'text',\r\n * fieldName: 'pcf_custom_field',\r\n * label: 'Custom Field',\r\n * maxLength: 100,\r\n * });\r\n *\r\n * // Create a picklist field\r\n * const result = await client.fields.create('1', {\r\n * type: 'picklist',\r\n * fieldName: 'pcf_status',\r\n * label: 'Status',\r\n * values: [\r\n * { name: 'Active', value: '1' },\r\n * { name: 'Inactive', value: '2' },\r\n * ],\r\n * });\r\n *\r\n * // Create a lookup field\r\n * const result = await client.fields.create('2', {\r\n * type: 'lookup',\r\n * fieldName: 'pcf_related_account',\r\n * label: 'Related Account',\r\n * relatedObjectId: '1',\r\n * });\r\n * ```\r\n */\r\n async create(\r\n objectType: string | number,\r\n options: CreateFieldOptions,\r\n ): Promise<CreateFieldResult> {\r\n const objectTypeStr = String(objectType);\r\n const { type, fieldName, label, defaultValue, follow, autoComplete } = options;\r\n\r\n // Build field data\r\n const fieldData: Record<string, unknown> = {\r\n fieldName,\r\n label,\r\n };\r\n\r\n // Add optional common properties\r\n if (defaultValue !== undefined) {\r\n fieldData.defaultValue = defaultValue;\r\n }\r\n if (follow !== undefined) {\r\n fieldData.follow = follow;\r\n }\r\n if (autoComplete !== undefined && ['text', 'email', 'url', 'phone', 'number'].includes(type)) {\r\n fieldData.autoComplete = autoComplete;\r\n }\r\n\r\n // Add field-type specific properties\r\n switch (type) {\r\n case 'text':\r\n case 'email':\r\n case 'url': {\r\n const opts = options as { maxLength?: number };\r\n if (opts.maxLength !== undefined && opts.maxLength > 0) {\r\n fieldData.maxLength = opts.maxLength;\r\n }\r\n break;\r\n }\r\n\r\n case 'number': {\r\n const opts = options as { precision?: number };\r\n if (opts.precision !== undefined) {\r\n fieldData.precision = opts.precision;\r\n }\r\n break;\r\n }\r\n\r\n case 'lookup': {\r\n const opts = options as { relatedObjectId: string };\r\n fieldData.relatedObjectId = opts.relatedObjectId;\r\n break;\r\n }\r\n\r\n case 'picklist': {\r\n const opts = options as { values: Array<{ name: string; value: string }> };\r\n fieldData.values = opts.values;\r\n break;\r\n }\r\n\r\n case 'summary': {\r\n const opts = options as {\r\n summaryType: string;\r\n relatedObjectId: string;\r\n summaryField?: string;\r\n };\r\n fieldData.summaryType = opts.summaryType;\r\n fieldData.relatedObjectId = opts.relatedObjectId;\r\n if (opts.summaryField) {\r\n fieldData.summaryField = opts.summaryField;\r\n }\r\n break;\r\n }\r\n\r\n case 'formula': {\r\n const opts = options as {\r\n formula: string;\r\n formulaFieldType: string;\r\n formulaPrecision?: number;\r\n };\r\n fieldData.formula = opts.formula;\r\n fieldData.fieldType = opts.formulaFieldType;\r\n if (opts.formulaFieldType === 'number' && opts.formulaPrecision !== undefined) {\r\n fieldData.precision = opts.formulaPrecision;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Get the API endpoint for this field type\r\n const endpoint = FIELD_TYPE_ENDPOINTS[type];\r\n if (!endpoint) {\r\n throw new Error(`Unsupported field type: ${type}`);\r\n }\r\n\r\n const response = await this.client.request<Record<string, unknown>>({\r\n method: 'POST',\r\n endpoint: `/api/v2/system-field/${objectTypeStr}/${endpoint}`,\r\n body: fieldData,\r\n });\r\n\r\n return {\r\n objectTypeId: objectTypeStr,\r\n fieldType: type,\r\n fieldData: response,\r\n success: true,\r\n };\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\n\r\n/**\r\n * Options for file upload\r\n */\r\nexport interface FileUploadOptions {\r\n /** File content as Buffer */\r\n buffer: Buffer;\r\n /** File name */\r\n filename: string;\r\n /** MIME type */\r\n mimeType: string;\r\n}\r\n\r\n/**\r\n * Result of file upload\r\n */\r\nexport interface FileUploadResult {\r\n /** Success flag */\r\n success: boolean;\r\n /** Object type */\r\n objectType: string;\r\n /** Record ID */\r\n recordId: string;\r\n /** Uploaded file name */\r\n fileName: string;\r\n /** File MIME type */\r\n mimeType: string;\r\n /** File size in bytes */\r\n fileSize: number;\r\n /** API response */\r\n response: unknown;\r\n}\r\n\r\n/**\r\n * Files API for file operations in Fireberry\r\n */\r\nexport class FilesAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Uploads a file attachment to a Fireberry record\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordId - The record ID to attach the file to\r\n * @param options - File upload options\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Upload result\r\n *\r\n * @example\r\n * ```typescript\r\n * import { readFileSync } from 'fs';\r\n *\r\n * const fileBuffer = readFileSync('document.pdf');\r\n * const result = await client.files.upload('1', 'abc123', {\r\n * buffer: fileBuffer,\r\n * filename: 'document.pdf',\r\n * mimeType: 'application/pdf',\r\n * });\r\n * ```\r\n */\r\n async upload(\r\n objectType: string | number,\r\n recordId: string,\r\n options: FileUploadOptions,\r\n signal?: AbortSignal,\r\n ): Promise<FileUploadResult> {\r\n const objectTypeStr = String(objectType);\r\n const { buffer, filename, mimeType } = options;\r\n const config = this.client.getConfig();\r\n\r\n // Ensure API key is available (file uploads not supported in SDK mode)\r\n if (!config.apiKey) {\r\n throw new FireberryError(\r\n 'File upload requires an API key. SDK mode does not support file uploads.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n }\r\n\r\n // Build the URL\r\n const url = `${config.baseUrl || 'https://api.fireberry.com'}/api/v2/record/${objectTypeStr}/${recordId}/files`;\r\n\r\n // Create form data\r\n // Note: In Node.js, we need to construct multipart/form-data manually\r\n // or use a library like form-data\r\n const boundary = `----FormBoundary${Date.now()}`;\r\n const formParts: Buffer[] = [];\r\n\r\n // Add file part\r\n const fileHeader = [\r\n `--${boundary}`,\r\n `Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"`,\r\n `Content-Type: ${mimeType}`,\r\n '',\r\n '',\r\n ].join('\\r\\n');\r\n\r\n formParts.push(Buffer.from(fileHeader));\r\n formParts.push(buffer);\r\n formParts.push(Buffer.from(`\\r\\n--${boundary}--\\r\\n`));\r\n\r\n const body = Buffer.concat(formParts);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n Accept: 'application/json',\r\n 'Content-Type': `multipart/form-data; boundary=${boundary}`,\r\n tokenid: config.apiKey,\r\n },\r\n body,\r\n signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new FireberryError(`File upload failed: ${response.statusText}`, {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n statusCode: response.status,\r\n });\r\n }\r\n\r\n const responseData = await response.json();\r\n\r\n return {\r\n success: true,\r\n objectType: objectTypeStr,\r\n recordId,\r\n fileName: filename,\r\n mimeType,\r\n fileSize: buffer.length,\r\n response: responseData,\r\n };\r\n } catch (error) {\r\n if (error instanceof FireberryError) {\r\n throw error;\r\n }\r\n throw new FireberryError(`File upload failed: ${(error as Error).message}`, {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n cause: error as Error,\r\n });\r\n }\r\n }\r\n}\r\n","import type {\r\n FireberryClientConfig,\r\n RequestOptions,\r\n CacheControl,\r\n} from './types/client';\r\nimport type { QueryOptions, QueryResult } from './types/query';\r\nimport type { Transport } from './types/transport';\r\nimport {\r\n FireberryError,\r\n FireberryErrorCode,\r\n} from './errors';\r\nimport { QueryBuilder } from './utils/queryBuilder';\r\nimport { createTransport, createMetadataTransport, isMetadataAvailable } from './utils/transport';\r\nimport { HTTPTransport } from './transport/http';\r\n\r\n// Import API modules\r\nimport { MetadataAPI } from './api/metadata';\r\nimport { RecordsAPI } from './api/records';\r\nimport { BatchAPI } from './api/batch';\r\nimport { FieldsAPI } from './api/fields';\r\nimport { FilesAPI } from './api/files';\r\n\r\n/**\r\n * Internal cache store for metadata\r\n */\r\ninterface CacheStore {\r\n objects?: { data: unknown; timestamp: number };\r\n fields: Map<string, { data: unknown; timestamp: number }>;\r\n fieldValues: Map<string, { data: unknown; timestamp: number }>;\r\n}\r\n\r\n/**\r\n * Internal cache store for query results\r\n */\r\ninterface QueryCache {\r\n data: QueryResult;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Generates a cache key from query options for deduplication\r\n */\r\nfunction generateQueryCacheKey(options: QueryOptions): string {\r\n const parts = [\r\n options.objectType,\r\n Array.isArray(options.fields) ? options.fields.join(',') : options.fields || '*',\r\n options.query || '',\r\n options.sortBy || 'modifiedon',\r\n options.sortType || 'desc',\r\n options.limit?.toString() || '',\r\n options.page?.toString() || '1',\r\n options.pageSize?.toString() || '500',\r\n options.showRealValue !== false ? '1' : '0',\r\n options.autoPage !== false ? '1' : '0',\r\n ];\r\n return parts.join('|');\r\n}\r\n\r\n/**\r\n * FireberryClient - Main client for interacting with the Fireberry CRM API\r\n *\r\n * @example\r\n * ```typescript\r\n * const client = new FireberryClient({\r\n * apiKey: 'your-api-key',\r\n * retryOn429: true,\r\n * maxRetries: 120,\r\n * });\r\n *\r\n * // Query records\r\n * const result = await client.query({\r\n * objectType: '1',\r\n * fields: ['accountid', 'name'],\r\n * query: '(statuscode = 1)',\r\n * });\r\n *\r\n * // Use query builder\r\n * const result = await client.queryBuilder()\r\n * .objectType('1')\r\n * .select('accountid', 'name')\r\n * .where('statuscode').equals('1')\r\n * .execute();\r\n * ```\r\n */\r\nexport class FireberryClient {\r\n private readonly config: FireberryClientConfig;\r\n private readonly normalizedConfig: {\r\n baseUrl: string;\r\n timeout: number;\r\n retryOn429: boolean;\r\n maxRetries: number;\r\n retryDelay: number;\r\n cacheMetadata: boolean;\r\n cacheTTL: number;\r\n cacheQueryResults: boolean;\r\n queryResultCacheTTL: number;\r\n invalidateCacheOnMutation: boolean;\r\n };\r\n private readonly cacheStore: CacheStore;\r\n private readonly inFlightQueries: Map<string, Promise<QueryResult>> = new Map();\r\n private readonly queryCache: Map<string, QueryCache> = new Map();\r\n private readonly transport: Transport;\r\n private readonly metadataTransport: HTTPTransport | null;\r\n\r\n /** Metadata API operations */\r\n readonly metadata: MetadataAPI;\r\n /** Records CRUD operations */\r\n readonly records: RecordsAPI;\r\n /** Batch operations */\r\n readonly batch: BatchAPI;\r\n /** Field management operations */\r\n readonly fields: FieldsAPI;\r\n /** File operations */\r\n readonly files: FilesAPI;\r\n\r\n /**\r\n * Creates a new FireberryClient instance\r\n */\r\n constructor(config: FireberryClientConfig) {\r\n // Store original config\r\n this.config = config;\r\n\r\n // Create normalized config for settings\r\n this.normalizedConfig = {\r\n baseUrl: config.baseUrl || 'https://api.fireberry.com',\r\n timeout: config.timeout || 30000,\r\n retryOn429: config.retryOn429 ?? true,\r\n maxRetries: config.maxRetries || 120,\r\n retryDelay: config.retryDelay || 1000,\r\n cacheMetadata: config.cacheMetadata || false,\r\n cacheTTL: config.cacheTTL || 300000, // 5 minutes default\r\n cacheQueryResults: config.cacheQueryResults || false,\r\n queryResultCacheTTL: config.queryResultCacheTTL || 60000, // 1 minute default\r\n invalidateCacheOnMutation: config.invalidateCacheOnMutation ?? true, // Smart cache invalidation enabled by default\r\n };\r\n\r\n // Initialize cache store\r\n this.cacheStore = {\r\n fields: new Map(),\r\n fieldValues: new Map(),\r\n };\r\n\r\n // Create transport layer\r\n this.transport = createTransport(config);\r\n this.metadataTransport = createMetadataTransport(config);\r\n\r\n // Initialize API modules\r\n this.metadata = new MetadataAPI(this);\r\n this.records = new RecordsAPI(this);\r\n this.batch = new BatchAPI(this);\r\n this.fields = new FieldsAPI(this);\r\n this.files = new FilesAPI(this);\r\n }\r\n\r\n /**\r\n * Gets the client configuration with all defaults applied\r\n */\r\n getConfig(): Readonly<FireberryClientConfig & {\r\n baseUrl: string;\r\n timeout: number;\r\n retryOn429: boolean;\r\n maxRetries: number;\r\n retryDelay: number;\r\n cacheMetadata: boolean;\r\n cacheTTL: number;\r\n cacheQueryResults: boolean;\r\n queryResultCacheTTL: number;\r\n invalidateCacheOnMutation: boolean;\r\n }> {\r\n return {\r\n ...this.config,\r\n ...this.normalizedConfig,\r\n };\r\n }\r\n\r\n /**\r\n * Gets the transport instance (for internal use by API modules)\r\n * @internal\r\n */\r\n getTransport(): Transport {\r\n return this.transport;\r\n }\r\n\r\n /**\r\n * Gets the metadata transport instance (for internal use by MetadataAPI)\r\n * Returns null if metadata is not available (SDK-only mode without API key)\r\n * @internal\r\n */\r\n getMetadataTransport(): HTTPTransport | null {\r\n return this.metadataTransport;\r\n }\r\n\r\n /**\r\n * Checks if metadata operations are available\r\n */\r\n isMetadataAvailable(): boolean {\r\n return isMetadataAvailable(this.config);\r\n }\r\n\r\n /**\r\n * Cache control methods\r\n */\r\n readonly cache: CacheControl & {\r\n /** Clear all query result cache */\r\n clearQueryResults: () => void;\r\n /** Clear query results for a specific object type */\r\n clearQueryResultsForObject: (objectType: string) => void;\r\n } = {\r\n clear: () => {\r\n this.cacheStore.objects = undefined;\r\n this.cacheStore.fields.clear();\r\n this.cacheStore.fieldValues.clear();\r\n this.queryCache.clear();\r\n },\r\n clearObjects: () => {\r\n this.cacheStore.objects = undefined;\r\n },\r\n clearFields: (objectType: string) => {\r\n this.cacheStore.fields.delete(objectType);\r\n },\r\n clearFieldValues: (objectType: string, fieldName?: string) => {\r\n if (fieldName) {\r\n this.cacheStore.fieldValues.delete(`${objectType}:${fieldName}`);\r\n } else {\r\n // Clear all field values for this object type\r\n for (const key of this.cacheStore.fieldValues.keys()) {\r\n if (key.startsWith(`${objectType}:`)) {\r\n this.cacheStore.fieldValues.delete(key);\r\n }\r\n }\r\n }\r\n },\r\n clearQueryResults: () => {\r\n this.queryCache.clear();\r\n },\r\n clearQueryResultsForObject: (objectType: string) => {\r\n // Clear all query results for this object type\r\n for (const key of this.queryCache.keys()) {\r\n if (key.startsWith(`${objectType}|`)) {\r\n this.queryCache.delete(key);\r\n }\r\n }\r\n },\r\n };\r\n\r\n /**\r\n * Invalidates the query cache for an object type after a mutation.\r\n * Called automatically by RecordsAPI and BatchAPI when mutations occur.\r\n * Only takes effect if `invalidateCacheOnMutation` is enabled (default: true).\r\n *\r\n * @param objectType - The object type that was mutated\r\n * @internal\r\n */\r\n invalidateCacheForMutation(objectType: string): void {\r\n if (this.normalizedConfig.invalidateCacheOnMutation) {\r\n this.cache.clearQueryResultsForObject(objectType);\r\n }\r\n }\r\n\r\n /**\r\n * Cleans up expired cache entries (called on write to prevent memory leaks)\r\n */\r\n private cleanupExpiredCacheEntries(): void {\r\n const now = Date.now();\r\n\r\n // Clean query cache\r\n if (this.normalizedConfig.cacheQueryResults) {\r\n for (const [key, entry] of this.queryCache) {\r\n if (now - entry.timestamp >= this.normalizedConfig.queryResultCacheTTL) {\r\n this.queryCache.delete(key);\r\n }\r\n }\r\n }\r\n\r\n // Clean metadata caches\r\n if (this.normalizedConfig.cacheMetadata) {\r\n // Clean objects cache\r\n if (this.cacheStore.objects && now - this.cacheStore.objects.timestamp >= this.normalizedConfig.cacheTTL) {\r\n this.cacheStore.objects = undefined;\r\n }\r\n\r\n // Clean fields cache\r\n for (const [key, entry] of this.cacheStore.fields) {\r\n if (now - entry.timestamp >= this.normalizedConfig.cacheTTL) {\r\n this.cacheStore.fields.delete(key);\r\n }\r\n }\r\n\r\n // Clean fieldValues cache\r\n for (const [key, entry] of this.cacheStore.fieldValues) {\r\n if (now - entry.timestamp >= this.normalizedConfig.cacheTTL) {\r\n this.cacheStore.fieldValues.delete(key);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Gets cached data if valid, or undefined if not cached or expired\r\n */\r\n getCached<T>(type: 'objects'): T | undefined;\r\n getCached<T>(type: 'fields', objectType: string): T | undefined;\r\n getCached<T>(type: 'fieldValues', objectType: string, fieldName: string): T | undefined;\r\n getCached<T>(\r\n type: 'objects' | 'fields' | 'fieldValues',\r\n objectType?: string,\r\n fieldName?: string,\r\n ): T | undefined {\r\n if (!this.normalizedConfig.cacheMetadata) {\r\n return undefined;\r\n }\r\n\r\n const now = Date.now();\r\n\r\n if (type === 'objects') {\r\n const cached = this.cacheStore.objects;\r\n if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {\r\n return cached.data as T;\r\n }\r\n } else if (type === 'fields' && objectType) {\r\n const cached = this.cacheStore.fields.get(objectType);\r\n if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {\r\n return cached.data as T;\r\n }\r\n } else if (type === 'fieldValues' && objectType && fieldName) {\r\n const key = `${objectType}:${fieldName}`;\r\n const cached = this.cacheStore.fieldValues.get(key);\r\n if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {\r\n return cached.data as T;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Sets cached data\r\n */\r\n setCache(type: 'objects', data: unknown): void;\r\n setCache(type: 'fields', objectType: string, data: unknown): void;\r\n setCache(type: 'fieldValues', objectType: string, fieldName: string, data: unknown): void;\r\n setCache(\r\n type: 'objects' | 'fields' | 'fieldValues',\r\n objectTypeOrData?: string | unknown,\r\n fieldNameOrData?: string | unknown,\r\n data?: unknown,\r\n ): void {\r\n if (!this.normalizedConfig.cacheMetadata) {\r\n return;\r\n }\r\n\r\n // Cleanup expired entries on write\r\n this.cleanupExpiredCacheEntries();\r\n\r\n const now = Date.now();\r\n\r\n if (type === 'objects') {\r\n this.cacheStore.objects = { data: objectTypeOrData, timestamp: now };\r\n } else if (type === 'fields' && typeof objectTypeOrData === 'string') {\r\n this.cacheStore.fields.set(objectTypeOrData, {\r\n data: fieldNameOrData,\r\n timestamp: now,\r\n });\r\n } else if (\r\n type === 'fieldValues' &&\r\n typeof objectTypeOrData === 'string' &&\r\n typeof fieldNameOrData === 'string'\r\n ) {\r\n const key = `${objectTypeOrData}:${fieldNameOrData}`;\r\n this.cacheStore.fieldValues.set(key, { data, timestamp: now });\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new QueryBuilder instance\r\n */\r\n queryBuilder(): QueryBuilder {\r\n return new QueryBuilder(this);\r\n }\r\n\r\n /**\r\n * Executes multiple queries in parallel\r\n * Respects rate limits by chunking concurrent requests\r\n *\r\n * @param queries - Array of query options to execute\r\n * @param options - Parallel execution options\r\n * @returns Array of query results in the same order as input queries\r\n *\r\n * @example\r\n * ```typescript\r\n * const results = await client.queryAll([\r\n * { objectType: '1', fields: ['accountid', 'name'] },\r\n * { objectType: '2', fields: ['contactid', 'fullname'] },\r\n * { objectType: '4', fields: ['opportunityid', 'name'] },\r\n * ]);\r\n * ```\r\n */\r\n async queryAll(\r\n queries: QueryOptions[],\r\n options: { concurrency?: number; signal?: AbortSignal } = {},\r\n ): Promise<QueryResult[]> {\r\n const { concurrency = 5, signal } = options;\r\n\r\n if (queries.length === 0) {\r\n return [];\r\n }\r\n\r\n const results: QueryResult[] = new Array(queries.length);\r\n\r\n // Process in chunks to respect rate limits\r\n for (let i = 0; i < queries.length; i += concurrency) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Query aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const chunk = queries.slice(i, i + concurrency);\r\n const chunkPromises = chunk.map((queryOpts, chunkIndex) => {\r\n // Pass signal to individual queries if provided\r\n const queryWithSignal = signal ? { ...queryOpts, signal } : queryOpts;\r\n return this.query(queryWithSignal).then((result) => {\r\n results[i + chunkIndex] = result;\r\n });\r\n });\r\n\r\n await Promise.all(chunkPromises);\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Streams query results using an async iterator (cursor-based pagination)\r\n * Yields batches of records, allowing processing of large datasets without loading all into memory\r\n *\r\n * @param options - Query options (autoPage is ignored, pagination is handled by the iterator)\r\n * @yields Batches of records as QueryResult objects\r\n *\r\n * @example\r\n * ```typescript\r\n * // Process records in batches\r\n * for await (const batch of client.queryStream({\r\n * objectType: '1',\r\n * fields: ['accountid', 'name'],\r\n * pageSize: 100,\r\n * })) {\r\n * console.log(`Processing ${batch.records.length} records...`);\r\n * for (const record of batch.records) {\r\n * // Process each record\r\n * }\r\n * }\r\n *\r\n * // Collect all records from stream\r\n * const allRecords: Record<string, unknown>[] = [];\r\n * for await (const batch of client.queryStream({ objectType: '1', fields: '*' })) {\r\n * allRecords.push(...batch.records);\r\n * }\r\n * ```\r\n */\r\n async *queryStream(\r\n options: Omit<QueryOptions, 'autoPage'>,\r\n ): AsyncGenerator<QueryResult, void, undefined> {\r\n const { objectType, fields, query, sortBy = 'modifiedon', sortType = 'desc', limit, pageSize = 500, showRealValue = true, signal } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // Handle '*' expansion for object types with excluded fields\r\n if (fieldsStr === '*') {\r\n fieldsStr = await this.expandStarFields(objectType, signal);\r\n }\r\n\r\n let currentPage = 1;\r\n let totalFetched = 0;\r\n let hasMore = true;\r\n\r\n while (hasMore) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n return;\r\n }\r\n\r\n // Calculate page size for this request\r\n const requestPageSize = limit\r\n ? Math.min(pageSize, limit - totalFetched)\r\n : pageSize;\r\n\r\n if (requestPageSize <= 0) {\r\n return;\r\n }\r\n\r\n const body = {\r\n objecttype: objectType,\r\n fields: fieldsStr,\r\n query: query || '',\r\n sort_by: sortBy,\r\n sort_type: sortType,\r\n page_size: requestPageSize,\r\n page_number: currentPage,\r\n show_real_value: showRealValue ? 1 : 0,\r\n };\r\n\r\n const response = await this.request<{ data?: { Data?: Record<string, unknown>[] } }>({\r\n method: 'POST',\r\n endpoint: '/api/query',\r\n body,\r\n signal,\r\n });\r\n\r\n const records = response.data?.Data || [];\r\n totalFetched += records.length;\r\n\r\n yield {\r\n records,\r\n total: records.length,\r\n success: true,\r\n page: currentPage,\r\n };\r\n\r\n // Check if there are more pages\r\n if (records.length < requestPageSize || (limit && totalFetched >= limit)) {\r\n hasMore = false;\r\n } else {\r\n currentPage++;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Executes a query against the Fireberry API\r\n * Automatically deduplicates concurrent identical requests\r\n * Optionally caches results (if cacheQueryResults is enabled)\r\n */\r\n async query(options: QueryOptions): Promise<QueryResult> {\r\n // Generate cache key for deduplication and caching\r\n const cacheKey = generateQueryCacheKey(options);\r\n\r\n // Check query result cache first\r\n if (this.normalizedConfig.cacheQueryResults) {\r\n const cached = this.queryCache.get(cacheKey);\r\n if (cached && Date.now() - cached.timestamp < this.normalizedConfig.queryResultCacheTTL) {\r\n return cached.data;\r\n }\r\n }\r\n\r\n // Check for in-flight request with same parameters\r\n const inFlight = this.inFlightQueries.get(cacheKey);\r\n if (inFlight) {\r\n return inFlight;\r\n }\r\n\r\n // Execute query and track it\r\n const queryPromise = this.executeQuery(options);\r\n\r\n // Store in-flight promise\r\n this.inFlightQueries.set(cacheKey, queryPromise);\r\n\r\n try {\r\n const result = await queryPromise;\r\n\r\n // Store in cache if caching is enabled\r\n if (this.normalizedConfig.cacheQueryResults) {\r\n // Cleanup expired entries on write\r\n this.cleanupExpiredCacheEntries();\r\n this.queryCache.set(cacheKey, {\r\n data: result,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n return result;\r\n } finally {\r\n // Remove from in-flight map when done\r\n this.inFlightQueries.delete(cacheKey);\r\n }\r\n }\r\n\r\n /**\r\n * Internal query execution (without deduplication)\r\n */\r\n private async executeQuery(options: QueryOptions): Promise<QueryResult> {\r\n const {\r\n objectType,\r\n fields,\r\n signal,\r\n } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // Handle '*' expansion for object types with excluded fields\r\n if (fieldsStr === '*') {\r\n fieldsStr = await this.expandStarFields(objectType, signal);\r\n }\r\n\r\n // Use transport to execute the query\r\n return this.transport.query({\r\n ...options,\r\n fields: fieldsStr,\r\n });\r\n }\r\n\r\n /**\r\n * Expands '*' fields to actual field names, excluding problematic fields for specific object types\r\n */\r\n private async expandStarFields(objectType: string, signal?: AbortSignal): Promise<string> {\r\n const { getExcludedFieldsForStarQuery } = await import('./constants/excludedFields');\r\n const excludedFields = getExcludedFieldsForStarQuery(objectType);\r\n\r\n // If no excluded fields for this object type, just return '*'\r\n if (excludedFields.length === 0) {\r\n return '*';\r\n }\r\n\r\n // Fetch metadata to get all field names\r\n const fieldsResult = await this.metadata.getFields(objectType, signal);\r\n const allFieldNames = fieldsResult.fields.map((f) => f.fieldName);\r\n\r\n // Filter out excluded fields\r\n const filteredFields = allFieldNames.filter(\r\n (fieldName) => !excludedFields.includes(fieldName),\r\n );\r\n\r\n return filteredFields.join(',');\r\n }\r\n\r\n /**\r\n * Makes a raw API request to the Fireberry API\r\n * @deprecated Use getTransport() or getMetadataTransport() for new code\r\n * @internal This method is kept for backwards compatibility with API modules\r\n */\r\n async request<T = unknown>(options: RequestOptions): Promise<T> {\r\n // Delegate to metadata transport if available (for metadata operations)\r\n // Otherwise use the main transport\r\n const transport = this.metadataTransport || this.transport;\r\n\r\n // For HTTP transport, delegate directly\r\n if (transport instanceof HTTPTransport) {\r\n return transport.request<T>(options);\r\n }\r\n\r\n // For SDK transport, throw error since raw requests aren't supported\r\n throw new FireberryError(\r\n 'Raw request() is not supported in SDK mode. Use specific methods like query(), createRecord(), etc.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n }\r\n}\r\n","/**\r\n * Special field name mappings that don't follow standard patterns\r\n * Key: original field name, Value: corresponding label field\r\n */\r\nconst SPECIAL_LABEL_FIELD_MAPPINGS: Record<string, string> = {\r\n objectid: 'objecttitle',\r\n lastactionid: 'lastactiontitle',\r\n wfruleid: 'rulename', // Object 55 (Workflow Rules)\r\n noteid: 'subject', // Object 7 (Note) - noteid maps to subject\r\n};\r\n\r\n/**\r\n * Fields ending with \"id\" that should NOT have \"id\" replaced with \"name\"\r\n * These fields will use the default append \"name\" behavior instead\r\n */\r\nconst EXCLUDED_ID_FIELDS: string[] = [\r\n 'businessunitid', // → businessunitidname (not businessunitname)\r\n 'crmuserid', // → no name field exists\r\n 'languageid', // → languageidname (not languagename)\r\n];\r\n\r\n/**\r\n * Fields ending with \"code\" that should NOT have \"code\" removed\r\n * These fields will use the default append \"name\" behavior instead\r\n */\r\nconst EXCLUDED_CODE_FIELDS: string[] = [\r\n 'duplicaterecordcode', // → duplicaterecordcodename (not duplicaterecord)\r\n];\r\n\r\n/**\r\n * Fields that have NO corresponding label field at all\r\n * These fields should not have any name transformation applied\r\n * Return empty string to signal \"no label field exists\"\r\n */\r\nconst FIELDS_WITHOUT_LABEL_FIELD: string[] = [\r\n 'systemfieldid', // Object 73 - no name field exists\r\n 'fieldobjecttype', // Object 73 - base field doesn't exist, only *name exists\r\n 'invoiceid', // Objects 78, 81 - no name field exists\r\n 'calllogid', // Object 100 - no name field exists (primary key)\r\n 'attendanceclockid', // Object 101 - no name field exists (primary key)\r\n 'activitylogid', // Object 102 - no name field exists (primary key)\r\n 'conversationid', // Object 104 - no name field exists (primary key)\r\n 'texttemplateid', // Text Template - no name field exists (primary key)\r\n 'smstemplateid', // Object 110 - no name field exists (primary key)\r\n 'deletedby', // Object 7 - no name field exists\r\n 'recordid', // Object 7 - no name field exists\r\n 'objecttypecode', // Object 7 - no name field exists\r\n];\r\n\r\n/**\r\n * Object-type specific overrides for field name transformations\r\n * Key: object type ID, Value: { excludedIdFields, excludedCodeFields }\r\n */\r\nconst OBJECT_TYPE_OVERRIDES: Record<\r\n number,\r\n { excludedIdFields?: string[]; excludedCodeFields?: string[] }\r\n> = {\r\n // CRM Orders (13) - uses *idname and *codename patterns\r\n 13: {\r\n excludedIdFields: ['ownerid', 'accountid', 'printtemplateid', 'pcfaccountid'],\r\n excludedCodeFields: [\r\n 'rounddiscountcode',\r\n 'taxincludecode',\r\n 'currencycode',\r\n 'transmissioncode',\r\n 'creditrejectioncode1',\r\n 'creditrejectioncode2',\r\n 'apartmentcode1',\r\n 'apartmentcode2',\r\n 'restrictioncode1',\r\n 'restrictioncode2',\r\n 'casescode1',\r\n 'casescode2',\r\n 'returncode1',\r\n 'returncode2',\r\n 'statuscode',\r\n ],\r\n },\r\n // Products (14)\r\n 14: {\r\n excludedCodeFields: ['categorycode'], // → categoryname (not category)\r\n },\r\n // CRM Order Items (17) - uses *idname pattern\r\n 17: {\r\n excludedIdFields: ['crmorderid', 'productid', 'ownerid'],\r\n },\r\n // Email Templates (20)\r\n 20: {\r\n excludedIdFields: ['mdobjectid'],\r\n },\r\n // Print Templates (27)\r\n 27: {\r\n excludedIdFields: ['mdobjectid'],\r\n },\r\n // System Fields (73) - uses *idname pattern\r\n 73: {\r\n excludedIdFields: ['mdobjectid', 'ownerid'],\r\n },\r\n // Invoices (78) - uses *codename and *idname patterns extensively\r\n 78: {\r\n excludedIdFields: [\r\n 'crmorderid',\r\n 'invoicereceiptid',\r\n 'accountid',\r\n 'ownerid',\r\n 'invoicerenoid',\r\n ],\r\n excludedCodeFields: [\r\n 'taxincludecode',\r\n 'depositcode',\r\n 'rounddiscountcode',\r\n 'currencycode',\r\n 'statecode',\r\n 'invoicetypecode',\r\n ],\r\n },\r\n // Invoice No (81) - uses *codename and *idname patterns extensively\r\n 81: {\r\n excludedIdFields: [\r\n 'ownerid',\r\n 'invoicecreditid',\r\n 'crmorderid',\r\n 'invoicereceiptid',\r\n 'invoicedeliveryid',\r\n 'accountid',\r\n ],\r\n excludedCodeFields: ['currencycode', 'rounddiscountcode', 'statecode', 'taxincludecode'],\r\n },\r\n // Invoice Draft (82) - uses *codename and *idname patterns extensively\r\n 82: {\r\n excludedIdFields: ['accountid', 'crmorderid', 'ownerid', 'invoicerenoid'],\r\n excludedCodeFields: ['taxincludecode', 'statecode', 'rounddiscountcode', 'currencycode'],\r\n },\r\n // Invoice Receipt (83) - uses *codename and *idname patterns\r\n 83: {\r\n excludedIdFields: ['invoicenoid', 'crmorderid', 'ownerid', 'accountid'],\r\n excludedCodeFields: ['statecode', 'currencycode'],\r\n },\r\n // Invoice Tax Receipt (84) - uses *codename and *idname patterns\r\n 84: {\r\n excludedIdFields: ['crmorderid', 'ownerid', 'invoicecreditid', 'accountid'],\r\n excludedCodeFields: ['rounddiscountcode', 'statecode', 'taxincludecode', 'currencycode'],\r\n },\r\n // Invoice Credit (85) - uses *codename and *idname patterns\r\n 85: {\r\n excludedIdFields: ['ownerid', 'crmorderid', 'accountid'],\r\n excludedCodeFields: ['taxincludecode', 'rounddiscountcode', 'currencycode', 'statecode'],\r\n },\r\n // Invoice (86) - uses *codename and *idname patterns\r\n 86: {\r\n excludedIdFields: ['accountid', 'ownerid', 'crmorderid'],\r\n excludedCodeFields: ['statecode', 'rounddiscountcode', 'currencycode', 'taxincludecode'],\r\n },\r\n // Call Log (100) - uses *idname pattern\r\n 100: {\r\n excludedIdFields: ['contactid', 'leadid', 'accountid', 'ownerid'],\r\n },\r\n // Attendance Clock (101) - uses *idname pattern\r\n 101: {\r\n excludedIdFields: ['ownerid'],\r\n },\r\n // Activity Log (102) - uses *idname and *codename patterns\r\n 102: {\r\n excludedIdFields: ['contactid', 'ownerid'],\r\n excludedCodeFields: ['objecttypecode', 'typecode', 'resultcode'],\r\n },\r\n // Conversation (104) - uses *idname pattern\r\n 104: {\r\n excludedIdFields: ['leadid', 'ownerid', 'contactid', 'accountid'],\r\n },\r\n // Text Template (106) - uses *idname pattern\r\n 106: {\r\n excludedIdFields: ['ownerid'],\r\n },\r\n // SMS Template (110) - uses *idname pattern\r\n 110: {\r\n excludedIdFields: ['ownerid'],\r\n },\r\n};\r\n\r\n/**\r\n * Converts a field API name to its corresponding label field.\r\n *\r\n * Rules:\r\n * - Special mappings (e.g., objectid → objecttitle)\r\n * - Fields starting with \"pcf\" (custom fields): append \"name\" → pcf_field → pcf_fieldname\r\n * - Fields ending with \"code\" (unless excluded): remove \"code\" → statuscode → status\r\n * - Fields ending with \"id\" (unless excluded): replace \"id\" with \"name\" → accountid → accountname\r\n * - All other fields: append \"name\"\r\n *\r\n * @param fieldName - The field API name\r\n * @param objectType - The object type ID (required for object-specific overrides)\r\n * @returns The corresponding label field, or empty string if no label field exists\r\n */\r\nexport function getLabelFieldForField(fieldName: string, objectType: string | number): string {\r\n // Check special mappings first\r\n if (SPECIAL_LABEL_FIELD_MAPPINGS[fieldName]) {\r\n return SPECIAL_LABEL_FIELD_MAPPINGS[fieldName];\r\n }\r\n\r\n // Check if field has no label field at all - return empty string\r\n if (FIELDS_WITHOUT_LABEL_FIELD.includes(fieldName)) {\r\n return '';\r\n }\r\n\r\n // Check for custom object primary keys (customobject{N}id pattern) → name\r\n if (/^customobject\\d+id$/.test(fieldName)) {\r\n return 'name';\r\n }\r\n\r\n // Custom fields (pcf prefix) - just append \"name\"\r\n if (fieldName.startsWith('pcf')) {\r\n return `${fieldName}name`;\r\n }\r\n\r\n // Get object-type specific overrides\r\n const objectTypeNum =\r\n typeof objectType === 'string' ? parseInt(objectType, 10) : objectType;\r\n const overrides = OBJECT_TYPE_OVERRIDES[objectTypeNum] || null;\r\n\r\n // For custom objects (1000+), add default exclusions\r\n const isCustomObject = objectTypeNum >= 1000;\r\n const customObjectExclusions = isCustomObject ? ['ownerid'] : [];\r\n\r\n // Combine global and object-specific exclusions\r\n const excludedCodeFields = [\r\n ...EXCLUDED_CODE_FIELDS,\r\n ...(overrides?.excludedCodeFields || []),\r\n ];\r\n const excludedIdFields = [\r\n ...EXCLUDED_ID_FIELDS,\r\n ...(overrides?.excludedIdFields || []),\r\n ...customObjectExclusions,\r\n ];\r\n\r\n // Remove \"code\" suffix (unless excluded) → statuscode → status\r\n if (fieldName.endsWith('code') && !excludedCodeFields.includes(fieldName)) {\r\n return fieldName.slice(0, -4);\r\n }\r\n\r\n // Replace \"id\" suffix with \"name\" (unless excluded) → accountid → accountname\r\n if (fieldName.endsWith('id') && !excludedIdFields.includes(fieldName)) {\r\n return fieldName.slice(0, -2) + 'name';\r\n }\r\n\r\n // Default: append \"name\"\r\n return `${fieldName}name`;\r\n}\r\n","/**\r\n * Related Field Mapping Utilities\r\n *\r\n * Functions for parsing and resolving related object field references.\r\n * Related fields use the pattern: {referenceField}_{relatedField}\r\n * Example: accountid_telephone1, contactid_fullname, accountid_statuscode\r\n */\r\n\r\nimport { OBJECT_ID_MAP } from '../constants/objectIds';\r\nimport { FIELD_TYPE_IDS } from '../constants/fieldTypes';\r\nimport { getLabelFieldForField } from './fieldMapping';\r\nimport type { FireberryField } from '../types/metadata';\r\n\r\n/**\r\n * Reverse mapping from ID field name to object type ID\r\n * Generated from OBJECT_ID_MAP\r\n */\r\nexport const ID_FIELD_TO_OBJECT_TYPE: Record<string, number> = Object.entries(OBJECT_ID_MAP).reduce(\r\n (acc, [objectTypeId, idFieldName]) => {\r\n acc[idFieldName] = parseInt(objectTypeId, 10);\r\n return acc;\r\n },\r\n {} as Record<string, number>,\r\n);\r\n\r\n/**\r\n * Information about a parsed related field\r\n */\r\nexport interface RelatedFieldInfo {\r\n /** The original field name (e.g., \"accountid_telephone1\") */\r\n originalField: string;\r\n /** The reference/lookup field (e.g., \"accountid\") */\r\n referenceField: string;\r\n /** The field on the related object (e.g., \"telephone1\") */\r\n relatedField: string;\r\n /** The object type ID of the related object (e.g., 1 for Account) */\r\n relatedObjectType: number;\r\n}\r\n\r\n/**\r\n * Result of resolving a related field with its label field(s)\r\n */\r\nexport interface RelatedFieldResolution {\r\n /** The original field name */\r\n originalField: string;\r\n /** All fields that should be selected/returned */\r\n fields: string[];\r\n /** The primary value field */\r\n valueField: string;\r\n /** The label/display field (may be same as valueField for non-code fields) */\r\n labelField: string;\r\n /** The code field if applicable (for dropdown fields) */\r\n codeField?: string;\r\n /** Whether this is a code field (ends with 'code') */\r\n isCodeField: boolean;\r\n /** Related object type ID */\r\n relatedObjectType: number;\r\n /** Field type from metadata (if available) */\r\n fieldType?: string;\r\n}\r\n\r\n/**\r\n * Field metadata map type - maps field name to field info\r\n */\r\nexport type FieldMetadataMap = Map<string, FireberryField>;\r\n\r\n/**\r\n * Gets the object type ID from a reference field name\r\n *\r\n * @param referenceField - The reference field name (e.g., \"accountid\", \"contactid\")\r\n * @returns The object type ID, or null if not a known reference field\r\n *\r\n * @example\r\n * getObjectTypeFromReferenceField('accountid') // 1\r\n * getObjectTypeFromReferenceField('contactid') // 2\r\n * getObjectTypeFromReferenceField('leadid') // 3\r\n * getObjectTypeFromReferenceField('unknown') // null\r\n */\r\nexport function getObjectTypeFromReferenceField(referenceField: string): number | null {\r\n // Check standard mappings\r\n if (ID_FIELD_TO_OBJECT_TYPE[referenceField]) {\r\n return ID_FIELD_TO_OBJECT_TYPE[referenceField];\r\n }\r\n\r\n // Check for custom object pattern: customobject{N}id\r\n const customMatch = referenceField.match(/^customobject(\\d+)id$/);\r\n if (customMatch) {\r\n return parseInt(customMatch[1], 10);\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parses a related field name into its components\r\n *\r\n * @param fieldName - The field name to parse (e.g., \"accountid_telephone1\")\r\n * @returns RelatedFieldInfo if it's a valid related field, null otherwise\r\n *\r\n * @example\r\n * parseRelatedField('accountid_telephone1')\r\n * // { originalField: 'accountid_telephone1', referenceField: 'accountid',\r\n * // relatedField: 'telephone1', relatedObjectType: 1 }\r\n *\r\n * parseRelatedField('accountid_statuscode')\r\n * // { originalField: 'accountid_statuscode', referenceField: 'accountid',\r\n * // relatedField: 'statuscode', relatedObjectType: 1 }\r\n *\r\n * parseRelatedField('telephone1') // null (not a related field)\r\n */\r\nexport function parseRelatedField(fieldName: string): RelatedFieldInfo | null {\r\n // Must contain underscore\r\n const underscoreIndex = fieldName.indexOf('_');\r\n if (underscoreIndex === -1) {\r\n return null;\r\n }\r\n\r\n // Try to find a valid reference field by checking progressively longer prefixes\r\n // This handles cases like pcf_accountid_status where we need to find the right split\r\n const parts = fieldName.split('_');\r\n\r\n // Start from the first part and try combinations\r\n for (let i = 0; i < parts.length - 1; i++) {\r\n const potentialRefField = parts.slice(0, i + 1).join('_');\r\n const objectType = getObjectTypeFromReferenceField(potentialRefField);\r\n\r\n if (objectType !== null) {\r\n const relatedField = parts.slice(i + 1).join('_');\r\n if (relatedField) {\r\n return {\r\n originalField: fieldName,\r\n referenceField: potentialRefField,\r\n relatedField,\r\n relatedObjectType: objectType,\r\n };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Determines if a field is a \"code\" field (stores internal value, has label equivalent)\r\n *\r\n * @param fieldName - The field name to check\r\n * @returns True if the field is a code field\r\n */\r\nexport function isCodeField(fieldName: string): boolean {\r\n return fieldName.endsWith('code');\r\n}\r\n\r\n/**\r\n * Gets the code field name for a label field\r\n * For example: status -> statuscode\r\n *\r\n * @param labelField - The label field name\r\n * @returns The code field name\r\n */\r\nexport function getCodeFieldFromLabel(labelField: string): string {\r\n return `${labelField}code`;\r\n}\r\n\r\n/**\r\n * Gets the label field name for a code field\r\n * For example: statuscode -> status\r\n *\r\n * @param codeField - The code field name\r\n * @returns The label field name\r\n */\r\nexport function getLabelFieldFromCode(codeField: string): string {\r\n if (codeField.endsWith('code')) {\r\n return codeField.slice(0, -4);\r\n }\r\n return codeField;\r\n}\r\n\r\n/**\r\n * Checks if a field is a dropdown type based on metadata\r\n *\r\n * @param fieldName - The field name to check\r\n * @param metadata - Field metadata map\r\n * @returns True if the field is a dropdown type\r\n */\r\nexport function isDropdownFieldByMetadata(\r\n fieldName: string,\r\n metadata: FieldMetadataMap,\r\n): boolean {\r\n const field = metadata.get(fieldName);\r\n return field?.systemFieldTypeId === FIELD_TYPE_IDS.DROPDOWN;\r\n}\r\n\r\n/**\r\n * Resolver class for related fields that uses metadata to determine field types\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create resolver with metadata\r\n * const fields = await client.metadata.getFields('1');\r\n * const resolver = new RelatedFieldResolver();\r\n * resolver.setMetadata(1, fields.fields);\r\n *\r\n * // Resolve a related field\r\n * const resolution = resolver.resolve('accountid_statuscode');\r\n * // Returns both statuscode and status fields for dropdown types\r\n * ```\r\n */\r\nexport class RelatedFieldResolver {\r\n private metadataByObjectType: Map<number, FieldMetadataMap> = new Map();\r\n\r\n /**\r\n * Sets field metadata for an object type\r\n *\r\n * @param objectType - The object type ID\r\n * @param fields - Array of field metadata\r\n */\r\n setMetadata(objectType: number, fields: FireberryField[]): void {\r\n const fieldMap: FieldMetadataMap = new Map();\r\n for (const field of fields) {\r\n fieldMap.set(field.fieldName, field);\r\n }\r\n this.metadataByObjectType.set(objectType, fieldMap);\r\n }\r\n\r\n /**\r\n * Gets field metadata for an object type\r\n *\r\n * @param objectType - The object type ID\r\n * @returns Field metadata map, or undefined if not loaded\r\n */\r\n getMetadata(objectType: number): FieldMetadataMap | undefined {\r\n return this.metadataByObjectType.get(objectType);\r\n }\r\n\r\n /**\r\n * Checks if metadata is loaded for an object type\r\n *\r\n * @param objectType - The object type ID\r\n * @returns True if metadata is loaded\r\n */\r\n hasMetadata(objectType: number): boolean {\r\n return this.metadataByObjectType.has(objectType);\r\n }\r\n\r\n /**\r\n * Clears all cached metadata\r\n */\r\n clearMetadata(): void {\r\n this.metadataByObjectType.clear();\r\n }\r\n\r\n /**\r\n * Resolves a related field into all necessary fields for querying and display\r\n * Uses metadata to determine if fields are dropdown types that need code/label pairs\r\n *\r\n * @param fieldName - The related field name to resolve\r\n * @param showRealValue - Whether labels are being returned (default: true).\r\n * When true, expands dropdown fields to include both code and label.\r\n * When false, returns only the requested field (no expansion needed).\r\n * @returns Resolution with all fields and metadata, or null if not a related field\r\n *\r\n * @example\r\n * // With showRealValue=true (default), dropdown fields get code/label pairs\r\n * resolver.resolve('accountid_status')\r\n * // { fields: ['accountid_status', 'accountid_statuscode'], ... }\r\n *\r\n * // With showRealValue=false, no expansion\r\n * resolver.resolve('accountid_status', false)\r\n * // { fields: ['accountid_status'], ... }\r\n *\r\n * // Regular fields stay as-is regardless of showRealValue\r\n * resolver.resolve('accountid_telephone1')\r\n * // { fields: ['accountid_telephone1'], ... }\r\n */\r\n resolve(fieldName: string, showRealValue: boolean = true): RelatedFieldResolution | null {\r\n const parsed = parseRelatedField(fieldName);\r\n if (!parsed) {\r\n return null;\r\n }\r\n\r\n const { referenceField, relatedField, relatedObjectType } = parsed;\r\n const metadata = this.metadataByObjectType.get(relatedObjectType);\r\n const fieldIsCode = isCodeField(relatedField);\r\n const fieldMeta = metadata?.get(relatedField);\r\n\r\n // When showRealValue is false, no expansion needed - just return the field as-is\r\n if (!showRealValue) {\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n isCodeField: fieldIsCode,\r\n relatedObjectType,\r\n fieldType: fieldMeta?.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // For code fields, we want to also get the label\r\n if (fieldIsCode) {\r\n const labelOnRelated = getLabelFieldForField(relatedField, relatedObjectType);\r\n const labelFieldName = labelOnRelated\r\n ? `${referenceField}_${labelOnRelated}`\r\n : `${referenceField}_${getLabelFieldFromCode(relatedField)}`;\r\n\r\n // Get field type from metadata for the code field\r\n const baseField = getLabelFieldFromCode(relatedField);\r\n const codeFieldMeta = metadata?.get(`${baseField}code`) || metadata?.get(relatedField);\r\n\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, labelFieldName],\r\n valueField: fieldName,\r\n labelField: labelFieldName,\r\n codeField: fieldName,\r\n isCodeField: true,\r\n relatedObjectType,\r\n fieldType: codeFieldMeta?.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // Input is NOT a code field - check if it's a dropdown using metadata\r\n const potentialCodeField = getCodeFieldFromLabel(relatedField);\r\n\r\n // Check if the code field exists and is a dropdown type\r\n const codeFieldMeta = metadata?.get(potentialCodeField);\r\n const isDropdown = codeFieldMeta?.systemFieldTypeId === FIELD_TYPE_IDS.DROPDOWN;\r\n\r\n if (isDropdown) {\r\n // This is a label field that has a corresponding dropdown code field\r\n const codeFieldName = `${referenceField}_${potentialCodeField}`;\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, codeFieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n codeField: codeFieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n fieldType: codeFieldMeta.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // Check if the field itself is a dropdown (for fields that don't follow code pattern)\r\n const fieldIsDropdown = fieldMeta?.systemFieldTypeId === FIELD_TYPE_IDS.DROPDOWN;\r\n\r\n if (fieldIsDropdown) {\r\n // The field itself is a dropdown - check if there's a code variant\r\n const codeFieldName = `${referenceField}_${potentialCodeField}`;\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, codeFieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n codeField: codeFieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n fieldType: fieldMeta.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // Regular field without code/label pairing\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n fieldType: fieldMeta?.systemFieldTypeId,\r\n };\r\n }\r\n\r\n /**\r\n * Expands a list of fields to include related field labels/codes\r\n *\r\n * @param fields - Array of field names to expand\r\n * @param showRealValue - Whether labels are being returned (default: true).\r\n * When true, expands dropdown fields to include both code and label.\r\n * When false, returns fields as-is (no expansion needed).\r\n * @returns Array of field names with related field expansions\r\n *\r\n * @example\r\n * // With showRealValue=true (default)\r\n * resolver.expandFields(['accountid_status', 'accountid_telephone1'])\r\n * // ['accountid_status', 'accountid_statuscode', 'accountid_telephone1']\r\n *\r\n * // With showRealValue=false\r\n * resolver.expandFields(['accountid_status', 'accountid_telephone1'], false)\r\n * // ['accountid_status', 'accountid_telephone1']\r\n */\r\n expandFields(fields: string[], showRealValue: boolean = true): string[] {\r\n const expanded = new Set<string>();\r\n\r\n for (const field of fields) {\r\n const resolution = this.resolve(field, showRealValue);\r\n if (resolution) {\r\n resolution.fields.forEach((f) => expanded.add(f));\r\n } else {\r\n expanded.add(field);\r\n }\r\n }\r\n\r\n return Array.from(expanded);\r\n }\r\n}\r\n\r\n/**\r\n * Resolves a related field without metadata (basic resolution)\r\n * Only handles code fields, does not detect dropdown types without metadata\r\n *\r\n * For full resolution with dropdown detection, use RelatedFieldResolver with metadata\r\n *\r\n * @param fieldName - The related field name to resolve\r\n * @returns Resolution with fields, or null if not a related field\r\n */\r\nexport function resolveRelatedField(fieldName: string): RelatedFieldResolution | null {\r\n const parsed = parseRelatedField(fieldName);\r\n if (!parsed) {\r\n return null;\r\n }\r\n\r\n const { referenceField, relatedField, relatedObjectType } = parsed;\r\n const fieldIsCode = isCodeField(relatedField);\r\n\r\n // For code fields, we always add the label\r\n if (fieldIsCode) {\r\n const labelOnRelated = getLabelFieldForField(relatedField, relatedObjectType);\r\n const labelFieldName = labelOnRelated\r\n ? `${referenceField}_${labelOnRelated}`\r\n : `${referenceField}_${getLabelFieldFromCode(relatedField)}`;\r\n\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, labelFieldName],\r\n valueField: fieldName,\r\n labelField: labelFieldName,\r\n codeField: fieldName,\r\n isCodeField: true,\r\n relatedObjectType,\r\n };\r\n }\r\n\r\n // Without metadata, we can only return the field as-is\r\n // Use RelatedFieldResolver with metadata for dropdown detection\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n };\r\n}\r\n\r\n/**\r\n * Expands a list of fields to include related field labels/codes\r\n * Basic expansion without metadata - only expands code fields\r\n *\r\n * For full expansion with dropdown detection, use RelatedFieldResolver with metadata\r\n *\r\n * @param fields - Array of field names to expand\r\n * @returns Array of field names with related field expansions\r\n */\r\nexport function expandRelatedFields(fields: string[]): string[] {\r\n const expanded = new Set<string>();\r\n\r\n for (const field of fields) {\r\n const resolution = resolveRelatedField(field);\r\n if (resolution) {\r\n resolution.fields.forEach((f) => expanded.add(f));\r\n } else {\r\n expanded.add(field);\r\n }\r\n }\r\n\r\n return Array.from(expanded);\r\n}\r\n\r\n/**\r\n * Gets all related field information for a field name\r\n * Combines parsing and basic resolution into a single call\r\n *\r\n * @param fieldName - The field name to analyze\r\n * @returns Combined info with parsing and resolution, or null if not a related field\r\n */\r\nexport function getRelatedFieldInfo(\r\n fieldName: string,\r\n): (RelatedFieldInfo & RelatedFieldResolution) | null {\r\n const parsed = parseRelatedField(fieldName);\r\n if (!parsed) {\r\n return null;\r\n }\r\n\r\n const resolved = resolveRelatedField(fieldName);\r\n if (!resolved) {\r\n return null;\r\n }\r\n\r\n return { ...parsed, ...resolved };\r\n}\r\n","/**\r\n * Transport layer types for abstracting communication with Fireberry\r\n * Supports both HTTP API and SDK iframe messaging\r\n */\r\n\r\nimport type { QueryOptions, QueryResult } from './query';\r\nimport type { FireberryRecord } from './records';\r\nimport type { FireberrySDKClient } from './sdk';\r\n\r\n/**\r\n * Generic transport request options\r\n */\r\nexport interface TransportRequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\r\n endpoint: string;\r\n query?: Record<string, string | number | boolean>;\r\n body?: unknown;\r\n headers?: Record<string, string>;\r\n signal?: AbortSignal;\r\n}\r\n\r\n/**\r\n * Transport interface that both HTTP and SDK implementations must follow\r\n */\r\nexport interface Transport {\r\n /**\r\n * Execute a raw request through this transport\r\n */\r\n request<T = unknown>(options: TransportRequestOptions): Promise<T>;\r\n\r\n /**\r\n * Execute a query operation\r\n */\r\n query(options: QueryOptions): Promise<QueryResult>;\r\n\r\n /**\r\n * Create a record\r\n */\r\n createRecord(objectType: string, data: FireberryRecord, signal?: AbortSignal): Promise<FireberryRecord>;\r\n\r\n /**\r\n * Update a record\r\n */\r\n updateRecord(\r\n objectType: string,\r\n recordId: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord>;\r\n\r\n /**\r\n * Delete a record\r\n */\r\n deleteRecord(\r\n objectType: string,\r\n recordId: string,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; id: string }>;\r\n\r\n /**\r\n * Batch create records\r\n */\r\n batchCreate(\r\n objectType: string,\r\n records: FireberryRecord[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }>;\r\n\r\n /**\r\n * Batch update records\r\n */\r\n batchUpdate(\r\n objectType: string,\r\n records: Array<{ id: string; record: FireberryRecord }>,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }>;\r\n\r\n /**\r\n * Batch delete records\r\n */\r\n batchDelete(\r\n objectType: string,\r\n recordIds: string[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; ids: string[]; count: number }>;\r\n\r\n /**\r\n * Get the transport type\r\n */\r\n getType(): 'http' | 'sdk';\r\n}\r\n\r\n/**\r\n * Configuration for HTTP transport\r\n */\r\nexport interface HTTPTransportConfig {\r\n apiKey: string;\r\n baseUrl?: string;\r\n timeout?: number;\r\n retryOn429?: boolean;\r\n maxRetries?: number;\r\n retryDelay?: number;\r\n}\r\n\r\n/**\r\n * Configuration for SDK transport\r\n */\r\nexport interface SDKTransportConfig {\r\n sdk: FireberrySDKClient;\r\n}\r\n\r\n/**\r\n * Union type for transport configuration\r\n */\r\nexport type TransportConfig = HTTPTransportConfig | SDKTransportConfig;\r\n\r\n/**\r\n * Type guard to check if config is HTTP transport config\r\n */\r\nexport function isHTTPTransportConfig(config: TransportConfig): config is HTTPTransportConfig {\r\n return 'apiKey' in config;\r\n}\r\n\r\n/**\r\n * Type guard to check if config is SDK transport config\r\n */\r\nexport function isSDKTransportConfig(config: TransportConfig): config is SDKTransportConfig {\r\n return 'sdk' in config;\r\n}\r\n","/**\r\n * Object Type ID to Name Field Mapping\r\n * Maps Fireberry object type IDs to their display name field\r\n * Generated from actual API responses\r\n */\r\nexport const OBJECT_NAME_MAP: Record<number, string> = {\r\n 1: 'accountname', // Account\r\n 2: 'fullname', // Contact\r\n 3: 'fullname', // Lead\r\n 4: 'name', // Opportunity\r\n 5: 'title', // Cases\r\n 6: 'subject', // Activity\r\n 7: 'notetext', // Note\r\n 8: 'competitorname', // Competitor\r\n 9: 'fullname', // CrmUser\r\n 10: 'subject', // Task\r\n 12: 'quotenumber', // Quote\r\n 13: 'crmordernumber', // CrmOrder\r\n 14: 'name', // Product\r\n 17: 'productname', // CrmOrderItem\r\n 20: 'title', // EmailTemplate\r\n 23: 'name', // BusinessUnit\r\n 25: 'orgname', // Org\r\n 27: 'name', // PrintTemplate\r\n 28: 'contractname', // Contract\r\n 33: 'productid', // AccountProduct (uses productid as display)\r\n 46: 'projectname', // Project\r\n 55: 'rulename', // WFRule\r\n 58: 'name', // MDObject\r\n 64: 'rolename', // Role\r\n 67: 'campaignname', // Campaign\r\n 70: 'browsername', // CrmUserLogin\r\n 73: 'label', // SystemField (using label as name field)\r\n 76: 'articlename', // Article\r\n 77: 'linkname', // Link\r\n 78: 'invoicenumber', // Invoice\r\n 80: 'documentnumber', // InvoiceReceiptItem\r\n 81: 'invoicenumber', // InvoiceNo\r\n 82: 'invoicenumber', // InvoiceDraft\r\n 83: 'invoicenumber', // InvoiceReceipt\r\n 84: 'invoicenumber', // InvoiceReno\r\n 85: 'invoicenumber', // InvoiceCredit\r\n 86: 'invoicenumber', // InvoiceDelivery\r\n 89: 'name', // IpRestriction\r\n 90: 'documentnumber', // TransactionItem\r\n 93: 'name', // Charge\r\n 100: 'callerid', // calllog\r\n 101: 'name', // AttendanceClock\r\n 102: 'activitylognumber', // ActivityLog\r\n 104: 'subject', // Conversation\r\n 105: 'name', // TeamInbox\r\n 106: 'name', // TextTemplate\r\n 107: 'name', // FacebookConnection\r\n 109: 'name', // AuditLog\r\n 110: 'name', // SMSTemplate\r\n 111: 'name', // ProviderVerification\r\n 114: 'name', // CalendarResource\r\n 115: 'name', // Journey\r\n 116: 'name', // Profile\r\n 117: 'name', // LandingPage\r\n};\r\n\r\n/**\r\n * Gets the display name field for a given object type\r\n *\r\n * @param objectTypeId - The numeric object type ID\r\n * @returns The name field for the object type\r\n */\r\nexport function getNameFieldByObjectType(objectTypeId: string | number): string {\r\n const objectTypeNum =\r\n typeof objectTypeId === 'string' ? parseInt(objectTypeId, 10) : objectTypeId;\r\n\r\n // Check if it's a mapped base object\r\n if (OBJECT_NAME_MAP[objectTypeNum]) {\r\n return OBJECT_NAME_MAP[objectTypeNum];\r\n }\r\n\r\n // For custom objects (1000 and up), use 'name'\r\n if (objectTypeNum >= 1000) {\r\n return 'name';\r\n }\r\n\r\n // Fallback to 'name' for unmapped objects\r\n return 'name';\r\n}\r\n","// Field type constants\r\nexport { FIELD_TYPE_IDS, FIELD_TYPE_MAPPINGS } from './fieldTypes';\r\n\r\n// Object ID mappings\r\nexport { OBJECT_ID_MAP, getObjectIdFieldName } from './objectIds';\r\n\r\n// Object name mappings\r\nexport { OBJECT_NAME_MAP, getNameFieldByObjectType } from './objectNames';\r\n\r\n// Excluded fields for star queries and lookup relations\r\nexport {\r\n EXCLUDED_FIELDS_FOR_STAR_QUERY,\r\n EXCLUDED_LOOKUP_FIELDS,\r\n isExcludedFromStarQuery,\r\n getExcludedFieldsForStarQuery,\r\n} from './excludedFields';\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants/excludedFields.ts","../src/errors.ts","../src/constants/objectIds.ts","../src/utils/queryBuilder.ts","../src/utils/helpers.ts","../src/transport/http.ts","../src/transport/sdk.ts","../src/utils/transport.ts","../src/constants/fieldTypes.ts","../src/api/metadata.ts","../src/api/records.ts","../src/api/batch.ts","../src/api/fields.ts","../src/api/files.ts","../src/client.ts","../src/utils/fieldMapping.ts","../src/utils/relatedFieldMapping.ts","../src/types/transport.ts","../src/constants/objectNames.ts","../src/constants/index.ts"],"names":["EXCLUDED_FIELDS_FOR_STAR_QUERY","FireberryErrorCode","BATCH_SIZE","getExcludedFieldsForStarQuery","codeFieldMeta"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Fields to exclude from queries when using '*' (all fields) for specific object types\r\n * These fields cause API errors when queried\r\n */\r\nexport const EXCLUDED_FIELDS_FOR_STAR_QUERY: Record<string, string[]> = {\r\n '7': ['deletedon', 'deletedby'], // Note\r\n '8': ['deletedon', 'deletedby', 's', 'w', 'o', 't', 'description'], // Competitor\r\n '114': ['deletedon', 'deletedby'], // Calendar Resource\r\n '115': ['deletedon', 'deletedby'], // Customer Journey\r\n '116': ['deletedon', 'deletedby'], // Profile\r\n '117': ['deletedon', 'deletedby'], // Landing Page\r\n};\r\n\r\n/**\r\n * Fields to exclude from lookup relation queries across ALL object types\r\n * These fields cause API errors when queried for lookup relationships\r\n */\r\nexport const EXCLUDED_LOOKUP_FIELDS: string[] = ['deletedby', 'deletedon'];\r\n\r\n/**\r\n * Checks if a field should be excluded from star queries for a given object type\r\n *\r\n * @param objectType - The object type ID\r\n * @param fieldName - The field name to check\r\n * @returns True if the field should be excluded\r\n */\r\nexport function isExcludedFromStarQuery(objectType: string | number, fieldName: string): boolean {\r\n const objectTypeStr = String(objectType);\r\n const excludedFields = EXCLUDED_FIELDS_FOR_STAR_QUERY[objectTypeStr];\r\n return excludedFields ? excludedFields.includes(fieldName) : false;\r\n}\r\n\r\n/**\r\n * Gets the list of excluded fields for a given object type\r\n *\r\n * @param objectType - The object type ID\r\n * @returns Array of field names to exclude, or empty array if none\r\n */\r\nexport function getExcludedFieldsForStarQuery(objectType: string | number): string[] {\r\n const objectTypeStr = String(objectType);\r\n return EXCLUDED_FIELDS_FOR_STAR_QUERY[objectTypeStr] || [];\r\n}\r\n","/**\r\n * Error codes for Fireberry API errors\r\n */\r\nexport enum FireberryErrorCode {\r\n /** Unknown or unexpected error */\r\n UNKNOWN = 'UNKNOWN',\r\n /** Network error (connection failed, DNS, etc.) */\r\n NETWORK_ERROR = 'NETWORK_ERROR',\r\n /** Request timeout */\r\n TIMEOUT = 'TIMEOUT',\r\n /** Authentication failed (invalid API key) */\r\n AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED',\r\n /** Authorization failed (missing permissions) */\r\n AUTHORIZATION_FAILED = 'AUTHORIZATION_FAILED',\r\n /** Resource not found */\r\n NOT_FOUND = 'NOT_FOUND',\r\n /** Rate limit exceeded (429) */\r\n RATE_LIMITED = 'RATE_LIMITED',\r\n /** Invalid request parameters */\r\n INVALID_REQUEST = 'INVALID_REQUEST',\r\n /** Server error (5xx) */\r\n SERVER_ERROR = 'SERVER_ERROR',\r\n /** Request was aborted */\r\n ABORTED = 'ABORTED',\r\n /** Invalid response from API */\r\n INVALID_RESPONSE = 'INVALID_RESPONSE',\r\n}\r\n\r\n/**\r\n * Options for creating a FireberryError\r\n */\r\nexport interface FireberryErrorOptions {\r\n /** Error code */\r\n code: FireberryErrorCode;\r\n /** HTTP status code if applicable */\r\n statusCode?: number;\r\n /** Original error that caused this error */\r\n cause?: Error;\r\n /** Additional context data */\r\n context?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Custom error class for Fireberry API errors\r\n */\r\nexport class FireberryError extends Error {\r\n /** Error code */\r\n readonly code: FireberryErrorCode;\r\n /** HTTP status code if applicable */\r\n readonly statusCode?: number;\r\n /** Original error that caused this error */\r\n readonly cause?: Error;\r\n /** Additional context data */\r\n readonly context?: Record<string, unknown>;\r\n\r\n constructor(message: string, options: FireberryErrorOptions) {\r\n super(message);\r\n this.name = 'FireberryError';\r\n this.code = options.code;\r\n this.statusCode = options.statusCode;\r\n this.cause = options.cause;\r\n this.context = options.context;\r\n\r\n // Maintains proper stack trace in V8 environments\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, FireberryError);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a string representation of the error\r\n */\r\n toString(): string {\r\n let str = `${this.name} [${this.code}]: ${this.message}`;\r\n if (this.statusCode) {\r\n str += ` (HTTP ${this.statusCode})`;\r\n }\r\n return str;\r\n }\r\n\r\n /**\r\n * Converts the error to a plain object for logging/serialization\r\n */\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n code: this.code,\r\n statusCode: this.statusCode,\r\n context: this.context,\r\n stack: this.stack,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Creates an error from an HTTP response\r\n */\r\nexport function createErrorFromResponse(\r\n response: Response,\r\n body?: unknown,\r\n): FireberryError {\r\n const status = response.status;\r\n let code: FireberryErrorCode;\r\n let message: string;\r\n\r\n switch (status) {\r\n case 400:\r\n code = FireberryErrorCode.INVALID_REQUEST;\r\n message = 'Invalid request parameters';\r\n break;\r\n case 401:\r\n code = FireberryErrorCode.AUTHENTICATION_FAILED;\r\n message = 'Authentication failed - invalid or missing API key';\r\n break;\r\n case 403:\r\n code = FireberryErrorCode.AUTHORIZATION_FAILED;\r\n message = 'Authorization failed - insufficient permissions';\r\n break;\r\n case 404:\r\n code = FireberryErrorCode.NOT_FOUND;\r\n message = 'Resource not found';\r\n break;\r\n case 429:\r\n code = FireberryErrorCode.RATE_LIMITED;\r\n message = 'Rate limit exceeded - too many requests';\r\n break;\r\n default:\r\n if (status >= 500) {\r\n code = FireberryErrorCode.SERVER_ERROR;\r\n message = `Server error (${status})`;\r\n } else {\r\n code = FireberryErrorCode.UNKNOWN;\r\n message = `HTTP error ${status}`;\r\n }\r\n }\r\n\r\n // Try to extract error message from response body\r\n if (body && typeof body === 'object') {\r\n const bodyObj = body as Record<string, unknown>;\r\n if (typeof bodyObj.message === 'string') {\r\n message = bodyObj.message;\r\n } else if (typeof bodyObj.error === 'string') {\r\n message = bodyObj.error;\r\n }\r\n }\r\n\r\n return new FireberryError(message, {\r\n code,\r\n statusCode: status,\r\n context: { body },\r\n });\r\n}\r\n\r\n/**\r\n * Creates an error from a network/fetch error\r\n */\r\nexport function createNetworkError(error: Error): FireberryError {\r\n // Check for abort\r\n if (error.name === 'AbortError') {\r\n return new FireberryError('Request was aborted', {\r\n code: FireberryErrorCode.ABORTED,\r\n cause: error,\r\n });\r\n }\r\n\r\n // Check for timeout\r\n if (error.name === 'TimeoutError' || error.message.includes('timeout')) {\r\n return new FireberryError('Request timed out', {\r\n code: FireberryErrorCode.TIMEOUT,\r\n cause: error,\r\n });\r\n }\r\n\r\n return new FireberryError(`Network error: ${error.message}`, {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n cause: error,\r\n });\r\n}\r\n","/**\r\n * Object Type ID to Primary Key Field Mapping\r\n * Maps Fireberry object type IDs to their primary key field names\r\n * Generated from actual API responses\r\n */\r\nexport const OBJECT_ID_MAP: Record<number, string> = {\r\n 1: 'accountid', // Account\r\n 2: 'contactid', // Contact\r\n 3: 'leadid', // Lead\r\n 4: 'opportunityid', // Opportunity\r\n 5: 'casesid', // Cases\r\n 6: 'activityid', // Activity\r\n 7: 'noteid', // Note\r\n 8: 'competitorid', // Competitor\r\n 9: 'crmuserid', // CrmUser\r\n 10: 'taskid', // Task\r\n 12: 'quoteid', // Quote\r\n 13: 'crmorderid', // CrmOrder\r\n 14: 'productid', // Product\r\n 17: 'crmorderitemid', // CrmOrderItem\r\n 20: 'emailtemplateid', // EmailTemplate\r\n 23: 'businessunitid', // BusinessUnit\r\n 25: 'orgid', // Org\r\n 27: 'printtemplateid', // PrintTemplate\r\n 28: 'contractid', // Contract\r\n 33: 'accountproductid', // AccountProduct\r\n 46: 'projectid', // Project\r\n 55: 'wfruleid', // WFRule\r\n 58: 'mdobjectid', // MDObject\r\n 64: 'roleid', // Role\r\n 67: 'campaignid', // Campaign\r\n 70: 'crmuserloginid', // CrmUserLogin\r\n 73: 'systemfieldid', // SystemField\r\n 76: 'articleid', // Article\r\n 77: 'linkid', // Link\r\n 78: 'invoiceid', // Invoice\r\n 80: 'invoicereceiptitemid', // InvoiceReceiptItem\r\n 81: 'invoiceid', // InvoiceNo\r\n 82: 'invoiceid', // InvoiceDraft\r\n 83: 'invoiceid', // InvoiceReceipt\r\n 84: 'invoiceid', // InvoiceReno\r\n 85: 'invoiceid', // InvoiceCredit\r\n 86: 'invoiceid', // InvoiceDelivery\r\n 89: 'iprestrictionid', // IpRestriction\r\n 90: 'transactionitemid', // TransactionItem\r\n 93: 'chargeid', // Charge\r\n 100: 'calllogid', // calllog\r\n 101: 'attendanceclockid', // AttendanceClock\r\n 102: 'activitylogid', // ActivityLog\r\n 104: 'conversationid', // Conversation\r\n 105: 'teaminboxid', // TeamInbox\r\n 106: 'texttemplateid', // TextTemplate\r\n 107: 'facebookconnectionid', // FacebookConnection\r\n 109: 'auditlogid', // AuditLog\r\n 110: 'smstemplateid', // SMSTemplate\r\n 111: 'providerverificationid', // ProviderVerification\r\n 114: 'calendarresourceid', // CalendarResource\r\n 115: 'journeyid', // Journey\r\n 116: 'profileid', // Profile\r\n 117: 'landingpageid', // LandingPage\r\n};\r\n\r\n/**\r\n * Gets the primary key field name for a given object type\r\n *\r\n * @param objectTypeId - The numeric object type ID\r\n * @returns The correct ID field name for the object type\r\n */\r\nexport function getObjectIdFieldName(objectTypeId: string | number): string {\r\n const objectTypeNum =\r\n typeof objectTypeId === 'string' ? parseInt(objectTypeId, 10) : objectTypeId;\r\n\r\n // Check if it's a mapped base object\r\n if (OBJECT_ID_MAP[objectTypeNum]) {\r\n return OBJECT_ID_MAP[objectTypeNum];\r\n }\r\n\r\n // For custom objects (1000 and up), use the pattern customobjectXid\r\n if (objectTypeNum >= 1000) {\r\n return `customobject${objectTypeNum}id`;\r\n }\r\n\r\n // Fallback to generic 'id' for unmapped objects\r\n return 'id';\r\n}\r\n","import type { QueryOperator, QueryMetadata, QueryResultWithMetadata, QueryExplainResult } from '../types/query';\r\nimport { getObjectIdFieldName } from '../constants/objectIds';\r\n\r\n/**\r\n * Regular expression to match pure date format (YYYY-MM-DD).\r\n * Does not match datetime formats like YYYY-MM-DDTHH:MM:SS or YYYY-MM-DD HH:MM:SS.\r\n */\r\nconst PURE_DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n\r\n/**\r\n * Checks if a value is a pure date string (YYYY-MM-DD format).\r\n * Returns false for datetime formats that include time components.\r\n *\r\n * @param value - The value to check\r\n * @returns True if the value is a pure date string\r\n *\r\n * @example\r\n * isPureDate('2024-01-15') // true\r\n * isPureDate('2024-01-15T10:30:00') // false\r\n * isPureDate('2024-01-15 10:30:00') // false\r\n * isPureDate('123') // false\r\n */\r\nexport function isPureDate(value: string): boolean {\r\n return PURE_DATE_REGEX.test(value);\r\n}\r\n\r\n/**\r\n * Adds a specified number of days to a date string.\r\n * Works with both pure dates (YYYY-MM-DD) and datetime formats.\r\n *\r\n * @param dateStr - The date string to modify\r\n * @param days - Number of days to add (can be negative)\r\n * @returns The modified date in YYYY-MM-DD format\r\n *\r\n * @example\r\n * addDays('2024-01-15', 1) // '2024-01-16'\r\n * addDays('2024-01-31', 1) // '2024-02-01'\r\n * addDays('2024-03-01', -1) // '2024-02-29' (leap year)\r\n */\r\nexport function addDays(dateStr: string, days: number): string {\r\n // Extract just the date part if datetime format\r\n const datePart = dateStr.split(/[T\\s]/)[0];\r\n const date = new Date(datePart + 'T00:00:00');\r\n date.setDate(date.getDate() + days);\r\n\r\n const year = date.getFullYear();\r\n const month = String(date.getMonth() + 1).padStart(2, '0');\r\n const day = String(date.getDate()).padStart(2, '0');\r\n\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Escapes special characters in query values to prevent query injection.\r\n * This is a security measure to ensure user-provided values cannot modify\r\n * the query structure or inject additional query logic.\r\n *\r\n * @param value - The value to escape\r\n * @returns Escaped value safe for use in Fireberry queries\r\n */\r\nexport function escapeQueryValue(value: string): string {\r\n if (!value) {\r\n return '';\r\n }\r\n // Escape backslashes first to avoid double-escaping\r\n let escaped = value.replace(/\\\\/g, '\\\\\\\\');\r\n // Escape parentheses which could break out of conditions\r\n escaped = escaped.replace(/\\(/g, '\\\\(');\r\n escaped = escaped.replace(/\\)/g, '\\\\)');\r\n // Escape logical operators that could inject additional conditions\r\n // Using word boundaries to only match standalone operators\r\n escaped = escaped.replace(/\\bor\\b/gi, '\\\\or');\r\n escaped = escaped.replace(/\\band\\b/gi, '\\\\and');\r\n return escaped;\r\n}\r\n\r\n/**\r\n * Sanitizes a query string to ensure proper syntax for the Fireberry API\r\n * Handles common syntax issues and removes extraneous elements\r\n *\r\n * @param query - Query string to sanitize\r\n * @returns Sanitized query string\r\n */\r\nexport function sanitizeQuery(query: string): string {\r\n if (!query) {\r\n return '';\r\n }\r\n\r\n // First, protect special operators from being modified\r\n // Temporarily mark is-null and is-not-null operators\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+)\\s+(is-null|is-not-null)\\s*\\)/g,\r\n '($1 __SPECIAL_OPERATOR__$2)',\r\n );\r\n\r\n // Also protect text operators like start-with, not-start-with\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+)\\s+(start-with|not-start-with)\\s+([^)]+)\\s*\\)/g,\r\n '($1 __TEXT_OPERATOR__$2 $3)',\r\n );\r\n\r\n // Fix missing operators: (field value) -> (field = value)\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+(?:field|Field|system|System)[0-9]*)\\s+(?!__SPECIAL_OPERATOR__|__TEXT_OPERATOR__)([^()<>=!]+)\\s*\\)/g,\r\n '($1 = $2)',\r\n );\r\n\r\n // Fix with a more general pattern for any field-value pair without operator\r\n query = query.replace(\r\n /\\(\\s*([a-zA-Z0-9_]+)\\s+(?!__SPECIAL_OPERATOR__|__TEXT_OPERATOR__|<=|>=|!=|<|>|=\\s)([^()<>]+)\\s*\\)/g,\r\n '($1 = $2)',\r\n );\r\n\r\n // Restore special operators\r\n query = query.replace(/__SPECIAL_OPERATOR__/g, '');\r\n query = query.replace(/__TEXT_OPERATOR__/g, '');\r\n\r\n // Remove parentheses containing only a comparison operator\r\n query = query.replace(/\\(\\s*(?:<=|>=|!=|<|>|=)\\s*\\)/g, '');\r\n // Remove parentheses containing only text operators\r\n query = query.replace(/\\(\\s*(?:start-with|not-start-with)\\s*\\)/gi, '');\r\n // Remove parentheses containing only logical operators (AND/OR)\r\n query = query.replace(/\\(\\s*(?:and|or)\\s*\\)/gi, '');\r\n // Remove empty parentheses\r\n query = query.replace(/\\(\\s*\\)/g, '');\r\n // Remove logical operators without operands at start/end\r\n query = query.replace(/^\\s*(and|or)\\s*/gi, '');\r\n query = query.replace(/\\s*(and|or)\\s*$/gi, '');\r\n // Remove redundant nested parentheses: ((x)) -> (x)\r\n const nestedPattern = /\\(\\s*\\(([^()]+)\\)\\s*\\)/g;\r\n while (nestedPattern.test(query)) {\r\n query = query.replace(nestedPattern, '($1)');\r\n }\r\n // Collapse multiple spaces\r\n query = query.replace(/\\s+/g, ' ');\r\n return query.trim();\r\n}\r\n\r\n/**\r\n * Gets today's date in YYYY-MM-DD format\r\n */\r\nexport function getToday(): string {\r\n const now = new Date();\r\n const year = now.getFullYear();\r\n const month = String(now.getMonth() + 1).padStart(2, '0');\r\n const day = String(now.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${day}`;\r\n}\r\n\r\n/**\r\n * Gets the start of current week (Monday) in YYYY-MM-DD format\r\n */\r\nexport function getStartOfWeek(): string {\r\n const now = new Date();\r\n const day = now.getDay();\r\n // Adjust so Monday is first day (day 0 = Sunday, so Monday = 1)\r\n const diff = now.getDate() - day + (day === 0 ? -6 : 1);\r\n const monday = new Date(now);\r\n monday.setDate(diff);\r\n const year = monday.getFullYear();\r\n const month = String(monday.getMonth() + 1).padStart(2, '0');\r\n const dayStr = String(monday.getDate()).padStart(2, '0');\r\n return `${year}-${month}-${dayStr}`;\r\n}\r\n\r\n/**\r\n * Gets the start of current month in YYYY-MM-DD format\r\n */\r\nexport function getStartOfMonth(): string {\r\n const now = new Date();\r\n const year = now.getFullYear();\r\n const month = String(now.getMonth() + 1).padStart(2, '0');\r\n return `${year}-${month}-01`;\r\n}\r\n\r\n/**\r\n * Date condition builder for fluent date query construction\r\n */\r\nexport interface DateConditionBuilder {\r\n /** Records from today */\r\n today(): QueryBuilder;\r\n /** Records from this week (Monday to now) */\r\n thisWeek(): QueryBuilder;\r\n /** Records from this month */\r\n thisMonth(): QueryBuilder;\r\n /** Records between two dates (inclusive) */\r\n between(startDate: string, endDate: string): QueryBuilder;\r\n /** Records from the last N days (including today) */\r\n daysAgo(days: number): QueryBuilder;\r\n /** Records before date */\r\n before(date: string): QueryBuilder;\r\n /** Records after date */\r\n after(date: string): QueryBuilder;\r\n /** Records on or before date */\r\n onOrBefore(date: string): QueryBuilder;\r\n /** Records on or after date */\r\n onOrAfter(date: string): QueryBuilder;\r\n}\r\n\r\n/**\r\n * Condition builder for fluent query construction\r\n */\r\nexport interface ConditionBuilder {\r\n /** Equals comparison (=) */\r\n equals(value: string | number): QueryBuilder;\r\n /** Not equals comparison (!=) */\r\n notEquals(value: string | number): QueryBuilder;\r\n /** IN comparison - matches any of the provided values (joined with OR) */\r\n in(values: (string | number)[]): QueryBuilder;\r\n /** Less than comparison (<) - works with numbers and dates */\r\n lessThan(value: string | number): QueryBuilder;\r\n /** Greater than comparison (>) - works with numbers and dates */\r\n greaterThan(value: string | number): QueryBuilder;\r\n /** Less than or equal (<=) - auto-converts pure dates (YYYY-MM-DD) to < nextDay */\r\n lessThanOrEqual(value: string | number): QueryBuilder;\r\n /** Greater than or equal (>=) - works with numbers and dates */\r\n greaterThanOrEqual(value: string | number): QueryBuilder;\r\n /** Contains value (translates to start-with %value) */\r\n contains(value: string): QueryBuilder;\r\n /** Does not contain value (translates to not-start-with %value) */\r\n notContains(value: string): QueryBuilder;\r\n /** Starts with value (start-with) */\r\n startsWith(value: string): QueryBuilder;\r\n /** Does not start with value (not-start-with) */\r\n notStartsWith(value: string): QueryBuilder;\r\n /** Field is null (is-null) */\r\n isNull(): QueryBuilder;\r\n /** Field is not null (is-not-null) */\r\n isNotNull(): QueryBuilder;\r\n}\r\n\r\n/**\r\n * Internal representation of a query condition\r\n */\r\ninterface QueryCondition {\r\n field: string;\r\n operator: QueryOperator;\r\n value?: string;\r\n}\r\n\r\n/**\r\n * Fluent query builder for constructing Fireberry queries\r\n *\r\n * @example\r\n * ```typescript\r\n * // Build a query string\r\n * const query = new QueryBuilder()\r\n * .where('statuscode').equals('1')\r\n * .and()\r\n * .where('emailaddress1').contains('@example.com')\r\n * .build();\r\n * // Output: \"(statuscode = 1) and (emailaddress1 start-with %@example.com)\"\r\n *\r\n * // With select and execute (requires client)\r\n * const result = await new QueryBuilder(client)\r\n * .objectType('1')\r\n * .select('accountid', 'name', 'emailaddress1')\r\n * .where('statuscode').equals('1')\r\n * .limit(100)\r\n * .execute();\r\n * ```\r\n */\r\n/**\r\n * Client interface for query execution\r\n */\r\ninterface QueryClient {\r\n query(options: {\r\n objectType: string;\r\n fields: string[];\r\n query: string;\r\n showRealValue: boolean;\r\n sortBy?: string;\r\n sortType?: 'asc' | 'desc';\r\n limit?: number;\r\n page?: number;\r\n signal?: AbortSignal;\r\n }): Promise<QueryResult>;\r\n}\r\n\r\n/**\r\n * Query result type\r\n */\r\ninterface QueryResult {\r\n records: Record<string, unknown>[];\r\n total: number;\r\n success: boolean;\r\n}\r\n\r\nexport class QueryBuilder {\r\n private conditions: QueryCondition[] = [];\r\n private joinOperators: ('and' | 'or')[] = [];\r\n private currentField: string | null = null;\r\n private selectedFields: string[] = [];\r\n private objectTypeId: string | null = null;\r\n private sortByField: string | null = null;\r\n private sortDirection: 'asc' | 'desc' = 'desc';\r\n private limitValue: number | null = null;\r\n private pageNumber: number = 1;\r\n private showRealValueFlag: boolean = true;\r\n private client: QueryClient | null = null;\r\n\r\n /**\r\n * Creates a new QueryBuilder\r\n * @param client - Optional FireberryClient for executing queries\r\n */\r\n constructor(client?: QueryClient) {\r\n this.client = client ?? null;\r\n }\r\n\r\n /**\r\n * Sets the object type for the query\r\n * @param objectType - Object type ID (e.g., '1' for Account)\r\n */\r\n objectType(objectType: string | number): this {\r\n this.objectTypeId = String(objectType);\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds fields to select\r\n * @param fields - Field names to select\r\n */\r\n select(...fields: string[]): this {\r\n this.selectedFields.push(...fields);\r\n return this;\r\n }\r\n\r\n /**\r\n * Starts a new WHERE condition\r\n * @param field - Field name to filter on\r\n */\r\n where(field: string): ConditionBuilder {\r\n this.currentField = field;\r\n return this.createConditionBuilder();\r\n }\r\n\r\n /**\r\n * Starts a new WHERE condition for a date field with date-specific helpers\r\n * @param field - Date field name to filter on\r\n *\r\n * @example\r\n * ```typescript\r\n * // Records created today\r\n * qb.whereDate('createdon').today()\r\n *\r\n * // Records from this week\r\n * qb.whereDate('createdon').thisWeek()\r\n *\r\n * // Records from the last 30 days\r\n * qb.whereDate('createdon').daysAgo(30)\r\n *\r\n * // Records between two dates\r\n * qb.whereDate('createdon').between('2024-01-01', '2024-12-31')\r\n * ```\r\n */\r\n whereDate(field: string): DateConditionBuilder {\r\n return this.createDateConditionBuilder(field);\r\n }\r\n\r\n /**\r\n * Adds a WHERE condition for the primary ID field, automatically mapped based on object type\r\n * @param value - The ID value to match\r\n * @throws Error if objectType is not set\r\n *\r\n * @example\r\n * ```typescript\r\n * // Instead of knowing the exact field name:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereId('abc123') // Automatically uses 'accountid' for object type 1\r\n * .execute();\r\n *\r\n * // Equivalent to:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .where('accountid').equals('abc123')\r\n * .execute();\r\n * ```\r\n */\r\n whereId(value: string | number): this {\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type must be set before using whereId(). Call .objectType() first.');\r\n }\r\n const idField = getObjectIdFieldName(this.objectTypeId);\r\n this.addCondition(idField, '=', String(value));\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds WHERE conditions for multiple primary ID values, joined with OR\r\n * @param values - Array of ID values to match\r\n * @throws Error if objectType is not set\r\n * @throws Error if values array is empty\r\n *\r\n * @example\r\n * ```typescript\r\n * // Query multiple accounts by ID:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereIds(['id1', 'id2', 'id3'])\r\n * .execute();\r\n *\r\n * // Generates: (accountid = id1) or (accountid = id2) or (accountid = id3)\r\n *\r\n * // Can be combined with other conditions:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereIds(['id1', 'id2'])\r\n * .and()\r\n * .where('statuscode').equals('1')\r\n * .execute();\r\n * ```\r\n */\r\n whereIds(values: (string | number)[]): this {\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type must be set before using whereIds(). Call .objectType() first.');\r\n }\r\n if (!values || values.length === 0) {\r\n throw new Error('whereIds() requires at least one ID value.');\r\n }\r\n const idField = getObjectIdFieldName(this.objectTypeId);\r\n\r\n // Add first condition\r\n this.addCondition(idField, '=', String(values[0]));\r\n\r\n // Add remaining conditions with OR\r\n for (let i = 1; i < values.length; i++) {\r\n this.joinOperators.push('or');\r\n this.addCondition(idField, '=', String(values[i]));\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a WHERE IN condition for a field with multiple values, joined with OR\r\n * @param field - Field name to filter on\r\n * @param values - Array of values to match\r\n * @throws Error if values array is empty\r\n *\r\n * @example\r\n * ```typescript\r\n * // Query accounts with specific status codes:\r\n * new QueryBuilder(client)\r\n * .objectType(1)\r\n * .whereIn('statuscode', [1, 2, 3])\r\n * .execute();\r\n *\r\n * // Generates: (statuscode = 1) or (statuscode = 2) or (statuscode = 3)\r\n * ```\r\n */\r\n whereIn(field: string, values: (string | number)[]): this {\r\n if (!values || values.length === 0) {\r\n throw new Error('whereIn() requires at least one value.');\r\n }\r\n // Add first condition\r\n this.addCondition(field, '=', String(values[0]));\r\n // Add remaining conditions with OR\r\n for (let i = 1; i < values.length; i++) {\r\n this.joinOperators.push('or');\r\n this.addCondition(field, '=', String(values[i]));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds an AND logical operator\r\n */\r\n and(): this {\r\n if (this.conditions.length > 0) {\r\n this.joinOperators.push('and');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds an OR logical operator\r\n */\r\n or(): this {\r\n if (this.conditions.length > 0) {\r\n this.joinOperators.push('or');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the sort field and direction\r\n * @param field - Field to sort by\r\n * @param direction - Sort direction ('asc' or 'desc')\r\n */\r\n sortBy(field: string, direction: 'asc' | 'desc' = 'desc'): this {\r\n this.sortByField = field;\r\n this.sortDirection = direction;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the maximum number of records to return\r\n * @param count - Maximum record count\r\n */\r\n limit(count: number): this {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the page number for pagination\r\n * @param page - Page number (1-based)\r\n */\r\n page(page: number): this {\r\n this.pageNumber = page;\r\n return this;\r\n }\r\n\r\n /**\r\n * Controls whether to show real values (labels) for dropdown fields\r\n * @param show - Whether to show real values (default: true)\r\n */\r\n showRealValue(show: boolean): this {\r\n this.showRealValueFlag = show;\r\n return this;\r\n }\r\n\r\n /**\r\n * Builds the query string from conditions\r\n * @returns The built query string\r\n */\r\n build(): string {\r\n if (this.conditions.length === 0) {\r\n return '';\r\n }\r\n\r\n const parts: string[] = [];\r\n\r\n for (let i = 0; i < this.conditions.length; i++) {\r\n const condition = this.conditions[i];\r\n let conditionStr: string;\r\n\r\n if (condition.operator === 'is-null' || condition.operator === 'is-not-null') {\r\n conditionStr = `(${condition.field} ${condition.operator})`;\r\n } else {\r\n const escapedValue = escapeQueryValue(condition.value || '');\r\n conditionStr = `(${condition.field} ${condition.operator} ${escapedValue})`;\r\n }\r\n\r\n parts.push(conditionStr);\r\n\r\n // Add join operator if there's a next condition\r\n if (i < this.joinOperators.length) {\r\n parts.push(this.joinOperators[i]);\r\n }\r\n }\r\n\r\n return parts.join(' ');\r\n }\r\n\r\n /**\r\n * Returns the selected fields array\r\n * Useful for inspecting the query configuration\r\n */\r\n getFields(): string[] {\r\n return [...this.selectedFields];\r\n }\r\n\r\n /**\r\n * Converts the query builder state to a payload compatible with @fireberry/sdk\r\n *\r\n * @returns Object with `fields` (comma-separated string) and `query` (filter string)\r\n *\r\n * @example\r\n * ```typescript\r\n * import FireberryClientSDK from '@fireberry/sdk/client';\r\n * import { QueryBuilder } from 'fireberry-api-client';\r\n *\r\n * const sdk = new FireberryClientSDK();\r\n * await sdk.initializeContext();\r\n *\r\n * const payload = new QueryBuilder()\r\n * .select('accountid', 'accountname')\r\n * .where('statuscode').equals('1')\r\n * .toSDKPayload();\r\n *\r\n * // Use with SDK\r\n * const results = await sdk.api.query(1, payload);\r\n * ```\r\n */\r\n toSDKPayload(): { fields: string; query: string; page_size?: number; page_number?: number } {\r\n const payload: { fields: string; query: string; page_size?: number; page_number?: number } = {\r\n fields: this.selectedFields.length > 0 ? this.selectedFields.join(',') : '*',\r\n query: this.build(),\r\n };\r\n\r\n if (this.limitValue !== null) {\r\n payload.page_size = this.limitValue;\r\n }\r\n\r\n if (this.pageNumber > 1) {\r\n payload.page_number = this.pageNumber;\r\n }\r\n\r\n return payload;\r\n }\r\n\r\n /**\r\n * Executes the query and returns the count of matching records\r\n * Uses minimal field selection (ID only) for efficiency\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Number of matching records\r\n *\r\n * @example\r\n * ```typescript\r\n * const activeCount = await client.queryBuilder()\r\n * .objectType(1)\r\n * .where('statuscode').equals('1')\r\n * .count();\r\n *\r\n * console.log(`Found ${activeCount} active accounts`);\r\n * ```\r\n */\r\n async count(signal?: AbortSignal): Promise<number> {\r\n if (!this.client) {\r\n throw new Error('QueryBuilder requires a client to execute queries. Pass a FireberryClient to the constructor.');\r\n }\r\n\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type is required. Use .objectType() before executing.');\r\n }\r\n\r\n // Use minimal fields for efficiency - just get the ID field\r\n const idField = getObjectIdFieldName(this.objectTypeId);\r\n\r\n const result = await this.client.query({\r\n objectType: this.objectTypeId,\r\n fields: [idField],\r\n query: this.build(),\r\n showRealValue: false, // No need for labels\r\n signal,\r\n });\r\n\r\n return result.total;\r\n }\r\n\r\n /**\r\n * Executes the query and returns the first record or null\r\n * Automatically sets limit to 1 for efficiency\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns First record or null if no records found\r\n *\r\n * @example\r\n * ```typescript\r\n * const account = await client.queryBuilder()\r\n * .objectType(1)\r\n * .where('accountname').equals('Acme Corp')\r\n * .first();\r\n *\r\n * if (account) {\r\n * console.log(account.accountid);\r\n * }\r\n * ```\r\n */\r\n async first(signal?: AbortSignal): Promise<Record<string, unknown> | null> {\r\n // Temporarily set limit to 1 for efficiency\r\n const originalLimit = this.limitValue;\r\n this.limitValue = 1;\r\n\r\n try {\r\n const result = await this.execute(signal);\r\n return result.records[0] ?? null;\r\n } finally {\r\n // Restore original limit\r\n this.limitValue = originalLimit;\r\n }\r\n }\r\n\r\n /**\r\n * Executes the query (requires client to be set)\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Query results\r\n */\r\n async execute(signal?: AbortSignal): Promise<QueryResult> {\r\n if (!this.client) {\r\n throw new Error('QueryBuilder requires a client to execute queries. Pass a FireberryClient to the constructor.');\r\n }\r\n\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type is required. Use .objectType() before executing.');\r\n }\r\n\r\n const queryOptions: Parameters<QueryClient['query']>[0] = {\r\n objectType: this.objectTypeId,\r\n fields: this.selectedFields.length > 0 ? this.selectedFields : ['*'],\r\n query: this.build(),\r\n showRealValue: this.showRealValueFlag,\r\n };\r\n\r\n if (this.sortByField) {\r\n queryOptions.sortBy = this.sortByField;\r\n queryOptions.sortType = this.sortDirection;\r\n }\r\n\r\n if (this.limitValue !== null) {\r\n queryOptions.limit = this.limitValue;\r\n }\r\n\r\n if (this.pageNumber > 1) {\r\n queryOptions.page = this.pageNumber;\r\n }\r\n\r\n if (signal) {\r\n queryOptions.signal = signal;\r\n }\r\n\r\n return this.client.query(queryOptions);\r\n }\r\n\r\n /**\r\n * Executes the query and returns results with debugging metadata\r\n * Includes query string, fields, pagination info, and execution time\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Query results with metadata\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.queryBuilder()\r\n * .objectType(1)\r\n * .select('accountid', 'accountname')\r\n * .where('statuscode').equals('1')\r\n * .executeWithDebug();\r\n *\r\n * console.log('Query:', result.metadata.queryString);\r\n * console.log('Fields:', result.metadata.fields);\r\n * console.log('Execution time:', result.metadata.executionTimeMs, 'ms');\r\n * console.log('Records:', result.records.length);\r\n * ```\r\n */\r\n async executeWithDebug(signal?: AbortSignal): Promise<QueryResultWithMetadata> {\r\n if (!this.client) {\r\n throw new Error('QueryBuilder requires a client to execute queries. Pass a FireberryClient to the constructor.');\r\n }\r\n\r\n if (!this.objectTypeId) {\r\n throw new Error('Object type is required. Use .objectType() before executing.');\r\n }\r\n\r\n const startTime = Date.now();\r\n const fields = this.selectedFields.length > 0 ? this.selectedFields : ['*'];\r\n const queryString = this.build();\r\n\r\n const queryOptions: Parameters<QueryClient['query']>[0] = {\r\n objectType: this.objectTypeId,\r\n fields,\r\n query: queryString,\r\n showRealValue: this.showRealValueFlag,\r\n };\r\n\r\n if (this.sortByField) {\r\n queryOptions.sortBy = this.sortByField;\r\n queryOptions.sortType = this.sortDirection;\r\n }\r\n\r\n if (this.limitValue !== null) {\r\n queryOptions.limit = this.limitValue;\r\n }\r\n\r\n if (this.pageNumber > 1) {\r\n queryOptions.page = this.pageNumber;\r\n }\r\n\r\n if (signal) {\r\n queryOptions.signal = signal;\r\n }\r\n\r\n const result = await this.client.query(queryOptions);\r\n const executionTimeMs = Date.now() - startTime;\r\n\r\n const metadata: QueryMetadata = {\r\n objectType: this.objectTypeId,\r\n fields,\r\n queryString,\r\n pageNumber: this.pageNumber,\r\n pageSize: this.limitValue ?? 500,\r\n autoPage: true, // Default behavior\r\n executionTimeMs,\r\n };\r\n\r\n if (this.sortByField) {\r\n metadata.sortBy = this.sortByField;\r\n metadata.sortType = this.sortDirection;\r\n }\r\n\r\n if (this.limitValue !== null) {\r\n metadata.limit = this.limitValue;\r\n }\r\n\r\n return {\r\n ...result,\r\n metadata,\r\n };\r\n }\r\n\r\n /**\r\n * Analyzes the query without executing it (dry run)\r\n * Returns information about what the query will do, potential issues, and optimization suggestions\r\n *\r\n * @returns Query analysis with warnings and suggestions\r\n *\r\n * @example\r\n * ```typescript\r\n * const analysis = client.queryBuilder()\r\n * .objectType('1')\r\n * .select('*')\r\n * .where('statuscode').equals('1')\r\n * .explain();\r\n *\r\n * console.log('Query:', analysis.query);\r\n * console.log('Warnings:', analysis.warnings);\r\n * console.log('Suggestions:', analysis.suggestions);\r\n * console.log('Estimated API calls:', analysis.estimatedApiCalls);\r\n * ```\r\n */\r\n explain(): QueryExplainResult {\r\n const warnings: string[] = [];\r\n const suggestions: string[] = [];\r\n\r\n // Check object type\r\n if (!this.objectTypeId) {\r\n warnings.push('Object type is not set. Call .objectType() before executing.');\r\n }\r\n\r\n // Analyze fields\r\n const fields = this.selectedFields.length > 0 ? this.selectedFields : ['*'];\r\n const usesWildcard = fields.includes('*') || fields.length === 0;\r\n\r\n if (usesWildcard) {\r\n warnings.push('Using wildcard (*) fields may include unnecessary data and slow down queries.');\r\n suggestions.push('Consider selecting only the specific fields you need with .select()');\r\n }\r\n\r\n // Analyze query\r\n const queryString = this.build();\r\n const conditionCount = this.conditions.length;\r\n\r\n if (conditionCount === 0 && !this.limitValue) {\r\n warnings.push('No query conditions or limit set. This may return a large number of records.');\r\n suggestions.push('Add filters with .where() or set a .limit() to control result size.');\r\n }\r\n\r\n // Check for potential performance issues\r\n const hasContainsOperator = this.conditions.some(\r\n (c) => c.operator === 'start-with' && c.value?.startsWith('%'),\r\n );\r\n if (hasContainsOperator) {\r\n warnings.push('Contains queries (using % prefix) may be slower than exact matches.');\r\n }\r\n\r\n // Check for OR conditions (may affect performance)\r\n const hasOrConditions = this.joinOperators.some((op) => op === 'or');\r\n if (hasOrConditions && conditionCount > 5) {\r\n warnings.push('Multiple OR conditions may affect query performance.');\r\n suggestions.push('Consider breaking into separate queries if possible.');\r\n }\r\n\r\n // Sorting analysis\r\n const sortField = this.sortByField || 'modifiedon';\r\n const sortDirection = this.sortDirection;\r\n\r\n // Estimate API calls\r\n let estimatedApiCalls = 1;\r\n const pageSize = 500; // Default page size\r\n const willAutoPage = this.limitValue === null; // Auto-page when no limit\r\n\r\n if (willAutoPage && conditionCount === 0) {\r\n // Without conditions, could be many pages\r\n estimatedApiCalls = -1; // Unknown/many\r\n warnings.push('Without filters, query may require many API calls for pagination.');\r\n } else if (this.limitValue !== null) {\r\n estimatedApiCalls = Math.ceil(this.limitValue / pageSize);\r\n }\r\n\r\n // Check for missing index hints\r\n if (!this.sortByField && conditionCount > 0) {\r\n suggestions.push('Consider adding .sortBy() to control result ordering.');\r\n }\r\n\r\n // Check showRealValue impact\r\n if (this.showRealValueFlag) {\r\n suggestions.push('showRealValue is enabled (default). Set .showRealValue(false) if you only need IDs.');\r\n }\r\n\r\n return {\r\n objectType: this.objectTypeId || '(not set)',\r\n query: queryString || '(no conditions)',\r\n fields,\r\n usesWildcard,\r\n willAutoPage,\r\n limit: this.limitValue,\r\n pageSize,\r\n sorting: {\r\n field: sortField,\r\n direction: sortDirection,\r\n },\r\n estimatedApiCalls,\r\n warnings,\r\n suggestions,\r\n conditionCount,\r\n showRealValue: this.showRealValueFlag,\r\n };\r\n }\r\n\r\n /**\r\n * Creates a condition builder for the current field\r\n */\r\n private createConditionBuilder(): ConditionBuilder {\r\n const field = this.currentField!;\r\n\r\n return {\r\n equals: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '=', String(value));\r\n return this;\r\n },\r\n notEquals: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '!=', String(value));\r\n return this;\r\n },\r\n in: (values: (string | number)[]): QueryBuilder => {\r\n if (!values || values.length === 0) {\r\n throw new Error('in() requires at least one value.');\r\n }\r\n // Add first condition\r\n this.addCondition(field, '=', String(values[0]));\r\n // Add remaining conditions with OR\r\n for (let i = 1; i < values.length; i++) {\r\n this.joinOperators.push('or');\r\n this.addCondition(field, '=', String(values[i]));\r\n }\r\n return this;\r\n },\r\n lessThan: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '<', String(value));\r\n return this;\r\n },\r\n greaterThan: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '>', String(value));\r\n return this;\r\n },\r\n lessThanOrEqual: (value: string | number): QueryBuilder => {\r\n const strValue = String(value);\r\n // Fireberry API bug: <= with pure dates (YYYY-MM-DD) behaves like <\r\n // because it interprets the date as midnight (00:00:00).\r\n // Auto-convert to < nextDay for correct \"on or before\" behavior.\r\n if (isPureDate(strValue)) {\r\n const nextDay = addDays(strValue, 1);\r\n this.addCondition(field, '<', nextDay);\r\n } else {\r\n this.addCondition(field, '<=', strValue);\r\n }\r\n return this;\r\n },\r\n greaterThanOrEqual: (value: string | number): QueryBuilder => {\r\n this.addCondition(field, '>=', String(value));\r\n return this;\r\n },\r\n contains: (value: string): QueryBuilder => {\r\n // Contains translates to \"start-with %value\"\r\n this.addCondition(field, 'start-with', `%${value}`);\r\n return this;\r\n },\r\n notContains: (value: string): QueryBuilder => {\r\n // Not contains translates to \"not-start-with %value\"\r\n this.addCondition(field, 'not-start-with', `%${value}`);\r\n return this;\r\n },\r\n startsWith: (value: string): QueryBuilder => {\r\n this.addCondition(field, 'start-with', value);\r\n return this;\r\n },\r\n notStartsWith: (value: string): QueryBuilder => {\r\n this.addCondition(field, 'not-start-with', value);\r\n return this;\r\n },\r\n isNull: (): QueryBuilder => {\r\n this.addCondition(field, 'is-null');\r\n return this;\r\n },\r\n isNotNull: (): QueryBuilder => {\r\n this.addCondition(field, 'is-not-null');\r\n return this;\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Creates a date condition builder for the specified field\r\n */\r\n private createDateConditionBuilder(field: string): DateConditionBuilder {\r\n return {\r\n today: (): QueryBuilder => {\r\n const today = getToday();\r\n // Records from today: >= today AND < tomorrow\r\n this.addCondition(field, '>=', today);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', addDays(today, 1));\r\n return this;\r\n },\r\n thisWeek: (): QueryBuilder => {\r\n const startOfWeek = getStartOfWeek();\r\n const tomorrow = addDays(getToday(), 1);\r\n // Records from start of week to now: >= monday AND < tomorrow\r\n this.addCondition(field, '>=', startOfWeek);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', tomorrow);\r\n return this;\r\n },\r\n thisMonth: (): QueryBuilder => {\r\n const startOfMonth = getStartOfMonth();\r\n const tomorrow = addDays(getToday(), 1);\r\n // Records from start of month to now: >= first day AND < tomorrow\r\n this.addCondition(field, '>=', startOfMonth);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', tomorrow);\r\n return this;\r\n },\r\n between: (startDate: string, endDate: string): QueryBuilder => {\r\n // Records between dates (inclusive): >= start AND < day after end\r\n this.addCondition(field, '>=', startDate);\r\n this.joinOperators.push('and');\r\n // Use < next day for inclusive end date (handles API quirk)\r\n const dayAfterEnd = isPureDate(endDate) ? addDays(endDate, 1) : endDate;\r\n this.addCondition(field, '<', dayAfterEnd);\r\n return this;\r\n },\r\n daysAgo: (days: number): QueryBuilder => {\r\n const today = getToday();\r\n const startDate = addDays(today, -days);\r\n const tomorrow = addDays(today, 1);\r\n // Records from N days ago to now: >= (today - N) AND < tomorrow\r\n this.addCondition(field, '>=', startDate);\r\n this.joinOperators.push('and');\r\n this.addCondition(field, '<', tomorrow);\r\n return this;\r\n },\r\n before: (date: string): QueryBuilder => {\r\n this.addCondition(field, '<', date);\r\n return this;\r\n },\r\n after: (date: string): QueryBuilder => {\r\n // After a date means > end of that day\r\n // For pure dates, use > date (API treats as > midnight, so actually > end of previous day)\r\n // We need >= next day for \"after\" to work correctly\r\n const nextDay = isPureDate(date) ? addDays(date, 1) : date;\r\n this.addCondition(field, '>=', nextDay);\r\n return this;\r\n },\r\n onOrBefore: (date: string): QueryBuilder => {\r\n // Use < next day for inclusive (handles API quirk with <=)\r\n const nextDay = isPureDate(date) ? addDays(date, 1) : date;\r\n this.addCondition(field, '<', nextDay);\r\n return this;\r\n },\r\n onOrAfter: (date: string): QueryBuilder => {\r\n this.addCondition(field, '>=', date);\r\n return this;\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Adds a condition to the query\r\n */\r\n private addCondition(field: string, operator: QueryOperator, value?: string): void {\r\n this.conditions.push({ field, operator, value });\r\n this.currentField = null;\r\n }\r\n}\r\n","/**\r\n * Waits for the specified number of milliseconds\r\n * Used for rate limit handling and retry logic\r\n *\r\n * @param ms - Time to wait in milliseconds\r\n * @returns Promise that resolves after the specified time\r\n */\r\nexport function wait(ms: number): Promise<void> {\r\n return new Promise<void>((resolve) => {\r\n setTimeout(resolve, ms);\r\n });\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of specified size\r\n * Used for processing large batches in Fireberry-compatible pieces (max 20 items)\r\n *\r\n * @param array - Array to split\r\n * @param size - Maximum chunk size\r\n * @returns Array of chunks\r\n */\r\nexport function chunkArray<T>(array: T[], size: number): T[][] {\r\n const result: T[][] = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n result.push(array.slice(i, i + size));\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Safely converts a value to a string for API usage\r\n * Handles null, undefined, numbers, and other types\r\n *\r\n * @param value - The value to convert\r\n * @returns String representation of the value\r\n */\r\nexport function safeStringValue(value: unknown): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n if (typeof value === 'string') {\r\n return value;\r\n }\r\n if (typeof value === 'number' || typeof value === 'boolean') {\r\n return String(value);\r\n }\r\n if (typeof value === 'object') {\r\n return JSON.stringify(value);\r\n }\r\n return String(value);\r\n}\r\n\r\n/**\r\n * Normalizes fields input to an array\r\n * Accepts both array of strings and comma-separated string\r\n *\r\n * @param fields - Fields as array or comma-separated string\r\n * @returns Array of field names\r\n *\r\n * @example\r\n * normalizeFields('a,b,c') // ['a', 'b', 'c']\r\n * normalizeFields(['a', 'b']) // ['a', 'b']\r\n * normalizeFields('*') // ['*']\r\n */\r\nexport function normalizeFields(fields: string | string[]): string[] {\r\n if (Array.isArray(fields)) {\r\n return fields;\r\n }\r\n if (typeof fields === 'string') {\r\n // Handle empty string\r\n if (!fields.trim()) {\r\n return [];\r\n }\r\n // Split by comma and trim whitespace\r\n return fields.split(',').map((f) => f.trim()).filter((f) => f.length > 0);\r\n }\r\n return [];\r\n}\r\n\r\n/**\r\n * Joins fields array into a comma-separated string\r\n * Useful for API requests that expect fields as a string\r\n *\r\n * @param fields - Array of field names\r\n * @returns Comma-separated string of fields\r\n */\r\nexport function joinFields(fields: string[]): string {\r\n return fields.join(',');\r\n}\r\n\r\n/**\r\n * Checks if a fields input represents \"select all\"\r\n *\r\n * @param fields - Fields input (string or array)\r\n * @returns True if fields is '*' or ['*'] or empty\r\n */\r\nexport function isSelectAll(fields: string | string[]): boolean {\r\n if (Array.isArray(fields)) {\r\n return fields.length === 0 || (fields.length === 1 && fields[0] === '*');\r\n }\r\n return !fields || fields === '*';\r\n}\r\n\r\n/**\r\n * Deep clones an object\r\n * Used for safely copying configuration objects\r\n *\r\n * @param obj - Object to clone\r\n * @returns Deep cloned copy of the object\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n return JSON.parse(JSON.stringify(obj));\r\n}\r\n\r\n/**\r\n * Checks if a value is a plain object (not array, null, etc.)\r\n *\r\n * @param value - Value to check\r\n * @returns True if value is a plain object\r\n */\r\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value);\r\n}\r\n","/**\r\n * HTTP Transport implementation for Fireberry API\r\n * Uses direct HTTP requests with API key authentication\r\n */\r\n\r\nimport type {\r\n Transport,\r\n TransportRequestOptions,\r\n HTTPTransportConfig,\r\n} from '../types/transport';\r\nimport type { QueryOptions, QueryResult } from '../types/query';\r\nimport type { FireberryRecord } from '../types/records';\r\nimport {\r\n FireberryError,\r\n FireberryErrorCode,\r\n createErrorFromResponse,\r\n createNetworkError,\r\n} from '../errors';\r\nimport { wait } from '../utils/helpers';\r\n\r\n/**\r\n * HTTP transport for API key-based communication\r\n */\r\nexport class HTTPTransport implements Transport {\r\n private readonly config: Required<HTTPTransportConfig>;\r\n\r\n constructor(config: HTTPTransportConfig) {\r\n this.config = {\r\n apiKey: config.apiKey,\r\n baseUrl: config.baseUrl || 'https://api.fireberry.com',\r\n timeout: config.timeout || 30000,\r\n retryOn429: config.retryOn429 ?? true,\r\n maxRetries: config.maxRetries || 120,\r\n retryDelay: config.retryDelay || 1000,\r\n };\r\n }\r\n\r\n getType(): 'http' {\r\n return 'http';\r\n }\r\n\r\n async request<T = unknown>(options: TransportRequestOptions): Promise<T> {\r\n const { method, endpoint, query: queryParams, body, headers: customHeaders, signal } = options;\r\n\r\n // Build URL\r\n let url = `${this.config.baseUrl}${endpoint}`;\r\n\r\n // Add query parameters if any\r\n if (queryParams && Object.keys(queryParams).length > 0) {\r\n const params = new URLSearchParams();\r\n for (const [key, value] of Object.entries(queryParams)) {\r\n if (value !== undefined && value !== null) {\r\n params.set(key, String(value));\r\n }\r\n }\r\n url += `?${params.toString()}`;\r\n }\r\n\r\n // Build headers\r\n const headers: Record<string, string> = {\r\n Accept: 'application/json',\r\n tokenid: this.config.apiKey,\r\n ...customHeaders,\r\n };\r\n\r\n if (body) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n // Build fetch options\r\n const fetchOptions: RequestInit = {\r\n method,\r\n headers,\r\n signal,\r\n };\r\n\r\n if (body) {\r\n fetchOptions.body = JSON.stringify(body);\r\n }\r\n\r\n // Execute with retry logic\r\n return this.executeWithRetry<T>(url, fetchOptions);\r\n }\r\n\r\n async query(options: QueryOptions): Promise<QueryResult> {\r\n const {\r\n objectType,\r\n fields,\r\n query,\r\n sortBy = 'modifiedon',\r\n sortType = 'desc',\r\n limit,\r\n page = 1,\r\n pageSize = 500,\r\n showRealValue = true,\r\n autoPage = true,\r\n signal,\r\n } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // If autoPage is true, fetch all pages\r\n if (autoPage) {\r\n return this.queryAllPages({\r\n objectType,\r\n fields: fieldsStr,\r\n query,\r\n sortBy,\r\n sortType,\r\n showRealValue,\r\n limit,\r\n signal,\r\n });\r\n }\r\n\r\n // Single page query\r\n const body = {\r\n objecttype: objectType,\r\n fields: fieldsStr,\r\n query: query || '',\r\n sort_by: sortBy,\r\n sort_type: sortType,\r\n page_size: Math.min(pageSize, limit || 500),\r\n page_number: page,\r\n show_real_value: showRealValue ? 1 : 0,\r\n };\r\n\r\n const response = await this.request<{ data?: { Data?: Record<string, unknown>[] } }>({\r\n method: 'POST',\r\n endpoint: '/api/query',\r\n body,\r\n signal,\r\n });\r\n\r\n const records = response.data?.Data || [];\r\n\r\n return {\r\n records,\r\n total: records.length,\r\n success: true,\r\n };\r\n }\r\n\r\n async createRecord(\r\n objectType: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n const response = await this.request<{\r\n success: boolean;\r\n record: FireberryRecord;\r\n _id?: string;\r\n }>({\r\n method: 'POST',\r\n endpoint: `/api/v2/record/${objectType}`,\r\n body: data,\r\n signal,\r\n });\r\n\r\n return response.record;\r\n }\r\n\r\n async updateRecord(\r\n objectType: string,\r\n recordId: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n const response = await this.request<{\r\n success: boolean;\r\n record: FireberryRecord;\r\n _id?: string;\r\n }>({\r\n method: 'PUT',\r\n endpoint: `/api/v2/record/${objectType}/${recordId}`,\r\n body: data,\r\n signal,\r\n });\r\n\r\n return response.record;\r\n }\r\n\r\n async deleteRecord(\r\n objectType: string,\r\n recordId: string,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; id: string }> {\r\n // Note: Delete uses /api/record (not /api/v2/record)\r\n await this.request({\r\n method: 'DELETE',\r\n endpoint: `/api/record/${objectType}/${recordId}`,\r\n signal,\r\n });\r\n\r\n return {\r\n success: true,\r\n id: recordId,\r\n };\r\n }\r\n\r\n async batchCreate(\r\n objectType: string,\r\n records: FireberryRecord[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const response = await this.request<{ data?: unknown[] }>({\r\n method: 'POST',\r\n endpoint: `/api/v3/record/${objectType}/batch/create`,\r\n body: { data: records },\r\n signal,\r\n });\r\n\r\n const data = response.data || [];\r\n const dataArray = Array.isArray(data) ? data : [data];\r\n\r\n return {\r\n success: true,\r\n data: dataArray,\r\n count: dataArray.length,\r\n };\r\n }\r\n\r\n async batchUpdate(\r\n objectType: string,\r\n records: Array<{ id: string; record: FireberryRecord }>,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const response = await this.request<{ data?: unknown[] }>({\r\n method: 'POST',\r\n endpoint: `/api/v3/record/${objectType}/batch/update`,\r\n body: { data: records },\r\n signal,\r\n });\r\n\r\n const data = response.data || [];\r\n const dataArray = Array.isArray(data) ? data : [data];\r\n\r\n return {\r\n success: true,\r\n data: dataArray,\r\n count: dataArray.length,\r\n };\r\n }\r\n\r\n async batchDelete(\r\n objectType: string,\r\n recordIds: string[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; ids: string[]; count: number }> {\r\n await this.request({\r\n method: 'POST',\r\n endpoint: `/api/v3/record/${objectType}/batch/delete`,\r\n body: { data: recordIds },\r\n signal,\r\n });\r\n\r\n return {\r\n success: true,\r\n ids: recordIds,\r\n count: recordIds.length,\r\n };\r\n }\r\n\r\n /**\r\n * Fetches all pages of a query\r\n */\r\n private async queryAllPages(options: {\r\n objectType: string;\r\n fields: string;\r\n query?: string;\r\n sortBy: string;\r\n sortType: string;\r\n showRealValue: boolean;\r\n limit?: number;\r\n signal?: AbortSignal;\r\n }): Promise<QueryResult> {\r\n const { objectType, fields, query, sortBy, sortType, showRealValue, limit, signal } = options;\r\n const maxPageSize = 500;\r\n const allRecords: Record<string, unknown>[] = [];\r\n let currentPage = 1;\r\n let hasMore = true;\r\n\r\n while (hasMore) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n const body = {\r\n objecttype: objectType,\r\n fields,\r\n query: query || '',\r\n sort_by: sortBy,\r\n sort_type: sortType,\r\n page_size: maxPageSize,\r\n page_number: currentPage,\r\n show_real_value: showRealValue ? 1 : 0,\r\n };\r\n\r\n const response = await this.request<{ data?: { Data?: Record<string, unknown>[] } }>({\r\n method: 'POST',\r\n endpoint: '/api/query',\r\n body,\r\n signal,\r\n });\r\n\r\n const pageData = response.data?.Data || [];\r\n allRecords.push(...pageData);\r\n\r\n // Check if we've reached the limit\r\n if (limit && allRecords.length >= limit) {\r\n allRecords.splice(limit);\r\n break;\r\n }\r\n\r\n // Check if there are more pages\r\n if (pageData.length < maxPageSize) {\r\n hasMore = false;\r\n } else {\r\n currentPage++;\r\n }\r\n }\r\n\r\n return {\r\n records: allRecords,\r\n total: allRecords.length,\r\n success: true,\r\n };\r\n }\r\n\r\n /**\r\n * Executes a fetch request with retry logic for 429 errors and timeouts\r\n * Implements exponential backoff for timeout duration\r\n */\r\n private async executeWithRetry<T>(\r\n url: string,\r\n options: RequestInit,\r\n retryCount = 0\r\n ): Promise<T> {\r\n try {\r\n // Calculate timeout with exponential backoff\r\n // Start with base timeout, double on each retry, cap at 5 minutes (300000ms)\r\n const maxTimeout = 300000; // 5 minutes\r\n const currentTimeout = Math.min(\r\n this.config.timeout * Math.pow(2, retryCount),\r\n maxTimeout\r\n );\r\n\r\n // Create timeout controller\r\n const timeoutController = new AbortController();\r\n const timeoutId = setTimeout(() => {\r\n timeoutController.abort();\r\n }, currentTimeout);\r\n\r\n // Combine signals if external signal provided\r\n const combinedSignal = options.signal\r\n ? this.combineSignals([options.signal, timeoutController.signal])\r\n : timeoutController.signal;\r\n\r\n const response = await fetch(url, {\r\n ...options,\r\n signal: combinedSignal,\r\n });\r\n\r\n clearTimeout(timeoutId);\r\n\r\n // Handle rate limiting\r\n if (response.status === 429 && this.config.retryOn429) {\r\n if (retryCount < this.config.maxRetries) {\r\n // Wait before retrying\r\n await wait(this.config.retryDelay);\r\n return this.executeWithRetry<T>(url, options, retryCount + 1);\r\n }\r\n throw new FireberryError('Rate limit exceeded after max retries', {\r\n code: FireberryErrorCode.RATE_LIMITED,\r\n statusCode: 429,\r\n context: { retryCount },\r\n });\r\n }\r\n\r\n // Parse response\r\n let body: unknown;\r\n const contentType = response.headers.get('content-type');\r\n if (contentType?.includes('application/json')) {\r\n body = await response.json();\r\n } else {\r\n body = await response.text();\r\n }\r\n\r\n // Handle errors\r\n if (!response.ok) {\r\n throw createErrorFromResponse(response, body);\r\n }\r\n\r\n return body as T;\r\n } catch (error) {\r\n // Handle abort/timeout\r\n if (error instanceof Error && error.name === 'AbortError') {\r\n // Check if this was caused by external abort signal (user cancellation)\r\n if (options.signal?.aborted) {\r\n throw createNetworkError(error);\r\n }\r\n\r\n // Otherwise it's a timeout - treat as rate limit and retry if enabled\r\n if (this.config.retryOn429 && retryCount < this.config.maxRetries) {\r\n // Wait before retrying\r\n await wait(this.config.retryDelay);\r\n return this.executeWithRetry<T>(url, options, retryCount + 1);\r\n }\r\n\r\n throw new FireberryError('Request timeout after max retries', {\r\n code: FireberryErrorCode.TIMEOUT,\r\n context: { retryCount },\r\n });\r\n }\r\n\r\n // Re-throw FireberryError\r\n if (error instanceof FireberryError) {\r\n throw error;\r\n }\r\n\r\n // Wrap other errors\r\n throw createNetworkError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Combines multiple abort signals into one\r\n */\r\n private combineSignals(signals: AbortSignal[]): AbortSignal {\r\n const controller = new AbortController();\r\n\r\n for (const signal of signals) {\r\n if (signal.aborted) {\r\n controller.abort();\r\n break;\r\n }\r\n signal.addEventListener('abort', () => controller.abort(), { once: true });\r\n }\r\n\r\n return controller.signal;\r\n }\r\n}\r\n","/**\r\n * SDK Transport implementation for Fireberry SDK\r\n * Uses iframe messaging through the @fireberry/sdk package\r\n */\r\n\r\nimport type {\r\n Transport,\r\n TransportRequestOptions,\r\n SDKTransportConfig,\r\n} from '../types/transport';\r\nimport type { QueryOptions, QueryResult } from '../types/query';\r\nimport type { FireberryRecord } from '../types/records';\r\nimport type { FireberrySDKClient, SDKQueryPayload } from '../types/sdk';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\nimport { chunkArray } from '../utils/helpers';\r\n\r\n/** Maximum records per batch operation */\r\nconst BATCH_SIZE = 20;\r\n\r\n/**\r\n * SDK transport for iframe messaging-based communication\r\n */\r\nexport class SDKTransport implements Transport {\r\n private readonly sdk: FireberrySDKClient;\r\n\r\n constructor(config: SDKTransportConfig) {\r\n this.sdk = config.sdk;\r\n }\r\n\r\n getType(): 'sdk' {\r\n return 'sdk';\r\n }\r\n\r\n async request<T = unknown>(_options: TransportRequestOptions): Promise<T> {\r\n throw new FireberryError(\r\n 'Raw request() is not supported in SDK mode. Use specific methods like query(), createRecord(), etc.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n }\r\n\r\n async query(options: QueryOptions): Promise<QueryResult> {\r\n const {\r\n objectType,\r\n fields,\r\n query,\r\n limit,\r\n page = 1,\r\n pageSize = 500,\r\n autoPage = true,\r\n signal,\r\n } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // If autoPage is true, fetch all pages\r\n if (autoPage) {\r\n return this.queryAllPages({\r\n objectType,\r\n fields: fieldsStr,\r\n query,\r\n limit,\r\n pageSize,\r\n signal,\r\n });\r\n }\r\n\r\n // Single page query\r\n const payload: SDKQueryPayload = {\r\n fields: fieldsStr,\r\n query: query || '',\r\n page_size: Math.min(pageSize, limit || 500),\r\n page_number: page,\r\n };\r\n\r\n const response = await this.sdk.api.query(objectType, payload);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK query failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n // SDK returns data differently than HTTP API\r\n // We need to normalize the response structure\r\n // The SDK response can be:\r\n // 1. {Columns: [...], Data: [...]} - query response with metadata\r\n // 2. An array of records\r\n // 3. A single record object\r\n let records: Record<string, unknown>[] = [];\r\n\r\n if (response.data && typeof response.data === 'object') {\r\n // Check if it's a query response with Data property\r\n if ('Data' in response.data && Array.isArray(response.data.Data)) {\r\n records = response.data.Data as Record<string, unknown>[];\r\n }\r\n // Check if data itself is an array\r\n else if (Array.isArray(response.data)) {\r\n records = response.data.filter(\r\n (record) => record && typeof record === 'object'\r\n ) as Record<string, unknown>[];\r\n }\r\n // Otherwise treat as a single record (but this shouldn't happen for queries)\r\n else if (!('Columns' in response.data)) {\r\n records = [response.data as Record<string, unknown>];\r\n }\r\n }\r\n\r\n return {\r\n records,\r\n total: records.length,\r\n success: true,\r\n };\r\n }\r\n\r\n async createRecord(\r\n objectType: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Request aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const response = await this.sdk.api.create(objectType, data);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK create failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n return response.data as FireberryRecord;\r\n }\r\n\r\n async updateRecord(\r\n objectType: string,\r\n recordId: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord> {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Request aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const response = await this.sdk.api.update(objectType, recordId, data);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK update failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n return response.data as FireberryRecord;\r\n }\r\n\r\n async deleteRecord(\r\n objectType: string,\r\n recordId: string,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; id: string }> {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Request aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const response = await this.sdk.api.delete(objectType, recordId);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK delete failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n return {\r\n success: true,\r\n id: recordId,\r\n };\r\n }\r\n\r\n async batchCreate(\r\n objectType: string,\r\n records: FireberryRecord[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n // SDK doesn't have native batch operations, so we create records one by one\r\n // This is less efficient but maintains consistency\r\n const batchPromises = batch.map((record) => this.createRecord(objectType, record, signal));\r\n const batchResults = await Promise.all(batchPromises);\r\n allResponses.push(...batchResults);\r\n }\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n async batchUpdate(\r\n objectType: string,\r\n records: Array<{ id: string; record: FireberryRecord }>,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }> {\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n // SDK doesn't have native batch operations, so we update records one by one\r\n const batchPromises = batch.map((item) =>\r\n this.updateRecord(objectType, item.id, item.record, signal)\r\n );\r\n const batchResults = await Promise.all(batchPromises);\r\n allResponses.push(...batchResults);\r\n }\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n async batchDelete(\r\n objectType: string,\r\n recordIds: string[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; ids: string[]; count: number }> {\r\n const batches = chunkArray(recordIds, BATCH_SIZE);\r\n const allDeletedIds: string[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n // SDK doesn't have native batch operations, so we delete records one by one\r\n const batchPromises = batch.map((id) => this.deleteRecord(objectType, id, signal));\r\n await Promise.all(batchPromises);\r\n allDeletedIds.push(...batch);\r\n }\r\n\r\n return {\r\n success: true,\r\n ids: allDeletedIds,\r\n count: allDeletedIds.length,\r\n };\r\n }\r\n\r\n /**\r\n * Fetches all pages of a query using SDK\r\n */\r\n private async queryAllPages(options: {\r\n objectType: string;\r\n fields: string;\r\n query?: string;\r\n limit?: number;\r\n pageSize?: number;\r\n signal?: AbortSignal;\r\n }): Promise<QueryResult> {\r\n const { objectType, fields, query, limit, pageSize = 500, signal } = options;\r\n const maxPageSize = 500;\r\n const allRecords: Record<string, unknown>[] = [];\r\n let currentPage = 1;\r\n let hasMore = true;\r\n\r\n while (hasMore) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n break;\r\n }\r\n\r\n const payload: SDKQueryPayload = {\r\n fields,\r\n query: query || '',\r\n page_size: Math.min(maxPageSize, pageSize),\r\n page_number: currentPage,\r\n };\r\n\r\n const response = await this.sdk.api.query(objectType, payload);\r\n\r\n if (!response.success && response.error) {\r\n throw new FireberryError(\r\n response.error.data?.Message || response.error.statusText || 'SDK query failed',\r\n {\r\n code: FireberryErrorCode.SERVER_ERROR,\r\n statusCode: response.error.status,\r\n context: { response },\r\n }\r\n );\r\n }\r\n\r\n // Normalize SDK response structure (same logic as single page query)\r\n let validRecords: Record<string, unknown>[] = [];\r\n\r\n if (response.data && typeof response.data === 'object') {\r\n // Check if it's a query response with Data property\r\n if ('Data' in response.data && Array.isArray(response.data.Data)) {\r\n validRecords = response.data.Data as Record<string, unknown>[];\r\n }\r\n // Check if data itself is an array\r\n else if (Array.isArray(response.data)) {\r\n validRecords = response.data.filter(\r\n (record) => record && typeof record === 'object'\r\n ) as Record<string, unknown>[];\r\n }\r\n // Otherwise treat as a single record (but this shouldn't happen for queries)\r\n else if (!('Columns' in response.data)) {\r\n validRecords = [response.data as Record<string, unknown>];\r\n }\r\n }\r\n\r\n allRecords.push(...validRecords);\r\n\r\n // Check if we've reached the limit\r\n if (limit && allRecords.length >= limit) {\r\n allRecords.splice(limit);\r\n break;\r\n }\r\n\r\n // Check if there are more pages\r\n if (validRecords.length < maxPageSize) {\r\n hasMore = false;\r\n } else {\r\n currentPage++;\r\n }\r\n }\r\n\r\n return {\r\n records: allRecords,\r\n total: allRecords.length,\r\n success: true,\r\n };\r\n }\r\n}\r\n","/**\r\n * Utility functions for creating and managing transport instances\r\n */\r\n\r\nimport type { FireberryClientConfig } from '../types/client';\r\nimport type { Transport } from '../types/transport';\r\nimport { HTTPTransport } from '../transport/http';\r\nimport { SDKTransport } from '../transport/sdk';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\n\r\n/**\r\n * Creates the appropriate transport based on client configuration\r\n * Priority: SDK > HTTP\r\n * If both are provided, SDK is used for CRUD operations\r\n */\r\nexport function createTransport(config: FireberryClientConfig): Transport {\r\n // SDK mode (with or without API key)\r\n if (config.sdk) {\r\n return new SDKTransport({ sdk: config.sdk });\r\n }\r\n\r\n // API key mode\r\n if (config.apiKey) {\r\n return new HTTPTransport({\r\n apiKey: config.apiKey,\r\n baseUrl: config.baseUrl,\r\n timeout: config.timeout,\r\n retryOn429: config.retryOn429,\r\n maxRetries: config.maxRetries,\r\n retryDelay: config.retryDelay,\r\n });\r\n }\r\n\r\n // Neither provided\r\n throw new FireberryError(\r\n 'Either apiKey or sdk must be provided in FireberryClientConfig',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n}\r\n\r\n/**\r\n * Creates HTTP transport for metadata operations when using SDK mode\r\n * Returns null if no API key is available\r\n */\r\nexport function createMetadataTransport(config: FireberryClientConfig): HTTPTransport | null {\r\n if (!config.apiKey) {\r\n return null;\r\n }\r\n\r\n return new HTTPTransport({\r\n apiKey: config.apiKey,\r\n baseUrl: config.baseUrl,\r\n timeout: config.timeout,\r\n retryOn429: config.retryOn429,\r\n maxRetries: config.maxRetries,\r\n retryDelay: config.retryDelay,\r\n });\r\n}\r\n\r\n/**\r\n * Checks if metadata operations are available\r\n */\r\nexport function isMetadataAvailable(config: FireberryClientConfig): boolean {\r\n // Metadata requires HTTP transport (API key)\r\n return Boolean(config.apiKey);\r\n}\r\n\r\n/**\r\n * Gets the connection mode based on configuration\r\n */\r\nexport function getConnectionMode(config: FireberryClientConfig): 'sdk' | 'api' | 'hybrid' {\r\n if (config.sdk && config.apiKey) {\r\n return 'hybrid';\r\n }\r\n if (config.sdk) {\r\n return 'sdk';\r\n }\r\n return 'api';\r\n}\r\n","/**\r\n * Field Type System IDs from Fireberry CRM\r\n * These UUIDs identify different field types in the metadata API\r\n */\r\nexport const FIELD_TYPE_IDS = {\r\n DROPDOWN: 'b4919f2e-2996-48e4-a03c-ba39fb64386c',\r\n LOOKUP: 'a8fcdf65-91bc-46fd-82f6-1234758345a1',\r\n EMAIL: 'c713d2f7-8fa9-43c3-8062-f07486eaf567',\r\n TEXT: 'a1e7ed6f-5083-477b-b44c-9943a6181359',\r\n URL: 'c820d32f-44df-4c2a-9c1e-18734e864fd5',\r\n LONG_TEXT: '80108f9d-1e75-40fa-9fa9-02be4ddc1da1',\r\n DATETIME: 'ce972d02-5013-46d4-9d1d-f09df1ac346a',\r\n DATE: '83bf530c-e04c-462b-9ffc-a46f750fc072',\r\n HTML: 'ed2ad39d-32fc-4585-8f5b-2e93463f050a',\r\n TELEPHONE: '3f62f67a-1cee-403a-bec6-aa02a9804edb',\r\n NUMERIC: '6a34bfe3-fece-4da1-9136-a7b1e5ae3319',\r\n} as const;\r\n\r\n/**\r\n * Human-readable mappings for field types\r\n * Used for display purposes\r\n */\r\nexport const FIELD_TYPE_MAPPINGS: Record<string, string> = {\r\n [FIELD_TYPE_IDS.DROPDOWN]: 'Dropdown',\r\n [FIELD_TYPE_IDS.EMAIL]: 'Email',\r\n [FIELD_TYPE_IDS.TEXT]: 'Text',\r\n [FIELD_TYPE_IDS.LOOKUP]: 'Lookup',\r\n [FIELD_TYPE_IDS.URL]: 'URL',\r\n [FIELD_TYPE_IDS.LONG_TEXT]: 'Long Text',\r\n [FIELD_TYPE_IDS.DATETIME]: 'DateTime',\r\n [FIELD_TYPE_IDS.DATE]: 'Date',\r\n [FIELD_TYPE_IDS.HTML]: 'HTML',\r\n [FIELD_TYPE_IDS.TELEPHONE]: 'Telephone',\r\n [FIELD_TYPE_IDS.NUMERIC]: 'Number',\r\n};\r\n","import type { FireberryClient } from '../client';\r\nimport type {\r\n GetObjectsResult,\r\n GetFieldsResult,\r\n GetFieldValuesResult,\r\n FireberryObject,\r\n FireberryField,\r\n FieldValue,\r\n} from '../types/metadata';\r\nimport { FIELD_TYPE_MAPPINGS, FIELD_TYPE_IDS } from '../constants/fieldTypes';\r\nimport { EXCLUDED_LOOKUP_FIELDS } from '../constants/excludedFields';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\n\r\n/** API endpoints used by MetadataAPI */\r\nconst ENDPOINTS = {\r\n OBJECTS: '/metadata/records',\r\n FIELDS: (objectType: string) => `/metadata/records/${objectType}/fields`,\r\n FIELD_VALUES: (objectType: string, fieldName: string) =>\r\n `/metadata/records/${objectType}/fields/${fieldName}/values`,\r\n QUERY: '/api/query',\r\n} as const;\r\n\r\n/**\r\n * Metadata API for retrieving Fireberry schema information\r\n */\r\nexport class MetadataAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Checks if metadata operations are available and throws error if not\r\n * @private\r\n */\r\n private ensureMetadataAvailable(): void {\r\n if (!this.client.isMetadataAvailable()) {\r\n throw new FireberryError(\r\n 'Metadata operations are not available in SDK-only mode. Please provide an API key in the FireberryClient configuration to use metadata features.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n context: {\r\n hint: 'Fireberry SDK does not yet support metadata operations. Use API key mode or hybrid mode (both SDK + API key) to access metadata.',\r\n },\r\n }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Gets all available objects/entity types from Fireberry\r\n *\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns List of all objects\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.metadata.getObjects();\r\n * console.log(result.objects); // [{ objectType: 1, name: 'Account', ... }, ...]\r\n * ```\r\n */\r\n async getObjects(signal?: AbortSignal): Promise<GetObjectsResult> {\r\n // Ensure metadata is available\r\n this.ensureMetadataAvailable();\r\n\r\n // Check cache first\r\n const cached = this.client.getCached<GetObjectsResult>('objects');\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: FireberryObject[];\r\n }>({\r\n method: 'GET',\r\n endpoint: ENDPOINTS.OBJECTS,\r\n signal,\r\n });\r\n\r\n const result: GetObjectsResult = {\r\n objects: response.data || [],\r\n total: response.data?.length || 0,\r\n success: true,\r\n };\r\n\r\n // Cache the result\r\n this.client.setCache('objects', result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets all fields for a specific object type\r\n *\r\n * @param objectType - The object type ID (e.g., '1' for Account)\r\n * @param options - Optional settings\r\n * @param options.includeLookupRelations - Fetches related object types for lookup fields (default: true)\r\n * @param options.signal - Optional AbortSignal for cancellation\r\n * @returns List of fields with metadata\r\n *\r\n * @example\r\n * ```typescript\r\n * // Lookup relations are included by default\r\n * const result = await client.metadata.getFields('1');\r\n * console.log(result.fields.find(f => f.fieldName === 'primarycontactid')?.relatedObjectType); // 2\r\n *\r\n * // Disable lookup relations for faster response\r\n * const result = await client.metadata.getFields('1', { includeLookupRelations: false });\r\n * ```\r\n */\r\n async getFields(\r\n objectType: string | number,\r\n options?: { includeLookupRelations?: boolean; signal?: AbortSignal } | AbortSignal,\r\n ): Promise<GetFieldsResult> {\r\n // Ensure metadata is available\r\n this.ensureMetadataAvailable();\r\n\r\n const objectTypeStr = String(objectType);\r\n\r\n // Handle both old signature (signal only) and new signature (options object)\r\n // Default includeLookupRelations to true\r\n const opts =\r\n options instanceof AbortSignal\r\n ? { signal: options, includeLookupRelations: true }\r\n : { signal: options?.signal, includeLookupRelations: options?.includeLookupRelations ?? true };\r\n\r\n // Check cache first\r\n const cached = this.client.getCached<GetFieldsResult>('fields', objectTypeStr);\r\n if (cached) {\r\n // If user wants lookup relations and cache has them (or doesn't need them), return cached\r\n // Since default is includeLookupRelations: true, cached results typically have relations\r\n const cachedHasRelations = cached.fields.some((f) => f.relatedObjectType !== undefined);\r\n if (!opts.includeLookupRelations || cachedHasRelations) {\r\n return cached;\r\n }\r\n // If user wants relations but cache doesn't have them, continue to fetch\r\n }\r\n\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: Array<{\r\n fieldName: string;\r\n label: string;\r\n systemFieldTypeId: string;\r\n required?: boolean;\r\n defaultValue?: unknown;\r\n maxLength?: number;\r\n precision?: number;\r\n }>;\r\n }>({\r\n method: 'GET',\r\n endpoint: ENDPOINTS.FIELDS(objectTypeStr),\r\n signal: opts.signal,\r\n });\r\n\r\n // Enhance fields with readable field types\r\n let fields: FireberryField[] = (response.data || []).map((field) => ({\r\n ...field,\r\n fieldType: FIELD_TYPE_MAPPINGS[field.systemFieldTypeId] || field.systemFieldTypeId,\r\n }));\r\n\r\n // If requested, fetch related object types for lookup fields\r\n if (opts.includeLookupRelations) {\r\n const lookupFields = fields.filter(\r\n (field) => field.systemFieldTypeId === FIELD_TYPE_IDS.LOOKUP,\r\n );\r\n\r\n if (lookupFields.length > 0) {\r\n const lookupRelations = await this.fetchLookupRelations(\r\n objectTypeStr,\r\n lookupFields.map((f) => f.fieldName),\r\n opts.signal,\r\n );\r\n\r\n // Merge lookup relations into fields\r\n fields = fields.map((field) => ({\r\n ...field,\r\n relatedObjectType: lookupRelations.get(field.fieldName),\r\n }));\r\n }\r\n }\r\n\r\n const result: GetFieldsResult = {\r\n objectTypeId: objectTypeStr,\r\n fields,\r\n total: fields.length,\r\n success: true,\r\n };\r\n\r\n // Cache the result\r\n this.client.setCache('fields', objectTypeStr, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Fetches related object types for lookup fields using the query endpoint.\r\n * The query endpoint returns Columns metadata with fieldobjecttype even without records.\r\n * Excludes fields that cause API errors (e.g., deletedby, deletedon).\r\n */\r\n private async fetchLookupRelations(\r\n objectType: string,\r\n lookupFieldNames: string[],\r\n signal?: AbortSignal,\r\n ): Promise<Map<string, number>> {\r\n const relations = new Map<string, number>();\r\n\r\n // Filter out excluded fields that cause API errors\r\n const queryableFields = lookupFieldNames.filter(\r\n (fieldName) => !EXCLUDED_LOOKUP_FIELDS.includes(fieldName),\r\n );\r\n\r\n if (queryableFields.length === 0) {\r\n return relations;\r\n }\r\n\r\n try {\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: {\r\n Columns?: Array<{\r\n fieldname: string;\r\n fieldobjecttype: number | null;\r\n }>;\r\n };\r\n }>({\r\n method: 'POST',\r\n endpoint: ENDPOINTS.QUERY,\r\n body: {\r\n objecttype: objectType,\r\n fields: queryableFields.join(','),\r\n query: '',\r\n page_size: 1,\r\n page_number: 1,\r\n show_real_value: 0,\r\n },\r\n signal,\r\n });\r\n\r\n // Extract fieldobjecttype from Columns metadata\r\n const columns = response.data?.Columns || [];\r\n for (const column of columns) {\r\n if (column.fieldobjecttype !== null && column.fieldobjecttype !== undefined) {\r\n relations.set(column.fieldname, column.fieldobjecttype);\r\n }\r\n }\r\n } catch (error) {\r\n // If fetching lookup relations fails, return empty map\r\n // This allows tests and edge cases to work without complete mocking\r\n // Lookup fields will still be returned, just without relatedObjectType\r\n }\r\n\r\n return relations;\r\n }\r\n\r\n /**\r\n * Gets all possible values for a dropdown field\r\n *\r\n * @param objectType - The object type ID\r\n * @param fieldName - The field name\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns List of dropdown values\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.metadata.getFieldValues('1', 'statuscode');\r\n * console.log(result.values); // [{ name: 'Active', value: '1' }, { name: 'Inactive', value: '2' }]\r\n * ```\r\n */\r\n async getFieldValues(\r\n objectType: string | number,\r\n fieldName: string,\r\n signal?: AbortSignal,\r\n ): Promise<GetFieldValuesResult> {\r\n // Ensure metadata is available\r\n this.ensureMetadataAvailable();\r\n\r\n const objectTypeStr = String(objectType);\r\n\r\n // Check cache first\r\n const cached = this.client.getCached<GetFieldValuesResult>(\r\n 'fieldValues',\r\n objectTypeStr,\r\n fieldName,\r\n );\r\n if (cached) {\r\n return cached;\r\n }\r\n\r\n const response = await this.client.request<{\r\n success: boolean;\r\n data?: {\r\n values?: FieldValue[];\r\n };\r\n }>({\r\n method: 'GET',\r\n endpoint: ENDPOINTS.FIELD_VALUES(objectTypeStr, fieldName),\r\n signal,\r\n });\r\n\r\n const result: GetFieldValuesResult = {\r\n objectTypeId: objectTypeStr,\r\n fieldName,\r\n values: response.data?.values || [],\r\n total: response.data?.values?.length || 0,\r\n success: true,\r\n };\r\n\r\n // Cache the result\r\n this.client.setCache('fieldValues', objectTypeStr, fieldName, result);\r\n\r\n return result;\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport type {\r\n FireberryRecord,\r\n CreateOptions,\r\n UpdateOptions,\r\n DeleteOptions,\r\n UpsertOptions,\r\n UpsertResult,\r\n} from '../types/records';\r\nimport { getObjectIdFieldName } from '../constants/objectIds';\r\n\r\n/**\r\n * Records API for CRUD operations on Fireberry records\r\n */\r\nexport class RecordsAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Creates a new record in Fireberry\r\n *\r\n * @param objectType - The object type ID (e.g., '1' for Account)\r\n * @param data - Record data to create\r\n * @param options - Optional settings\r\n * @returns Created record data\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.records.create('1', {\r\n * accountname: 'New Account',\r\n * emailaddress1: 'contact@example.com',\r\n * });\r\n * ```\r\n */\r\n async create(\r\n objectType: string | number,\r\n data: FireberryRecord,\r\n options?: CreateOptions,\r\n ): Promise<FireberryRecord> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n\r\n const record = await transport.createRecord(objectTypeStr, data, options?.signal);\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return record;\r\n }\r\n\r\n /**\r\n * Updates an existing record in Fireberry\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordId - The record ID to update\r\n * @param data - Record data to update\r\n * @param options - Optional settings\r\n * @returns Updated record data\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.records.update('1', 'abc123', {\r\n * accountname: 'Updated Account Name',\r\n * });\r\n * ```\r\n */\r\n async update(\r\n objectType: string | number,\r\n recordId: string,\r\n data: FireberryRecord,\r\n options?: UpdateOptions,\r\n ): Promise<FireberryRecord> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n\r\n const record = await transport.updateRecord(objectTypeStr, recordId, data, options?.signal);\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return record;\r\n }\r\n\r\n /**\r\n * Deletes a record from Fireberry\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordId - The record ID to delete\r\n * @param options - Optional settings\r\n * @returns Success status\r\n *\r\n * @example\r\n * ```typescript\r\n * await client.records.delete('1', 'abc123');\r\n * ```\r\n */\r\n async delete(\r\n objectType: string | number,\r\n recordId: string,\r\n options?: DeleteOptions,\r\n ): Promise<{ success: boolean; id: string }> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n\r\n const result = await transport.deleteRecord(objectTypeStr, recordId, options?.signal);\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Upserts a record (creates if not exists, updates if exists)\r\n *\r\n * @param objectType - The object type ID\r\n * @param keyFields - Fields to use for matching existing records\r\n * @param data - Record data to upsert\r\n * @param options - Optional settings\r\n * @returns Upsert result with operation type and record data\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.records.upsert('1', ['emailaddress1'], {\r\n * accountname: 'Acme Corp',\r\n * emailaddress1: 'contact@acme.com',\r\n * });\r\n * console.log(result.operationType); // 'create' or 'update'\r\n * ```\r\n */\r\n async upsert(\r\n objectType: string | number,\r\n keyFields: string[],\r\n data: FireberryRecord,\r\n options?: UpsertOptions,\r\n ): Promise<UpsertResult> {\r\n const objectTypeStr = String(objectType);\r\n\r\n // Build key values from data\r\n const upsertKeyValues: Record<string, unknown> = {};\r\n for (const key of keyFields) {\r\n if (!(key in data)) {\r\n throw new Error(`Missing value for upsert key field: ${key}`);\r\n }\r\n upsertKeyValues[key] = data[key];\r\n }\r\n\r\n // Build query to check if record exists\r\n const queryConditions = keyFields.map((key) => `(${key} = ${data[key]})`);\r\n const queryString = queryConditions.join(' and ');\r\n\r\n // Query for existing record\r\n const queryResult = await this.client.query({\r\n objectType: objectTypeStr,\r\n fields: '*',\r\n query: queryString,\r\n limit: 1,\r\n showRealValue: true,\r\n signal: options?.signal,\r\n });\r\n\r\n const existingRecords = queryResult.records as FireberryRecord[];\r\n\r\n if (existingRecords.length > 0) {\r\n // Record exists - UPDATE\r\n const existingRecord = existingRecords[0];\r\n const idFieldName = getObjectIdFieldName(objectTypeStr);\r\n\r\n // Try to get the ID field value with exact casing first\r\n let recordId = existingRecord[idFieldName];\r\n\r\n // If not found, try case-insensitive lookup (for SDK compatibility)\r\n if (recordId === undefined || recordId === null) {\r\n const actualIdField = Object.keys(existingRecord).find(\r\n (key) => key.toLowerCase() === idFieldName.toLowerCase(),\r\n );\r\n\r\n if (actualIdField) {\r\n recordId = existingRecord[actualIdField];\r\n }\r\n }\r\n\r\n // If still not found, throw descriptive error\r\n if (recordId === undefined || recordId === null) {\r\n throw new Error(\r\n `Could not find ID field \"${idFieldName}\" in existing record. ` +\r\n `Available fields: ${Object.keys(existingRecord).join(', ')}`,\r\n );\r\n }\r\n\r\n const updatedRecord = await this.update(objectTypeStr, String(recordId), data, options);\r\n\r\n return {\r\n success: true,\r\n operationType: 'update',\r\n upsertKeys: keyFields,\r\n upsertKeyValues,\r\n oldRecord: existingRecord,\r\n newRecord: updatedRecord,\r\n };\r\n } else {\r\n // Record doesn't exist - CREATE\r\n const createdRecord = await this.create(objectTypeStr, data, options);\r\n\r\n return {\r\n success: true,\r\n operationType: 'create',\r\n upsertKeys: keyFields,\r\n upsertKeyValues,\r\n oldRecord: null,\r\n newRecord: createdRecord,\r\n };\r\n }\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport type {\r\n FireberryRecord,\r\n BatchCreateOptions,\r\n BatchUpdateOptions,\r\n BatchUpdateRecord,\r\n BatchDeleteOptions,\r\n BatchResult,\r\n BatchDeleteResult,\r\n} from '../types/records';\r\nimport { chunkArray } from '../utils/helpers';\r\n\r\n/** Maximum records per batch API call */\r\nconst BATCH_SIZE = 20;\r\n\r\n/**\r\n * Batch API for bulk operations on Fireberry records\r\n * Automatically chunks large datasets into API-compatible batches of 20\r\n */\r\nexport class BatchAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Creates multiple records in batch\r\n * Automatically chunks into batches of 20 records\r\n *\r\n * @param objectType - The object type ID\r\n * @param records - Array of records to create\r\n * @param options - Optional settings\r\n * @returns Batch result with all created records\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.batch.create('1', [\r\n * { accountname: 'Account 1' },\r\n * { accountname: 'Account 2' },\r\n * ]);\r\n * console.log(result.count); // 2\r\n * ```\r\n */\r\n async create(\r\n objectType: string | number,\r\n records: FireberryRecord[],\r\n options?: BatchCreateOptions,\r\n ): Promise<BatchResult> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (options?.signal?.aborted) {\r\n break;\r\n }\r\n\r\n const result = await transport.batchCreate(objectTypeStr, batch, options?.signal);\r\n allResponses.push(...result.data);\r\n }\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n /**\r\n * Updates multiple records in batch\r\n * Automatically chunks into batches of 20 records\r\n *\r\n * @param objectType - The object type ID\r\n * @param records - Array of records with ID and data to update\r\n * @param options - Optional settings\r\n * @returns Batch result with all updated records\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.batch.update('1', [\r\n * { id: 'abc123', record: { accountname: 'Updated 1' } },\r\n * { id: 'def456', record: { accountname: 'Updated 2' } },\r\n * ]);\r\n * ```\r\n */\r\n async update(\r\n objectType: string | number,\r\n records: BatchUpdateRecord[],\r\n options?: BatchUpdateOptions,\r\n ): Promise<BatchResult> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n const batches = chunkArray(records, BATCH_SIZE);\r\n const allResponses: unknown[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (options?.signal?.aborted) {\r\n break;\r\n }\r\n\r\n const result = await transport.batchUpdate(objectTypeStr, batch, options?.signal);\r\n allResponses.push(...result.data);\r\n }\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return {\r\n success: true,\r\n data: allResponses,\r\n count: allResponses.length,\r\n };\r\n }\r\n\r\n /**\r\n * Deletes multiple records in batch\r\n * Automatically chunks into batches of 20 records\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordIds - Array of record IDs to delete\r\n * @param options - Optional settings\r\n * @returns Batch delete result with deleted IDs\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await client.batch.delete('1', ['abc123', 'def456']);\r\n * console.log(result.ids); // ['abc123', 'def456']\r\n * ```\r\n */\r\n async delete(\r\n objectType: string | number,\r\n recordIds: string[],\r\n options?: BatchDeleteOptions,\r\n ): Promise<BatchDeleteResult> {\r\n const objectTypeStr = String(objectType);\r\n const transport = this.client.getTransport();\r\n const batches = chunkArray(recordIds, BATCH_SIZE);\r\n const allDeletedIds: string[] = [];\r\n\r\n for (const batch of batches) {\r\n // Check for abort\r\n if (options?.signal?.aborted) {\r\n break;\r\n }\r\n\r\n const result = await transport.batchDelete(objectTypeStr, batch, options?.signal);\r\n allDeletedIds.push(...result.ids);\r\n }\r\n\r\n // Smart cache invalidation\r\n this.client.invalidateCacheForMutation(objectTypeStr);\r\n\r\n return {\r\n success: true,\r\n ids: allDeletedIds,\r\n count: allDeletedIds.length,\r\n };\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport type { CreateFieldOptions, CreateFieldResult } from '../types/fields';\r\n\r\n/**\r\n * Field type to API endpoint mapping\r\n */\r\nconst FIELD_TYPE_ENDPOINTS: Record<string, string> = {\r\n text: 'text',\r\n email: 'email',\r\n url: 'url',\r\n phone: 'phone',\r\n number: 'number',\r\n textarea: 'textarea',\r\n html: 'html',\r\n date: 'date',\r\n datetime: 'datetime',\r\n lookup: 'lookup',\r\n summary: 'summary',\r\n formula: 'formula',\r\n picklist: 'picklist',\r\n};\r\n\r\n/**\r\n * Fields API for creating custom fields in Fireberry\r\n */\r\nexport class FieldsAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Creates a new custom field in a Fireberry object\r\n *\r\n * @param objectType - The object type ID\r\n * @param options - Field creation options\r\n * @returns Created field result\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a text field\r\n * const result = await client.fields.create('1', {\r\n * type: 'text',\r\n * fieldName: 'pcf_custom_field',\r\n * label: 'Custom Field',\r\n * maxLength: 100,\r\n * });\r\n *\r\n * // Create a picklist field\r\n * const result = await client.fields.create('1', {\r\n * type: 'picklist',\r\n * fieldName: 'pcf_status',\r\n * label: 'Status',\r\n * values: [\r\n * { name: 'Active', value: '1' },\r\n * { name: 'Inactive', value: '2' },\r\n * ],\r\n * });\r\n *\r\n * // Create a lookup field\r\n * const result = await client.fields.create('2', {\r\n * type: 'lookup',\r\n * fieldName: 'pcf_related_account',\r\n * label: 'Related Account',\r\n * relatedObjectId: '1',\r\n * });\r\n * ```\r\n */\r\n async create(\r\n objectType: string | number,\r\n options: CreateFieldOptions,\r\n ): Promise<CreateFieldResult> {\r\n const objectTypeStr = String(objectType);\r\n const { type, fieldName, label, defaultValue, follow, autoComplete } = options;\r\n\r\n // Build field data\r\n const fieldData: Record<string, unknown> = {\r\n fieldName,\r\n label,\r\n };\r\n\r\n // Add optional common properties\r\n if (defaultValue !== undefined) {\r\n fieldData.defaultValue = defaultValue;\r\n }\r\n if (follow !== undefined) {\r\n fieldData.follow = follow;\r\n }\r\n if (autoComplete !== undefined && ['text', 'email', 'url', 'phone', 'number'].includes(type)) {\r\n fieldData.autoComplete = autoComplete;\r\n }\r\n\r\n // Add field-type specific properties\r\n switch (type) {\r\n case 'text':\r\n case 'email':\r\n case 'url': {\r\n const opts = options as { maxLength?: number };\r\n if (opts.maxLength !== undefined && opts.maxLength > 0) {\r\n fieldData.maxLength = opts.maxLength;\r\n }\r\n break;\r\n }\r\n\r\n case 'number': {\r\n const opts = options as { precision?: number };\r\n if (opts.precision !== undefined) {\r\n fieldData.precision = opts.precision;\r\n }\r\n break;\r\n }\r\n\r\n case 'lookup': {\r\n const opts = options as { relatedObjectId: string };\r\n fieldData.relatedObjectId = opts.relatedObjectId;\r\n break;\r\n }\r\n\r\n case 'picklist': {\r\n const opts = options as { values: Array<{ name: string; value: string }> };\r\n fieldData.values = opts.values;\r\n break;\r\n }\r\n\r\n case 'summary': {\r\n const opts = options as {\r\n summaryType: string;\r\n relatedObjectId: string;\r\n summaryField?: string;\r\n };\r\n fieldData.summaryType = opts.summaryType;\r\n fieldData.relatedObjectId = opts.relatedObjectId;\r\n if (opts.summaryField) {\r\n fieldData.summaryField = opts.summaryField;\r\n }\r\n break;\r\n }\r\n\r\n case 'formula': {\r\n const opts = options as {\r\n formula: string;\r\n formulaFieldType: string;\r\n formulaPrecision?: number;\r\n };\r\n fieldData.formula = opts.formula;\r\n fieldData.fieldType = opts.formulaFieldType;\r\n if (opts.formulaFieldType === 'number' && opts.formulaPrecision !== undefined) {\r\n fieldData.precision = opts.formulaPrecision;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n // Get the API endpoint for this field type\r\n const endpoint = FIELD_TYPE_ENDPOINTS[type];\r\n if (!endpoint) {\r\n throw new Error(`Unsupported field type: ${type}`);\r\n }\r\n\r\n const response = await this.client.request<Record<string, unknown>>({\r\n method: 'POST',\r\n endpoint: `/api/v2/system-field/${objectTypeStr}/${endpoint}`,\r\n body: fieldData,\r\n });\r\n\r\n return {\r\n objectTypeId: objectTypeStr,\r\n fieldType: type,\r\n fieldData: response,\r\n success: true,\r\n };\r\n }\r\n}\r\n","import type { FireberryClient } from '../client';\r\nimport { FireberryError, FireberryErrorCode } from '../errors';\r\n\r\n/**\r\n * Options for file upload\r\n */\r\nexport interface FileUploadOptions {\r\n /** File content as Buffer */\r\n buffer: Buffer;\r\n /** File name */\r\n filename: string;\r\n /** MIME type */\r\n mimeType: string;\r\n}\r\n\r\n/**\r\n * Result of file upload\r\n */\r\nexport interface FileUploadResult {\r\n /** Success flag */\r\n success: boolean;\r\n /** Object type */\r\n objectType: string;\r\n /** Record ID */\r\n recordId: string;\r\n /** Uploaded file name */\r\n fileName: string;\r\n /** File MIME type */\r\n mimeType: string;\r\n /** File size in bytes */\r\n fileSize: number;\r\n /** API response */\r\n response: unknown;\r\n}\r\n\r\n/**\r\n * Files API for file operations in Fireberry\r\n */\r\nexport class FilesAPI {\r\n constructor(private readonly client: FireberryClient) {}\r\n\r\n /**\r\n * Uploads a file attachment to a Fireberry record\r\n *\r\n * @param objectType - The object type ID\r\n * @param recordId - The record ID to attach the file to\r\n * @param options - File upload options\r\n * @param signal - Optional AbortSignal for cancellation\r\n * @returns Upload result\r\n *\r\n * @example\r\n * ```typescript\r\n * import { readFileSync } from 'fs';\r\n *\r\n * const fileBuffer = readFileSync('document.pdf');\r\n * const result = await client.files.upload('1', 'abc123', {\r\n * buffer: fileBuffer,\r\n * filename: 'document.pdf',\r\n * mimeType: 'application/pdf',\r\n * });\r\n * ```\r\n */\r\n async upload(\r\n objectType: string | number,\r\n recordId: string,\r\n options: FileUploadOptions,\r\n signal?: AbortSignal,\r\n ): Promise<FileUploadResult> {\r\n const objectTypeStr = String(objectType);\r\n const { buffer, filename, mimeType } = options;\r\n const config = this.client.getConfig();\r\n\r\n // Ensure API key is available (file uploads not supported in SDK mode)\r\n if (!config.apiKey) {\r\n throw new FireberryError(\r\n 'File upload requires an API key. SDK mode does not support file uploads.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n }\r\n\r\n // Build the URL\r\n const url = `${config.baseUrl || 'https://api.fireberry.com'}/api/v2/record/${objectTypeStr}/${recordId}/files`;\r\n\r\n // Create form data\r\n // Note: In Node.js, we need to construct multipart/form-data manually\r\n // or use a library like form-data\r\n const boundary = `----FormBoundary${Date.now()}`;\r\n const formParts: Buffer[] = [];\r\n\r\n // Add file part\r\n const fileHeader = [\r\n `--${boundary}`,\r\n `Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"`,\r\n `Content-Type: ${mimeType}`,\r\n '',\r\n '',\r\n ].join('\\r\\n');\r\n\r\n formParts.push(Buffer.from(fileHeader));\r\n formParts.push(buffer);\r\n formParts.push(Buffer.from(`\\r\\n--${boundary}--\\r\\n`));\r\n\r\n const body = Buffer.concat(formParts);\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n Accept: 'application/json',\r\n 'Content-Type': `multipart/form-data; boundary=${boundary}`,\r\n tokenid: config.apiKey,\r\n },\r\n body,\r\n signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new FireberryError(`File upload failed: ${response.statusText}`, {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n statusCode: response.status,\r\n });\r\n }\r\n\r\n const responseData = await response.json();\r\n\r\n return {\r\n success: true,\r\n objectType: objectTypeStr,\r\n recordId,\r\n fileName: filename,\r\n mimeType,\r\n fileSize: buffer.length,\r\n response: responseData,\r\n };\r\n } catch (error) {\r\n if (error instanceof FireberryError) {\r\n throw error;\r\n }\r\n throw new FireberryError(`File upload failed: ${(error as Error).message}`, {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n cause: error as Error,\r\n });\r\n }\r\n }\r\n}\r\n","import type {\r\n FireberryClientConfig,\r\n RequestOptions,\r\n CacheControl,\r\n} from './types/client';\r\nimport type { QueryOptions, QueryResult } from './types/query';\r\nimport type { Transport } from './types/transport';\r\nimport {\r\n FireberryError,\r\n FireberryErrorCode,\r\n} from './errors';\r\nimport { QueryBuilder } from './utils/queryBuilder';\r\nimport { createTransport, createMetadataTransport, isMetadataAvailable } from './utils/transport';\r\nimport { HTTPTransport } from './transport/http';\r\n\r\n// Import API modules\r\nimport { MetadataAPI } from './api/metadata';\r\nimport { RecordsAPI } from './api/records';\r\nimport { BatchAPI } from './api/batch';\r\nimport { FieldsAPI } from './api/fields';\r\nimport { FilesAPI } from './api/files';\r\n\r\n/**\r\n * Internal cache store for metadata\r\n */\r\ninterface CacheStore {\r\n objects?: { data: unknown; timestamp: number };\r\n fields: Map<string, { data: unknown; timestamp: number }>;\r\n fieldValues: Map<string, { data: unknown; timestamp: number }>;\r\n}\r\n\r\n/**\r\n * Internal cache store for query results\r\n */\r\ninterface QueryCache {\r\n data: QueryResult;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Generates a cache key from query options for deduplication\r\n */\r\nfunction generateQueryCacheKey(options: QueryOptions): string {\r\n const parts = [\r\n options.objectType,\r\n Array.isArray(options.fields) ? options.fields.join(',') : options.fields || '*',\r\n options.query || '',\r\n options.sortBy || 'modifiedon',\r\n options.sortType || 'desc',\r\n options.limit?.toString() || '',\r\n options.page?.toString() || '1',\r\n options.pageSize?.toString() || '500',\r\n options.showRealValue !== false ? '1' : '0',\r\n options.autoPage !== false ? '1' : '0',\r\n ];\r\n return parts.join('|');\r\n}\r\n\r\n/**\r\n * FireberryClient - Main client for interacting with the Fireberry CRM API\r\n *\r\n * @example\r\n * ```typescript\r\n * const client = new FireberryClient({\r\n * apiKey: 'your-api-key',\r\n * retryOn429: true,\r\n * maxRetries: 120,\r\n * });\r\n *\r\n * // Query records\r\n * const result = await client.query({\r\n * objectType: '1',\r\n * fields: ['accountid', 'name'],\r\n * query: '(statuscode = 1)',\r\n * });\r\n *\r\n * // Use query builder\r\n * const result = await client.queryBuilder()\r\n * .objectType('1')\r\n * .select('accountid', 'name')\r\n * .where('statuscode').equals('1')\r\n * .execute();\r\n * ```\r\n */\r\nexport class FireberryClient {\r\n private readonly config: FireberryClientConfig;\r\n private readonly normalizedConfig: {\r\n baseUrl: string;\r\n timeout: number;\r\n retryOn429: boolean;\r\n maxRetries: number;\r\n retryDelay: number;\r\n cacheMetadata: boolean;\r\n cacheTTL: number;\r\n cacheQueryResults: boolean;\r\n queryResultCacheTTL: number;\r\n invalidateCacheOnMutation: boolean;\r\n };\r\n private readonly cacheStore: CacheStore;\r\n private readonly inFlightQueries: Map<string, Promise<QueryResult>> = new Map();\r\n private readonly queryCache: Map<string, QueryCache> = new Map();\r\n private readonly transport: Transport;\r\n private readonly metadataTransport: HTTPTransport | null;\r\n\r\n /** Metadata API operations */\r\n readonly metadata: MetadataAPI;\r\n /** Records CRUD operations */\r\n readonly records: RecordsAPI;\r\n /** Batch operations */\r\n readonly batch: BatchAPI;\r\n /** Field management operations */\r\n readonly fields: FieldsAPI;\r\n /** File operations */\r\n readonly files: FilesAPI;\r\n\r\n /**\r\n * Creates a new FireberryClient instance\r\n */\r\n constructor(config: FireberryClientConfig) {\r\n // Store original config\r\n this.config = config;\r\n\r\n // Create normalized config for settings\r\n this.normalizedConfig = {\r\n baseUrl: config.baseUrl || 'https://api.fireberry.com',\r\n timeout: config.timeout || 30000,\r\n retryOn429: config.retryOn429 ?? true,\r\n maxRetries: config.maxRetries || 120,\r\n retryDelay: config.retryDelay || 1000,\r\n cacheMetadata: config.cacheMetadata || false,\r\n cacheTTL: config.cacheTTL || 300000, // 5 minutes default\r\n cacheQueryResults: config.cacheQueryResults || false,\r\n queryResultCacheTTL: config.queryResultCacheTTL || 60000, // 1 minute default\r\n invalidateCacheOnMutation: config.invalidateCacheOnMutation ?? true, // Smart cache invalidation enabled by default\r\n };\r\n\r\n // Initialize cache store\r\n this.cacheStore = {\r\n fields: new Map(),\r\n fieldValues: new Map(),\r\n };\r\n\r\n // Create transport layer\r\n this.transport = createTransport(config);\r\n this.metadataTransport = createMetadataTransport(config);\r\n\r\n // Initialize API modules\r\n this.metadata = new MetadataAPI(this);\r\n this.records = new RecordsAPI(this);\r\n this.batch = new BatchAPI(this);\r\n this.fields = new FieldsAPI(this);\r\n this.files = new FilesAPI(this);\r\n }\r\n\r\n /**\r\n * Gets the client configuration with all defaults applied\r\n */\r\n getConfig(): Readonly<FireberryClientConfig & {\r\n baseUrl: string;\r\n timeout: number;\r\n retryOn429: boolean;\r\n maxRetries: number;\r\n retryDelay: number;\r\n cacheMetadata: boolean;\r\n cacheTTL: number;\r\n cacheQueryResults: boolean;\r\n queryResultCacheTTL: number;\r\n invalidateCacheOnMutation: boolean;\r\n }> {\r\n return {\r\n ...this.config,\r\n ...this.normalizedConfig,\r\n };\r\n }\r\n\r\n /**\r\n * Gets the transport instance (for internal use by API modules)\r\n * @internal\r\n */\r\n getTransport(): Transport {\r\n return this.transport;\r\n }\r\n\r\n /**\r\n * Gets the metadata transport instance (for internal use by MetadataAPI)\r\n * Returns null if metadata is not available (SDK-only mode without API key)\r\n * @internal\r\n */\r\n getMetadataTransport(): HTTPTransport | null {\r\n return this.metadataTransport;\r\n }\r\n\r\n /**\r\n * Checks if metadata operations are available\r\n */\r\n isMetadataAvailable(): boolean {\r\n return isMetadataAvailable(this.config);\r\n }\r\n\r\n /**\r\n * Cache control methods\r\n */\r\n readonly cache: CacheControl & {\r\n /** Clear all query result cache */\r\n clearQueryResults: () => void;\r\n /** Clear query results for a specific object type */\r\n clearQueryResultsForObject: (objectType: string) => void;\r\n } = {\r\n clear: () => {\r\n this.cacheStore.objects = undefined;\r\n this.cacheStore.fields.clear();\r\n this.cacheStore.fieldValues.clear();\r\n this.queryCache.clear();\r\n },\r\n clearObjects: () => {\r\n this.cacheStore.objects = undefined;\r\n },\r\n clearFields: (objectType: string) => {\r\n this.cacheStore.fields.delete(objectType);\r\n },\r\n clearFieldValues: (objectType: string, fieldName?: string) => {\r\n if (fieldName) {\r\n this.cacheStore.fieldValues.delete(`${objectType}:${fieldName}`);\r\n } else {\r\n // Clear all field values for this object type\r\n for (const key of this.cacheStore.fieldValues.keys()) {\r\n if (key.startsWith(`${objectType}:`)) {\r\n this.cacheStore.fieldValues.delete(key);\r\n }\r\n }\r\n }\r\n },\r\n clearQueryResults: () => {\r\n this.queryCache.clear();\r\n },\r\n clearQueryResultsForObject: (objectType: string) => {\r\n // Clear all query results for this object type\r\n for (const key of this.queryCache.keys()) {\r\n if (key.startsWith(`${objectType}|`)) {\r\n this.queryCache.delete(key);\r\n }\r\n }\r\n },\r\n };\r\n\r\n /**\r\n * Invalidates the query cache for an object type after a mutation.\r\n * Called automatically by RecordsAPI and BatchAPI when mutations occur.\r\n * Only takes effect if `invalidateCacheOnMutation` is enabled (default: true).\r\n *\r\n * @param objectType - The object type that was mutated\r\n * @internal\r\n */\r\n invalidateCacheForMutation(objectType: string): void {\r\n if (this.normalizedConfig.invalidateCacheOnMutation) {\r\n this.cache.clearQueryResultsForObject(objectType);\r\n }\r\n }\r\n\r\n /**\r\n * Cleans up expired cache entries (called on write to prevent memory leaks)\r\n */\r\n private cleanupExpiredCacheEntries(): void {\r\n const now = Date.now();\r\n\r\n // Clean query cache\r\n if (this.normalizedConfig.cacheQueryResults) {\r\n for (const [key, entry] of this.queryCache) {\r\n if (now - entry.timestamp >= this.normalizedConfig.queryResultCacheTTL) {\r\n this.queryCache.delete(key);\r\n }\r\n }\r\n }\r\n\r\n // Clean metadata caches\r\n if (this.normalizedConfig.cacheMetadata) {\r\n // Clean objects cache\r\n if (this.cacheStore.objects && now - this.cacheStore.objects.timestamp >= this.normalizedConfig.cacheTTL) {\r\n this.cacheStore.objects = undefined;\r\n }\r\n\r\n // Clean fields cache\r\n for (const [key, entry] of this.cacheStore.fields) {\r\n if (now - entry.timestamp >= this.normalizedConfig.cacheTTL) {\r\n this.cacheStore.fields.delete(key);\r\n }\r\n }\r\n\r\n // Clean fieldValues cache\r\n for (const [key, entry] of this.cacheStore.fieldValues) {\r\n if (now - entry.timestamp >= this.normalizedConfig.cacheTTL) {\r\n this.cacheStore.fieldValues.delete(key);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Gets cached data if valid, or undefined if not cached or expired\r\n */\r\n getCached<T>(type: 'objects'): T | undefined;\r\n getCached<T>(type: 'fields', objectType: string): T | undefined;\r\n getCached<T>(type: 'fieldValues', objectType: string, fieldName: string): T | undefined;\r\n getCached<T>(\r\n type: 'objects' | 'fields' | 'fieldValues',\r\n objectType?: string,\r\n fieldName?: string,\r\n ): T | undefined {\r\n if (!this.normalizedConfig.cacheMetadata) {\r\n return undefined;\r\n }\r\n\r\n const now = Date.now();\r\n\r\n if (type === 'objects') {\r\n const cached = this.cacheStore.objects;\r\n if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {\r\n return cached.data as T;\r\n }\r\n } else if (type === 'fields' && objectType) {\r\n const cached = this.cacheStore.fields.get(objectType);\r\n if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {\r\n return cached.data as T;\r\n }\r\n } else if (type === 'fieldValues' && objectType && fieldName) {\r\n const key = `${objectType}:${fieldName}`;\r\n const cached = this.cacheStore.fieldValues.get(key);\r\n if (cached && now - cached.timestamp < this.normalizedConfig.cacheTTL) {\r\n return cached.data as T;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Sets cached data\r\n */\r\n setCache(type: 'objects', data: unknown): void;\r\n setCache(type: 'fields', objectType: string, data: unknown): void;\r\n setCache(type: 'fieldValues', objectType: string, fieldName: string, data: unknown): void;\r\n setCache(\r\n type: 'objects' | 'fields' | 'fieldValues',\r\n objectTypeOrData?: string | unknown,\r\n fieldNameOrData?: string | unknown,\r\n data?: unknown,\r\n ): void {\r\n if (!this.normalizedConfig.cacheMetadata) {\r\n return;\r\n }\r\n\r\n // Cleanup expired entries on write\r\n this.cleanupExpiredCacheEntries();\r\n\r\n const now = Date.now();\r\n\r\n if (type === 'objects') {\r\n this.cacheStore.objects = { data: objectTypeOrData, timestamp: now };\r\n } else if (type === 'fields' && typeof objectTypeOrData === 'string') {\r\n this.cacheStore.fields.set(objectTypeOrData, {\r\n data: fieldNameOrData,\r\n timestamp: now,\r\n });\r\n } else if (\r\n type === 'fieldValues' &&\r\n typeof objectTypeOrData === 'string' &&\r\n typeof fieldNameOrData === 'string'\r\n ) {\r\n const key = `${objectTypeOrData}:${fieldNameOrData}`;\r\n this.cacheStore.fieldValues.set(key, { data, timestamp: now });\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new QueryBuilder instance\r\n */\r\n queryBuilder(): QueryBuilder {\r\n return new QueryBuilder(this);\r\n }\r\n\r\n /**\r\n * Executes multiple queries in parallel\r\n * Respects rate limits by chunking concurrent requests\r\n *\r\n * @param queries - Array of query options to execute\r\n * @param options - Parallel execution options\r\n * @returns Array of query results in the same order as input queries\r\n *\r\n * @example\r\n * ```typescript\r\n * const results = await client.queryAll([\r\n * { objectType: '1', fields: ['accountid', 'name'] },\r\n * { objectType: '2', fields: ['contactid', 'fullname'] },\r\n * { objectType: '4', fields: ['opportunityid', 'name'] },\r\n * ]);\r\n * ```\r\n */\r\n async queryAll(\r\n queries: QueryOptions[],\r\n options: { concurrency?: number; signal?: AbortSignal } = {},\r\n ): Promise<QueryResult[]> {\r\n const { concurrency = 5, signal } = options;\r\n\r\n if (queries.length === 0) {\r\n return [];\r\n }\r\n\r\n const results: QueryResult[] = new Array(queries.length);\r\n\r\n // Process in chunks to respect rate limits\r\n for (let i = 0; i < queries.length; i += concurrency) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n throw new FireberryError('Query aborted', {\r\n code: FireberryErrorCode.NETWORK_ERROR,\r\n });\r\n }\r\n\r\n const chunk = queries.slice(i, i + concurrency);\r\n const chunkPromises = chunk.map((queryOpts, chunkIndex) => {\r\n // Pass signal to individual queries if provided\r\n const queryWithSignal = signal ? { ...queryOpts, signal } : queryOpts;\r\n return this.query(queryWithSignal).then((result) => {\r\n results[i + chunkIndex] = result;\r\n });\r\n });\r\n\r\n await Promise.all(chunkPromises);\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Streams query results using an async iterator (cursor-based pagination)\r\n * Yields batches of records, allowing processing of large datasets without loading all into memory\r\n *\r\n * @param options - Query options (autoPage is ignored, pagination is handled by the iterator)\r\n * @yields Batches of records as QueryResult objects\r\n *\r\n * @example\r\n * ```typescript\r\n * // Process records in batches\r\n * for await (const batch of client.queryStream({\r\n * objectType: '1',\r\n * fields: ['accountid', 'name'],\r\n * pageSize: 100,\r\n * })) {\r\n * console.log(`Processing ${batch.records.length} records...`);\r\n * for (const record of batch.records) {\r\n * // Process each record\r\n * }\r\n * }\r\n *\r\n * // Collect all records from stream\r\n * const allRecords: Record<string, unknown>[] = [];\r\n * for await (const batch of client.queryStream({ objectType: '1', fields: '*' })) {\r\n * allRecords.push(...batch.records);\r\n * }\r\n * ```\r\n */\r\n async *queryStream(\r\n options: Omit<QueryOptions, 'autoPage'>,\r\n ): AsyncGenerator<QueryResult, void, undefined> {\r\n const { objectType, fields, query, sortBy = 'modifiedon', sortType = 'desc', limit, pageSize = 500, showRealValue = true, signal } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // Handle '*' expansion for object types with excluded fields\r\n if (fieldsStr === '*') {\r\n fieldsStr = await this.expandStarFields(objectType, signal);\r\n }\r\n\r\n let currentPage = 1;\r\n let totalFetched = 0;\r\n let hasMore = true;\r\n\r\n while (hasMore) {\r\n // Check for abort\r\n if (signal?.aborted) {\r\n return;\r\n }\r\n\r\n // Calculate page size for this request\r\n const requestPageSize = limit\r\n ? Math.min(pageSize, limit - totalFetched)\r\n : pageSize;\r\n\r\n if (requestPageSize <= 0) {\r\n return;\r\n }\r\n\r\n const body = {\r\n objecttype: objectType,\r\n fields: fieldsStr,\r\n query: query || '',\r\n sort_by: sortBy,\r\n sort_type: sortType,\r\n page_size: requestPageSize,\r\n page_number: currentPage,\r\n show_real_value: showRealValue ? 1 : 0,\r\n };\r\n\r\n const response = await this.request<{ data?: { Data?: Record<string, unknown>[] } }>({\r\n method: 'POST',\r\n endpoint: '/api/query',\r\n body,\r\n signal,\r\n });\r\n\r\n const records = response.data?.Data || [];\r\n totalFetched += records.length;\r\n\r\n yield {\r\n records,\r\n total: records.length,\r\n success: true,\r\n page: currentPage,\r\n };\r\n\r\n // Check if there are more pages\r\n if (records.length < requestPageSize || (limit && totalFetched >= limit)) {\r\n hasMore = false;\r\n } else {\r\n currentPage++;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Executes a query against the Fireberry API\r\n * Automatically deduplicates concurrent identical requests\r\n * Optionally caches results (if cacheQueryResults is enabled)\r\n */\r\n async query(options: QueryOptions): Promise<QueryResult> {\r\n // Generate cache key for deduplication and caching\r\n const cacheKey = generateQueryCacheKey(options);\r\n\r\n // Check query result cache first\r\n if (this.normalizedConfig.cacheQueryResults) {\r\n const cached = this.queryCache.get(cacheKey);\r\n if (cached && Date.now() - cached.timestamp < this.normalizedConfig.queryResultCacheTTL) {\r\n return cached.data;\r\n }\r\n }\r\n\r\n // Check for in-flight request with same parameters\r\n const inFlight = this.inFlightQueries.get(cacheKey);\r\n if (inFlight) {\r\n return inFlight;\r\n }\r\n\r\n // Execute query and track it\r\n const queryPromise = this.executeQuery(options);\r\n\r\n // Store in-flight promise\r\n this.inFlightQueries.set(cacheKey, queryPromise);\r\n\r\n try {\r\n const result = await queryPromise;\r\n\r\n // Store in cache if caching is enabled\r\n if (this.normalizedConfig.cacheQueryResults) {\r\n // Cleanup expired entries on write\r\n this.cleanupExpiredCacheEntries();\r\n this.queryCache.set(cacheKey, {\r\n data: result,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n return result;\r\n } finally {\r\n // Remove from in-flight map when done\r\n this.inFlightQueries.delete(cacheKey);\r\n }\r\n }\r\n\r\n /**\r\n * Internal query execution (without deduplication)\r\n */\r\n private async executeQuery(options: QueryOptions): Promise<QueryResult> {\r\n const {\r\n objectType,\r\n fields,\r\n signal,\r\n } = options;\r\n\r\n // Normalize fields to string\r\n let fieldsStr: string;\r\n if (Array.isArray(fields)) {\r\n fieldsStr = fields.join(',');\r\n } else if (typeof fields === 'string') {\r\n fieldsStr = fields;\r\n } else {\r\n fieldsStr = '*';\r\n }\r\n\r\n // Handle '*' expansion for object types with excluded fields\r\n if (fieldsStr === '*') {\r\n fieldsStr = await this.expandStarFields(objectType, signal);\r\n }\r\n\r\n // Use transport to execute the query\r\n return this.transport.query({\r\n ...options,\r\n fields: fieldsStr,\r\n });\r\n }\r\n\r\n /**\r\n * Expands '*' fields to actual field names, excluding problematic fields for specific object types\r\n */\r\n private async expandStarFields(objectType: string, signal?: AbortSignal): Promise<string> {\r\n const { getExcludedFieldsForStarQuery } = await import('./constants/excludedFields');\r\n const excludedFields = getExcludedFieldsForStarQuery(objectType);\r\n\r\n // If no excluded fields for this object type, just return '*'\r\n if (excludedFields.length === 0) {\r\n return '*';\r\n }\r\n\r\n // Fetch metadata to get all field names\r\n const fieldsResult = await this.metadata.getFields(objectType, signal);\r\n const allFieldNames = fieldsResult.fields.map((f) => f.fieldName);\r\n\r\n // Filter out excluded fields\r\n const filteredFields = allFieldNames.filter(\r\n (fieldName) => !excludedFields.includes(fieldName),\r\n );\r\n\r\n return filteredFields.join(',');\r\n }\r\n\r\n /**\r\n * Makes a raw API request to the Fireberry API\r\n * @deprecated Use getTransport() or getMetadataTransport() for new code\r\n * @internal This method is kept for backwards compatibility with API modules\r\n */\r\n async request<T = unknown>(options: RequestOptions): Promise<T> {\r\n // Delegate to metadata transport if available (for metadata operations)\r\n // Otherwise use the main transport\r\n const transport = this.metadataTransport || this.transport;\r\n\r\n // For HTTP transport, delegate directly\r\n if (transport instanceof HTTPTransport) {\r\n return transport.request<T>(options);\r\n }\r\n\r\n // For SDK transport, throw error since raw requests aren't supported\r\n throw new FireberryError(\r\n 'Raw request() is not supported in SDK mode. Use specific methods like query(), createRecord(), etc.',\r\n {\r\n code: FireberryErrorCode.INVALID_REQUEST,\r\n }\r\n );\r\n }\r\n}\r\n","/**\r\n * Special field name mappings that don't follow standard patterns\r\n * Key: original field name, Value: corresponding label field\r\n */\r\nconst SPECIAL_LABEL_FIELD_MAPPINGS: Record<string, string> = {\r\n objectid: 'objecttitle',\r\n lastactionid: 'lastactiontitle',\r\n wfruleid: 'rulename', // Object 55 (Workflow Rules)\r\n noteid: 'subject', // Object 7 (Note) - noteid maps to subject\r\n};\r\n\r\n/**\r\n * Fields ending with \"id\" that should NOT have \"id\" replaced with \"name\"\r\n * These fields will use the default append \"name\" behavior instead\r\n */\r\nconst EXCLUDED_ID_FIELDS: string[] = [\r\n 'businessunitid', // → businessunitidname (not businessunitname)\r\n 'crmuserid', // → no name field exists\r\n 'languageid', // → languageidname (not languagename)\r\n];\r\n\r\n/**\r\n * Fields ending with \"code\" that should NOT have \"code\" removed\r\n * These fields will use the default append \"name\" behavior instead\r\n */\r\nconst EXCLUDED_CODE_FIELDS: string[] = [\r\n 'duplicaterecordcode', // → duplicaterecordcodename (not duplicaterecord)\r\n];\r\n\r\n/**\r\n * Fields that have NO corresponding label field at all\r\n * These fields should not have any name transformation applied\r\n * Return empty string to signal \"no label field exists\"\r\n */\r\nconst FIELDS_WITHOUT_LABEL_FIELD: string[] = [\r\n 'systemfieldid', // Object 73 - no name field exists\r\n 'fieldobjecttype', // Object 73 - base field doesn't exist, only *name exists\r\n 'invoiceid', // Objects 78, 81 - no name field exists\r\n 'calllogid', // Object 100 - no name field exists (primary key)\r\n 'attendanceclockid', // Object 101 - no name field exists (primary key)\r\n 'activitylogid', // Object 102 - no name field exists (primary key)\r\n 'conversationid', // Object 104 - no name field exists (primary key)\r\n 'texttemplateid', // Text Template - no name field exists (primary key)\r\n 'smstemplateid', // Object 110 - no name field exists (primary key)\r\n 'deletedby', // Object 7 - no name field exists\r\n 'recordid', // Object 7 - no name field exists\r\n 'objecttypecode', // Object 7 - no name field exists\r\n];\r\n\r\n/**\r\n * Object-type specific overrides for field name transformations\r\n * Key: object type ID, Value: { excludedIdFields, excludedCodeFields }\r\n */\r\nconst OBJECT_TYPE_OVERRIDES: Record<\r\n number,\r\n { excludedIdFields?: string[]; excludedCodeFields?: string[] }\r\n> = {\r\n // Account (1) - uses *codename pattern for some fields\r\n 1: {\r\n excludedCodeFields: ['actionstatuscode', 'businesstypecode'],\r\n },\r\n // CRM Orders (13) - uses *idname and *codename patterns\r\n 13: {\r\n excludedIdFields: ['ownerid', 'accountid', 'printtemplateid', 'pcfaccountid'],\r\n excludedCodeFields: [\r\n 'rounddiscountcode',\r\n 'taxincludecode',\r\n 'currencycode',\r\n 'transmissioncode',\r\n 'creditrejectioncode1',\r\n 'creditrejectioncode2',\r\n 'apartmentcode1',\r\n 'apartmentcode2',\r\n 'restrictioncode1',\r\n 'restrictioncode2',\r\n 'casescode1',\r\n 'casescode2',\r\n 'returncode1',\r\n 'returncode2',\r\n 'statuscode',\r\n ],\r\n },\r\n // Products (14)\r\n 14: {\r\n excludedCodeFields: ['categorycode'], // → categoryname (not category)\r\n },\r\n // CRM Order Items (17) - uses *idname pattern\r\n 17: {\r\n excludedIdFields: ['crmorderid', 'productid', 'ownerid'],\r\n },\r\n // Email Templates (20)\r\n 20: {\r\n excludedIdFields: ['mdobjectid'],\r\n },\r\n // Print Templates (27)\r\n 27: {\r\n excludedIdFields: ['mdobjectid'],\r\n },\r\n // System Fields (73) - uses *idname pattern\r\n 73: {\r\n excludedIdFields: ['mdobjectid', 'ownerid'],\r\n },\r\n // Invoices (78) - uses *codename and *idname patterns extensively\r\n 78: {\r\n excludedIdFields: [\r\n 'crmorderid',\r\n 'invoicereceiptid',\r\n 'accountid',\r\n 'ownerid',\r\n 'invoicerenoid',\r\n ],\r\n excludedCodeFields: [\r\n 'taxincludecode',\r\n 'depositcode',\r\n 'rounddiscountcode',\r\n 'currencycode',\r\n 'statecode',\r\n 'invoicetypecode',\r\n ],\r\n },\r\n // Invoice No (81) - uses *codename and *idname patterns extensively\r\n 81: {\r\n excludedIdFields: [\r\n 'ownerid',\r\n 'invoicecreditid',\r\n 'crmorderid',\r\n 'invoicereceiptid',\r\n 'invoicedeliveryid',\r\n 'accountid',\r\n ],\r\n excludedCodeFields: ['currencycode', 'rounddiscountcode', 'statecode', 'taxincludecode'],\r\n },\r\n // Invoice Draft (82) - uses *codename and *idname patterns extensively\r\n 82: {\r\n excludedIdFields: ['accountid', 'crmorderid', 'ownerid', 'invoicerenoid'],\r\n excludedCodeFields: ['taxincludecode', 'statecode', 'rounddiscountcode', 'currencycode'],\r\n },\r\n // Invoice Receipt (83) - uses *codename and *idname patterns\r\n 83: {\r\n excludedIdFields: ['invoicenoid', 'crmorderid', 'ownerid', 'accountid'],\r\n excludedCodeFields: ['statecode', 'currencycode'],\r\n },\r\n // Invoice Tax Receipt (84) - uses *codename and *idname patterns\r\n 84: {\r\n excludedIdFields: ['crmorderid', 'ownerid', 'invoicecreditid', 'accountid'],\r\n excludedCodeFields: ['rounddiscountcode', 'statecode', 'taxincludecode', 'currencycode'],\r\n },\r\n // Invoice Credit (85) - uses *codename and *idname patterns\r\n 85: {\r\n excludedIdFields: ['ownerid', 'crmorderid', 'accountid'],\r\n excludedCodeFields: ['taxincludecode', 'rounddiscountcode', 'currencycode', 'statecode'],\r\n },\r\n // Invoice (86) - uses *codename and *idname patterns\r\n 86: {\r\n excludedIdFields: ['accountid', 'ownerid', 'crmorderid'],\r\n excludedCodeFields: ['statecode', 'rounddiscountcode', 'currencycode', 'taxincludecode'],\r\n },\r\n // Call Log (100) - uses *idname pattern\r\n 100: {\r\n excludedIdFields: ['contactid', 'leadid', 'accountid', 'ownerid'],\r\n },\r\n // Attendance Clock (101) - uses *idname pattern\r\n 101: {\r\n excludedIdFields: ['ownerid'],\r\n },\r\n // Activity Log (102) - uses *idname and *codename patterns\r\n 102: {\r\n excludedIdFields: ['contactid', 'ownerid'],\r\n excludedCodeFields: ['objecttypecode', 'typecode', 'resultcode'],\r\n },\r\n // Conversation (104) - uses *idname pattern\r\n 104: {\r\n excludedIdFields: ['leadid', 'ownerid', 'contactid', 'accountid'],\r\n },\r\n // Text Template (106) - uses *idname pattern\r\n 106: {\r\n excludedIdFields: ['ownerid'],\r\n },\r\n // SMS Template (110) - uses *idname pattern\r\n 110: {\r\n excludedIdFields: ['ownerid'],\r\n },\r\n};\r\n\r\n/**\r\n * Checks if a field is a label-only/display field that cannot be queried directly.\r\n * Label fields are virtual fields derived from code/id fields (e.g., `actionstatus` from `actionstatuscode`).\r\n * Fireberry returns them automatically when you query their code counterpart.\r\n *\r\n * @param fieldName - The field name to check\r\n * @param allFieldNames - All field names for this object type (from metadata)\r\n * @param objectType - The object type ID\r\n * @returns True if the field is a label-only field that should not be included in queries\r\n */\r\nexport function isLabelOnlyField(\r\n fieldName: string,\r\n allFieldNames: string[],\r\n objectType: string | number,\r\n): boolean {\r\n // Check if this field is the label output of any other field in the list\r\n for (const otherField of allFieldNames) {\r\n if (otherField === fieldName) continue;\r\n const labelField = getLabelFieldForField(otherField, objectType);\r\n if (labelField === fieldName) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Filters out label-only fields from a field list, returning only queryable fields.\r\n * Use this before sending fields to the Fireberry query API.\r\n *\r\n * @param fieldNames - Array of field names to filter\r\n * @param objectType - The object type ID\r\n * @returns Array with label-only fields removed\r\n */\r\nexport function filterLabelOnlyFields(\r\n fieldNames: string[],\r\n objectType: string | number,\r\n): string[] {\r\n return fieldNames.filter(\r\n (fieldName) => !isLabelOnlyField(fieldName, fieldNames, objectType),\r\n );\r\n}\r\n\r\n/**\r\n * Converts a field API name to its corresponding label field.\r\n *\r\n * Rules:\r\n * - Special mappings (e.g., objectid → objecttitle)\r\n * - Fields starting with \"pcf\" (custom fields): append \"name\" → pcf_field → pcf_fieldname\r\n * - Fields ending with \"code\" (unless excluded): remove \"code\" → statuscode → status\r\n * - Fields ending with \"id\" (unless excluded): replace \"id\" with \"name\" → accountid → accountname\r\n * - All other fields: append \"name\"\r\n *\r\n * @param fieldName - The field API name\r\n * @param objectType - The object type ID (required for object-specific overrides)\r\n * @returns The corresponding label field, or empty string if no label field exists\r\n */\r\nexport function getLabelFieldForField(fieldName: string, objectType: string | number): string {\r\n // Check special mappings first\r\n if (SPECIAL_LABEL_FIELD_MAPPINGS[fieldName]) {\r\n return SPECIAL_LABEL_FIELD_MAPPINGS[fieldName];\r\n }\r\n\r\n // Check if field has no label field at all - return empty string\r\n if (FIELDS_WITHOUT_LABEL_FIELD.includes(fieldName)) {\r\n return '';\r\n }\r\n\r\n // Check for custom object primary keys (customobject{N}id pattern) → name\r\n if (/^customobject\\d+id$/.test(fieldName)) {\r\n return 'name';\r\n }\r\n\r\n // Custom fields (pcf prefix) - just append \"name\"\r\n if (fieldName.startsWith('pcf')) {\r\n return `${fieldName}name`;\r\n }\r\n\r\n // Get object-type specific overrides\r\n const objectTypeNum =\r\n typeof objectType === 'string' ? parseInt(objectType, 10) : objectType;\r\n const overrides = OBJECT_TYPE_OVERRIDES[objectTypeNum] || null;\r\n\r\n // For custom objects (1000+), add default exclusions\r\n const isCustomObject = objectTypeNum >= 1000;\r\n const customObjectExclusions = isCustomObject ? ['ownerid'] : [];\r\n\r\n // Combine global and object-specific exclusions\r\n const excludedCodeFields = [\r\n ...EXCLUDED_CODE_FIELDS,\r\n ...(overrides?.excludedCodeFields || []),\r\n ];\r\n const excludedIdFields = [\r\n ...EXCLUDED_ID_FIELDS,\r\n ...(overrides?.excludedIdFields || []),\r\n ...customObjectExclusions,\r\n ];\r\n\r\n // Remove \"code\" suffix (unless excluded) → statuscode → status\r\n if (fieldName.endsWith('code') && !excludedCodeFields.includes(fieldName)) {\r\n return fieldName.slice(0, -4);\r\n }\r\n\r\n // Replace \"id\" suffix with \"name\" (unless excluded) → accountid → accountname\r\n if (fieldName.endsWith('id') && !excludedIdFields.includes(fieldName)) {\r\n return fieldName.slice(0, -2) + 'name';\r\n }\r\n\r\n // Default: append \"name\"\r\n return `${fieldName}name`;\r\n}\r\n","/**\r\n * Related Field Mapping Utilities\r\n *\r\n * Functions for parsing and resolving related object field references.\r\n * Related fields use the pattern: {referenceField}_{relatedField}\r\n * Example: accountid_telephone1, contactid_fullname, accountid_statuscode\r\n */\r\n\r\nimport { OBJECT_ID_MAP } from '../constants/objectIds';\r\nimport { FIELD_TYPE_IDS } from '../constants/fieldTypes';\r\nimport { getLabelFieldForField } from './fieldMapping';\r\nimport type { FireberryField } from '../types/metadata';\r\n\r\n/**\r\n * Reverse mapping from ID field name to object type ID\r\n * Generated from OBJECT_ID_MAP\r\n */\r\nexport const ID_FIELD_TO_OBJECT_TYPE: Record<string, number> = Object.entries(OBJECT_ID_MAP).reduce(\r\n (acc, [objectTypeId, idFieldName]) => {\r\n acc[idFieldName] = parseInt(objectTypeId, 10);\r\n return acc;\r\n },\r\n {} as Record<string, number>,\r\n);\r\n\r\n/**\r\n * Information about a parsed related field\r\n */\r\nexport interface RelatedFieldInfo {\r\n /** The original field name (e.g., \"accountid_telephone1\") */\r\n originalField: string;\r\n /** The reference/lookup field (e.g., \"accountid\") */\r\n referenceField: string;\r\n /** The field on the related object (e.g., \"telephone1\") */\r\n relatedField: string;\r\n /** The object type ID of the related object (e.g., 1 for Account) */\r\n relatedObjectType: number;\r\n}\r\n\r\n/**\r\n * Result of resolving a related field with its label field(s)\r\n */\r\nexport interface RelatedFieldResolution {\r\n /** The original field name */\r\n originalField: string;\r\n /** All fields that should be selected/returned */\r\n fields: string[];\r\n /** The primary value field */\r\n valueField: string;\r\n /** The label/display field (may be same as valueField for non-code fields) */\r\n labelField: string;\r\n /** The code field if applicable (for dropdown fields) */\r\n codeField?: string;\r\n /** Whether this is a code field (ends with 'code') */\r\n isCodeField: boolean;\r\n /** Related object type ID */\r\n relatedObjectType: number;\r\n /** Field type from metadata (if available) */\r\n fieldType?: string;\r\n}\r\n\r\n/**\r\n * Field metadata map type - maps field name to field info\r\n */\r\nexport type FieldMetadataMap = Map<string, FireberryField>;\r\n\r\n/**\r\n * Gets the object type ID from a reference field name\r\n *\r\n * @param referenceField - The reference field name (e.g., \"accountid\", \"contactid\")\r\n * @returns The object type ID, or null if not a known reference field\r\n *\r\n * @example\r\n * getObjectTypeFromReferenceField('accountid') // 1\r\n * getObjectTypeFromReferenceField('contactid') // 2\r\n * getObjectTypeFromReferenceField('leadid') // 3\r\n * getObjectTypeFromReferenceField('unknown') // null\r\n */\r\nexport function getObjectTypeFromReferenceField(referenceField: string): number | null {\r\n // Check standard mappings\r\n if (ID_FIELD_TO_OBJECT_TYPE[referenceField]) {\r\n return ID_FIELD_TO_OBJECT_TYPE[referenceField];\r\n }\r\n\r\n // Check for custom object pattern: customobject{N}id\r\n const customMatch = referenceField.match(/^customobject(\\d+)id$/);\r\n if (customMatch) {\r\n return parseInt(customMatch[1], 10);\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parses a related field name into its components\r\n *\r\n * @param fieldName - The field name to parse (e.g., \"accountid_telephone1\")\r\n * @returns RelatedFieldInfo if it's a valid related field, null otherwise\r\n *\r\n * @example\r\n * parseRelatedField('accountid_telephone1')\r\n * // { originalField: 'accountid_telephone1', referenceField: 'accountid',\r\n * // relatedField: 'telephone1', relatedObjectType: 1 }\r\n *\r\n * parseRelatedField('accountid_statuscode')\r\n * // { originalField: 'accountid_statuscode', referenceField: 'accountid',\r\n * // relatedField: 'statuscode', relatedObjectType: 1 }\r\n *\r\n * parseRelatedField('telephone1') // null (not a related field)\r\n */\r\nexport function parseRelatedField(fieldName: string): RelatedFieldInfo | null {\r\n // Must contain underscore\r\n const underscoreIndex = fieldName.indexOf('_');\r\n if (underscoreIndex === -1) {\r\n return null;\r\n }\r\n\r\n // Try to find a valid reference field by checking progressively longer prefixes\r\n // This handles cases like pcf_accountid_status where we need to find the right split\r\n const parts = fieldName.split('_');\r\n\r\n // Start from the first part and try combinations\r\n for (let i = 0; i < parts.length - 1; i++) {\r\n const potentialRefField = parts.slice(0, i + 1).join('_');\r\n const objectType = getObjectTypeFromReferenceField(potentialRefField);\r\n\r\n if (objectType !== null) {\r\n const relatedField = parts.slice(i + 1).join('_');\r\n if (relatedField) {\r\n return {\r\n originalField: fieldName,\r\n referenceField: potentialRefField,\r\n relatedField,\r\n relatedObjectType: objectType,\r\n };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Determines if a field is a \"code\" field (stores internal value, has label equivalent)\r\n *\r\n * @param fieldName - The field name to check\r\n * @returns True if the field is a code field\r\n */\r\nexport function isCodeField(fieldName: string): boolean {\r\n return fieldName.endsWith('code');\r\n}\r\n\r\n/**\r\n * Gets the code field name for a label field\r\n * For example: status -> statuscode\r\n *\r\n * @param labelField - The label field name\r\n * @returns The code field name\r\n */\r\nexport function getCodeFieldFromLabel(labelField: string): string {\r\n return `${labelField}code`;\r\n}\r\n\r\n/**\r\n * Gets the label field name for a code field\r\n * For example: statuscode -> status\r\n *\r\n * @param codeField - The code field name\r\n * @returns The label field name\r\n */\r\nexport function getLabelFieldFromCode(codeField: string): string {\r\n if (codeField.endsWith('code')) {\r\n return codeField.slice(0, -4);\r\n }\r\n return codeField;\r\n}\r\n\r\n/**\r\n * Checks if a field is a dropdown type based on metadata\r\n *\r\n * @param fieldName - The field name to check\r\n * @param metadata - Field metadata map\r\n * @returns True if the field is a dropdown type\r\n */\r\nexport function isDropdownFieldByMetadata(\r\n fieldName: string,\r\n metadata: FieldMetadataMap,\r\n): boolean {\r\n const field = metadata.get(fieldName);\r\n return field?.systemFieldTypeId === FIELD_TYPE_IDS.DROPDOWN;\r\n}\r\n\r\n/**\r\n * Resolver class for related fields that uses metadata to determine field types\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create resolver with metadata\r\n * const fields = await client.metadata.getFields('1');\r\n * const resolver = new RelatedFieldResolver();\r\n * resolver.setMetadata(1, fields.fields);\r\n *\r\n * // Resolve a related field\r\n * const resolution = resolver.resolve('accountid_statuscode');\r\n * // Returns both statuscode and status fields for dropdown types\r\n * ```\r\n */\r\nexport class RelatedFieldResolver {\r\n private metadataByObjectType: Map<number, FieldMetadataMap> = new Map();\r\n\r\n /**\r\n * Sets field metadata for an object type\r\n *\r\n * @param objectType - The object type ID\r\n * @param fields - Array of field metadata\r\n */\r\n setMetadata(objectType: number, fields: FireberryField[]): void {\r\n const fieldMap: FieldMetadataMap = new Map();\r\n for (const field of fields) {\r\n fieldMap.set(field.fieldName, field);\r\n }\r\n this.metadataByObjectType.set(objectType, fieldMap);\r\n }\r\n\r\n /**\r\n * Gets field metadata for an object type\r\n *\r\n * @param objectType - The object type ID\r\n * @returns Field metadata map, or undefined if not loaded\r\n */\r\n getMetadata(objectType: number): FieldMetadataMap | undefined {\r\n return this.metadataByObjectType.get(objectType);\r\n }\r\n\r\n /**\r\n * Checks if metadata is loaded for an object type\r\n *\r\n * @param objectType - The object type ID\r\n * @returns True if metadata is loaded\r\n */\r\n hasMetadata(objectType: number): boolean {\r\n return this.metadataByObjectType.has(objectType);\r\n }\r\n\r\n /**\r\n * Clears all cached metadata\r\n */\r\n clearMetadata(): void {\r\n this.metadataByObjectType.clear();\r\n }\r\n\r\n /**\r\n * Resolves a related field into all necessary fields for querying and display\r\n * Uses metadata to determine if fields are dropdown types that need code/label pairs\r\n *\r\n * @param fieldName - The related field name to resolve\r\n * @param showRealValue - Whether labels are being returned (default: true).\r\n * When true, expands dropdown fields to include both code and label.\r\n * When false, returns only the requested field (no expansion needed).\r\n * @returns Resolution with all fields and metadata, or null if not a related field\r\n *\r\n * @example\r\n * // With showRealValue=true (default), dropdown fields get code/label pairs\r\n * resolver.resolve('accountid_status')\r\n * // { fields: ['accountid_status', 'accountid_statuscode'], ... }\r\n *\r\n * // With showRealValue=false, no expansion\r\n * resolver.resolve('accountid_status', false)\r\n * // { fields: ['accountid_status'], ... }\r\n *\r\n * // Regular fields stay as-is regardless of showRealValue\r\n * resolver.resolve('accountid_telephone1')\r\n * // { fields: ['accountid_telephone1'], ... }\r\n */\r\n resolve(fieldName: string, showRealValue: boolean = true): RelatedFieldResolution | null {\r\n const parsed = parseRelatedField(fieldName);\r\n if (!parsed) {\r\n return null;\r\n }\r\n\r\n const { referenceField, relatedField, relatedObjectType } = parsed;\r\n const metadata = this.metadataByObjectType.get(relatedObjectType);\r\n const fieldIsCode = isCodeField(relatedField);\r\n const fieldMeta = metadata?.get(relatedField);\r\n\r\n // When showRealValue is false, no expansion needed - just return the field as-is\r\n if (!showRealValue) {\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n isCodeField: fieldIsCode,\r\n relatedObjectType,\r\n fieldType: fieldMeta?.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // For code fields, we want to also get the label\r\n if (fieldIsCode) {\r\n const labelOnRelated = getLabelFieldForField(relatedField, relatedObjectType);\r\n const labelFieldName = labelOnRelated\r\n ? `${referenceField}_${labelOnRelated}`\r\n : `${referenceField}_${getLabelFieldFromCode(relatedField)}`;\r\n\r\n // Get field type from metadata for the code field\r\n const baseField = getLabelFieldFromCode(relatedField);\r\n const codeFieldMeta = metadata?.get(`${baseField}code`) || metadata?.get(relatedField);\r\n\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, labelFieldName],\r\n valueField: fieldName,\r\n labelField: labelFieldName,\r\n codeField: fieldName,\r\n isCodeField: true,\r\n relatedObjectType,\r\n fieldType: codeFieldMeta?.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // Input is NOT a code field - check if it's a dropdown using metadata\r\n const potentialCodeField = getCodeFieldFromLabel(relatedField);\r\n\r\n // Check if the code field exists and is a dropdown type\r\n const codeFieldMeta = metadata?.get(potentialCodeField);\r\n const isDropdown = codeFieldMeta?.systemFieldTypeId === FIELD_TYPE_IDS.DROPDOWN;\r\n\r\n if (isDropdown) {\r\n // This is a label field that has a corresponding dropdown code field\r\n const codeFieldName = `${referenceField}_${potentialCodeField}`;\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, codeFieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n codeField: codeFieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n fieldType: codeFieldMeta.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // Check if the field itself is a dropdown (for fields that don't follow code pattern)\r\n const fieldIsDropdown = fieldMeta?.systemFieldTypeId === FIELD_TYPE_IDS.DROPDOWN;\r\n\r\n if (fieldIsDropdown) {\r\n // The field itself is a dropdown - check if there's a code variant\r\n const codeFieldName = `${referenceField}_${potentialCodeField}`;\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, codeFieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n codeField: codeFieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n fieldType: fieldMeta.systemFieldTypeId,\r\n };\r\n }\r\n\r\n // Regular field without code/label pairing\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n fieldType: fieldMeta?.systemFieldTypeId,\r\n };\r\n }\r\n\r\n /**\r\n * Expands a list of fields to include related field labels/codes\r\n *\r\n * @param fields - Array of field names to expand\r\n * @param showRealValue - Whether labels are being returned (default: true).\r\n * When true, expands dropdown fields to include both code and label.\r\n * When false, returns fields as-is (no expansion needed).\r\n * @returns Array of field names with related field expansions\r\n *\r\n * @example\r\n * // With showRealValue=true (default)\r\n * resolver.expandFields(['accountid_status', 'accountid_telephone1'])\r\n * // ['accountid_status', 'accountid_statuscode', 'accountid_telephone1']\r\n *\r\n * // With showRealValue=false\r\n * resolver.expandFields(['accountid_status', 'accountid_telephone1'], false)\r\n * // ['accountid_status', 'accountid_telephone1']\r\n */\r\n expandFields(fields: string[], showRealValue: boolean = true): string[] {\r\n const expanded = new Set<string>();\r\n\r\n for (const field of fields) {\r\n const resolution = this.resolve(field, showRealValue);\r\n if (resolution) {\r\n resolution.fields.forEach((f) => expanded.add(f));\r\n } else {\r\n expanded.add(field);\r\n }\r\n }\r\n\r\n return Array.from(expanded);\r\n }\r\n}\r\n\r\n/**\r\n * Resolves a related field without metadata (basic resolution)\r\n * Only handles code fields, does not detect dropdown types without metadata\r\n *\r\n * For full resolution with dropdown detection, use RelatedFieldResolver with metadata\r\n *\r\n * @param fieldName - The related field name to resolve\r\n * @returns Resolution with fields, or null if not a related field\r\n */\r\nexport function resolveRelatedField(fieldName: string): RelatedFieldResolution | null {\r\n const parsed = parseRelatedField(fieldName);\r\n if (!parsed) {\r\n return null;\r\n }\r\n\r\n const { referenceField, relatedField, relatedObjectType } = parsed;\r\n const fieldIsCode = isCodeField(relatedField);\r\n\r\n // For code fields, we always add the label\r\n if (fieldIsCode) {\r\n const labelOnRelated = getLabelFieldForField(relatedField, relatedObjectType);\r\n const labelFieldName = labelOnRelated\r\n ? `${referenceField}_${labelOnRelated}`\r\n : `${referenceField}_${getLabelFieldFromCode(relatedField)}`;\r\n\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName, labelFieldName],\r\n valueField: fieldName,\r\n labelField: labelFieldName,\r\n codeField: fieldName,\r\n isCodeField: true,\r\n relatedObjectType,\r\n };\r\n }\r\n\r\n // Without metadata, we can only return the field as-is\r\n // Use RelatedFieldResolver with metadata for dropdown detection\r\n return {\r\n originalField: fieldName,\r\n fields: [fieldName],\r\n valueField: fieldName,\r\n labelField: fieldName,\r\n isCodeField: false,\r\n relatedObjectType,\r\n };\r\n}\r\n\r\n/**\r\n * Expands a list of fields to include related field labels/codes\r\n * Basic expansion without metadata - only expands code fields\r\n *\r\n * For full expansion with dropdown detection, use RelatedFieldResolver with metadata\r\n *\r\n * @param fields - Array of field names to expand\r\n * @returns Array of field names with related field expansions\r\n */\r\nexport function expandRelatedFields(fields: string[]): string[] {\r\n const expanded = new Set<string>();\r\n\r\n for (const field of fields) {\r\n const resolution = resolveRelatedField(field);\r\n if (resolution) {\r\n resolution.fields.forEach((f) => expanded.add(f));\r\n } else {\r\n expanded.add(field);\r\n }\r\n }\r\n\r\n return Array.from(expanded);\r\n}\r\n\r\n/**\r\n * Gets all related field information for a field name\r\n * Combines parsing and basic resolution into a single call\r\n *\r\n * @param fieldName - The field name to analyze\r\n * @returns Combined info with parsing and resolution, or null if not a related field\r\n */\r\nexport function getRelatedFieldInfo(\r\n fieldName: string,\r\n): (RelatedFieldInfo & RelatedFieldResolution) | null {\r\n const parsed = parseRelatedField(fieldName);\r\n if (!parsed) {\r\n return null;\r\n }\r\n\r\n const resolved = resolveRelatedField(fieldName);\r\n if (!resolved) {\r\n return null;\r\n }\r\n\r\n return { ...parsed, ...resolved };\r\n}\r\n","/**\r\n * Transport layer types for abstracting communication with Fireberry\r\n * Supports both HTTP API and SDK iframe messaging\r\n */\r\n\r\nimport type { QueryOptions, QueryResult } from './query';\r\nimport type { FireberryRecord } from './records';\r\nimport type { FireberrySDKClient } from './sdk';\r\n\r\n/**\r\n * Generic transport request options\r\n */\r\nexport interface TransportRequestOptions {\r\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\r\n endpoint: string;\r\n query?: Record<string, string | number | boolean>;\r\n body?: unknown;\r\n headers?: Record<string, string>;\r\n signal?: AbortSignal;\r\n}\r\n\r\n/**\r\n * Transport interface that both HTTP and SDK implementations must follow\r\n */\r\nexport interface Transport {\r\n /**\r\n * Execute a raw request through this transport\r\n */\r\n request<T = unknown>(options: TransportRequestOptions): Promise<T>;\r\n\r\n /**\r\n * Execute a query operation\r\n */\r\n query(options: QueryOptions): Promise<QueryResult>;\r\n\r\n /**\r\n * Create a record\r\n */\r\n createRecord(objectType: string, data: FireberryRecord, signal?: AbortSignal): Promise<FireberryRecord>;\r\n\r\n /**\r\n * Update a record\r\n */\r\n updateRecord(\r\n objectType: string,\r\n recordId: string,\r\n data: FireberryRecord,\r\n signal?: AbortSignal\r\n ): Promise<FireberryRecord>;\r\n\r\n /**\r\n * Delete a record\r\n */\r\n deleteRecord(\r\n objectType: string,\r\n recordId: string,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; id: string }>;\r\n\r\n /**\r\n * Batch create records\r\n */\r\n batchCreate(\r\n objectType: string,\r\n records: FireberryRecord[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }>;\r\n\r\n /**\r\n * Batch update records\r\n */\r\n batchUpdate(\r\n objectType: string,\r\n records: Array<{ id: string; record: FireberryRecord }>,\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; data: unknown[]; count: number }>;\r\n\r\n /**\r\n * Batch delete records\r\n */\r\n batchDelete(\r\n objectType: string,\r\n recordIds: string[],\r\n signal?: AbortSignal\r\n ): Promise<{ success: boolean; ids: string[]; count: number }>;\r\n\r\n /**\r\n * Get the transport type\r\n */\r\n getType(): 'http' | 'sdk';\r\n}\r\n\r\n/**\r\n * Configuration for HTTP transport\r\n */\r\nexport interface HTTPTransportConfig {\r\n apiKey: string;\r\n baseUrl?: string;\r\n timeout?: number;\r\n retryOn429?: boolean;\r\n maxRetries?: number;\r\n retryDelay?: number;\r\n}\r\n\r\n/**\r\n * Configuration for SDK transport\r\n */\r\nexport interface SDKTransportConfig {\r\n sdk: FireberrySDKClient;\r\n}\r\n\r\n/**\r\n * Union type for transport configuration\r\n */\r\nexport type TransportConfig = HTTPTransportConfig | SDKTransportConfig;\r\n\r\n/**\r\n * Type guard to check if config is HTTP transport config\r\n */\r\nexport function isHTTPTransportConfig(config: TransportConfig): config is HTTPTransportConfig {\r\n return 'apiKey' in config;\r\n}\r\n\r\n/**\r\n * Type guard to check if config is SDK transport config\r\n */\r\nexport function isSDKTransportConfig(config: TransportConfig): config is SDKTransportConfig {\r\n return 'sdk' in config;\r\n}\r\n","/**\r\n * Object Type ID to Name Field Mapping\r\n * Maps Fireberry object type IDs to their display name field\r\n * Generated from actual API responses\r\n */\r\nexport const OBJECT_NAME_MAP: Record<number, string> = {\r\n 1: 'accountname', // Account\r\n 2: 'fullname', // Contact\r\n 3: 'fullname', // Lead\r\n 4: 'name', // Opportunity\r\n 5: 'title', // Cases\r\n 6: 'subject', // Activity\r\n 7: 'notetext', // Note\r\n 8: 'competitorname', // Competitor\r\n 9: 'fullname', // CrmUser\r\n 10: 'subject', // Task\r\n 12: 'quotenumber', // Quote\r\n 13: 'crmordernumber', // CrmOrder\r\n 14: 'name', // Product\r\n 17: 'productname', // CrmOrderItem\r\n 20: 'title', // EmailTemplate\r\n 23: 'name', // BusinessUnit\r\n 25: 'orgname', // Org\r\n 27: 'name', // PrintTemplate\r\n 28: 'contractname', // Contract\r\n 33: 'productid', // AccountProduct (uses productid as display)\r\n 46: 'projectname', // Project\r\n 55: 'rulename', // WFRule\r\n 58: 'name', // MDObject\r\n 64: 'rolename', // Role\r\n 67: 'campaignname', // Campaign\r\n 70: 'browsername', // CrmUserLogin\r\n 73: 'label', // SystemField (using label as name field)\r\n 76: 'articlename', // Article\r\n 77: 'linkname', // Link\r\n 78: 'invoicenumber', // Invoice\r\n 80: 'documentnumber', // InvoiceReceiptItem\r\n 81: 'invoicenumber', // InvoiceNo\r\n 82: 'invoicenumber', // InvoiceDraft\r\n 83: 'invoicenumber', // InvoiceReceipt\r\n 84: 'invoicenumber', // InvoiceReno\r\n 85: 'invoicenumber', // InvoiceCredit\r\n 86: 'invoicenumber', // InvoiceDelivery\r\n 89: 'name', // IpRestriction\r\n 90: 'documentnumber', // TransactionItem\r\n 93: 'name', // Charge\r\n 100: 'callerid', // calllog\r\n 101: 'name', // AttendanceClock\r\n 102: 'activitylognumber', // ActivityLog\r\n 104: 'subject', // Conversation\r\n 105: 'name', // TeamInbox\r\n 106: 'name', // TextTemplate\r\n 107: 'name', // FacebookConnection\r\n 109: 'name', // AuditLog\r\n 110: 'name', // SMSTemplate\r\n 111: 'name', // ProviderVerification\r\n 114: 'name', // CalendarResource\r\n 115: 'name', // Journey\r\n 116: 'name', // Profile\r\n 117: 'name', // LandingPage\r\n};\r\n\r\n/**\r\n * Gets the display name field for a given object type\r\n *\r\n * @param objectTypeId - The numeric object type ID\r\n * @returns The name field for the object type\r\n */\r\nexport function getNameFieldByObjectType(objectTypeId: string | number): string {\r\n const objectTypeNum =\r\n typeof objectTypeId === 'string' ? parseInt(objectTypeId, 10) : objectTypeId;\r\n\r\n // Check if it's a mapped base object\r\n if (OBJECT_NAME_MAP[objectTypeNum]) {\r\n return OBJECT_NAME_MAP[objectTypeNum];\r\n }\r\n\r\n // For custom objects (1000 and up), use 'name'\r\n if (objectTypeNum >= 1000) {\r\n return 'name';\r\n }\r\n\r\n // Fallback to 'name' for unmapped objects\r\n return 'name';\r\n}\r\n","// Field type constants\r\nexport { FIELD_TYPE_IDS, FIELD_TYPE_MAPPINGS } from './fieldTypes';\r\n\r\n// Object ID mappings\r\nexport { OBJECT_ID_MAP, getObjectIdFieldName } from './objectIds';\r\n\r\n// Object name mappings\r\nexport { OBJECT_NAME_MAP, getNameFieldByObjectType } from './objectNames';\r\n\r\n// Excluded fields for star queries and lookup relations\r\nexport {\r\n EXCLUDED_FIELDS_FOR_STAR_QUERY,\r\n EXCLUDED_LOOKUP_FIELDS,\r\n isExcludedFromStarQuery,\r\n getExcludedFieldsForStarQuery,\r\n} from './excludedFields';\r\n"]}
|