Skip to content

Bu-okem/crag

Repository files navigation

Crag - API Client Generator

A CLI tool that generates TypeScript API clients and React Query hooks from OpenAPI specifications or Postman collections.

Features

  • Generate TypeScript clients from OpenAPI specs or Postman collections
  • Create React Query hooks for all API endpoints
  • Type-safe API calls with TypeScript support
  • Simple configuration and easy setup

Installation

# Using npm
npm install crag

# Using yarn
yarn add crag

# Using pnpm
pnpm add crag

Usage

Basic Usage

# Generate from an OpenAPI spec
crag generate api --path ./api-spec.yaml

# Generate from a Postman collection
crag generate api --path ./collection.json

# Specify output directory
crag generate api --path ./api-spec.yaml --destination ./src/api

Options

  • --path: Path to the API specification file (required)
  • --destination: Output directory (default: current directory)
  • --client-only: Generate only the TypeScript client
  • --hooks-only: Generate only React Query hooks

Development

  1. Clone the repository
  2. Install dependencies:
    pnpm install
  3. Build the project:
    pnpm build
  4. Run in development mode:
    pnpm dev

License

ISC

Contributing

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

Configuration

Create a crag.config.ts file:

export default {
  input: [
    { path: './api-spec.json', type: 'postman' }
  ],
  output: './src/api'
}

Using the client

The generated client is imported and configured like this:

import { client } from './client.gen';

// Configure the client
client.setConfig({
  baseUrl: 'https://api.example.com',
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

Direct API Calls

import { getAccessCohorts, postAccessLogin } from './sdk.gen';

// GET request
const cohorts = await getAccessCohorts();

// POST request with body
const loginResult = await postAccessLogin({
  body: {
    email: '[email protected]',
    password: 'password123'
  }
});

// Request with path parameters
const learner = await getAccessGetLearners({
  path: { learner_id: '123' }
});

// Request with query parameters
const searchResults = await getAccessSearchLearners({
  query: { 
    cohort_id: 'abc',
    search: 'john' 
  }
});

You can call the generated API functions directly:

Using the hooks

1. Query Options (for GET endpoints)

These are used with useQuery:

// Example: Get learners

export const getAccessGetLearnersOptions = (options?: Options<GetAccessGetLearnersData>) => {
  return queryOptions({
    queryFn: async ({ queryKey, signal }) => {
      const { data } = await getAccessGetLearners({
        ...options,
        ...queryKey[0],
        signal,
        throwOnError: true
      });
      return data;
    },
    queryKey: getAccessGetLearnersQueryKey(options)
  });
};

2. Mutation Options (for POST/PATCH/DELETE endpoints)

These are used with useMutation:

// Example: Create user mutation

export const postAccessRegisterLearnerMutation = (options?: Partial<Options<PostAccessRegisterLearnerData>>): UseMutationOptions<...> => {
  const mutationOptions: UseMutationOptions<...> = {
    mutationFn: async (localOptions) => {
      const { data } = await postAccessRegisterLearner({
        ...options,
        ...localOptions,
        throwOnError: true
      });
      return data;
    }
  };
  return mutationOptions;
};

3. Infinite Query Options (for paginated data)

export const getSearchPhotosInfiniteOptions = (options?: Options<GetSearchPhotosData>) => {
  return infiniteQueryOptions<...>({
    queryFn: async ({ pageParam, queryKey, signal }) => {
      // Handle pagination
    },
    queryKey: getSearchPhotosInfiniteQueryKey(options)
  });
};

How to Use These in React Components:

import { useQuery, useMutation } from '@tanstack/react-query';
import { 
  getAccessGetLearnersOptions, 
  postAccessRegisterLearnerMutation 
} from './react-query.gen';

function LearnersComponent() {
  // Query hook - automatically fetches data
  const { data: learners, isLoading, error } = useQuery(
    getAccessGetLearnersOptions()
  );

  // Mutation hook - for creating/updating
  const registerLearnerMutation = useMutation(
    postAccessRegisterLearnerMutation()
  );

  const handleRegister = (learnerData: any) => {
    registerLearnerMutation.mutate({
      body: learnerData
    });
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      {/* Your component JSX */}
      <button onClick={() => handleRegister({ name: 'John', email: '[email protected]' })}>
        Register Learner
      </button>
    </div>
  );
}

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Run in dev mode
pnpm dev

License

ISC

About

A CLI tool to generate tanstack queries from Postman specifications

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •