# @flatfile/records

A TypeScript library for managing record data with change tracking and validation.

## Installation

```bash
npm install @flatfile/records
```

## Usage

```typescript
import { FlatfileRecord } from '@flatfile/records';

// Create a new record
const record = new FlatfileRecord({
  name: 'John Doe',
  email: 'john@example.com'
});

// Get values
console.log(record.get('name')); // 'John Doe'
console.log(record.str('email')); // 'john@example.com'
console.log(record.num('age')); // 0 (converts to number)

// Set values
record.set('age', 30);

// Check if values exist
console.log(record.has('age')); // true
console.log(record.isEmpty('phone')); // true

// Get all keys
console.log(record.keys()); // ['name', 'email', 'age']

// Add messages
record.err('email', 'Invalid email format'); // error
record.info('email', 'Will send verification'); // info message
record.warn('age', 'Age seems low'); // warning

// Get changes
console.log(record.isDirty()); // true
console.log(record.changeset());

// Check for errors
console.log(record.hasError('email')); // true
console.log(record.errorFields()); // ['email']

// Commit changes
record.commit();

// Get metadata and links
console.log(record.meta); // Record metadata
console.log(record.getLinks()); // All links
console.log(record.getLinks('category')); // Links for specific key

// Configure fields
record.setReadOnly('email');
record.setFieldConfig('age', { min: 18, max: 100 });
```

## Record Utilities

The package also includes utility functions for working with Flatfile records:

```typescript
import {
  formatRecord,
  toSimpleRecord,
  toSimpleFilteredRecord,
  toNarrowRecord,
  formatUpdate,
  patchOneColumn,
  type SimpleRecord,
} from '@flatfile/records';

// Convert simple record to Flatfile format
const simpleRecord: SimpleRecord = { name: "John" };
const flatfileRecord = formatRecord(simpleRecord);
// => { name: { value: "John" } }

// Convert Flatfile record to simple format
const flatfileData = { id: "1", values: { name: { value: "John" } } };
const simple = toSimpleRecord(flatfileData);
// => { id: "1", name: "John" }

// Filter record to specific keys
const filtered = toSimpleFilteredRecord(flatfileData, ["name"]);
// => { id: "1", name: "John" }

// Create an update patch
const update = formatUpdate(simpleRecord);
// => { id: "...", values: { name: { value: "John" } } }

// Create a column update function
const toUpperCase = patchOneColumn("name", (val) => val.toUpperCase());
const updated = toUpperCase(flatfileData, 0);
// => { id: "1", values: { name: { value: "JOHN" } } }
```

## API Reference

### FlatfileRecord Class

#### Constructor

```typescript
new FlatfileRecord<T>(data: Readonly<Partial<T>>, dirty?: boolean)
```

#### Properties

- `data`: The underlying data object (readonly)
- `id`: The record's ID (`__k`) or temporary ID
- `slug`: The record's slug (`__n`)
- `sheetId`: The record's sheet ID (`__s`)
- `meta`: Record metadata (`__m`)

#### Methods

##### Data Access
- `get(key: string)`: Get a value
- `set(key: string, value: any)`: Set a value
- `has(key: string)`: Check if a key exists with a value
- `isEmpty(key: string)`: Check if a key is empty
- `str(key: string)`: Get a value as a nullable string
- `defStr(key: string)`: Get a value as a string (empty string if null)
- `bool(key: string)`: Get a value as a boolean
- `num(key: string)`: Get a value as a number
- `date(key: string)`: Get a value as a Date

##### Keys and Values
- `keys(options?: { omit?: string[]; pick?: string[] })`: Get all keys
- `keysWithData(props?: { exclude?: Array<string | string[]> })`: Get keys with data
- `values(castAs?: "str" | "defStr" | "bool" | "num" | "date")`: Get all values with optional casting
- `entries()`: Get all entries as [key, value] pairs
- `pick(...keys: string[])`: Pick specific keys and their values

##### State Management
- `isDirty(key?: string)`: Check if record or specific key is dirty
- `commit()`: Commit all changes
- `changeset()`: Get pending changes
- `delete()`: Mark record as deleted
- `isDeleted()`: Check if record is marked as deleted

##### Validation and Messages
- `err(key: string, msg: string)`: Add an error message
- `info(key: string, msg: string)`: Add an info message
- `warn(key: string, msg: string)`: Add a warning message
- `hasError(...keys: string[])`: Check for errors
- `errorFields(...keys: string[])`: Get fields with errors
- `errorIf(key: string, cb: (val: any) => any, err: string)`: Add error conditionally

##### Configuration
- `setReadOnly(key: string)`: Make a field read-only
- `setConfig(setter: (config: RecordConfig) => RecordConfig)`: Set record configuration
- `setFieldConfig(key: string, config: CellConfig)`: Set field configuration

##### Links and Metadata
- `getLinks(key?: string)`: Get all links or links for a specific key
- `meta`: Access record metadata

##### Utilities
- `hash(...keys: string[])`: Generate a hash from specified keys
- `copy(props?: { mixin?: FlatfileRecord; select?: string[]; slug?: string; sheetId?: string })`: Create a copy
- `merge(item: FlatfileRecord, props?: { overwrite?: boolean })`: Merge another record
- `hasConflict(b: FlatfileRecord, keys?: string[])`: Check for conflicts
- `toSimpleRecord()`: Convert to simple record format

### Utility Functions

#### Record Conversion
- `formatRecord(obj: SimpleRecord)`: Convert simple record to Flatfile format
- `toSimpleRecord(r: FlatfileTypes["Record_"])`: Convert Flatfile record to simple format
- `toSimpleFilteredRecord(r: FlatfileTypes["Record_"], keyFilter: string[])`: Convert and filter Flatfile record
- `toNarrowRecord(r: SimpleRecord, keyFilter: string[])`: Filter simple record to specific keys
- `formatUpdate(obj: SimpleRecord)`: Format record for update operation
- `patchOneColumn(key: string, cb: (val: string, record: Record<string, any>, i: number) => string | null)`: Create column update function

#### Types
- `SimpleRecord`: Record with primitive values
- `SafeRecord`: Record with string, undefined, or null values
- `Primitive`: Union type of string, number, null, boolean
- `FlatfileTypes`: Interface for Flatfile record types

## License

MIT 