npm package: @stardyn/angular-data-source
Description: Angular Data Source Package - Lightweight, configurable HTTP data source service for Angular applications with authentication, filtering, and storage support
Author: Stardyn Team
Latest version: 2.0.13

# @stardyn/angular-data-source

Lightweight, configurable HTTP data source service for Angular applications with authentication, filtering, and storage support. Provides comprehensive API client functionality with automatic token refresh, request/response interceptors, and local storage management.

## Features

- **HTTP Client Integration**: Seamless integration with Axios HTTP client
- **Absolute URL Support**: Support for both relative paths and absolute URLs
- **Authentication Support**: Token-based authentication with automatic refresh
- **Request/Response Interceptors**: Configurable interceptors for all HTTP requests
- **API Response Wrapper**: Standardized response handling with ApiResponse class
- **Local Storage Service**: Site-specific storage management with debugging
- **Advanced Filtering**: Comprehensive filtering system with multiple operators
- **Pagination Support**: Built-in pagination handling for data sources
- **Performance Focused**: Zero overhead configuration with singleton patterns
- **Rich Logging**: Debug mode with detailed logging for development
- **Production Ready**: Automatically optimized for production environments

## Installation

```bash
npm install @stardyn/angular-data-source
```

## Prerequisites

This package requires Angular and RxJS:

```bash
npm install @angular/core @angular/common rxjs
```

## Quick Start

### 1. App Module Configuration

```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { provideXconDataSource } from '@stardyn/angular-data-source';

import { AppComponent } from './app.component';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    provideXconDataSource({
      apiUrl: environment.apiUrl,
      site_key: 'my-app',
      debugMode: !environment.production
    })
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

### 2. Standalone Application Configuration

```typescript
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideXconDataSource } from '@stardyn/angular-data-source';

import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';

bootstrapApplication(AppComponent, {
  providers: [
    provideXconDataSource({
      apiUrl: environment.apiUrl,
      site_key: 'my-app',
      debugMode: !environment.production
    })
  ]
});
```

### 3. Service Usage

```typescript
import { Component, OnInit } from '@angular/core';
import { DataSourceApi, StorageService } from '@stardyn/angular-data-source';

@Component({
  selector: 'app-root',
  template: `
    <h1>{{ title }}</h1>
    <button (click)="loadData()">Load Data</button>
  `
})
export class AppComponent implements OnInit {
  title = 'My App with Data Source';

  constructor(
    private apiService: DataSourceApi,
    private storage: StorageService
  ) {}

  ngOnInit() {
    // Set authentication token
    const token = this.storage.get('auth_token', null);
    if (token) {
      this.apiService.getDataSource().tokenSet(token);
    }
  }

  async loadData() {
    try {
      const response = await this.apiService.get('/api/users');
      if (response.success) {
        console.log('Users loaded:', response.data);
      }
    } catch (error) {
      console.error('Failed to load users:', error);
    }
  }
}
```

## API Reference

### DataSource Configuration

```typescript
interface XconDataSourceBasicConfig {
  apiUrl?: string;        // Base API URL
  site_key?: string;      // Site key for storage isolation
  debugMode?: boolean;    // Enable/disable debug logging
}
```

### DataSourceWithRefresh Configuration

```typescript
interface XconDataSourceConfig {
  apiUrl?: string;
  site_key?: string;
  debugMode?: boolean;
  refreshToken?: () => Promise<ApiResponse>;  // Token refresh callback
  onAuthFail?: () => void;                    // Authentication failure callback
}
```

### DataSourceApi Methods

```typescript
// HTTP Methods
async post(path: string, data: any): Promise<ApiResponse>
async get(path: string): Promise<ApiResponse>
async put(path: string, data: any): Promise<ApiResponse>
async del(path: string, data: any): Promise<ApiResponse>

// Utility Methods
getDataSource(): DataSource
isReady(): boolean
```

### StorageService Methods

```typescript
// Basic Storage Operations
set(key: string, value: any): void
get(key: string, defaultValue: any): any
remove(key: string): void
exists(key: string): boolean

// Advanced Operations
getKeys(): string[]
clear(): void                    // Clear site-specific data
clean(): void                   // Clear all localStorage
getStorageSize(): number
isStorageAvailable(): boolean
```

### ApiResponse Class

```typescript
class ApiResponse {
  code: number;           // HTTP status code
  data: any;             // Response data
  success: boolean;      // Success flag
  message: string;       // Response message
  dataItems: any;        // Items array for paginated responses
  dataItemCount: number; // Total item count

  static create(params: {
    success: boolean;
    data?: any;
    message?: string;
    code?: number;
  }): ApiResponse
}
```

## Configuration Examples

### Basic Configuration

```typescript
provideXconDataSource({
  apiUrl: 'https://api.example.com',
  site_key: 'my-app',
  debugMode: true
})
```

### Configuration with Token Refresh

```typescript
provideXconDataSourceWithRefreshToken({
  apiUrl: 'https://api.example.com',
  site_key: 'my-app',
  debugMode: true,
  refreshToken: async () => {
    // Your token refresh logic
    const response = await fetch('/auth/refresh');
    const data = await response.json();
    return ApiResponse.create({
      success: response.ok,
      data: data
    });
  },
  onAuthFail: () => {
    // Redirect to login or show authentication error
    window.location.href = '/login';
  }
})
```

### Environment-Based Configuration

```typescript
// environments/environment.ts
export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/api',
  dataSource: {
    site_key: 'dev-app',
    debugMode: true
  }
};

// app.module.ts
provideXconDataSource({
  apiUrl: environment.apiUrl,
  ...environment.dataSource
})
```

## Advanced Usage

### URL Handling: Relative vs Absolute

The DataSource API supports both relative paths and absolute URLs:

#### Relative Paths (uses configured baseURL)
```typescript
// With baseURL configured as 'https://api.example.com'
await apiService.get('/users');
// Requests: https://api.example.com/users

await apiService.post('/auth/login', credentials);
// Requests: https://api.example.com/auth/login
```

#### Absolute URLs (bypasses baseURL)
```typescript
// Direct external API calls
await apiService.get('https://external-api.com/data');
// Requests: https://external-api.com/data

await apiService.post('https://another-service.com/webhook', payload);
// Requests: https://another-service.com/webhook
```

#### Mixed Usage Example
```typescript
async loadAllData() {
  // Internal API (uses baseURL)
  const users = await this.apiService.get('/users');
  
  // External API (absolute URL)
  const weather = await this.apiService.get('https://api.weather.com/current');
  
  // Another microservice (absolute URL)
  const analytics = await this.apiService.get('https://analytics.myapp.com/stats');
  
  return { users, weather, analytics };
}
```

#### Benefits of Absolute URL Support
- **Microservices**: Easy integration with multiple backend services
- **Third-Party APIs**: Direct calls to external APIs without proxy
- **Token Management**: Authorization headers automatically included for both relative and absolute URLs
- **Interceptors**: All requests go through configured interceptors
- **Refresh Token**: Automatic token refresh works for absolute URLs too

### Filtering and Pagination

```typescript
import { ApiPage, ApiPageFilter, ApiPageFilterOperator } from '@stardyn/angular-data-source';

// Create pagination
const page = new ApiPage(1, 20); // Page 1, 20 items per page

// Add filters
page.filter.filters.push({
  field: 'name',
  operator: ApiPageFilterOperator.Contains,
  value: 'john'
});

page.filter.filters.push({
  field: 'age',
  operator: ApiPageFilterOperator.GreaterThan,
  value: 18
});

// Convert to query string
const queryString = page.toDataSourceRequestString();
// Result: "skip=0&take=20&pageSize=20&page=1&query=..."

// Use with API
const response = await apiService.get(`/api/users?${queryString}`);
```

### Storage Management

```typescript
// Store user preferences
storage.set('user_preferences', {
  theme: 'dark',
  language: 'en'
});

// Retrieve with default
const preferences = storage.get('user_preferences', {
  theme: 'light',
  language: 'tr'
});

// Check storage status
if (storage.isStorageAvailable()) {
  console.log('Storage size:', storage.getStorageSize(), 'bytes');
  console.log('Keys:', storage.getKeys());
}
```

### Error Handling

```typescript
try {
  const response = await apiService.post('/api/users', userData);
  
  if (response.success) {
    console.log('User created:', response.data);
  } else {
    console.error('API Error:', response.message);
  }
} catch (error) {
  if (error.response?.status === 401) {
    // Handle authentication error
    console.log('Authentication required');
  } else {
    console.error('Network error:', error);
  }
}
```

## Provider Functions

### Standard DataSource

```typescript
// Provide both DataSource and DataSourceApi
provideXconDataSource(config): Provider

// Provide only DataSource
provideXconDataSourceOnly(config): Provider

// Provide only DataSourceApi
provideXconDataSourceApiOnly(config): Provider
```

### DataSource with Refresh Token

```typescript
// Provide DataSourceWithRefresh and DataSourceWithRefreshApi
provideXconDataSourceWithRefreshToken(config): Provider

// Provide only DataSourceWithRefresh
provideXconDataSourceWithRefreshOnly(config): Provider

// Provide only DataSourceWithRefreshApi
provideXconDataSourceWithRefreshApiOnly(config): Provider
```

### Storage Service

```typescript
// Provide StorageService
provideXconStorage(config): Provider
```

## Debug Output Examples

When debug mode is enabled, console outputs appear in this format:

```
[XconDataSource] DataSource service initialized
[XconDataSource] Setting environment configuration {"apiUrl": "...", "siteKey": "..."}
[XconDataSourceApi] POST request initiated {"path": "/api/users", "hasData": true}
[XconDataSourceApi] Using relative path with baseURL {"method": "POST", "path": "/api/users"}
[XconDataSourceApi] API POST /api/users [200] (245ms)

[XconDataSourceApi] GET request initiated {"path": "https://external-api.com/data"}
[XconDataSourceApi] Using absolute URL for request {"method": "GET", "path": "https://external-api.com/data"}
[XconDataSourceApi] API GET https://external-api.com/data [200] (312ms)
```

## Dependencies

### Peer Dependencies

- `@angular/core` >= 16.0.0
- `@angular/common` >= 16.0.0
- `rxjs` >= 7.0.0

### Dependencies

- `axios` - HTTP client
- `@stardyn/angular-console` - Console logging service

## Performance

- **Singleton Pattern**: Services use singleton pattern to prevent multiple instances
- **Memory Efficient**: Minimal memory footprint with proper cleanup
- **Production Optimized**: Debug logging automatically disabled in production
- **Lazy Loading**: Services only initialize when first used

## TypeScript Support

Full TypeScript support with intellisense and type safety:

```typescript
import { 
  XconDataSourceBasicConfig, 
  XconDataSourceConfig,
  ApiResponse,
  ApiPageFilterOperator
} from '@stardyn/angular-data-source';
```

## Troubleshooting

### API Requests Failing

1. Check if DataSource is properly configured with `apiUrl`
2. Verify authentication token is set if required
3. Enable debug mode to see detailed request logs
4. For absolute URLs, ensure the full URL including protocol is provided

### Storage Issues

1. Check if localStorage is available in the browser
2. Verify `site_key` is properly configured
3. Check browser storage quota if saving large data

### Token Refresh Not Working

1. Ensure `refreshToken` callback is properly implemented
2. Check `onAuthFail` callback is handling failures
3. Verify token refresh endpoint returns proper response format

### Absolute URL Not Working

1. Ensure URL starts with `http://` or `https://`
2. Check CORS settings on the external API
3. Verify authentication token is being sent if required

## License

MIT License - see LICENSE file for details.

## Repository

https://github.com/stardyn/angular-data-source