@openfn/language-odoo 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ast.json +201 -0
- package/dist/index.cjs +58 -0
- package/dist/index.js +56 -0
- package/package.json +2 -2
- package/types/Adaptor.d.ts +81 -0
package/ast.json
CHANGED
|
@@ -278,6 +278,207 @@
|
|
|
278
278
|
]
|
|
279
279
|
},
|
|
280
280
|
"valid": true
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"name": "searchRecord",
|
|
284
|
+
"params": [
|
|
285
|
+
"model",
|
|
286
|
+
"domain"
|
|
287
|
+
],
|
|
288
|
+
"docs": {
|
|
289
|
+
"description": "Search a record from Odoo. Only returns record IDs. Use `searchReadRecord` to download full\nrecords which match the criteria.",
|
|
290
|
+
"tags": [
|
|
291
|
+
{
|
|
292
|
+
"title": "public",
|
|
293
|
+
"description": null,
|
|
294
|
+
"type": null
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"title": "example",
|
|
298
|
+
"description": "searchRecord('res.partner', {\n country_id: 'United States',\n});"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"title": "function",
|
|
302
|
+
"description": null,
|
|
303
|
+
"name": null
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"title": "param",
|
|
307
|
+
"description": "The specific record model i.e. \"res.partner\"",
|
|
308
|
+
"type": {
|
|
309
|
+
"type": "NameExpression",
|
|
310
|
+
"name": "string"
|
|
311
|
+
},
|
|
312
|
+
"name": "model"
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"title": "param",
|
|
316
|
+
"description": "Optional search domain to filter records.",
|
|
317
|
+
"type": {
|
|
318
|
+
"type": "NameExpression",
|
|
319
|
+
"name": "object"
|
|
320
|
+
},
|
|
321
|
+
"name": "domain"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"title": "state",
|
|
325
|
+
"description": "{OdooState}"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"title": "state",
|
|
329
|
+
"description": "data - An array of matching record IDs"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"title": "returns",
|
|
333
|
+
"description": null,
|
|
334
|
+
"type": {
|
|
335
|
+
"type": "NameExpression",
|
|
336
|
+
"name": "Operation"
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
},
|
|
341
|
+
"valid": true
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"name": "searchReadRecord",
|
|
345
|
+
"params": [
|
|
346
|
+
"model",
|
|
347
|
+
"domain",
|
|
348
|
+
"fields",
|
|
349
|
+
"options"
|
|
350
|
+
],
|
|
351
|
+
"docs": {
|
|
352
|
+
"description": "Search and a read record from Odoo. It returns the records that match the search criteria, with the specified fields or full records if no fields are given.",
|
|
353
|
+
"tags": [
|
|
354
|
+
{
|
|
355
|
+
"title": "public",
|
|
356
|
+
"description": null,
|
|
357
|
+
"type": null
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"title": "example",
|
|
361
|
+
"description": "searchReadRecord('res.partner', {\n country_id: 'United States',\n});",
|
|
362
|
+
"caption": "Search and read a record with a domain filter"
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"title": "example",
|
|
366
|
+
"description": "searchReadRecord(\n 'res.partner',\n {\n is_company: true,\n },\n ['name']\n);",
|
|
367
|
+
"caption": "Search and read a record with specific fields"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"title": "example",
|
|
371
|
+
"description": "searchReadRecord('res.partner', {}, [], {\n limit: 200,\n});",
|
|
372
|
+
"caption": "Fetch records with a limit"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"title": "function",
|
|
376
|
+
"description": null,
|
|
377
|
+
"name": null
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"title": "param",
|
|
381
|
+
"description": "The specific record model i.e. \"res.partner\"",
|
|
382
|
+
"type": {
|
|
383
|
+
"type": "NameExpression",
|
|
384
|
+
"name": "string"
|
|
385
|
+
},
|
|
386
|
+
"name": "model"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"title": "param",
|
|
390
|
+
"description": "Optional search domain to filter records.",
|
|
391
|
+
"type": {
|
|
392
|
+
"type": "NameExpression",
|
|
393
|
+
"name": "object"
|
|
394
|
+
},
|
|
395
|
+
"name": "domain"
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"title": "param",
|
|
399
|
+
"description": "An optional array of field strings to read from the record. i.e ['name', 'state_id']",
|
|
400
|
+
"type": {
|
|
401
|
+
"type": "TypeApplication",
|
|
402
|
+
"expression": {
|
|
403
|
+
"type": "NameExpression",
|
|
404
|
+
"name": "Array"
|
|
405
|
+
},
|
|
406
|
+
"applications": [
|
|
407
|
+
{
|
|
408
|
+
"type": "NameExpression",
|
|
409
|
+
"name": "string"
|
|
410
|
+
}
|
|
411
|
+
]
|
|
412
|
+
},
|
|
413
|
+
"name": "fields"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"title": "param",
|
|
417
|
+
"description": "Additional options to configure the search.",
|
|
418
|
+
"type": {
|
|
419
|
+
"type": "OptionalType",
|
|
420
|
+
"expression": {
|
|
421
|
+
"type": "NameExpression",
|
|
422
|
+
"name": "object"
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
"name": "options",
|
|
426
|
+
"default": "{}"
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"title": "param",
|
|
430
|
+
"description": "Maximum number of records to fetch. If undefined, defaults to 1000, and all records available will be fetched.",
|
|
431
|
+
"type": {
|
|
432
|
+
"type": "OptionalType",
|
|
433
|
+
"expression": {
|
|
434
|
+
"type": "NameExpression",
|
|
435
|
+
"name": "number"
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
"name": "options.limit",
|
|
439
|
+
"default": "1000"
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"title": "param",
|
|
443
|
+
"description": "The index of the first record to return.",
|
|
444
|
+
"type": {
|
|
445
|
+
"type": "OptionalType",
|
|
446
|
+
"expression": {
|
|
447
|
+
"type": "NameExpression",
|
|
448
|
+
"name": "number"
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
"name": "options.offset",
|
|
452
|
+
"default": "0"
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
"title": "param",
|
|
456
|
+
"description": "The number of records to fetch in each request. Defaults to 200.",
|
|
457
|
+
"type": {
|
|
458
|
+
"type": "OptionalType",
|
|
459
|
+
"expression": {
|
|
460
|
+
"type": "NameExpression",
|
|
461
|
+
"name": "number"
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
"name": "options.pageSize",
|
|
465
|
+
"default": "200"
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
"title": "state",
|
|
469
|
+
"description": "{OdooState}"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"title": "returns",
|
|
473
|
+
"description": null,
|
|
474
|
+
"type": {
|
|
475
|
+
"type": "NameExpression",
|
|
476
|
+
"name": "Operation"
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
]
|
|
480
|
+
},
|
|
481
|
+
"valid": false
|
|
281
482
|
}
|
|
282
483
|
],
|
|
283
484
|
"exports": [],
|
package/dist/index.cjs
CHANGED
|
@@ -39,6 +39,8 @@ __export(src_exports, {
|
|
|
39
39
|
lastReferenceValue: () => import_language_common2.lastReferenceValue,
|
|
40
40
|
merge: () => import_language_common2.merge,
|
|
41
41
|
read: () => read,
|
|
42
|
+
searchReadRecord: () => searchReadRecord,
|
|
43
|
+
searchRecord: () => searchRecord,
|
|
42
44
|
setMockClient: () => setMockClient,
|
|
43
45
|
sourceValue: () => import_language_common2.sourceValue,
|
|
44
46
|
update: () => update
|
|
@@ -61,6 +63,8 @@ __export(Adaptor_exports, {
|
|
|
61
63
|
lastReferenceValue: () => import_language_common2.lastReferenceValue,
|
|
62
64
|
merge: () => import_language_common2.merge,
|
|
63
65
|
read: () => read,
|
|
66
|
+
searchReadRecord: () => searchReadRecord,
|
|
67
|
+
searchRecord: () => searchRecord,
|
|
64
68
|
setMockClient: () => setMockClient,
|
|
65
69
|
sourceValue: () => import_language_common2.sourceValue,
|
|
66
70
|
update: () => update
|
|
@@ -175,6 +179,58 @@ function deleteRecord(model, recordId) {
|
|
|
175
179
|
return (0, import_language_common.composeNextState)(state, response);
|
|
176
180
|
};
|
|
177
181
|
}
|
|
182
|
+
function searchRecord(model, domain = {}) {
|
|
183
|
+
return async (state) => {
|
|
184
|
+
const [resolvedModel, resolvedDomain] = (0, import_util.expandReferences)(
|
|
185
|
+
state,
|
|
186
|
+
model,
|
|
187
|
+
domain
|
|
188
|
+
);
|
|
189
|
+
console.log(`Searching ${resolvedModel} resource...`);
|
|
190
|
+
const response = await odooConn.search(resolvedModel, resolvedDomain);
|
|
191
|
+
return (0, import_language_common.composeNextState)(state, response);
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function searchReadRecord(model, domain = {}, fields2 = [], options = {}) {
|
|
195
|
+
return async (state) => {
|
|
196
|
+
const results = [];
|
|
197
|
+
const [resolvedModel, resolvedDomain, resolvedFields, resolvedOptions] = (0, import_util.expandReferences)(state, model, domain, fields2, options);
|
|
198
|
+
const { limit = 1e3, offset = 0, pageSize = 200 } = resolvedOptions;
|
|
199
|
+
let totalFetched = 0;
|
|
200
|
+
let nextOffset = offset;
|
|
201
|
+
if (limit <= 0 || pageSize <= 0) {
|
|
202
|
+
return (0, import_language_common.composeNextState)(state, {
|
|
203
|
+
rows: results,
|
|
204
|
+
nextOffset: null,
|
|
205
|
+
totalFetched
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
while (totalFetched < limit) {
|
|
209
|
+
const remainingItems = limit - totalFetched;
|
|
210
|
+
const fetchSize = Math.min(pageSize, remainingItems);
|
|
211
|
+
console.log(
|
|
212
|
+
`Searching and reading ${resolvedModel} resources. From offset ${nextOffset} with limit ${fetchSize}...`
|
|
213
|
+
);
|
|
214
|
+
const rows = await odooConn.searchRead(
|
|
215
|
+
resolvedModel,
|
|
216
|
+
resolvedDomain,
|
|
217
|
+
resolvedFields,
|
|
218
|
+
{
|
|
219
|
+
offset: nextOffset,
|
|
220
|
+
limit: fetchSize
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
results.push(...rows);
|
|
224
|
+
totalFetched += rows.length;
|
|
225
|
+
nextOffset += rows.length;
|
|
226
|
+
if (rows.length === 0 || rows.length < fetchSize || totalFetched >= limit) {
|
|
227
|
+
nextOffset = null;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return (0, import_language_common.composeNextState)(state, { rows: results, nextOffset, totalFetched });
|
|
232
|
+
};
|
|
233
|
+
}
|
|
178
234
|
|
|
179
235
|
// src/index.js
|
|
180
236
|
var src_default = Adaptor_exports;
|
|
@@ -193,6 +249,8 @@ var src_default = Adaptor_exports;
|
|
|
193
249
|
lastReferenceValue,
|
|
194
250
|
merge,
|
|
195
251
|
read,
|
|
252
|
+
searchReadRecord,
|
|
253
|
+
searchRecord,
|
|
196
254
|
setMockClient,
|
|
197
255
|
sourceValue,
|
|
198
256
|
update
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,8 @@ __export(Adaptor_exports, {
|
|
|
20
20
|
lastReferenceValue: () => lastReferenceValue,
|
|
21
21
|
merge: () => merge,
|
|
22
22
|
read: () => read,
|
|
23
|
+
searchReadRecord: () => searchReadRecord,
|
|
24
|
+
searchRecord: () => searchRecord,
|
|
23
25
|
setMockClient: () => setMockClient,
|
|
24
26
|
sourceValue: () => sourceValue,
|
|
25
27
|
update: () => update
|
|
@@ -148,6 +150,58 @@ function deleteRecord(model, recordId) {
|
|
|
148
150
|
return composeNextState(state, response);
|
|
149
151
|
};
|
|
150
152
|
}
|
|
153
|
+
function searchRecord(model, domain = {}) {
|
|
154
|
+
return async (state) => {
|
|
155
|
+
const [resolvedModel, resolvedDomain] = expandReferences(
|
|
156
|
+
state,
|
|
157
|
+
model,
|
|
158
|
+
domain
|
|
159
|
+
);
|
|
160
|
+
console.log(`Searching ${resolvedModel} resource...`);
|
|
161
|
+
const response = await odooConn.search(resolvedModel, resolvedDomain);
|
|
162
|
+
return composeNextState(state, response);
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function searchReadRecord(model, domain = {}, fields2 = [], options = {}) {
|
|
166
|
+
return async (state) => {
|
|
167
|
+
const results = [];
|
|
168
|
+
const [resolvedModel, resolvedDomain, resolvedFields, resolvedOptions] = expandReferences(state, model, domain, fields2, options);
|
|
169
|
+
const { limit = 1e3, offset = 0, pageSize = 200 } = resolvedOptions;
|
|
170
|
+
let totalFetched = 0;
|
|
171
|
+
let nextOffset = offset;
|
|
172
|
+
if (limit <= 0 || pageSize <= 0) {
|
|
173
|
+
return composeNextState(state, {
|
|
174
|
+
rows: results,
|
|
175
|
+
nextOffset: null,
|
|
176
|
+
totalFetched
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
while (totalFetched < limit) {
|
|
180
|
+
const remainingItems = limit - totalFetched;
|
|
181
|
+
const fetchSize = Math.min(pageSize, remainingItems);
|
|
182
|
+
console.log(
|
|
183
|
+
`Searching and reading ${resolvedModel} resources. From offset ${nextOffset} with limit ${fetchSize}...`
|
|
184
|
+
);
|
|
185
|
+
const rows = await odooConn.searchRead(
|
|
186
|
+
resolvedModel,
|
|
187
|
+
resolvedDomain,
|
|
188
|
+
resolvedFields,
|
|
189
|
+
{
|
|
190
|
+
offset: nextOffset,
|
|
191
|
+
limit: fetchSize
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
results.push(...rows);
|
|
195
|
+
totalFetched += rows.length;
|
|
196
|
+
nextOffset += rows.length;
|
|
197
|
+
if (rows.length === 0 || rows.length < fetchSize || totalFetched >= limit) {
|
|
198
|
+
nextOffset = null;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return composeNextState(state, { rows: results, nextOffset, totalFetched });
|
|
203
|
+
};
|
|
204
|
+
}
|
|
151
205
|
|
|
152
206
|
// src/index.js
|
|
153
207
|
var src_default = Adaptor_exports;
|
|
@@ -166,6 +220,8 @@ export {
|
|
|
166
220
|
lastReferenceValue,
|
|
167
221
|
merge,
|
|
168
222
|
read,
|
|
223
|
+
searchReadRecord,
|
|
224
|
+
searchRecord,
|
|
169
225
|
setMockClient,
|
|
170
226
|
sourceValue,
|
|
171
227
|
update
|
package/package.json
CHANGED
package/types/Adaptor.d.ts
CHANGED
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
* @property {number} externalId - An optional id to be used in the request
|
|
13
13
|
* @property {boolean} downloadNewRecord - An option defaulted to `false` incase a user intends to receive the whole created resource in the response. The collective response will be written in `state.data`.
|
|
14
14
|
*/
|
|
15
|
+
/**
|
|
16
|
+
* Options object
|
|
17
|
+
* @typedef {Object} SearchOptions
|
|
18
|
+
* @property {number} limit - Limit the number of records to return
|
|
19
|
+
* @property {number} offset - Set to the number of records to skip
|
|
20
|
+
* @property {string} order - Order to sort the records by. i.e "name, desc"
|
|
21
|
+
* @property {object} context - Context to be used in the request. i.e `{lang: 'en_US', timezone: 'UTC'}`.
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
15
24
|
/**
|
|
16
25
|
* Execute a sequence of operations.
|
|
17
26
|
* Wraps `language-common/execute` to make working with this API easier.
|
|
@@ -83,6 +92,57 @@ export function update(model: string, recordId: number, data: object): Operation
|
|
|
83
92
|
* @returns {Operation}
|
|
84
93
|
*/
|
|
85
94
|
export function deleteRecord(model: string, recordId: number): Operation;
|
|
95
|
+
/**
|
|
96
|
+
* Search a record from Odoo. Only returns record IDs. Use `searchReadRecord` to download full
|
|
97
|
+
* records which match the criteria.
|
|
98
|
+
* @public
|
|
99
|
+
* @example
|
|
100
|
+
* searchRecord('res.partner', {
|
|
101
|
+
* country_id: 'United States',
|
|
102
|
+
* });
|
|
103
|
+
* @function
|
|
104
|
+
* @param {string} model - The specific record model i.e. "res.partner"
|
|
105
|
+
* @param {object} domain - Optional search domain to filter records.
|
|
106
|
+
* @state {OdooState}
|
|
107
|
+
* @state data - An array of matching record IDs
|
|
108
|
+
* @returns {Operation}
|
|
109
|
+
*/
|
|
110
|
+
export function searchRecord(model: string, domain?: object): Operation;
|
|
111
|
+
/**
|
|
112
|
+
* Search and a read record from Odoo. It returns the records that match the search criteria, with the specified fields or full records if no fields are given.
|
|
113
|
+
* @public
|
|
114
|
+
* @example <caption>Search and read a record with a domain filter</caption>
|
|
115
|
+
* searchReadRecord('res.partner', {
|
|
116
|
+
* country_id: 'United States',
|
|
117
|
+
* });
|
|
118
|
+
* @example <caption>Search and read a record with specific fields</caption>
|
|
119
|
+
* searchReadRecord(
|
|
120
|
+
* 'res.partner',
|
|
121
|
+
* {
|
|
122
|
+
* is_company: true,
|
|
123
|
+
* },
|
|
124
|
+
* ['name']
|
|
125
|
+
* );
|
|
126
|
+
* @example <caption> Fetch records with a limit</caption>
|
|
127
|
+
* searchReadRecord('res.partner', {}, [], {
|
|
128
|
+
* limit: 200,
|
|
129
|
+
* });
|
|
130
|
+
* @function
|
|
131
|
+
* @param {string} model - The specific record model i.e. "res.partner"
|
|
132
|
+
* @param {object} domain - Optional search domain to filter records.
|
|
133
|
+
* @param {string[]} fields - An optional array of field strings to read from the record. i.e ['name', 'state_id']
|
|
134
|
+
* @param {object} [options = {}] - Additional options to configure the search.
|
|
135
|
+
* @param {number} [options.limit=1000] - Maximum number of records to fetch. If undefined, defaults to 1000, and all records available will be fetched.
|
|
136
|
+
* @param {number} [options.offset=0] - The index of the first record to return.
|
|
137
|
+
* @param {number} [options.pageSize=200] - The number of records to fetch in each request. Defaults to 200.
|
|
138
|
+
* @state {OdooState}
|
|
139
|
+
* @returns {Operation}
|
|
140
|
+
*/
|
|
141
|
+
export function searchReadRecord(model: string, domain?: object, fields?: string[], options?: {
|
|
142
|
+
limit?: number;
|
|
143
|
+
offset?: number;
|
|
144
|
+
pageSize?: number;
|
|
145
|
+
}): Operation;
|
|
86
146
|
/**
|
|
87
147
|
* State object
|
|
88
148
|
*/
|
|
@@ -113,4 +173,25 @@ export type CreateOptions = {
|
|
|
113
173
|
*/
|
|
114
174
|
downloadNewRecord: boolean;
|
|
115
175
|
};
|
|
176
|
+
/**
|
|
177
|
+
* Options object
|
|
178
|
+
*/
|
|
179
|
+
export type SearchOptions = {
|
|
180
|
+
/**
|
|
181
|
+
* - Limit the number of records to return
|
|
182
|
+
*/
|
|
183
|
+
limit: number;
|
|
184
|
+
/**
|
|
185
|
+
* - Set to the number of records to skip
|
|
186
|
+
*/
|
|
187
|
+
offset: number;
|
|
188
|
+
/**
|
|
189
|
+
* - Order to sort the records by. i.e "name, desc"
|
|
190
|
+
*/
|
|
191
|
+
order: string;
|
|
192
|
+
/**
|
|
193
|
+
* - Context to be used in the request. i.e `{lang: 'en_US', timezone: 'UTC'}`.
|
|
194
|
+
*/
|
|
195
|
+
context: object;
|
|
196
|
+
};
|
|
116
197
|
export { dataPath, dataValue, dateFns, each, field, fields, fn, lastReferenceValue, merge, sourceValue } from "@openfn/language-common";
|