300 lines
7.1 KiB
Markdown
300 lines
7.1 KiB
Markdown
# Tryton RPC Client for JavaScript
|
|
|
|
JavaScript implementation of a Tryton ERP RPC client, based on the Python `sabatron-tryton-rpc-client` package. This client allows you to connect to Tryton servers via JSON-RPC and perform operations programmatically.
|
|
|
|
## Features
|
|
|
|
- ✅ **Full RPC Support** - Complete implementation of Tryton's JSON-RPC protocol
|
|
- ✅ **Connection Pooling** - Efficient connection reuse with configurable pool size
|
|
- ✅ **Smart Caching** - LRU cache with expiration support for improved performance
|
|
- ✅ **Session Management** - Automatic session handling and authentication
|
|
- ✅ **Type Safety** - Proper serialization/deserialization of Tryton data types
|
|
- ✅ **Error Handling** - Comprehensive error handling with retry logic
|
|
- ✅ **SSL/TLS Support** - Secure connections with certificate validation
|
|
- ✅ **Helper Methods** - Convenient methods for common operations (CRUD)
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install tryton-rpc-client-js
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```javascript
|
|
const { TrytonClient } = require("tryton-rpc-client-js");
|
|
|
|
async function main() {
|
|
// Create client instance
|
|
const client = new TrytonClient({
|
|
hostname: "localhost",
|
|
database: "tryton",
|
|
username: "admin",
|
|
password: "admin",
|
|
port: 8000,
|
|
language: "en",
|
|
});
|
|
|
|
try {
|
|
// Connect to server
|
|
await client.connect();
|
|
console.log("Connected successfully!");
|
|
|
|
// Read a party record
|
|
const parties = await client.read(
|
|
"party.party",
|
|
[1],
|
|
["id", "name", "code"]
|
|
);
|
|
console.log("Party:", parties[0]);
|
|
|
|
// Create a new party
|
|
const newParties = await client.create("party.party", [
|
|
{ name: "From JavaScript" },
|
|
]);
|
|
console.log("Created party ID:", newParties[0]);
|
|
} catch (error) {
|
|
console.error("Error:", error.message);
|
|
} finally {
|
|
client.close();
|
|
}
|
|
}
|
|
|
|
main();
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Constructor
|
|
|
|
```javascript
|
|
const client = new TrytonClient({
|
|
hostname: "localhost", // Server hostname
|
|
database: "tryton", // Database name
|
|
username: "admin", // Username
|
|
password: "admin", // Password
|
|
port: 8000, // Server port (default: 8000)
|
|
language: "en", // Language code (default: 'en')
|
|
options: {
|
|
// Additional options
|
|
verbose: false, // Enable verbose logging
|
|
cache: true, // Enable caching (default: true)
|
|
keepMax: 4, // Max pooled connections (default: 4)
|
|
connectTimeout: 5000, // Connection timeout in ms
|
|
timeout: 30000, // Request timeout in ms
|
|
},
|
|
});
|
|
```
|
|
|
|
### Methods
|
|
|
|
#### Connection Management
|
|
|
|
```javascript
|
|
// Connect to server
|
|
await client.connect();
|
|
|
|
// Check connection status
|
|
console.log(client.isConnected); // true/false
|
|
|
|
// Get connection info
|
|
console.log(client.getConfig());
|
|
|
|
// Close connection
|
|
client.close();
|
|
```
|
|
|
|
#### RPC Calls
|
|
|
|
```javascript
|
|
// Generic RPC call
|
|
const result = await client.call("method.name", [arg1, arg2, arg3]);
|
|
|
|
// Multiple calls in sequence
|
|
const results = await client.callMultiple([
|
|
{ method: "model.party.party.read", args: [[1], ["name"]] },
|
|
{ method: "model.company.company.read", args: [[1], ["name"]] },
|
|
]);
|
|
|
|
// Multiple calls in parallel
|
|
const results = await client.callParallel([
|
|
{ method: "model.party.party.read", args: [[1], ["name"]] },
|
|
{ method: "model.company.company.read", args: [[1], ["name"]] },
|
|
]);
|
|
```
|
|
|
|
#### CRUD Operations
|
|
|
|
```javascript
|
|
// Create records
|
|
const ids = await client.create("party.party", [
|
|
{ name: "John Doe", code: "JOHN001" },
|
|
{ name: "Jane Smith", code: "JANE001" },
|
|
]);
|
|
|
|
// Read records
|
|
const records = await client.read(
|
|
"party.party",
|
|
[1, 2],
|
|
["id", "name", "code"]
|
|
);
|
|
|
|
// Update records
|
|
await client.write("party.party", [1], { name: "Updated Name" });
|
|
|
|
// Delete records
|
|
await client.delete("party.party", [1]);
|
|
```
|
|
|
|
#### Search Operations
|
|
|
|
```javascript
|
|
// Search for record IDs
|
|
const ids = await client.search("party.party", [["name", "like", "John%"]]);
|
|
|
|
// Search and read in one call
|
|
const records = await client.searchRead(
|
|
"party.party",
|
|
[["active", "=", true]],
|
|
["id", "name", "code"],
|
|
0, // offset
|
|
10, // limit
|
|
["name"] // order
|
|
);
|
|
|
|
// Count records
|
|
const count = await client.searchCount("party.party", [["active", "=", true]]);
|
|
```
|
|
|
|
#### Server Information
|
|
|
|
```javascript
|
|
// Get server version
|
|
const version = await client.getVersion();
|
|
|
|
// List databases
|
|
const databases = await client.listDatabases();
|
|
|
|
// Get database info
|
|
const dbInfo = await client.getDatabaseInfo();
|
|
```
|
|
|
|
#### Cache Management
|
|
|
|
```javascript
|
|
// Clear all cache
|
|
client.clearCache();
|
|
|
|
// Clear cache for specific prefix
|
|
client.clearCache("model.party.party");
|
|
```
|
|
|
|
## Advanced Usage
|
|
|
|
### Custom Options
|
|
|
|
```javascript
|
|
const client = new TrytonClient({
|
|
hostname: "localhost",
|
|
database: "tryton",
|
|
username: "admin",
|
|
password: "admin",
|
|
options: {
|
|
verbose: true, // Enable request/response logging
|
|
cache: true, // Enable response caching
|
|
keepMax: 8, // Keep up to 8 pooled connections
|
|
connectTimeout: 10000, // 10 second connection timeout
|
|
timeout: 60000, // 60 second request timeout
|
|
},
|
|
});
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
```javascript
|
|
const { TrytonClient, Fault, ProtocolError } = require("tryton-rpc-client-js");
|
|
|
|
try {
|
|
await client.call("invalid.method", []);
|
|
} catch (error) {
|
|
if (error instanceof Fault) {
|
|
console.log("RPC Fault:", error.faultCode, error.faultString);
|
|
} else if (error instanceof ProtocolError) {
|
|
console.log("Protocol Error:", error.errcode, error.errmsg);
|
|
} else {
|
|
console.log("Other Error:", error.message);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Connection Cloning
|
|
|
|
```javascript
|
|
// Clone client with same configuration
|
|
const client2 = client.clone();
|
|
await client2.connect();
|
|
|
|
// Both clients can work independently
|
|
const result1 = await client.read("party.party", [1], ["name"]);
|
|
const result2 = await client2.read("company.company", [1], ["name"]);
|
|
```
|
|
|
|
## Data Types
|
|
|
|
The client automatically handles Tryton's special data types:
|
|
|
|
- **Date/DateTime** - JavaScript `Date` objects
|
|
- **Decimal** - JavaScript `number` (with precision handling)
|
|
- **Bytes** - Node.js `Buffer` objects
|
|
- **TimeDelta** - Number of seconds
|
|
|
|
## Error Types
|
|
|
|
- **`Fault`** - RPC errors from server
|
|
- **`ProtocolError`** - HTTP/connection errors
|
|
- **`ResponseError`** - Invalid response format
|
|
|
|
## Requirements
|
|
|
|
- Node.js >= 12.0.0
|
|
- No external dependencies (uses only Node.js built-in modules)
|
|
|
|
## Compatibility
|
|
|
|
This client is compatible with:
|
|
|
|
- Tryton 6.x
|
|
- Tryton 7.x
|
|
- Any Tryton server supporting JSON-RPC
|
|
|
|
## License
|
|
|
|
GNU General Public License v3.0 (GPL-3.0)
|
|
|
|
## Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Make your changes
|
|
4. Add tests if applicable
|
|
5. Submit a pull request
|
|
|
|
## Support
|
|
|
|
For issues and questions:
|
|
|
|
- Open an issue on GitHub
|
|
- Check the Tryton documentation
|
|
- Review the examples in the `examples/` directory
|
|
|
|
## Changelog
|
|
|
|
### v1.0.0
|
|
|
|
- Initial release
|
|
- Full RPC implementation
|
|
- Connection pooling
|
|
- Smart caching
|
|
- Helper methods for CRUD operations
|
|
- Comprehensive error handling
|