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​