roboto-js 1.0.21 → 1.1.2
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/dist/cjs/index.cjs +162 -48
- package/dist/cjs/rbt_api.cjs +521 -132
- package/dist/cjs/rbt_object.cjs +59 -19
- package/dist/cjs/rbt_user.cjs +172 -0
- package/dist/esm/index.js +162 -48
- package/dist/esm/rbt_api.js +521 -132
- package/dist/esm/rbt_object.js +59 -19
- package/dist/esm/rbt_user.js +172 -0
- package/package.json +1 -1
- package/src/index.js +40 -2
- package/src/rbt_api.js +280 -19
- package/src/rbt_object.js +53 -15
- package/src/rbt_user.js +135 -0
package/src/rbt_api.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import CryptoJS from 'crypto-js';
|
|
3
3
|
import RbtObject from './rbt_object.js';
|
|
4
|
+
import RbtUser from './rbt_user.js';
|
|
4
5
|
import RbtFile from './rbt_file.js';
|
|
5
6
|
import _ from 'lodash';
|
|
6
7
|
import { openDB } from 'idb';
|
|
@@ -22,6 +23,7 @@ export default class RbtApi {
|
|
|
22
23
|
this.localDb = null;
|
|
23
24
|
this.iac_session = null;
|
|
24
25
|
this.authtoken = authTokenToUse;
|
|
26
|
+
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
async initLocalDb(){
|
|
@@ -36,6 +38,14 @@ export default class RbtApi {
|
|
|
36
38
|
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Logs in a user and stores the authToken.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} params - The login parameters.
|
|
45
|
+
* @param {string} params.email - The email of the user.
|
|
46
|
+
* @param {string} params.password - The password of the user.
|
|
47
|
+
* @returns {Promise<Object>} - The response data from the API.
|
|
48
|
+
*/
|
|
39
49
|
async login(params) {
|
|
40
50
|
try {
|
|
41
51
|
|
|
@@ -66,6 +76,81 @@ export default class RbtApi {
|
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
78
|
|
|
79
|
+
async logout() {
|
|
80
|
+
try {
|
|
81
|
+
// Call logout endpoint if necessary. Here, I assume there's a '/user_service/logoutUser' endpoint.
|
|
82
|
+
// This is optional and depends on how your backend is set up.
|
|
83
|
+
const response = await this.axios.post('/user_service/logoutUser');
|
|
84
|
+
|
|
85
|
+
if (response.data.ok === false) {
|
|
86
|
+
return this._handleError(response);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Clear the iac_session and remove the auth token from axios headers
|
|
90
|
+
this.iac_session = null;
|
|
91
|
+
if (this.axios.defaults.headers.common['authtoken']) {
|
|
92
|
+
delete this.axios.defaults.headers.common['authtoken'];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Clear localStorage if it's being used
|
|
96
|
+
if (typeof localStorage !== 'undefined') {
|
|
97
|
+
localStorage.removeItem('authtoken');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Return some kind of success response or the response from the server
|
|
101
|
+
return response.data;
|
|
102
|
+
} catch (e) {
|
|
103
|
+
this._handleError(e);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async loadCurrentUser(){
|
|
108
|
+
|
|
109
|
+
// TODO - get the actual user from the session
|
|
110
|
+
let params = { id: 'superuser_tom' };
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
|
|
114
|
+
const response = await this.axios.post('/user_service/loadUser', [params]);
|
|
115
|
+
let userData = response?.data?.user;
|
|
116
|
+
|
|
117
|
+
let User = new RbtUser({ id: userData.id }, this.axios);
|
|
118
|
+
User.setData(userData);
|
|
119
|
+
return User;
|
|
120
|
+
|
|
121
|
+
//const record = response.data;
|
|
122
|
+
//
|
|
123
|
+
//if(dataHash){
|
|
124
|
+
// record.data = dataHash;
|
|
125
|
+
//}
|
|
126
|
+
//return new RbtObject(record, this.axios);
|
|
127
|
+
} catch (e) {
|
|
128
|
+
return this._handleError(e);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async refreshAuthToken(authtoken){
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
|
|
137
|
+
const response = await this.axios.post('/user_service/refreshAuthToken', [authtoken]);
|
|
138
|
+
return response.data;
|
|
139
|
+
|
|
140
|
+
} catch (e) {
|
|
141
|
+
|
|
142
|
+
this._handleError(e);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Registers a new user.
|
|
149
|
+
*
|
|
150
|
+
* @param {Object} dataHash - The data for the new user.
|
|
151
|
+
* @returns {Promise<RbtObject>} - The newly created user as an RbtObject.
|
|
152
|
+
*
|
|
153
|
+
*/
|
|
69
154
|
async registerUser(dataHash={}) {
|
|
70
155
|
try {
|
|
71
156
|
const response = await this.axios.post('/user_service/registerUser', [dataHash]);
|
|
@@ -76,10 +161,18 @@ export default class RbtApi {
|
|
|
76
161
|
}
|
|
77
162
|
return new RbtObject(record, this.axios);
|
|
78
163
|
} catch (e) {
|
|
164
|
+
debugger;
|
|
79
165
|
return this._handleError(e);
|
|
80
166
|
}
|
|
81
167
|
}
|
|
82
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Creates a new file in the system.
|
|
171
|
+
*
|
|
172
|
+
* @param {Object} dataHash - The data for the new file.
|
|
173
|
+
* @returns {Promise<RbtFile>} - The newly created file as an RbtFile.
|
|
174
|
+
*
|
|
175
|
+
*/
|
|
83
176
|
async createFile(dataHash){
|
|
84
177
|
|
|
85
178
|
//return this.create('<@filekit.file>', dataHash);
|
|
@@ -98,6 +191,13 @@ export default class RbtApi {
|
|
|
98
191
|
}
|
|
99
192
|
|
|
100
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Creates a new object of the given type.
|
|
196
|
+
*
|
|
197
|
+
* @param {string} type - The type of object to create.
|
|
198
|
+
* @param {Object} dataHash - The data for the new object.
|
|
199
|
+
* @returns {Promise<RbtObject>} - The newly created object as an RbtObject.
|
|
200
|
+
*/
|
|
101
201
|
async create(type, dataHash={}) {
|
|
102
202
|
try {
|
|
103
203
|
const response = await this.axios.post('/object_service/createObject', [type, dataHash]);
|
|
@@ -106,19 +206,50 @@ export default class RbtApi {
|
|
|
106
206
|
if(dataHash){
|
|
107
207
|
record.data = dataHash;
|
|
108
208
|
}
|
|
109
|
-
return new RbtObject(record, this.axios);
|
|
209
|
+
return new RbtObject(record, this.axios, { isNew: true });
|
|
110
210
|
} catch (e) {
|
|
111
211
|
return this._handleError(e);
|
|
112
212
|
}
|
|
113
213
|
}
|
|
114
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Queries objects of a given type based on specified parameters.
|
|
217
|
+
*
|
|
218
|
+
* @param {string} type - The type of object to query, specified as a doctree.typedef.
|
|
219
|
+
* @param {Object} params - The query parameters, including optional filters and configurations.
|
|
220
|
+
* @returns {Promise<Array<RbtObject>>} - An array of queried objects as RbtObjects.
|
|
221
|
+
*
|
|
222
|
+
* The `params` object can include the following properties:
|
|
223
|
+
* - where: A SQL-like where clause string for filtering the results.
|
|
224
|
+
* - orderBy: An object specifying the ordering of the results. It should include:
|
|
225
|
+
* - column: The attribute name to sort by. This must be either a column in the @doctree.model schema or an indexed type attribute.
|
|
226
|
+
* - direction: The sort direction, either 'ASC' for ascending or 'DESC' for descending.
|
|
227
|
+
* - limit: An object to control the pagination of results. It includes:
|
|
228
|
+
* - offset: The starting point from where to fetch the results.
|
|
229
|
+
* - results: The maximum number of results to return.
|
|
230
|
+
* - resolveReferences: An array of attribute names whose references should be resolved in the returned objects.
|
|
231
|
+
* - timeout: A numerical value in milliseconds to set a maximum time limit for the query execution.
|
|
232
|
+
*
|
|
233
|
+
* Example usage:
|
|
234
|
+
* query("<@testuser>", {
|
|
235
|
+
* where: 'email="tom@pospa.com"',
|
|
236
|
+
* orderBy: { column: 'timeCreated', direction: 'DESC' },
|
|
237
|
+
* limit: { offset: 0, results: 50 },
|
|
238
|
+
* resolveReferences: ['translatableContent']
|
|
239
|
+
* });
|
|
240
|
+
*
|
|
241
|
+
* Note: A default orderBy is applied if none is provided, ordering items by 'timeCreated' in descending order.
|
|
242
|
+
*/
|
|
115
243
|
async query(type, params = {}) {
|
|
116
244
|
try {
|
|
117
245
|
params.type = type;
|
|
118
246
|
|
|
119
|
-
//
|
|
247
|
+
// Default ordering and pagination
|
|
120
248
|
const defaultOrderBy = { orderBy: { column: 'timeCreated', direction: 'DESC' } };
|
|
121
|
-
const
|
|
249
|
+
const defaultLimit = { limit: { offset: 0, results: 50 } };
|
|
250
|
+
|
|
251
|
+
// Merge defaults with provided params
|
|
252
|
+
const mergedParams = { ...defaultOrderBy, ...defaultLimit, ...params };
|
|
122
253
|
|
|
123
254
|
const response = await this.axios.post('/object_service/queryObjects', [mergedParams]);
|
|
124
255
|
if (response.data.ok === false) {
|
|
@@ -127,7 +258,7 @@ export default class RbtApi {
|
|
|
127
258
|
|
|
128
259
|
// Process items into RbtObject instances
|
|
129
260
|
if (Array.isArray(response.data.items)) {
|
|
130
|
-
response.data.items = response.data.items.map(record => new RbtObject(record, this.axios));
|
|
261
|
+
response.data.items = response.data.items.map(record => new RbtObject(record, this.axios, { isNew: true }));
|
|
131
262
|
}
|
|
132
263
|
return response.data.items;
|
|
133
264
|
} catch (e) {
|
|
@@ -135,15 +266,26 @@ export default class RbtApi {
|
|
|
135
266
|
}
|
|
136
267
|
}
|
|
137
268
|
|
|
138
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Loads one or multiple objects of a given type by their IDs.
|
|
271
|
+
*
|
|
272
|
+
* @param {string} type - The type of object to load.
|
|
273
|
+
* @param {Array<string>|string} ids - The ID(s) of the object(s) to load.
|
|
274
|
+
*
|
|
275
|
+
* @returns {Promise<RbtObject|RbtObject[]>} - The loaded object(s) as RbtObject(s).
|
|
276
|
+
*/
|
|
277
|
+
async load(type, ids, params={}){
|
|
139
278
|
|
|
140
279
|
try{
|
|
141
|
-
|
|
280
|
+
let mergedParams;
|
|
281
|
+
|
|
142
282
|
if(Array.isArray(ids)){
|
|
143
|
-
|
|
283
|
+
mergedParams = { ...params, where: "id IN (" + ids.join(',') + ")" };
|
|
284
|
+
return this.query(type, mergedParams);
|
|
144
285
|
}
|
|
145
286
|
else{
|
|
146
|
-
|
|
287
|
+
mergedParams = { ...params, where: "id="+ids };
|
|
288
|
+
let res = await this.query(type, mergedParams);
|
|
147
289
|
return res[0];
|
|
148
290
|
}
|
|
149
291
|
|
|
@@ -153,6 +295,112 @@ export default class RbtApi {
|
|
|
153
295
|
|
|
154
296
|
}
|
|
155
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Makes a POST request to a specific endpoint to run a task and handle progress updates.
|
|
300
|
+
*
|
|
301
|
+
* @param {Object} params - The parameters to be sent in the POST request.
|
|
302
|
+
* @param {Object} callbacks - An object containing callback functions for progress and error handling.
|
|
303
|
+
*
|
|
304
|
+
* The function expects a response in the following format:
|
|
305
|
+
* {
|
|
306
|
+
* ok: boolean, // Indicates if the request was successful or not
|
|
307
|
+
* jobId: string, // The job identifier
|
|
308
|
+
* status: string // Can be 'RUNNING', 'DONE', or 'ERROR'
|
|
309
|
+
* }
|
|
310
|
+
*/
|
|
311
|
+
async runTask(params = {}, callbacks = {}) {
|
|
312
|
+
const { onProgress, onError, onFinish } = callbacks;
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
const response = await this.post('http://localhost:3004/runChain', params);
|
|
316
|
+
// Check if response and response.data are defined
|
|
317
|
+
if (!response) {
|
|
318
|
+
throw new Error('Invalid server response');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Validate response structure
|
|
322
|
+
const { ok, jobId, status, message, output } = response;
|
|
323
|
+
if (!ok || typeof jobId !== 'string' || typeof status !== 'string') {
|
|
324
|
+
throw new Error('Invalid response structure');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// If the task is still in progress, start polling for updates
|
|
328
|
+
if (status === 'RUNNING' || status === 'SCHEDULED' || status === 'QUEUED') {
|
|
329
|
+
this.pollTaskProgress(jobId, callbacks);
|
|
330
|
+
}
|
|
331
|
+
if (status === 'ERROR' && onError){
|
|
332
|
+
// Provide the current progress to the callback function
|
|
333
|
+
onError(response);
|
|
334
|
+
}
|
|
335
|
+
if (status === 'DONE' && onFinish){
|
|
336
|
+
// Provide the current progress to the callback function
|
|
337
|
+
console.log('Finish (request) ',response);
|
|
338
|
+
onFinish(response);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return { ok, jobId, status, message, output };
|
|
342
|
+
|
|
343
|
+
} catch (e) {
|
|
344
|
+
|
|
345
|
+
if (typeof onError === 'function') {
|
|
346
|
+
onError(e);
|
|
347
|
+
} else {
|
|
348
|
+
console.error('Error in runTask:', e);
|
|
349
|
+
}
|
|
350
|
+
return { ok: false, jobId: null, status: 'ERROR', error: e.message };
|
|
351
|
+
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Polls the progress of a long-running task.
|
|
358
|
+
*
|
|
359
|
+
* @param {string} jobId - The ID of the job to poll for progress.
|
|
360
|
+
* @param {function} onProgress - Callback function that receives progress updates.
|
|
361
|
+
*
|
|
362
|
+
* The function periodically sends GET requests to check the task's progress
|
|
363
|
+
* and reports back via the provided callback function. The polling stops when
|
|
364
|
+
* the task is completed or an error occurs.
|
|
365
|
+
*/
|
|
366
|
+
async pollTaskProgress(jobId, callbacks) {
|
|
367
|
+
const { onProgress, onError, onFinish } = callbacks;
|
|
368
|
+
try {
|
|
369
|
+
const checkProgress = async () => {
|
|
370
|
+
const response = await this.get(`http://localhost:3004/pollChainProgress`, { jobId: jobId });
|
|
371
|
+
|
|
372
|
+
// If the task is still in progress, start polling for updates
|
|
373
|
+
if (response.status === 'DONE' && onFinish){
|
|
374
|
+
// Provide the current progress to the callback function
|
|
375
|
+
console.log('Finish (progress) ',response);
|
|
376
|
+
onFinish(response);
|
|
377
|
+
}
|
|
378
|
+
if (response.status === 'ERROR' && onError){
|
|
379
|
+
// Provide the current progress to the callback function
|
|
380
|
+
onError(response);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Provide the current progress to the callback function
|
|
384
|
+
if(response.status == 'RUNNING'){
|
|
385
|
+
onProgress(response);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Continue polling if the status is 'RUNNING'
|
|
389
|
+
if (['RUNNING'].includes(response.status)) {
|
|
390
|
+
setTimeout(checkProgress, 1000); // Poll every 2 seconds
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
checkProgress();
|
|
395
|
+
} catch (e) {
|
|
396
|
+
// Handle error based on your application's logic
|
|
397
|
+
return this._handleError(e);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
156
404
|
/**
|
|
157
405
|
* Performs a GET request to the specified endpoint.
|
|
158
406
|
*
|
|
@@ -224,18 +472,31 @@ export default class RbtApi {
|
|
|
224
472
|
}
|
|
225
473
|
|
|
226
474
|
|
|
227
|
-
|
|
475
|
+
setErrorHandler(customErrorHandler) {
|
|
476
|
+
this.customErrorHandler = customErrorHandler;
|
|
477
|
+
}
|
|
228
478
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
// all other errors
|
|
237
|
-
throw new Error(err);
|
|
479
|
+
_handleError(err) {
|
|
480
|
+
|
|
481
|
+
debugger;
|
|
482
|
+
// Invoke the custom error handler if provided
|
|
483
|
+
if (this.customErrorHandler) {
|
|
484
|
+
let res = this.customErrorHandler(err);
|
|
485
|
+
if(res) return;
|
|
238
486
|
}
|
|
239
487
|
|
|
488
|
+
if (_.isObject(err) && _.get(err, 'response')) {
|
|
489
|
+
const msg = _.get(err, 'response.data.message', 'Error in API response');
|
|
490
|
+
|
|
491
|
+
if(msg.key){
|
|
492
|
+
throw new Error(msg.key);
|
|
493
|
+
}
|
|
494
|
+
else{
|
|
495
|
+
throw new Error(msg);
|
|
496
|
+
}
|
|
497
|
+
} else {
|
|
498
|
+
throw new Error(err.message || 'Unknown error');
|
|
499
|
+
}
|
|
240
500
|
}
|
|
241
|
-
|
|
501
|
+
|
|
502
|
+
}
|
package/src/rbt_object.js
CHANGED
|
@@ -2,50 +2,67 @@ import _ from 'lodash';
|
|
|
2
2
|
|
|
3
3
|
export default class RbtObject {
|
|
4
4
|
|
|
5
|
-
constructor(record, axiosInstance) {
|
|
5
|
+
constructor(record, axiosInstance, options = {}) {
|
|
6
6
|
this._axios = axiosInstance;
|
|
7
7
|
this._internalData = record;
|
|
8
8
|
this.id = record.id;
|
|
9
9
|
this.id_revision = record.id_revision;
|
|
10
|
+
this.rpcMeta = {
|
|
11
|
+
changes: [],
|
|
12
|
+
isNew: options.isNew || false
|
|
13
|
+
};
|
|
14
|
+
|
|
10
15
|
if(record.data){
|
|
11
|
-
this._data = record.data;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
this._data = record.dataJson ? JSON.parse(record.dataJson) : {};
|
|
16
|
+
this._data = this._deepUnpackJson(record.data);
|
|
17
|
+
} else {
|
|
18
|
+
this._data = record.dataJson ? this._deepUnpackJson(record.dataJson) : {};
|
|
15
19
|
}
|
|
20
|
+
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
get(path) {
|
|
19
24
|
return _.get(this._data, path);
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
set(path, value) {
|
|
23
|
-
_.set(this._data, path, value);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
27
|
getData() {
|
|
27
28
|
return {
|
|
28
29
|
...this._data
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
_addChange(path) {
|
|
34
|
+
// Ensure no duplicate paths
|
|
35
|
+
if (!this.rpcMeta.changes.includes(path)) {
|
|
36
|
+
this.rpcMeta.changes.push(path);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
set(path, value) {
|
|
41
|
+
const currentValue = _.get(this._data, path);
|
|
42
|
+
if (!_.isEqual(currentValue, value)) {
|
|
43
|
+
_.set(this._data, path, value);
|
|
44
|
+
this._addChange(path);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
32
48
|
setData(newData) {
|
|
33
|
-
// Ensure the input is an object
|
|
34
49
|
if (typeof newData !== 'object' || newData === null) {
|
|
35
50
|
throw new Error('setData expects an object');
|
|
36
51
|
}
|
|
37
52
|
|
|
38
|
-
// Iterate over each key in the newData object
|
|
39
53
|
Object.keys(newData).forEach(key => {
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
if (!_.isEqual(_.get(this._data, key), newData[key])) {
|
|
55
|
+
_.set(this._data, key, newData[key]);
|
|
56
|
+
this._addChange(key);
|
|
57
|
+
}
|
|
42
58
|
});
|
|
43
59
|
}
|
|
44
60
|
|
|
45
61
|
toRecord() {
|
|
46
62
|
return {
|
|
47
63
|
...this._internalData,
|
|
48
|
-
dataJson: JSON.stringify(this._data)
|
|
64
|
+
dataJson: JSON.stringify(this._data),
|
|
65
|
+
rpcMeta: this.rpcMeta
|
|
49
66
|
};
|
|
50
67
|
}
|
|
51
68
|
|
|
@@ -58,7 +75,7 @@ export default class RbtObject {
|
|
|
58
75
|
delete clonedData.id_revision;
|
|
59
76
|
|
|
60
77
|
// Create a new instance of RbtObject with the cloned data
|
|
61
|
-
const clonedObject = new RbtObject(clonedData, this._axios);
|
|
78
|
+
const clonedObject = new RbtObject(clonedData, this._axios, { isNew: true });
|
|
62
79
|
|
|
63
80
|
return clonedObject;
|
|
64
81
|
}
|
|
@@ -82,11 +99,14 @@ export default class RbtObject {
|
|
|
82
99
|
this.id_revision = response.data.id_revision;
|
|
83
100
|
this.type = response.data.type;
|
|
84
101
|
|
|
102
|
+
this.rpcMeta.isNew = false;
|
|
103
|
+
|
|
85
104
|
return this;
|
|
86
105
|
|
|
87
106
|
} catch (e) {
|
|
88
107
|
console.log('RbtObject.save.error:');
|
|
89
108
|
console.log(e.response.data);
|
|
109
|
+
throw e;
|
|
90
110
|
}
|
|
91
111
|
}
|
|
92
112
|
|
|
@@ -109,7 +129,25 @@ export default class RbtObject {
|
|
|
109
129
|
} catch (e) {
|
|
110
130
|
console.log('RbtObject.delete.error:');
|
|
111
131
|
console.log(e.response.data);
|
|
132
|
+
throw e;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
_deepUnpackJson(value){
|
|
137
|
+
if (typeof value === 'string') {
|
|
138
|
+
try {
|
|
139
|
+
const parsed = JSON.parse(value);
|
|
140
|
+
return this._deepUnpackJson(parsed); // Recursively parse if the result is a string, object, or array
|
|
141
|
+
} catch (e) {
|
|
142
|
+
return value; // Return the original string if parsing fails
|
|
143
|
+
}
|
|
144
|
+
} else if (value !== null && typeof value === 'object') {
|
|
145
|
+
// If it's an object (including arrays), recursively parse each value
|
|
146
|
+
for (const key in value) {
|
|
147
|
+
value[key] = this._deepUnpackJson(value[key]);
|
|
148
|
+
}
|
|
112
149
|
}
|
|
150
|
+
return value;
|
|
113
151
|
}
|
|
114
152
|
|
|
115
153
|
}
|
package/src/rbt_user.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
|
|
3
|
+
export default class RbtUser {
|
|
4
|
+
|
|
5
|
+
constructor(record, axiosInstance, options = {}) {
|
|
6
|
+
this._axios = axiosInstance;
|
|
7
|
+
this._internalData = record;
|
|
8
|
+
this.id = record.id;
|
|
9
|
+
this.id_revision = record.id_revision;
|
|
10
|
+
this.rpcMeta = {
|
|
11
|
+
changes: [],
|
|
12
|
+
isNew: options.isNew || false
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
if(record.data){
|
|
16
|
+
this._data = record.data;
|
|
17
|
+
} else {
|
|
18
|
+
this._data = record.dataJson ? JSON.parse(record.dataJson) : {};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get(path) {
|
|
24
|
+
return _.get(this._data, path);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getData() {
|
|
28
|
+
return {
|
|
29
|
+
...this._data
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_addChange(path) {
|
|
34
|
+
// Ensure no duplicate paths
|
|
35
|
+
if (!this.rpcMeta.changes.includes(path)) {
|
|
36
|
+
this.rpcMeta.changes.push(path);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
set(path, value) {
|
|
41
|
+
const currentValue = _.get(this._data, path);
|
|
42
|
+
if (!_.isEqual(currentValue, value)) {
|
|
43
|
+
_.set(this._data, path, value);
|
|
44
|
+
this._addChange(path);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setData(newData) {
|
|
49
|
+
if (typeof newData !== 'object' || newData === null) {
|
|
50
|
+
throw new Error('setData expects an object');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Object.keys(newData).forEach(key => {
|
|
54
|
+
if (!_.isEqual(_.get(this._data, key), newData[key])) {
|
|
55
|
+
_.set(this._data, key, newData[key]);
|
|
56
|
+
this._addChange(key);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
toRecord() {
|
|
62
|
+
return {
|
|
63
|
+
...this._internalData,
|
|
64
|
+
dataJson: JSON.stringify(this._data),
|
|
65
|
+
rpcMeta: this.rpcMeta
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
clone() {
|
|
70
|
+
// Create a deep copy of the current object's data
|
|
71
|
+
const clonedData = _.cloneDeep(this._internalData);
|
|
72
|
+
|
|
73
|
+
// Reset unique identifiers to ensure a new ID is generated upon saving
|
|
74
|
+
delete clonedData.id;
|
|
75
|
+
delete clonedData.id_revision;
|
|
76
|
+
|
|
77
|
+
// Create a new instance of RbtUser with the cloned data
|
|
78
|
+
const clonedObject = new RbtUser(clonedData, this._axios, { isNew: true });
|
|
79
|
+
|
|
80
|
+
return clonedObject;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async save() {
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
debugger;
|
|
87
|
+
const record = this.toRecord();
|
|
88
|
+
record.type = '<@iac.user>';
|
|
89
|
+
const response = await this._axios.post('/user_service/saveUser', [record]);
|
|
90
|
+
|
|
91
|
+
if (response.data.ok === false) {
|
|
92
|
+
throw new Error(response.data.message);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this._internalData = response.data;
|
|
96
|
+
|
|
97
|
+
this.id = response.data.id;
|
|
98
|
+
this.id_revision = response.data.id_revision;
|
|
99
|
+
this.type = response.data.type;
|
|
100
|
+
|
|
101
|
+
this.rpcMeta.isNew = false;
|
|
102
|
+
|
|
103
|
+
return this;
|
|
104
|
+
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.log('RbtUser.save.error:');
|
|
107
|
+
console.log(e.response.data);
|
|
108
|
+
throw e;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//async delete() {
|
|
113
|
+
// if (!this._internalData.type) {
|
|
114
|
+
// throw new Error('Cannot delete object without type');
|
|
115
|
+
// }
|
|
116
|
+
//
|
|
117
|
+
// try {
|
|
118
|
+
// const record = this.toRecord();
|
|
119
|
+
// const response = await this._axios.post('/object_service/deleteObject', [record]);
|
|
120
|
+
//
|
|
121
|
+
// if (response.data.ok === false) {
|
|
122
|
+
// throw new Error(response.data.message);
|
|
123
|
+
// }
|
|
124
|
+
//
|
|
125
|
+
// this._internalData = response.data;
|
|
126
|
+
// return this;
|
|
127
|
+
//
|
|
128
|
+
// } catch (e) {
|
|
129
|
+
// console.log('RbtUser.delete.error:');
|
|
130
|
+
// console.log(e.response.data);
|
|
131
|
+
// throw e;
|
|
132
|
+
// }
|
|
133
|
+
//}
|
|
134
|
+
|
|
135
|
+
}
|