npm package: @origins-digital/prisma-setter
Description: Common prisma setter utilities for all projects
Author: Origins Digital
Latest version: 3.1.4

# @origins-digital/prisma-setter

A utility package for managing relationships in Prisma ORM with type safety.

## Installation

```bash
npm install @origins-digital/prisma-setter
```

## Features

- Type-safe relationship management
- Automatic handling of create, update, and delete operations
- Support for complex relationship structures
- Configurable comparison fields
- Transaction-safe operations

## Usage

### Basic Setup

```typescript
import { setItems } from '@origins-digital/prisma-setter';

// Define your Prisma model types
type User = {
  id: string;
  name: string;
  email: string;
};

type Post = {
  id: string;
  title: string;
  content: string;
  userId: string;
};

// Setup the setter for posts
const setUserPosts = setItems(prisma.post, 'userId', {
  comparableFields: {
    targetKey: 'id',
    extraKeys: ['title'],
  },
  updatableFields: ['content'],
});

// Use in a transaction
await prisma.$transaction(async (tx) => {
  await setUserPosts(userId, [
    { id: '1', title: 'First Post', content: 'Content 1' },
    { id: '2', title: 'Second Post', content: 'Content 2' },
  ]);
});
```

### Complex Relationships

```typescript
// Define nested relationships
type Comment = {
  id: string;
  content: string;
  postId: string;
  userId: string;
};

const setPostComments = setItems(prisma.comment, 'postId', {
  comparableFields: {
    targetKey: 'id',
    extraKeys: ['userId'],
  },
  updatableFields: ['content'],
});

// Use with nested relationships
await prisma.$transaction(async (tx) => {
  await setPostComments(postId, [
    { id: '1', content: 'Comment 1', userId: 'user1' },
    { id: '2', content: 'Comment 2', userId: 'user2' },
  ]);
});
```

### Updating Existing Relationships

```typescript
const setUserRoles = setItems(prisma.userRole, 'userId', {
  comparableFields: {
    targetKey: 'roleId',
  },
  updatableFields: ['permissions'],
});

// Update user roles
await prisma.$transaction(async (tx) => {
  await setUserRoles(userId, [
    { roleId: 'admin', permissions: ['read', 'write'] },
    { roleId: 'editor', permissions: ['read'] },
  ]);
});
```

## API Reference

### setItems

```typescript
const setItems =
  <T, U extends keyof PrismaModelWithoutRelationships<T>>(
    prismaModel: T,
    sourceFKKey: U,
    options: SetItemsOptions<T>,
  ) =>
  async (
    sourceFK: SourceFk<T, U>,
    data: PrismaModelWithoutRelationships<T>[],
  ) =>
    Promise<{
      obsoleteItems: PrismaModelWithoutRelationships<T>[];
      newItems: PrismaModelWithoutRelationships<T>[];
      updatedItems: PrismaModelWithoutRelationships<T>[];
    }>;
```

### SetItemsOptions

```typescript
type SetItemsOptions<T> = {
  comparableFields: {
    targetKey: PrismaModelFieldName<T>;
    extraKeys?: PrismaModelFieldName<T>[];
  };
  updatableFields?: PrismaModelFieldName<T>[];
};
```

## Response Format

The setItems function returns an object with the following structure:

```typescript
{
  obsoleteItems: T[];    // Items that were removed
  newItems: T[];         // Items that were created
  updatedItems: T[];     // Items that were updated
}
```

## Best Practices

1. Always use within a transaction to ensure data consistency
2. Define appropriate comparable fields for accurate relationship matching
3. Specify updatable fields to control which fields can be modified
4. Use extraKeys for complex relationship matching
5. Handle the response to track changes in relationships

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.