391 lines
8.5 KiB
Markdown
391 lines
8.5 KiB
Markdown
# Tryton RPC Client para Node.js
|
|
|
|
Cliente TypeScript completo para conectar con servidores Tryton ERP a través de JSON-RPC.
|
|
|
|
## 🚀 Características
|
|
|
|
- ✅ **100% TypeScript** - Tipado completo y seguro
|
|
- ✅ **Compatible con Node.js** - Versión 14 o superior
|
|
- ✅ **Operaciones CRUD** - Create, Read, Update, Delete
|
|
- ✅ **Búsquedas avanzadas** - Search, SearchRead, SearchCount
|
|
- ✅ **Cache integrado** - Sistema LRU cache para optimización
|
|
- ✅ **Pool de conexiones** - Manejo eficiente de múltiples conexiones
|
|
- ✅ **Soporte HTTPS/HTTP** - Conexiones seguras
|
|
- ✅ **Operaciones tipadas** - Factory para modelos con tipos específicos
|
|
|
|
## 📦 Instalación
|
|
|
|
### Opción 1: Instalación local (sin npm)
|
|
|
|
Simplemente copia la carpeta completa a tu proyecto y construye:
|
|
|
|
```bash
|
|
cd trytonClientNode
|
|
npm install
|
|
npm run build
|
|
```
|
|
|
|
### Opción 2: Usar directamente en otro proyecto
|
|
|
|
Desde la carpeta de tu proyecto:
|
|
|
|
```bash
|
|
npm install /ruta/a/trytonClientNode
|
|
```
|
|
|
|
## 🔧 Uso
|
|
|
|
### Conexión básica
|
|
|
|
```typescript
|
|
import { TrytonClient } from '@tryton/client-node';
|
|
|
|
// Crear cliente
|
|
const client = new TrytonClient({
|
|
hostname: 'localhost',
|
|
port: 8000,
|
|
database: 'tryton_db',
|
|
username: 'admin',
|
|
password: 'admin',
|
|
language: 'es'
|
|
});
|
|
|
|
// Conectar
|
|
await client.connect();
|
|
```
|
|
|
|
### Operaciones CRUD
|
|
|
|
#### Leer registros
|
|
|
|
```typescript
|
|
// Leer registros específicos
|
|
const parties = await client.read(
|
|
'party.party',
|
|
[1, 2, 3],
|
|
['name', 'code', 'email']
|
|
);
|
|
|
|
console.log(parties);
|
|
// [{ id: 1, name: 'Company A', code: 'C001', email: 'a@example.com' }, ...]
|
|
```
|
|
|
|
#### Crear registros
|
|
|
|
```typescript
|
|
// Crear nuevos registros
|
|
const ids = await client.create('party.party', [
|
|
{ name: 'New Company', code: 'NC001' },
|
|
{ name: 'Another Company', code: 'AC001' }
|
|
]);
|
|
|
|
console.log(ids); // [4, 5]
|
|
```
|
|
|
|
#### Actualizar registros
|
|
|
|
```typescript
|
|
// Actualizar registros existentes
|
|
await client.write(
|
|
'party.party',
|
|
[1, 2],
|
|
{ active: false }
|
|
);
|
|
```
|
|
|
|
#### Eliminar registros
|
|
|
|
```typescript
|
|
// Eliminar registros
|
|
await client.delete('party.party', [4, 5]);
|
|
```
|
|
|
|
### Búsquedas
|
|
|
|
#### Search - Buscar IDs
|
|
|
|
```typescript
|
|
// Buscar IDs que cumplan criterios
|
|
const ids = await client.search(
|
|
'party.party',
|
|
[['name', 'like', '%Company%']],
|
|
0, // offset
|
|
10, // limit
|
|
['name'] // order
|
|
);
|
|
|
|
console.log(ids); // [1, 2, 3]
|
|
```
|
|
|
|
#### SearchRead - Buscar y leer en una sola operación
|
|
|
|
```typescript
|
|
// Buscar y leer directamente
|
|
const parties = await client.searchRead(
|
|
'party.party',
|
|
[['active', '=', true]],
|
|
['name', 'code', 'email'],
|
|
0,
|
|
100
|
|
);
|
|
```
|
|
|
|
#### SearchCount - Contar registros
|
|
|
|
```typescript
|
|
// Contar registros que cumplen criterios
|
|
const count = await client.searchCount(
|
|
'party.party',
|
|
[['active', '=', true]]
|
|
);
|
|
|
|
console.log(count); // 150
|
|
```
|
|
|
|
### Operaciones tipadas (Type-safe)
|
|
|
|
```typescript
|
|
// Definir interfaz del modelo
|
|
interface Party {
|
|
id: number;
|
|
name: string;
|
|
code: string;
|
|
email?: string;
|
|
active: boolean;
|
|
}
|
|
|
|
// Usar operaciones tipadas
|
|
const partyModel = client.model<Party>('party.party');
|
|
|
|
// Todas las operaciones están tipadas
|
|
const parties = await partyModel.searchRead(
|
|
[['active', '=', true]],
|
|
['name', 'code', 'email']
|
|
);
|
|
|
|
// TypeScript sabe que 'parties' es Party[]
|
|
parties.forEach(party => {
|
|
console.log(party.name); // ✅ Autocompletado
|
|
});
|
|
```
|
|
|
|
### Métodos de utilidad
|
|
|
|
```typescript
|
|
// Obtener información del usuario actual
|
|
const user = await client.getCurrentUser();
|
|
console.log(user.name, user.login);
|
|
|
|
// Obtener preferencias del usuario
|
|
const prefs = await client.getUserPreferences();
|
|
console.log(prefs.language);
|
|
|
|
// Obtener versión del servidor
|
|
const version = await client.getVersion();
|
|
console.log(version);
|
|
|
|
// Listar bases de datos disponibles
|
|
const databases = await client.listDatabases();
|
|
console.log(databases);
|
|
```
|
|
|
|
### Llamadas RPC personalizadas
|
|
|
|
```typescript
|
|
// Llamar a cualquier método RPC
|
|
const result = await client.call('model.party.party.custom_method', [
|
|
arg1,
|
|
arg2,
|
|
{ context: 'value' }
|
|
]);
|
|
```
|
|
|
|
### Manejo de cache
|
|
|
|
```typescript
|
|
// Limpiar cache completo
|
|
client.clearCache();
|
|
|
|
// Limpiar cache con prefijo específico
|
|
client.clearCache('model.party.party');
|
|
```
|
|
|
|
## 📋 API Principal
|
|
|
|
### Constructor
|
|
|
|
```typescript
|
|
new TrytonClient(config: TrytonClientConfig)
|
|
```
|
|
|
|
**TrytonClientConfig:**
|
|
- `hostname` - Host del servidor (con o sin `http://`/`https://`)
|
|
- `database` - Nombre de la base de datos
|
|
- `username` - Usuario de Tryton
|
|
- `password` - Contraseña
|
|
- `port` - Puerto del servidor (default: 8000)
|
|
- `language` - Idioma (default: 'en')
|
|
- `options` - Opciones adicionales (cache, timeouts, etc.)
|
|
|
|
### Métodos principales
|
|
|
|
| Método | Descripción |
|
|
|--------|-------------|
|
|
| `connect()` | Conecta y autentica con el servidor |
|
|
| `read(model, ids, fields, context?)` | Lee registros específicos |
|
|
| `create(model, records, context?)` | Crea nuevos registros |
|
|
| `write(model, ids, values, context?)` | Actualiza registros |
|
|
| `delete(model, ids, context?)` | Elimina registros |
|
|
| `search(model, domain, offset?, limit?, order?, context?)` | Busca IDs |
|
|
| `searchRead(model, domain, fields, offset?, limit?, order?, context?)` | Busca y lee |
|
|
| `searchCount(model, domain, context?)` | Cuenta registros |
|
|
| `call(method, args?)` | Llamada RPC genérica |
|
|
| `model(modelName)` | Factory de operaciones tipadas |
|
|
|
|
### Propiedades
|
|
|
|
| Propiedad | Descripción |
|
|
|-----------|-------------|
|
|
| `isConnected` | Indica si está conectado |
|
|
| `ssl` | Indica si usa HTTPS |
|
|
| `url` | URL de conexión |
|
|
|
|
## 🔒 Dominios de búsqueda
|
|
|
|
Los dominios en Tryton siguen la sintaxis de Python:
|
|
|
|
```typescript
|
|
// Operadores básicos
|
|
[['field', '=', value]] // Igual
|
|
[['field', '!=', value]] // Diferente
|
|
[['field', '>', value]] // Mayor que
|
|
[['field', '<', value]] // Menor que
|
|
[['field', '>=', value]] // Mayor o igual
|
|
[['field', '<=', value]] // Menor o igual
|
|
[['field', 'like', '%pattern%']] // Like (SQL)
|
|
[['field', 'in', [1, 2, 3]]] // En lista
|
|
|
|
// Operadores lógicos
|
|
['OR', [['f1', '=', 'a']], [['f2', '=', 'b']]] // OR
|
|
['AND', [['f1', '=', 'a']], [['f2', '=', 'b']]] // AND (default)
|
|
|
|
// Ejemplo complejo
|
|
[
|
|
'OR',
|
|
['AND', [['name', 'like', '%Inc%']], [['active', '=', true]]],
|
|
[['code', 'in', ['A001', 'B002']]]
|
|
]
|
|
```
|
|
|
|
## 🛠️ Scripts de desarrollo
|
|
|
|
```bash
|
|
# Compilar el código TypeScript
|
|
npm run build
|
|
|
|
# Compilar en modo watch
|
|
npm run build:watch
|
|
|
|
# Limpiar archivos compilados
|
|
npm run clean
|
|
```
|
|
|
|
## 📁 Estructura de archivos
|
|
|
|
```
|
|
trytonClientNode/
|
|
├── cache.ts # Sistema de cache LRU
|
|
├── client.ts # Cliente principal
|
|
├── index.ts # Exports públicos
|
|
├── jsonrpc.ts # Implementación JSON-RPC
|
|
├── types.ts # Definiciones de tipos
|
|
├── package.json # Configuración del paquete
|
|
├── tsconfig.json # Configuración TypeScript
|
|
└── README.md # Este archivo
|
|
```
|
|
|
|
## 🔍 Ejemplo completo
|
|
|
|
```typescript
|
|
import { TrytonClient } from '@tryton/client-node';
|
|
|
|
async function main() {
|
|
// 1. Crear y conectar
|
|
const client = new TrytonClient({
|
|
hostname: 'http://localhost',
|
|
port: 8000,
|
|
database: 'tryton',
|
|
username: 'admin',
|
|
password: 'admin'
|
|
});
|
|
|
|
await client.connect();
|
|
console.log('✅ Conectado');
|
|
|
|
// 2. Buscar empresas activas
|
|
const activeParties = await client.searchRead(
|
|
'party.party',
|
|
[['active', '=', true]],
|
|
['name', 'code'],
|
|
0,
|
|
10
|
|
);
|
|
|
|
console.log('Empresas activas:', activeParties);
|
|
|
|
// 3. Crear una nueva empresa
|
|
const [newId] = await client.create('party.party', [{
|
|
name: 'Mi Nueva Empresa',
|
|
code: 'MNE001'
|
|
}]);
|
|
|
|
console.log('✅ Empresa creada con ID:', newId);
|
|
|
|
// 4. Leer la empresa creada
|
|
const [newParty] = await client.read(
|
|
'party.party',
|
|
[newId],
|
|
['name', 'code', 'create_date']
|
|
);
|
|
|
|
console.log('Empresa creada:', newParty);
|
|
|
|
// 5. Actualizar la empresa
|
|
await client.write(
|
|
'party.party',
|
|
[newId],
|
|
{ name: 'Empresa Actualizada' }
|
|
);
|
|
|
|
console.log('✅ Empresa actualizada');
|
|
|
|
// 6. Verificar actualización
|
|
const [updated] = await client.read(
|
|
'party.party',
|
|
[newId],
|
|
['name']
|
|
);
|
|
|
|
console.log('Nuevo nombre:', updated.name);
|
|
}
|
|
|
|
main().catch(console.error);
|
|
```
|
|
|
|
## ⚠️ Requisitos
|
|
|
|
- Node.js >= 14.0.0
|
|
- Servidor Tryton activo y accesible
|
|
|
|
## 📝 Licencia
|
|
|
|
MIT
|
|
|
|
## 🤝 Contribuciones
|
|
|
|
Este es un paquete independiente. Puedes modificarlo y adaptarlo según tus necesidades.
|
|
|
|
## 📧 Soporte
|
|
|
|
Para problemas o preguntas, revisa la documentación oficial de Tryton en https://www.tryton.org/
|