# @incubrain/client

A type-safe GraphQL client for Hasura, optimized for Node.js and Nuxt environments with full TypeScript support.

## Features

- 🚀 ESM-first architecture
- 🎯 Full TypeScript support with generated types
- 📦 Auto-generated mutations and queries
- 🔄 Built-in GraphQL code generation
- 🛡️ Type-safe API calls
- ⚡ Optimized for Hasura
- 🌐 Universal runtime support (Node.js and Nuxt)
- 🔒 Built-in authentication handling
- 💪 Flexible query building
- 🎯 Direct GraphQL query support
- 🗄️ Built-in caching system

## Installation

```bash
# Using pnpm (recommended)
pnpm add @incubrain/client

# Using npm
npm install @incubrain/client

# Using yarn
yarn add @incubrain/client
```

## Quick Start

### Basic Setup

```typescript
import { createClient } from "@incubrain/client";

const client = createClient({
  endpoint: "YOUR_HASURA_ENDPOINT",
  headers: {
    "x-hasura-admin-secret": "YOUR_ADMIN_SECRET",
  },
});
```

### Query Methods

The client supports multiple ways to query your data:

#### 1. Type-Safe Generated Queries

```typescript
// Using generated type-safe operations
const response = await client.FetchManyCompany({
  limit: 10,
  order_by: { created_at: 'desc' },
});
```

#### 2. Flexible Query Builder

```typescript
// Using the flexible query builder
const { companies } = await client.query('companies', {
  limit: 10,
  order_by: { scraped_at: 'desc_nulls_first' },
  cols: ['id', 'name', 'scraped_at', 'url']
});

// With nested selections
const { users } = await client.query('users', {
  limit: 5,
  cols: {
    id: true,
    name: true,
    profile: {
      avatar_url: true,
      bio: true
    }
  }
});
```

#### 3. Raw GraphQL Queries

```typescript
// Using raw GraphQL (great for quick prototyping)
const { companies } = await client.rawQuery(`
  companies(limit: 10, order_by: {scraped_at: desc_nulls_first}) {
    id
    name
    scraped_at
    url
  }
`);
```

### Type-Safe Imports

You can import types directly from specific paths:

```typescript
// Import table types
import { UserTable } from '@incubrain/client/tables';

// Import view types
import { UserProfileView } from '@incubrain/client/views';

// Import enums and constants
import { UserRoleEnum } from '@incubrain/client/constants';

// Import operation types
import { FetchUserProfileResult } from '@incubrain/client/operations';
```

### Caching

The client includes built-in caching support:

```typescript
const client = createClient({
  endpoint: "YOUR_HASURA_ENDPOINT",
  cache: true,      // Enable caching
  cacheTTL: 300,    // Cache for 5 minutes
});

// Clear cache
await client.clearCache();                  // Clear all cache
await client.clearCache('users:*');         // Clear user-related cache
```

## Configuration

### Client Options

```typescript
interface ClientConfig {
  endpoint: string;                    // GraphQL endpoint URL
  headers?: Record<string, string>;    // Custom headers
  cache?: boolean;                     // Enable/disable caching
  cacheTTL?: number;                   // Cache duration in seconds
  logger?: Logger;                     // Custom logger
}
```

### Environment Variables

```env
HASURA_ENDPOINT=https://your-hasura-endpoint/v1/graphql
HASURA_ADMIN_SECRET=your-admin-secret
```

## Usage in Nuxt

### Plugin Setup

```typescript
// plugins/graphql.ts
import { createClient } from "@incubrain/client";

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig();

  const client = createClient({
    endpoint: config.public.hasuraEndpoint,
    headers: {
      "x-hasura-admin-secret": config.hasuraAdminSecret,
    },
    cache: true
  });

  return {
    provide: {
      api: client,
    },
  };
});
```

### Component Usage

```vue
<script setup lang="ts">
const { $api } = useNuxtApp();

// Using flexible query builder
const { users } = await $api.query('users', {
  limit: 10,
  cols: ['id', 'name', 'email']
});

// Using raw query
const { stats } = await $api.rawQuery(`
  user_stats {
    total_users
    active_users
  }
`);

// Using generated operations
const response = await $api.FetchUserProfile({ 
  id: '123' 
});
</script>
```

## Development

### Generate Operations

```bash
pnpm generate:operations
```

### Generate Types

```bash
pnpm generate
```

### Build

```bash
pnpm build
```

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## Future Considerations

- Enable splitting of the client into categories like admin | auth | client etc.
  - This could be interesting if it was based on role, although the admin client would have everything then...


## License

MIT