/** * Airtable Integration for WORKWAY * * Weniger, aber besser: Extends BaseAPIClient for shared HTTP logic. * * @example * ```typescript * import { Airtable } from '@workwayco/integrations/airtable'; * * const airtable = new Airtable({ * accessToken: tokens.airtable.access_token, * baseId: 'appXXXXXXXXXXXXXX' * }); * * // List records from a table * const records = await airtable.listRecords({ tableId: 'Tasks' }); * * // Create a record * const created = await airtable.createRecord({ * tableId: 'Tasks', * fields: { Name: 'New Task', Status: 'Todo' } * }); * * // Update a record * const updated = await airtable.updateRecord({ * tableId: 'Tasks', * recordId: 'recXXX', * fields: { Status: 'Done' } * }); * ``` */ import { ActionResult } from '@workwayco/sdk'; import { BaseAPIClient } from '../core/index.js'; /** * Airtable integration configuration */ export interface AirtableConfig { /** Personal access token or OAuth access token */ accessToken: string; /** Base ID (appXXXXXXXXXXXXXX) */ baseId: string; /** Optional: Override API endpoint (for testing) */ apiUrl?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; } /** * Airtable record object */ export interface AirtableRecord { id: string; createdTime: string; fields: Record; } /** * Airtable field value types */ export type AirtableFieldValue = string | number | boolean | null | string[] | AirtableAttachment[] | AirtableCollaborator | AirtableCollaborator[] | AirtableRecordLink[] | AirtableBarcode | AirtableButton | { label: string; url: string; }; /** * Airtable attachment object */ export interface AirtableAttachment { id: string; url: string; filename: string; size: number; type: string; width?: number; height?: number; thumbnails?: { small: { url: string; width: number; height: number; }; large: { url: string; width: number; height: number; }; full?: { url: string; width: number; height: number; }; }; } /** * Airtable collaborator object */ export interface AirtableCollaborator { id: string; email: string; name: string; } /** * Airtable linked record reference */ export interface AirtableRecordLink { id: string; } /** * Airtable barcode object */ export interface AirtableBarcode { text: string; } /** * Airtable button object */ export interface AirtableButton { label: string; url?: string; } /** * Airtable table schema */ export interface AirtableTable { id: string; name: string; primaryFieldId: string; fields: AirtableField[]; views: AirtableView[]; } /** * Airtable field schema */ export interface AirtableField { id: string; name: string; type: string; description?: string; options?: Record; } /** * Airtable view schema */ export interface AirtableView { id: string; name: string; type: 'grid' | 'form' | 'calendar' | 'gallery' | 'kanban' | 'timeline' | 'block'; } /** * Airtable list response */ export interface AirtableListResponse { records: AirtableRecord[]; offset?: string; } /** * Options for listing records */ export interface ListRecordsOptions { /** Table name or ID */ tableId: string; /** Fields to return (default: all fields) */ fields?: string[]; /** Filter formula (Airtable formula syntax) */ filterByFormula?: string; /** Maximum records to return (max 100 per request) */ maxRecords?: number; /** Page size (max 100) */ pageSize?: number; /** Sort by fields */ sort?: Array<{ field: string; direction: 'asc' | 'desc'; }>; /** View ID or name to filter records */ view?: string; /** Pagination offset from previous response */ offset?: string; /** Cell format: 'json' (default) or 'string' */ cellFormat?: 'json' | 'string'; /** Timezone for date calculations */ timeZone?: string; /** User locale for formatting */ userLocale?: string; /** * Explicit field name to use as title (Zuhandenheit: no guessing) * If not provided, falls back to first string field */ titleField?: string; /** * Explicit field name to use as description * If not provided, falls back to first long text field */ descriptionField?: string; } /** * Options for getting a single record */ export interface GetRecordOptions { /** Table name or ID */ tableId: string; /** Record ID */ recordId: string; } /** * Options for creating a record */ export interface CreateRecordOptions { /** Table name or ID */ tableId: string; /** Field values */ fields: Record; /** Typecast values (attempts to convert string values to the correct type) */ typecast?: boolean; } /** * Options for updating a record */ export interface UpdateRecordOptions { /** Table name or ID */ tableId: string; /** Record ID */ recordId: string; /** Field values to update */ fields: Record; /** Typecast values */ typecast?: boolean; } /** * Options for deleting a record */ export interface DeleteRecordOptions { /** Table name or ID */ tableId: string; /** Record ID */ recordId: string; } /** * Options for batch creating records */ export interface BatchCreateOptions { /** Table name or ID */ tableId: string; /** Array of records to create (max 10 per request) */ records: Array<{ fields: Record; }>; /** Typecast values */ typecast?: boolean; } /** * Options for batch updating records */ export interface BatchUpdateOptions { /** Table name or ID */ tableId: string; /** Array of records to update (max 10 per request) */ records: Array<{ id: string; fields: Record; }>; /** Typecast values */ typecast?: boolean; } /** * Options for batch deleting records */ export interface BatchDeleteOptions { /** Table name or ID */ tableId: string; /** Record IDs to delete (max 10 per request) */ recordIds: string[]; } /** * Airtable Integration * * Weniger, aber besser: Extends BaseAPIClient for shared HTTP logic. */ export declare class Airtable extends BaseAPIClient { private readonly baseId; constructor(config: AirtableConfig); /** * List records from a table * * @returns ActionResult with records and StandardList format */ listRecords(options: ListRecordsOptions): Promise>; /** * Get a single record by ID * * @returns ActionResult with record data */ getRecord(options: GetRecordOptions): Promise>; /** * Create a new record * * @returns ActionResult with created record */ createRecord(options: CreateRecordOptions): Promise>; /** * Update an existing record * * @returns ActionResult with updated record */ updateRecord(options: UpdateRecordOptions): Promise>; /** * Replace all fields of a record (destructive update) * * @returns ActionResult with updated record */ replaceRecord(options: UpdateRecordOptions): Promise>; /** * Delete a record * * @returns ActionResult with deleted record ID */ deleteRecord(options: DeleteRecordOptions): Promise>; /** * Create multiple records (max 10 per request) * * @returns ActionResult with created records */ batchCreate(options: BatchCreateOptions): Promise>; /** * Update multiple records (max 10 per request) * * @returns ActionResult with updated records */ batchUpdate(options: BatchUpdateOptions): Promise>; /** * Delete multiple records (max 10 per request) * * @returns ActionResult with deleted record IDs */ batchDelete(options: BatchDeleteOptions): Promise>>; /** * Get table schema (requires Meta API scope) * * Note: Uses separate Meta API endpoint, so we make a direct fetch here * * @returns ActionResult with table schemas */ getTables(): Promise>; /** * Get a record as a task (with StandardTask transformation) * * Use this when working with task-like tables * * @returns ActionResult with record and StandardTask format */ getTask(tableId: string, recordId: string): Promise>; /** * Query tasks from a table (with StandardTask transformations) * * @returns ActionResult with tasks */ queryTasks(options: ListRecordsOptions): Promise>; /** * Get capabilities for Airtable actions */ private getCapabilities; /** * Extract title from a record * * Zuhandenheit: If explicit titleField provided, use it directly. * Fallback to first string field only when no explicit field given. * * @param record - The Airtable record * @param titleField - Explicit field name (recommended) */ private extractTitle; /** * Extract description from a record * * Zuhandenheit: If explicit descriptionField provided, use it directly. * * @param record - The Airtable record * @param descriptionField - Explicit field name (recommended) */ private extractDescription; /** * Convert Airtable record to StandardTask format * * Attempts to map common field names to StandardTask fields */ private toStandardTask; } //# sourceMappingURL=index.d.ts.map