Skip to main content

Kubb Configuration

Kubb adalah OpenAPI code generator yang digunakan untuk mengenerate TypeScript types dan React Query hooks secara otomatis dari OpenAPI specification.

📋 Overview

🔧 Alur Kerja Kubb

📁 Generated Structure

gen/
├── hooks/ # React Query hooks
│ ├── AuthPenggunaHooks/
│ │ ├── useGetAuthPengguna.ts
│ │ └── index.ts
│ ├── KeuanganPengelolaanGudangIndukHooks/
│ │ ├── usePostKeuanganPengelolaanGudangIndukNonInventarisasi.ts
│ │ └── index.ts
│ └── index.ts # Barrel export
├── types/ # TypeScript types
│ ├── models/
│ │ ├── PengelolaanGudangIndukNonInventarisasi.ts
│ │ └── ...
│ ├── dto/
│ │ ├── PenggunaPostRequest.ts
│ │ └── ...
│ └── index.ts # Barrel export
└── index.ts # Main barrel export

⚙️ Konfigurasi Utama

Input Configuration

input: {
path: './sisappra.filtered.json'
}

Menggunakan file yang sudah difilter oleh filter-openapi.mjs untuk menghindari generate endpoint yang tidak diperlukan.

Output Configuration

output: {
path: './gen', // Output directory
format: 'prettier', // Auto-format generated code
lint: 'eslint', // Auto-lint generated code
defaultBanner: false, // Tidak tambahkan banner default
clean: true // Clean output directory sebelum generate
}

🔌 Plugin Configuration

1. OAS Plugin (pluginOas)

pluginOas({
validate: true, // Validasi OpenAPI specification
contentType: 'application/json', // Default content type
generators: [] // Custom generators (kosong)
})

Fungsi: Memproses dan memvalidasi OpenAPI specification sebelum generation.

2. TypeScript Plugin (pluginTs)

pluginTs({
output: { path: './types' }, // Output untuk types
group: { type: 'tag', name: '{Group}Types' }, // Group by API tags
transformers: [{ // Custom name transformers
type: 'name',
fn: (name) => name.replace('ApiV1', '')
}],
enumType: 'asConst', // Enums sebagai const assertions
dateType: 'date', // Date objects, bukan string
oasType: false // Tidak gunakan OAS-specific types
})

Fitur Utama:

  • Strong Typing: Enums sebagai as const untuk better type safety
  • Date Handling: Otomatis generate sebagai Date objects
  • Clean Naming: Hapus ApiV1 prefix dari nama types
  • Organized Structure: Group by API tags

3. React Query Plugin (pluginReactQuery)

pluginReactQuery({
output: { path: './hooks' }, // Output untuk hooks
group: { type: 'tag', name: '{Group}Hooks' }, // Group by API tags
client: '@/lib/axios/config', // Custom axios instance
suspense: false, // Disable suspense untuk performance
transformers: [{ // Custom name transformers
type: 'name',
fn: (name) => name.replace('ApiV1', '')
}]
})

Fitur Utama:

  • React Query Integration: Generate hooks dengan proper React Query integration
  • Custom Client: Menggunakan axios instance yang sudah dikonfigurasi
  • Performance Optimized: Tanpa suspense untuk better UX
  • Consistent Naming: Sama dengan types naming convention

🎯 Contoh Penggunaan Generated Code

Import Types

import type {
PengelolaanGudangIndukNonInventarisasi,
PengelolaanGudangIndukNonInventarisasiRequest
} from '@/gen/types';

// atau grouped import
import type {
KeuanganPengelolaanGudangIndukTypes
} from '@/gen/types/models';

Import Hooks

import {
usePostKeuanganPengelolaanGudangIndukNonInventarisasi,
usePutKeuanganPengelolaanGudangIndukVerifikasi
} from '@/gen/hooks';

// atau grouped import
import {
KeuanganPengelolaanGudangIndukHooks
} from '@/gen/hooks/KeuanganPengelolaanGudangIndukHooks';

Usage in Component

import React from 'react';
import { usePostKeuanganPengelolaanGudangIndukNonInventarisasi } from '@/gen/hooks';
import type { PengelolaanGudangIndukNonInventarisasiRequest } from '@/gen/types';

function CreateInventoryForm() {
const createMutation = usePostKeuanganPengelolaanGudangIndukNonInventarisasi();

const handleSubmit = async (data: PengelolaanGudangIndukNonInventarisasiRequest) => {
try {
const result = await createMutation.mutateAsync({ data });
console.log('Success:', result);
} catch (error) {
console.error('Error:', error);
}
};

return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
<button type="submit" disabled={createMutation.isPending}>
{createMutation.isPending ? 'Saving...' : 'Save'}
</button>
</form>
);
}

🔄 Development Workflow

1. Update OpenAPI

# Run filter script untuk update OpenAPI spec
node scripts/filter-openapi.mjs

# Generate types dan hooks
npx kubb build --config kubb.config.ts

2. Environment Variables

# Override default OpenAPI URL
export SWAGGER_URL="https://custom-api.example.com/docs.json"

# Override filtered output path
export FILTERED_PATH="./custom-filtered.json"

3. Package Scripts

{
"scripts": {
"generate": "node scripts/filter-openapi.mjs && npx kubb build",
"generate:watch": "npx kubb build --watch",
"generate:clean": "rm -rf gen && npm run generate"
}
}

🎨 Customization

Menambah Custom Transformers

transformers: [
{
type: 'name',
fn: (name) => {
// Custom naming logic
return name
.replace('ApiV1', '')
.replace(/([A-Z])/g, ' $1')
.trim();
}
}
]

Menambah Custom Generators

pluginOas({
generators: [
{
name: 'custom-generator',
output: './custom-output',
build: (api) => {
// Custom generation logic
return `// Custom generated code`;
}
}
]
})

🔧 Configuration Options

Available Plugin Options

PluginOptionTypeDefaultDescription
pluginOasvalidatebooleantrueValidasi OpenAPI spec
pluginTsenumTypestring'enum'Type untuk enums
pluginTsdateTypestring'string'Type untuk dates
pluginReactQuerysuspensebooleanfalseEnable suspense mode
pluginReactQueryclientstring-Custom query client

Group Options

group: {
type: 'tag', // Group by API tags
name: '{Group}Types', // Template untuk nama folder
output: './types' // Output directory
}

🚨 Best Practices

1. Consistent Tagging

Pastikan API endpoints dikelompokkan dengan tags yang konsisten di OpenAPI spec.

2. Proper Type Safety

Manfaatkan generated types untuk menghindari runtime errors.

3. Error Handling

Gunakan proper error handling dengan generated hooks.

4. Code Organization

Import hooks dan types dengan proper barrel exports.

5. Regeneration

Regenerate code setiap ada perubahan di OpenAPI spec.

🔍 Troubleshooting

Common Issues

Problem: Generated types tidak update Solution: Jalankan filter-openapi.mjs dulu, kemudian kubb build

Problem: Missing dependencies Solution: Pastikan @kubb/cli dan plugins terinstall

Problem: Import errors Solution: Check barrel exports di gen/index.ts

Debug Commands

# Check generated files
ls -la gen/hooks/ gen/types/

# Validate OpenAPI spec
npx kubb validate --input sisappra.filtered.json

# Build with verbose output
npx kubb build --config kubb.config.ts --verbose

📚 Additional Resources