@codegenapps/frontend-sdk
v1.0.12
Published
A frontend SDK for seamless API integration, driven by a dynamic schema.
Readme
CGA Frontend SDK (The Ultimate Guide)
A high-performance, dynamic, schema-driven frontend SDK. It automatically maps your backend API (via Swagger/OpenAPI) into a fluent, chainable TypeScript client with built-in JWT management and auto-refresh.
🚀 1. Installation & Setup
Install
npm install @codegenapps/frontend-sdkInitialization
The SDK should be initialized once (usually in your app's entry point).
import cga from '@codegenapps/frontend-sdk';
await cga.init({
baseUrl: 'https://api.yourproject.com/api', // Required: Your API root
apiKey: 'YOUR_CGA_API_KEY', // Required: For auth endpoints
// Token Management (Required for Auth)
getToken: () => localStorage.getItem('access_token'),
getRefreshToken: () => localStorage.getItem('refresh_token'),
onTokensRefreshed: (access, refresh) => {
localStorage.setItem('access_token', access);
localStorage.setItem('refresh_token', refresh);
},
// Advanced Options
headers: { 'X-App-Platform': 'Web' }, // Global headers
debug: true, // Detailed logs in console
schema: null, // Optional: Pre-loaded swagger JSON
});Lifecycle: ready()
In frameworks like React, use await cga.ready() to ensure the schema is loaded before the first query.
useEffect(() => {
const loadData = async () => {
await cga.ready();
const { data } = await cga.from('products').select().run();
setProducts(data);
};
loadData();
}, []);🔐 2. Authentication (cga.auth)
The SDK handles token injection and automatic 401 refresh internally.
| Method | Description | Example |
| :--- | :--- | :--- |
| login(payload \| acc, pwd) | Login & get tokens. | cga.auth.login('user', 'pass') |
| register(payload) | Create new account. | cga.auth.register({ account, password, name }) |
| oauth(provider) | Browser redirect to provider. | cga.auth.oauth('google') |
| logout() | Clear server session. | await cga.auth.logout() |
🔍 3. The Query Builder (.from(path))
The core of the SDK is a fluent builder that supports both REST and ORM styles.
Selection & HTTP Methods
| Method | Type | Description |
| :--- | :--- | :--- |
| .get(options?) | REST | Standard GET request. |
| .select(fields?, options?)| ORM | GET request, optionally specifying fields. |
| .post(data, options?) | REST | Standard POST request. |
| .insert(data, options?) | ORM | POST request (Supports single or Array for batch). |
| .put(data, options?) | REST | Full update (PUT). |
| .update(data, options?) | ORM | Full update (PUT). |
| .patch(data, options?) | REST | Partial update (PATCH). |
| .delete(data?, options?) | REST | DELETE request (Supports single or ID array for batch). |
| .remove(data?, options?) | ORM | Alias for .delete(). |
Advanced Filtering (GET Only)
All filters are cumulative (AND).
const query = cga.from('products').select()
.eq('status', 'active') // Equals
.neq('type', 'virtual') // Not Equals
.gt('price', 100) // Greater Than
.gte('stock', 1) // Greater Than or Equal
.lt('weight', 50) // Less Than
.lte('discount', 0.5) // Less Than or Equal
.like('name', 'Apple') // Substring search (auto %...%)
.in('id', [1, 2, 5]) // Value in list
.or('category,eq,A|category,eq,B'); // Custom OR logic stringModifiers (Pagination, Sort, Groups)
query
.range(1, 20) // Page 1, Size 20
.order('created_at', { ascending: false }) // Sort
.expand(['author', 'tags']) // Eager load relationships
.meta(['count(id)', 'avg(price)']) // Aggregation/Statistics
.groupBy(['category_id']) // Grouping resultsExecution
Every chain MUST end with .run() to trigger the network request.
const { data, error } = await query.run();🛠️ 4. Path Parameters & Composite Keys
Use .byPk() to fill URL placeholders or specify primary keys.
// 1. Placeholder Replacement: users/{id} -> users/123
await cga.from('users/{id}').byPk({ id: 123 }).get().run();
// 2. Composite Keys: orders/{order_id}/{item_id}
await cga.from('orders/{order_id}/{item_id}')
.byPk({ order_id: 10, item_id: 1 })
.get().run();🌐 5. Third-Party & Custom Requests
Calling Proxied APIs (e.g., Gemini, FCM)
The SDK works seamlessly with backend proxies.
// Call Gemini AI
const { data } = await cga.from('gemini').post({ prompt: '...' }).run();
// Send Push Notification
await cga.from('fcm').post({ to: '...', message: '...' }).run();Request Options (Custom Headers & Axios)
Every terminal method (select, post, run, etc.) accepts an options object.
const options = {
headers: { 'X-Custom-Header': 'foo' },
axiosConfig: {
timeout: 10000,
responseType: 'blob', // Download files
params: { legacy_param: 'value' } // Extra raw query params
}
};
await cga.from('reports').get(options).run();📁 6. File Uploads (.asFormData())
When you need to upload files (e.g., Images, Documents), use the .asFormData() modifier. This automatically converts your payload into multipart/form-data and handles the boundary headers for you.
// Example: Uploading an avatar image
const fileInput = document.getElementById('avatar-input');
const file = fileInput.files[0];
await cga.from('users/{id}')
.byPk({ id: 123 })
.asFormData() // Instructs SDK to use FormData
.patch({
name: 'New Name', // Text fields work normally
avatar: file // File/Blob objects are appended correctly
})
.run();🛡️ 7. Client-Side Validation
The SDK leverages the pre-loaded swagger.json to perform immediate client-side validation for POST, PUT, and PATCH requests. If you miss a required field as defined by the backend API, the SDK will catch it before making the network request, saving time and bandwidth.
// Assuming the schema requires 'title' and 'content' for a POST to 'posts'
const { data, error } = await cga.from('posts').insert({
title: 'My Title' // Missing 'content'
}).run();
if (error) {
console.log(error.message); // "Client-side validation failed"
console.log(error.details); // "Missing required field: 'content'."
}🤖 AI Agent Guide (Context for LLMs)
When generating code for this SDK, follow these rules:
- Always use
.run(): Chains are not thenable. - Resource Discovery: Use the exact paths from the Swagger documentation (e.g.,
cart_items,auth/login). - Error Handling: Destructure
{ data, error }fromrun().datais usually the array/object,errorcontains backend error messages. - Batch Conventions:
insert([...])triggers/batchPOST.remove([...])triggers/batchDELETE with{ ids: [...] }.
- Path Params: Prefer
.byPk()over manual string concatenation for paths likeusers/{id}.
📄 License
MIT
