npm package: @ponceca/storage-sdk
Description: Firebase Storage Clone SDK - Compatible con Firebase v9
Author: ponceca
Latest version: 1.0.3

# Firebase Storage Clone SDK

Clon 100% compatible con Firebase Storage v9+, con funcionalidades extendidas.

## Instalación

```bash
npm install @ponceca/storage-sdk
# o
yarn add @ponceca/storage-sdk
```

## Uso Básico

```typescript
import { 
    getStorage, 
    ref, 
    uploadBytesResumable, 
    getDownloadURL,
    getMetadata,
    deleteObject,
    listAll
} from '@ponceca/storage-sdk';

// Inicializar (igual que Firebase)
const storage = getStorage({
    authEndpoint: 'http://localhost:8080/api',
    tokenGetter: async () => localStorage.getItem('token')
});

// Subir archivo
const fileRef = ref(storage, 'users/photo.jpg');
const task = uploadBytesResumable(fileRef, file, { contentType: 'image/jpeg' });

task.on('state_changed',
    (snapshot) => console.log(snapshot.bytesTransferred),
    (error) => console.error(error),
    () => console.log('¡Completado!')
);

// Obtener URL de descarga
const url = await getDownloadURL(fileRef);

// Metadata
const metadata = await getMetadata(fileRef);

// Eliminar
await deleteObject(fileRef);
```

## Funciones Disponibles

### Upload
| Función | Descripción |
|---------|-------------|
| `uploadBytesResumable(ref, data, metadata)` | Subida resumible con progreso |
| `uploadBytes(ref, data, metadata)` | Subida simple (Promise) |
| `uploadString(ref, value, format, metadata)` | Subir string (raw/base64/data_url) |

### Download
| Función | Descripción |
|---------|-------------|
| `getDownloadURL(ref)` | URL firmada para descargar |
| `getBytes(ref, maxSize?)` | Descargar como ArrayBuffer |
| `getBlob(ref, maxSize?)` | Descargar como Blob |
| `getStream(ref, maxSize?)` | Descargar como ReadableStream |

### Metadata
| Función | Descripción |
|---------|-------------|
| `getMetadata(ref)` | Obtener metadata del archivo |
| `updateMetadata(ref, metadata)` | Actualizar metadata |

### Listado
| Función | Descripción |
|---------|-------------|
| `listAll(ref)` | Listar todos los archivos |
| `list(ref, options)` | Listar con paginación |

### Eliminación
| Función | Descripción |
|---------|-------------|
| `deleteObject(ref)` | Eliminar archivo |

## Integración Angular (wrapper delgado)

El SDK incluye un wrapper Angular con provider + inyección + helpers reactivos.

Guía completa (Angular + integración con Firestore clone):

- `ANGULAR_FIRESTORE_INTEGRACION.md`
- `.github/docs/GUIA_ANGULAR_CLONES_FIRESTORE_STORAGE.md`

### Imports disponibles

- `@ponceca/storage-sdk/angular/storage`
- `@ponceca/storage-sdk/angular/fire/storage` (compat con sintaxis tipo AngularFire)

### Configuración en `app.config.ts`

```typescript
import { ApplicationConfig } from '@angular/core';
import { getStorage } from '@ponceca/storage-sdk/storage';
import { provideStorage } from '@ponceca/storage-sdk/angular/storage';

export const appConfig: ApplicationConfig = {
    providers: [
        ...provideStorage(() => getStorage({
            authEndpoint: 'http://localhost:8080/api',
            tokenGetter: async () => localStorage.getItem('token'),
            project: 'mi-proyecto',
            bucket: 'mi-bucket'
        }))
    ]
};
```

### Uso en servicio Angular

```typescript
import { injectStorage, ref, uploadBytes, getDownloadURL } from '@ponceca/storage-sdk/angular/storage';

const storage = injectStorage();
const fileRef = ref(storage, 'uploads/foto.png');
await uploadBytes(fileRef, archivo);
const url = await getDownloadURL(fileRef);
```

### Multi-instancia (opcional)

```typescript
providers: [
    ...provideStorage(() => getStorage(mainConfig)),
    ...provideStorage(() => getStorage(backupConfig), { name: 'backup' })
]

const backupStorage = injectStorage('backup');
```

### Helpers reactivos

- `uploadTaskObservable(task)`
- `uploadTaskSignal(task)`
- `downloadUrlSignal(ref)`

> Nota: `uploadTaskObservable` requiere `rxjs` en la app Angular.

## Compatibilidad de imports (IA / código legado)

Se añadieron subpaths para facilitar aliases:

- `@ponceca/storage-sdk/firebase/storage` -> core storage
- `@ponceca/storage-sdk/angular/fire/storage` -> wrapper Angular

Para soportar código que importa `firebase/storage`, configura alias en la app consumidora (`tsconfig` + bundler) hacia `@ponceca/storage-sdk/firebase/storage`.

## Funciones Exclusivas (Super-Firebase)

### Thumbnails Automáticos

```typescript
import { getThumbnailURL } from '@ponceca/storage-sdk';

// Thumbnail de 320px (por defecto)
const thumbUrl = await getThumbnailURL(fileRef);

// Thumbnail de tamaño específico
const thumb500 = await getThumbnailURL(fileRef, 500);
```

### Video Streaming HLS

```typescript
import { getHLSStreamURL } from '@ponceca/storage-sdk';

// Obtiene URL del manifest HLS (.m3u8)
const hlsUrl = await getHLSStreamURL(fileRef);

// Usar con video.js, hls.js, etc.
```

## Configuración del Backend

Variables de entorno requeridas:

```env
DATABASE_URL=postgres://user:pass@localhost:5432/storage_db
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin123
JWT_SECRET=tu-secreto-jwt
RATE_LIMIT_REQUESTS=10000
```

## Diferencias con Firebase Original

| Característica | Firebase | Este Clon |
|----------------|----------|-----------|
| Thumbnails automáticos | ❌ | ✅ |
| Video streaming HLS | ❌ | ✅ |
| Self-hosted | ❌ | ✅ |
| Rate limit configurable | Fijo | ✅ 10k/min |
| Sin límites de egreso | ❌ (costoso) | ✅ |

## Tests

```bash
cd productiontest
node firebase_sdk_test.js
```

### Tests E2E reales del wrapper Angular (SDK compilado)

La suite `tests/angular.wrapper.compat.test.ts` ejecuta operaciones reales contra backend usando `dist/src/angular-wrapper/index.js`.

Variables requeridas:

```bash
set STORAGE_E2E_ENDPOINT=http://localhost:8080/api
set STORAGE_E2E_TOKEN=tu_jwt_valido
```

Opcionales:

```bash
set STORAGE_E2E_API_KEY=tu_api_key
set STORAGE_E2E_PROJECT=default
set STORAGE_E2E_BUCKET=default
```

Ejecución:

```bash
npm run build:ts
npm test -- tests/angular.wrapper.compat.test.ts --runInBand
```

Si faltan `STORAGE_E2E_ENDPOINT` o `STORAGE_E2E_TOKEN`, la suite se omite (`skip`) intencionalmente.

## Licencia

MIT