import Airtable from 'airtable'; // Airtable service for plant care application using the official Airtable SDK export interface AirtableConfig { apiKey: string; baseId: string; tableName: string; } export interface AirtableRecord { id: string; createdTime: string; fields: Record; } export interface AirtableResponse { records: AirtableRecord[]; offset?: string; } export class AirtableService { private table: any; constructor(config: AirtableConfig) { const base = new Airtable({ apiKey: config.apiKey }).base(config.baseId); this.table = base(config.tableName); } async listRecords(filter?: string, sort?: Array<{ field: string; direction?: 'asc' | 'desc' }>, limit?: number, offset?: string): Promise { return new Promise((resolve, reject) => { const selectOptions: any = {}; if (filter) selectOptions.filterByFormula = filter; if (sort && sort.length > 0) { selectOptions.sort = sort.map(s => ({ field: s.field, direction: s.direction || 'asc' })); } if (limit) selectOptions.maxRecords = limit; if (offset) selectOptions.offset = offset; const records: AirtableRecord[] = []; this.table.select(selectOptions).eachPage( (pageRecords: any[], fetchNextPage: () => void) => { records.push(...pageRecords.map(record => ({ id: record.id, createdTime: record._rawJson.createdTime, fields: record.fields }))); fetchNextPage(); }, (err: any) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else { resolve({ records }); } } ); }); } async getRecord(recordId: string): Promise { return new Promise((resolve, reject) => { this.table.find(recordId, (err: any, record: any) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else if (!record) { reject(new Error(`Record ${recordId} not found`)); } else { resolve({ id: record.id, createdTime: record._rawJson.createdTime, fields: record.fields }); } }); }); } async createRecord(fields: Record): Promise { return new Promise((resolve, reject) => { this.table.create(fields, (err: any, record: any) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else { resolve({ id: record.id, createdTime: record._rawJson.createdTime, fields: record.fields }); } }); }); } async updateRecord(recordId: string, fields: Record): Promise { return new Promise((resolve, reject) => { this.table.update(recordId, fields, (err: any, record: any) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else { resolve({ id: record.id, createdTime: record._rawJson.createdTime, fields: record.fields }); } }); }); } async deleteRecord(recordId: string): Promise { return new Promise((resolve, reject) => { this.table.destroy(recordId, (err: any) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else { resolve(); } }); }); } async batchCreateRecords(records: Array<{ fields: Record }>): Promise { return new Promise((resolve, reject) => { const recordsToCreate = records.map(r => r.fields); this.table.create(recordsToCreate, (err: any, records: any[]) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else { resolve(records.map(record => ({ id: record.id, createdTime: record._rawJson.createdTime, fields: record.fields }))); } }); }); } async batchUpdateRecords(records: Array<{ id: string; fields: Record }>): Promise { return new Promise((resolve, reject) => { const updates = records.reduce((acc, record) => { acc[record.id] = record.fields; return acc; }, {} as Record); this.table.update(updates, (err: any, records: any[]) => { if (err) { reject(new Error(`Airtable API error: ${err.message || err}`)); } else { resolve(records.map(record => ({ id: record.id, createdTime: record._rawJson.createdTime, fields: record.fields }))); } }); }); } } // Factory function to create Airtable services for different tables export function createAirtableServices(apiKey: string, baseId: string) { return { plants: new AirtableService({ apiKey, baseId, tableName: 'Plants' }), wateringLogs: new AirtableService({ apiKey, baseId, tableName: 'WateringLogs' }), users: new AirtableService({ apiKey, baseId, tableName: 'Users' }), settings: new AirtableService({ apiKey, baseId, tableName: 'Settings' }) }; }