# Custom Browser API

### Overview

The FPS platform provides a global browser API for custom HTML components. This API handles authentication automatically using secure HTTP-only cookies, eliminating the need to manage session tokens in your code.

### Available APIs

#### `window.callEndpoint()`

Makes authenticated API requests to your backend endpoints.

**Signature:**

```javascript
window.callEndpoint(endpoint, method, body, params, callback, options)
```

**Parameters:**

* `endpoint` (string) - The API endpoint name (e.g., `'getFeatures'`, `'updateUser'`)
* `method` (string) - HTTP method: `'GET'`, `'POST'`, `'PUT'`, `'DELETE'`
* `body` (object) - Request body for POST/PUT/DELETE requests (ignored for GET)
* `params` (object) - Query parameters (e.g., `{ page: 1, limit: 10 }`)
* `callback` (function) - Callback function: `(status, data, settings, fullResponse) => {}`
  * `status` (string) - `'ok'` or `'error'`
  * `data` (array|object) - Response data
  * `settings` (object) - View settings (optional)
  * `fullResponse` (object) - Full API response
* `options` (object) - Optional settings (e.g., `{ signal: abortController.signal }`)

**Returns:** Nothing (results passed to callback)

### Examples

#### Basic GET Request

```javascript
// Fetch user list
window.callEndpoint(
  'getUsers',           // endpoint
  'GET',                // method
  undefined,            // body (not used for GET)
  { limit: 10 },        // params
  (status, data) => {   // callback
    if (status === 'ok') {
      console.log('Users:', data);
      // Render your data here
    } else {
      console.error('Error:', data);
    }
  }
);
```

#### POST Request with Body

```javascript
// Create new item
window.callEndpoint(
  'createItem',
  'POST',
  { 
    title: 'New Item',
    description: 'Item description',
    price: 99.99
  },
  {},
  (status, data) => {
    if (status === 'ok') {
      console.log('Created:', data);
    }
  }
);
```

#### Update Request

```javascript
// Update existing record
window.callEndpoint(
  'updateItem',
  'POST',
  { 
    id: '123',
    title: 'Updated Title'
  },
  {},
  (status, data, settings, fullResponse) => {
    if (status === 'ok') {
      console.log('Updated successfully');
      console.log('Full response:', fullResponse);
    }
  }
);
```

#### Search with Filters

```javascript
// Search with query parameters
window.callEndpoint(
  'searchItems',
  'GET',
  undefined,
  {
    _value: 'search term',
    category: 'electronics',
    minPrice: 50
  },
  (status, data) => {
    if (status === 'ok') {
      document.getElementById('results').innerHTML = 
        data.map(item => `<div>${item.title}</div>`).join('');
    }
  }
);
```

#### With Abort Controller

```javascript
const abortController = new AbortController();

window.callEndpoint(
  'getLargeData',
  'GET',
  undefined,
  {},
  (status, data) => {
    console.log('Data received:', data);
  },
  { signal: abortController.signal }
);

// Cancel request after 5 seconds
setTimeout(() => abortController.abort(), 5000);
```

### Authentication

**All requests are automatically authenticated.** The session token is stored in a secure HTTP-only cookie and is automatically included with every request. You don't need to:

* Store tokens in localStorage/sessionStorage
* Manually add authorization headers
* Handle token refresh

The platform manages authentication for you.

### Error Handling

```javascript
window.callEndpoint(
  'riskyOperation',
  'POST',
  { data: 'value' },
  {},
  (status, data) => {
    if (status === 'error') {
      // API returned an error
      console.error('API Error:', data.msg || data);
      // Show error to user
      alert('Operation failed: ' + (data.msg || 'Unknown error'));
    } else {
      // Success
      console.log('Success:', data);
    }
  }
);
```

### Migration Guide

If you have existing code using `fetch()` directly, you need to migrate to `window.callEndpoint()` for authentication to work properly.

#### Before (Old Code - Will Not Work)

```javascript
// ❌ This will NOT work - no access to session token
fetch('https://api.example.com/endpoint?sessionID=TOKEN', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ key: 'value' })
})
.then(res => res.json())
.then(data => console.log(data));
```

#### After (New Code - Works)

```javascript
// ✅ This works - automatic authentication
window.callEndpoint(
  'endpoint',
  'POST',
  { key: 'value' },
  {},
  (status, data) => {
    if (status === 'ok') {
      console.log(data);
    }
  }
);
```

### File Upload with FormData

```javascript
// Upload file to backend
const fileInput = document.getElementById('fileInput');

fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  
  if (!file) return;
  
  // Create FormData and append file
  const formData = new FormData();
  formData.append('file', file);
  
  // You can add additional fields
  formData.append('description', 'My uploaded file');
  formData.append('category', 'documents');
  
  window.callEndpoint(
    'uploadFile',         // endpoint name
    'POST',               // method
    formData,             // FormData body (not JSON!)
    { 
      fileStorage: 'my-storage',
      maxSize: 10485760  // optional params
    },
    (status, data) => {
      if (status === 'ok') {
        console.log('File uploaded:', data);
        // data might contain file URL, ID, etc.
        alert('File uploaded successfully!');
      } else {
        console.error('Upload failed:', data);
        alert('Upload error: ' + (data.msg || 'Unknown error'));
      }
    }
  );
});
```

Important for file uploads:

* Use FormData instead of plain object for body parameter
* The browser automatically sets correct Content-Type with boundary for multipart/form-data
* Field name 'file' must match your backend FileUpload data structure field
* You can append multiple files or additional text fields to FormData

### AI Migration Prompt

Use this prompt with an AI assistant to automatically convert your old code:

***

**PROMPT:**

```
I need to migrate my fetch() API calls to use window.callEndpoint() for the FPS platform.

OLD PATTERN (fetch):
- Direct fetch() calls to API endpoints
- Manual sessionID/token in URL or headers
- Promise-based (.then/.catch)

NEW PATTERN (window.callEndpoint):
- window.callEndpoint(endpoint, method, body, params, callback)
- Automatic authentication (no token needed)
- Callback-based

CONVERSION RULES:
1. Extract endpoint name from URL (last segment)
2. Convert HTTP method (GET/POST/PUT/DELETE)
3. Move body from fetch options to 3rd parameter
4. Move URL query params to 4th parameter (as object)
5. Convert .then(res => res.json()).then(data => ...) to callback: (status, data) => { if (status === 'ok') { ... } }
6. Remove all sessionID, token, Authorization headers
7. Keep only 'signal' in options if using AbortController

Please convert this code:

[PASTE YOUR CODE HERE]
```

***

**Example Conversion:**

Input:

```javascript
fetch('/api/sl?sl=getFeatures&limit=10', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ category: 'electronics' })
})
.then(res => res.json())
.then(data => {
  console.log(data);
  renderItems(data);
})
.catch(err => console.error(err));
```

AI Output:

```javascript
window.callEndpoint(
  'getFeatures',
  'POST',
  { category: 'electronics' },
  { limit: 10 },
  (status, data) => {
    if (status === 'ok') {
      console.log(data);
      renderItems(data);
    } else {
      console.error(data);
    }
  }
);
```

### Best Practices

1. **Always check status** in the callback before using data
2. **Don't store tokens** - authentication is handled automatically
3. **Use meaningful endpoint names** that match your backend structure
4. **Handle errors gracefully** with user-friendly messages
5. **Use AbortController** for long-running requests that can be cancelled
6. **Test in browser console** before integrating into your component

### Troubleshooting

#### Request not authenticated

* Make sure you're logged in to the platform
* Check that the user has valid session (check browser cookies for `token_new_*`)

#### Endpoint not found

* Verify the endpoint name matches your backend configuration
* Check for typos in the endpoint string

#### Data not received

* Verify the callback function is being called
* Check browser console for errors
* Inspect network tab in DevTools to see the actual request/response

### Additional Resources

* See `SESSION_AUTH.md` for details on session management
* Check your backend API documentation for available endpoints
* Use browser DevTools Network tab to debug requests
