Skip to content

Commit 1e6a42b

Browse files
committed
initial commit
0 parents  commit 1e6a42b

10 files changed

Lines changed: 7127 additions & 0 deletions

File tree

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.env
2+
.env.*
3+
!.env.example
4+
node_modules/
5+
dist/
6+
coverage/
7+
.jest/
8+
.cache/
9+
*.tsbuildinfo
10+
11+
# Logs
12+
npm-debug.log*
13+
yarn-debug.log*
14+
yarn-error.log*
15+
pnpm-debug.log*
16+
17+
# Editors/OS
18+
.DS_Store
19+
.idea/
20+
.vscode/
21+
22+
# Swap/temp files
23+
*.swp
24+
*.swo

README.md

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
# @terrakernel/odxproxy-client
2+
3+
Official JavaScript/TypeScript client for ODXProxy. This SDK provides a simple, typed interface to execute Odoo JSON-RPC operations via the ODXProxy Gateway.
4+
5+
- Repository package name: `@odxproxy/client`
6+
- License: MIT
7+
- Runtime: Node.js 18+
8+
- Language: TypeScript (bundled to ESM and CJS)
9+
10+
## Table of Contents
11+
- What is ODXProxy?
12+
- Features
13+
- Installation
14+
- Quick Start
15+
- Configuration
16+
- API Reference
17+
- init
18+
- search
19+
- search_read
20+
- read
21+
- fields_get
22+
- search_count
23+
- create
24+
- update
25+
- remove
26+
- call_method
27+
- Error Handling
28+
- Examples
29+
- Testing
30+
- Build
31+
- Versioning
32+
- License
33+
34+
## What is ODXProxy?
35+
ODXProxy is a gateway that securely exposes Odoo RPC functionality over HTTPS with API key protection. Using this client, you can perform common CRUD operations and call arbitrary model methods without dealing with low-level JSON-RPC details.
36+
37+
## Features
38+
- Friendly, typed wrapper around ODXProxy endpoints
39+
- Supports both ESM and CommonJS
40+
- Works with TypeScript out of the box (bundled type definitions)
41+
- Covers common Odoo actions: search, search_read, read, fields_get, search_count, create, write (update), unlink (remove), and call_method
42+
- Request IDs are auto-generated with ULID (can be overridden)
43+
44+
## Installation
45+
46+
```
47+
npm install @odxproxy/client
48+
# or
49+
yarn add @odxproxy/client
50+
# or
51+
pnpm add @odxproxy/client
52+
```
53+
54+
## Quick Start
55+
56+
```ts
57+
import { init, search_read } from "@odxproxy/client";
58+
59+
// Initialize once at app startup
60+
init({
61+
instance: {
62+
url: process.env.ODOO_URL || "",
63+
db: process.env.ODOO_DB || "",
64+
user_id: Number(process.env.ODOO_UID || 2),
65+
api_key: process.env.ODOO_API_KEY || "",
66+
},
67+
odx_api_key: process.env.ODX_API_KEY || "",
68+
// gateway_url: "https://gateway.odxproxy.io" // optional, default shown
69+
});
70+
71+
// Use any of the exported helpers thereafter
72+
const res = await search_read<{ id: number; name?: string }>(
73+
"res.partner",
74+
[[ ["is_company", "=", false] ]],
75+
{ context: { tz: "UTC" }, limit: 10, fields: ["name"] }
76+
);
77+
78+
console.log(res.jsonrpc, res.result);
79+
```
80+
81+
## Configuration
82+
Call `init` once with the following structure:
83+
84+
```ts
85+
// Type shape for init options
86+
init({
87+
instance: {
88+
url: "https://your-odoo.example.com", // Base URL to your Odoo instance
89+
db: "your-db", // Odoo database name
90+
user_id: 2, // Odoo user ID
91+
api_key: "odoo-user-api-key", // Odoo API key for that user
92+
},
93+
odx_api_key: "your-odxproxy-gateway-api-key", // ODXProxy Gateway API key
94+
gateway_url: "https://gateway.odxproxy.io", // Optional. Default shown (trailing slash trimmed)
95+
});
96+
```
97+
98+
Context (passed inside `keyword`) supports:
99+
100+
```json
101+
{
102+
"context": {
103+
"tz": "UTC",
104+
"default_company_id": 1,
105+
"allowed_company_ids": [1]
106+
},
107+
"fields": ["name", "email"],
108+
"sort": "name asc",
109+
"limit": 10,
110+
"offset": 0
111+
}
112+
```
113+
114+
Note: For actions that do not use fields/sort/limit/offset, the client will strip those keys before sending.
115+
116+
## API Reference
117+
All functions return a promise resolving to:
118+
119+
```
120+
{
121+
jsonrpc: string; // typically "2.0"
122+
id: string; // request id (ULID by default)
123+
result?: any; // present on success
124+
error?: { // present on error
125+
code: number;
126+
message: string;
127+
data: any;
128+
};
129+
}
130+
```
131+
132+
- init(options)
133+
- Initializes the singleton client. Must be called before any other function.
134+
135+
- search<T = number>(model, params, keyword, id?)
136+
- params: domain array (e.g., [[ ["is_company", "=", false] ]])
137+
- returns: result?: T[] (commonly record IDs unless fields requested via search_read)
138+
139+
- search_read<T = any>(model, params, keyword, id?)
140+
- params: domain array
141+
- keyword: can include fields, limit, offset, sort, and context
142+
- returns: result?: T[] (records)
143+
144+
- read<T = any>(model, params, keyword, id?)
145+
- params: array of record IDs wrapped (e.g., [[1,2,3]])
146+
- returns: result?: T
147+
148+
- fields_get<T = any>(model, keyword, id?)
149+
- returns: result?: T[] (field metadata)
150+
151+
- search_count<T = number>(model, params, keyword, id?)
152+
- returns: result?: T (count)
153+
154+
- create<T = any>(model, params, keyword, id?)
155+
- params: array with a single object of field values (e.g., [{ name: "Acme" }])
156+
- returns: result?: T (typically new record ID)
157+
158+
- update<T = any>(model, params, keyword, id?)
159+
- params: [[ids], { field: value }]
160+
- returns: result?: T
161+
162+
- remove<T = any>(model, params, keyword, id?)
163+
- params: [[ids]]
164+
- returns: result?: T
165+
166+
- call_method<T = any>(model, params, keyword, function_name, id?)
167+
- params: method parameters array
168+
- returns: result?: T
169+
170+
## Error Handling
171+
The client normalizes errors from Axios into a consistent structure. Timeouts (default 45s) surface as:
172+
173+
```
174+
{ code: 408, message: "Request Timeout: exceeded client limit of 45000ms", data: null }
175+
```
176+
177+
For other HTTP errors, you will receive:
178+
179+
```
180+
{ code: number, message: string, data: any }
181+
```
182+
183+
Wrap calls in try/catch if you prefer exceptions, or check for `error` on the returned object if you treat it as a value.
184+
185+
## Examples
186+
- Search partners (IDs only):
187+
188+
```ts
189+
const res = await search<number>("res.partner", [[ ["is_company", "=", false] ]], { context: { tz: "UTC" } });
190+
console.log(res.result); // [1,2,3,...]
191+
```
192+
193+
- Search and read names and emails:
194+
195+
```ts
196+
const res = await search_read<{ id: number; name?: string; email?: string }>(
197+
"res.partner",
198+
[[ ["is_company", "=", false] ]],
199+
{ context: { tz: "UTC" }, limit: 10, fields: ["name", "email"] }
200+
);
201+
console.log(res.result);
202+
```
203+
204+
- Create, update, remove:
205+
206+
```ts
207+
const created = await create<number>("res.partner", [{ name: "Acme" }], { context: { tz: "UTC" } });
208+
const id = created.result!;
209+
await update("res.partner", [[id], { name: "ACME Updated" }], { context: { tz: "UTC" } });
210+
await remove("res.partner", [[id]], { context: { tz: "UTC" } });
211+
```
212+
213+
- Call arbitrary method:
214+
215+
```ts
216+
await call_method("account.move", [[5]], { context: { tz: "UTC" } }, "action_post");
217+
```
218+
219+
## Testing
220+
This repo uses Jest. You can run tests locally (requires valid environment variables to hit a real ODXProxy/Odoo instance):
221+
222+
```
223+
npm test
224+
```
225+
226+
Environment variables used in tests:
227+
- url, db, uid, api_key, odx_api_key
228+
229+
You can define them in a local .env and load with dotenv in your test runner setup if desired.
230+
231+
## Build
232+
Build the package (generates ESM, CJS, and type definitions):
233+
234+
```
235+
npm run build
236+
```
237+
238+
Outputs are placed under `dist/` and are referenced via `exports` in package.json.
239+
240+
## Versioning
241+
This package follows semantic versioning when published to npm. Current version is defined in package.json.
242+
243+
## License
244+
MIT © 2025 TerraKernel. PTE. LTD / ODXProxy Team

0 commit comments

Comments
 (0)