@azrico/webobject 1.5.58 → 1.5.61

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.
Files changed (33) hide show
  1. package/README.md +9 -9
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +1 -0
  4. package/dist/src/WebObjects/ParentWebObject.d.ts +24 -0
  5. package/dist/src/WebObjects/ParentWebObject.js +77 -0
  6. package/dist/src/WebObjects/WebObject.d.ts +153 -0
  7. package/dist/src/WebObjects/WebObject.js +654 -0
  8. package/dist/src/WebObjects/WebObjectHelper.d.ts +9 -0
  9. package/dist/src/WebObjects/WebObjectHelper.js +18 -0
  10. package/dist/src/WebObjects/WebObjectHelper.test.d.ts +1 -0
  11. package/dist/src/WebObjects/WebObjectHelper.test.js +45 -0
  12. package/dist/src/WebObjects/WebObjectManager.d.ts +68 -0
  13. package/dist/src/WebObjects/WebObjectManager.js +290 -0
  14. package/dist/src/WebObjects/WebObjectPathHelper.d.ts +36 -0
  15. package/dist/src/WebObjects/WebObjectPathHelper.js +84 -0
  16. package/dist/src/WebObjects/WebObjectPathHelper.test.d.ts +1 -0
  17. package/dist/src/WebObjects/WebObjectPathHelper.test.js +31 -0
  18. package/dist/src/index.d.ts +10 -0
  19. package/dist/src/index.js +10 -0
  20. package/dist/src/structs/DummyObject.d.ts +5 -0
  21. package/dist/src/structs/DummyObject.js +8 -0
  22. package/dist/src/structs/MapableObject.d.ts +43 -0
  23. package/dist/src/structs/MapableObject.js +77 -0
  24. package/dist/src/structs/MetaObject.d.ts +15 -0
  25. package/dist/src/structs/MetaObject.js +35 -0
  26. package/dist/src/structs/ObjectArray.d.ts +10 -0
  27. package/dist/src/structs/ObjectArray.js +43 -0
  28. package/dist/src/structs/ObjectManager.d.ts +136 -0
  29. package/dist/src/structs/ObjectManager.js +332 -0
  30. package/dist/src/structs/ObjectWithTemp.d.ts +16 -0
  31. package/dist/src/structs/ObjectWithTemp.js +35 -0
  32. package/dist/src/structs/SimpleObject.js +1138 -0
  33. package/package.json +1 -1
@@ -0,0 +1,654 @@
1
+ import { SimpleObject } from "../index";
2
+ import { array_chunks, array_first, array_intersection, array_merge, array_remove_duplicates, fn_eval_this, object_clean, object_equals, object_getStatic, object_isEmpty, wrap_array, } from "@azrico/object";
3
+ import { string_compress, string_decompress } from "@azrico/string";
4
+ import { gcache, gfunc } from "@azrico/global";
5
+ import FormatHelper from "@azrico/convert";
6
+ import WebObjectPathHelper from "./WebObjectPathHelper";
7
+ import WebObjectHelper from "./WebObjectHelper";
8
+ export class WebObject extends SimpleObject {
9
+ static __web_path = "";
10
+ static __protectedProperties = ["_users"];
11
+ //you cant create a new weboject without these properties
12
+ static __requiredProperties = [];
13
+ meta_data;
14
+ //created date
15
+ _created_date;
16
+ //the owner of the object
17
+ _creator;
18
+ //multiple users can work on one object
19
+ _users;
20
+ constructor(is_readonly = false) {
21
+ super(is_readonly);
22
+ this.meta_data = {};
23
+ }
24
+ /**
25
+ * get a list of all user ids that work on the given object
26
+ * _creator + _users + attentions(old)
27
+ * removes duplicates
28
+ * @returns array of ids
29
+ */
30
+ getAllUsers() {
31
+ return WebObject.getAllUsers(this);
32
+ }
33
+ /**
34
+ * get a unique list of all user ids that work on the given object
35
+ * `_creator + _users + attentions`
36
+ * @returns array of ids
37
+ */
38
+ static getAllUsers(obj) {
39
+ if (typeof obj != "object")
40
+ return [];
41
+ return array_remove_duplicates(array_merge(obj._creator, wrap_array(obj._users), wrap_array(obj.attentions))
42
+ .map((r) => String(typeof r === "object" ? WebObject.getID(r) : r))
43
+ .filter((s) => s));
44
+ }
45
+ /* -------------------------------------------------------------------------- */
46
+ /* Meta data */
47
+ /* -------------------------------------------------------------------------- */
48
+ /**
49
+ * Update meta value of this object , meta data is stored in meta_data variable
50
+ * @param key
51
+ * @param value
52
+ * @param sendChange
53
+ * @returns
54
+ */
55
+ async setMetaValue(key, value, sendChange = "auto") {
56
+ if (!this.canModify) {
57
+ if (this.__throw_errors !== false)
58
+ throw Error(`Cant use setMetaValue on ${key} when on readonly mode`);
59
+ else
60
+ return false;
61
+ }
62
+ if (!key || typeof key != "string") {
63
+ if (this.__throw_errors !== false)
64
+ throw Error(`Bad key at setMetaValue`);
65
+ else
66
+ return false;
67
+ }
68
+ const old_value = WebObject.getMetaValue(this, key);
69
+ if (object_equals(old_value, value))
70
+ return false; //same value, no changes
71
+ const new_metalist = { ...this.get("meta_data") };
72
+ new_metalist[key] = value;
73
+ await this.set("meta_data", new_metalist);
74
+ if (sendChange !== false)
75
+ await this.notifyChanged("meta", key, value);
76
+ return true;
77
+ }
78
+ /**
79
+ * Get meta value by key
80
+ * @param key
81
+ * @returns value or undefined
82
+ */
83
+ getMetaValue(key) {
84
+ return WebObject.getMetaValue(this, key);
85
+ }
86
+ /**
87
+ * Get meta value by key
88
+ * @param o
89
+ * @param key
90
+ * @returns value or undefined
91
+ */
92
+ static getMetaValue(o, key) {
93
+ if (o == null)
94
+ return null;
95
+ if (!key || typeof key != "string")
96
+ return undefined;
97
+ let metalist = {};
98
+ if (typeof o === "object") {
99
+ metalist =
100
+ typeof o.get === "function" ? o.get("meta_data") : o.meta_data;
101
+ }
102
+ return metalist[key];
103
+ }
104
+ /* -------------------------------------------------------------------------- */
105
+ /* Save */
106
+ /* -------------------------------------------------------------------------- */
107
+ static zipSaveList(svlist) {
108
+ if (typeof svlist === "object")
109
+ svlist = JSON.stringify(svlist);
110
+ return string_compress(svlist);
111
+ }
112
+ static unzipSaveList(svlist) {
113
+ try {
114
+ if (typeof svlist === "object") {
115
+ if (Array.isArray(svlist))
116
+ return svlist;
117
+ if (svlist.__save_list)
118
+ return this.unzipSaveList(svlist.__save_list);
119
+ }
120
+ else if (typeof svlist === "string")
121
+ return wrap_array(JSON.parse(string_decompress(svlist)));
122
+ }
123
+ catch { }
124
+ return wrap_array(svlist);
125
+ }
126
+ static async saveList(itemList, extraOptions = {}) {
127
+ if (!extraOptions)
128
+ extraOptions = {};
129
+ const chunks = array_chunks(itemList, extraOptions.chunksize ?? 50);
130
+ delete extraOptions.chunksize;
131
+ const putAddress = this.get_webpath();
132
+ for (let index = 0; index < chunks.length; index++) {
133
+ const items_to_save = chunks[index];
134
+ const save_array = [];
135
+ for (let k = 0; k < items_to_save.length; k++) {
136
+ const item = items_to_save[k];
137
+ const dlt = await item.get_deltaObject();
138
+ save_array.push(item.isNew
139
+ ? {
140
+ ...dlt,
141
+ }
142
+ : {
143
+ _id: item.getID(),
144
+ ...dlt,
145
+ });
146
+ }
147
+ const resultObject = await gfunc.run_action("post", putAddress, {
148
+ __save_list: WebObject.zipSaveList(save_array),
149
+ ...extraOptions,
150
+ });
151
+ if (Array.isArray(resultObject)) {
152
+ for (let index = 0; index < Math.min(resultObject.length, items_to_save.length); index++) {
153
+ const res = resultObject[index];
154
+ const item = items_to_save[index];
155
+ item.setSaveResult(res);
156
+ await item.onSave();
157
+ }
158
+ }
159
+ }
160
+ for (let index = 0; index < itemList.length; index++) {
161
+ const item = itemList[index];
162
+ if (!item.isSaved)
163
+ return false;
164
+ if (item.getSaveResultType() != "normal")
165
+ return false;
166
+ }
167
+ return true;
168
+ }
169
+ async Save() {
170
+ try {
171
+ if (this.manager) {
172
+ await this.manager.setOption("saving", true);
173
+ await this.manager.setOption("loading", true);
174
+ }
175
+ const deltaObject = await this.get_deltaObject();
176
+ const putAction = "post";
177
+ const usepath = await WebObjectPathHelper.get_path(this, this.isNew ? "new" : "save");
178
+ /* ---------------------------------- save ---------------------------------- */
179
+ if (!object_isEmpty(deltaObject)) {
180
+ const canSaveResult = this.canSave(deltaObject);
181
+ if (canSaveResult !== true) {
182
+ WebObject.addError(this, "Save not allowed", String(canSaveResult), true);
183
+ this.setSaveResult(false, "canceled");
184
+ return false;
185
+ }
186
+ const resultObject = await gfunc.run_action(putAction, usepath, deltaObject);
187
+ this.setSaveResult(resultObject, "auto", true);
188
+ }
189
+ else {
190
+ /* nothing to save */
191
+ this.setSaveResult(null, "nothing");
192
+ }
193
+ if (this.isSaved) {
194
+ await this.onSave();
195
+ return this.getSaveResult();
196
+ }
197
+ }
198
+ finally {
199
+ if (this.manager) {
200
+ await this.manager.setOption("saving", false);
201
+ await this.manager.setOption("loading", false);
202
+ }
203
+ }
204
+ }
205
+ async Delete() {
206
+ if (this.isNew)
207
+ return;
208
+ const usepath = await WebObjectPathHelper.get_path(this, "delete");
209
+ const resultObject = await gfunc.run_action("delete", usepath);
210
+ this.setSaveResult(resultObject, "auto", true);
211
+ await this.onDelete();
212
+ return resultObject;
213
+ }
214
+ async Lock() {
215
+ if (this.isNew || this.isArchived)
216
+ return;
217
+ const usepath = await WebObjectPathHelper.get_path(this, "lock");
218
+ const resultObject = await gfunc.run_action("post", usepath);
219
+ this.setSaveResult(resultObject, "auto", true);
220
+ await this.onLock();
221
+ return resultObject;
222
+ }
223
+ async UnLock() {
224
+ if (this.isNew || this.isArchived)
225
+ return;
226
+ const usepath = await WebObjectPathHelper.get_path(this, "unlock");
227
+ const resultObject = await gfunc.run_action("post", usepath);
228
+ this.setSaveResult(resultObject, "auto", true);
229
+ await this.onUnLock();
230
+ return resultObject;
231
+ }
232
+ async Archive() {
233
+ if (this.isNew || this.isArchived)
234
+ return;
235
+ const usepath = await WebObjectPathHelper.get_path(this, "archive");
236
+ const resultObject = await gfunc.run_action("post", usepath);
237
+ this.setSaveResult(resultObject, "auto", true);
238
+ await this.onArchive();
239
+ return resultObject;
240
+ }
241
+ async UnArchive() {
242
+ if (this.isNew || !this.isArchived)
243
+ return;
244
+ const usepath = await WebObjectPathHelper.get_path(this, "unarchive");
245
+ const resultObject = await gfunc.run_action("post", usepath);
246
+ await this.onUnArchive();
247
+ return resultObject;
248
+ }
249
+ /* -------------------------------------------------------------------------- */
250
+ canSave(deltaObj) {
251
+ const deltaRes = this.deltaIsValid(deltaObj);
252
+ if (deltaRes !== true)
253
+ return deltaRes;
254
+ return true;
255
+ }
256
+ canDelete() {
257
+ return true;
258
+ }
259
+ canArchive() {
260
+ return true;
261
+ }
262
+ deltaIsValid(d) {
263
+ return true;
264
+ }
265
+ /* -------------------------------------------------------------------------- */
266
+ /* get delta */
267
+ /* -------------------------------------------------------------------------- */
268
+ /**
269
+ * converts this object to an basic object
270
+ * that can be passed into client components from server components
271
+ *
272
+ * uses `get_fullDeltaObject`
273
+ * @param p
274
+ * @returns
275
+ */
276
+ async get_basicObject() {
277
+ const fullobject = await this.get_fullObject();
278
+ for (const key in fullobject) {
279
+ const element = fullobject[key];
280
+ /* --------------------------- check for id fields -------------------------- */
281
+ if (element != null && typeof element === "object") {
282
+ if ((key === "id" || key.endsWith("_id")) &&
283
+ typeof element.toString === "function") {
284
+ fullobject[key] = String(element);
285
+ }
286
+ else {
287
+ fullobject[key] = JSON.parse(JSON.stringify(element));
288
+ }
289
+ }
290
+ }
291
+ return fullobject;
292
+ }
293
+ /**
294
+ * calls the `get_deltaObject` with
295
+ * `allProperties` `extraProperties`
296
+ * set to true
297
+ *
298
+ * @returns
299
+ */
300
+ async get_fullDeltaObject(p) {
301
+ return await this.get_deltaObject({
302
+ allProperties: true,
303
+ extraProperties: true,
304
+ ...p,
305
+ });
306
+ }
307
+ /**
308
+ * calls the `get_deltaObject` with
309
+ * `allProperties` `extraProperties` `tempProperties`
310
+ * set to true
311
+ *
312
+ * @returns
313
+ */
314
+ async get_fullObject(p) {
315
+ return await this.get_deltaObject({
316
+ allProperties: true,
317
+ extraProperties: true,
318
+ tempProperties: true,
319
+ ...p,
320
+ });
321
+ }
322
+ /**
323
+ * You will post this to the server for saving
324
+ * automatically removes unchangeable fields
325
+ * @returns
326
+ */
327
+ async get_deltaObject(p) {
328
+ if (!p)
329
+ p = {};
330
+ const final_object = {};
331
+ const useDelta = Boolean(this.__use_delta || p.useDelta);
332
+ /**
333
+ * child objects usually dont update their __delta
334
+ * so we read info from all of its properties
335
+ */
336
+ const changedFields = Boolean(p.allProperties || p.isChild || !useDelta)
337
+ ? { ...this.allproperties }
338
+ : { ...this.__delta };
339
+ /* ------------- parse children that have WebObject as delta ------------- */
340
+ for (const key in this) {
341
+ if (key.startsWith("__") || key in changedFields)
342
+ continue;
343
+ if (WebObjectHelper.isChangedWebObjectField(this[key])) {
344
+ /**
345
+ * if a child has any change we must add it into our delta
346
+ * notice that the changes may not be saved to database depending on __changeables
347
+ * but they are changes nevertheless
348
+ */
349
+ changedFields[key] = this[key];
350
+ }
351
+ }
352
+ /**
353
+ * get keys that can be changed.
354
+ * intersection of keys in delta and keys that are defined as changeable
355
+ */
356
+ let changeableKeys = array_intersection(Object.keys(changedFields), WebObject.getChangeableKeys(this, p));
357
+ /**
358
+ * if parameter of changeableKeys is given, limit our keys with that param
359
+ */
360
+ if (p.changeableKeys) {
361
+ changeableKeys = array_intersection(changeableKeys, p.changeableKeys);
362
+ }
363
+ /* -------------------------------------------------------------------------- */
364
+ FormatHelper.format({
365
+ original: this,
366
+ inputobject: changedFields,
367
+ formats: object_getStatic(this, "__formatList"),
368
+ isNew: this.isNew,
369
+ changeableKeys: changeableKeys,
370
+ applyDefaults: true,
371
+ });
372
+ /* -------------------------------------------------------------------------- */
373
+ /* __functionProperties */
374
+ /* -------------------------------------------------------------------------- */
375
+ const functionProps = object_getStatic(this, "__functionProperties");
376
+ for (let index = 0; index < functionProps.length; index++) {
377
+ const fp = functionProps[index];
378
+ if (changedFields[fp])
379
+ changedFields[fp] = fn_eval_this(this, changedFields[fp]);
380
+ }
381
+ /* -------------------------------------------------------------------------- */
382
+ /* parse all changeableKeys */
383
+ /* -------------------------------------------------------------------------- */
384
+ async function parseObj(key, obj) {
385
+ if (obj == null)
386
+ return undefined;
387
+ if (Array.isArray(obj))
388
+ return await Promise.all(obj.map(async (r, i) => await parseObj(key, r)));
389
+ if (obj instanceof WebObject &&
390
+ typeof obj.get_deltaObject === "function") {
391
+ /* -------------------- parse changeableKeys for children -------------------- */
392
+ const keydot = `${key}.`;
393
+ let child_changeableKeys = p?.changeableKeys
394
+ ?.filter((s) => s.startsWith(keydot))
395
+ .map((r) => r.substring(keydot.length));
396
+ /**
397
+ * if no key is set for children consider it as undefined
398
+ * if we send the empty array to get_delta we get no keys
399
+ */
400
+ if (child_changeableKeys == null ||
401
+ child_changeableKeys?.length === 0) {
402
+ child_changeableKeys = undefined;
403
+ }
404
+ /* -------------------------------------------------------------------------- */
405
+ //child elements have different kind of delta
406
+ const newobj_dlt = await obj.get_deltaObject({
407
+ ...p,
408
+ isChild: true,
409
+ changeableKeys: child_changeableKeys,
410
+ });
411
+ if (!object_isEmpty(newobj_dlt))
412
+ return newobj_dlt;
413
+ else
414
+ return obj;
415
+ }
416
+ return obj;
417
+ }
418
+ for (const key of changeableKeys) {
419
+ final_object[key] = await parseObj(key, changedFields[key]);
420
+ }
421
+ /* -------------------- add acrhived and date properties -------------------- */
422
+ if (p.allProperties) {
423
+ final_object["_created_date"] = this["_created_date"];
424
+ final_object["_archived"] = this.isArchived;
425
+ final_object["_deleted"] = this.isDeleted;
426
+ }
427
+ if (p.tempProperties) {
428
+ final_object["__temp"] = this.__temp;
429
+ }
430
+ /* ---------------------------- add id properties --------------------------- */
431
+ if (p.allProperties || p.needId || p.isChild) {
432
+ if (this["_index_key"])
433
+ final_object["_index_key"] = this["_index_key"];
434
+ const gotIndex = this.getIndex();
435
+ const gotId = this.getID();
436
+ if (gotIndex && gotIndex >= 0)
437
+ final_object["_index_value"] = gotIndex;
438
+ if (gotId)
439
+ final_object["_id"] = gotId;
440
+ }
441
+ /* -------------------------------------------------------------------------- */
442
+ /* fix _user property */
443
+ /* -------------------------------------------------------------------------- */
444
+ if (final_object["_users"]) {
445
+ let tempusers = final_object["_users"];
446
+ if (typeof tempusers === "string")
447
+ tempusers = tempusers.split(",").filter((s) => s);
448
+ final_object["_users"] = wrap_array(tempusers);
449
+ }
450
+ if (p.clean)
451
+ return object_clean(final_object, false, true);
452
+ return final_object;
453
+ }
454
+ /* --------------------------------- Getters -------------------------------- */
455
+ get manager() {
456
+ return this.get_managerClass() || undefined;
457
+ }
458
+ get __web_path() {
459
+ return this.constructor["__web_path"] || this.__db_name;
460
+ }
461
+ get_webpath() {
462
+ return this.__web_path || this.__db_name || "";
463
+ }
464
+ static get_webpath() {
465
+ return this.__web_path || this.__db_name || "";
466
+ }
467
+ static get_dbname() {
468
+ return this.__db_name || this.__web_path || "";
469
+ }
470
+ /* -------------------------------------------------------------------------- */
471
+ async onDelete(...p) {
472
+ if (this.isSaved)
473
+ this.isDeleted = true;
474
+ return await this.manager?.onDelete(...p); //events are handled by the manager
475
+ }
476
+ async onArchive(...p) {
477
+ if (this.isSaved)
478
+ this.isArchived = true;
479
+ return await this.manager?.onArchive(...p); //events are handled by the manager
480
+ }
481
+ async onUnArchive(...p) {
482
+ if (this.isSaved)
483
+ this.isArchived = false;
484
+ return await this.manager?.onUnArchive(...p); //events are handled by the manager
485
+ }
486
+ async onLock(...p) {
487
+ if (this.isSaved)
488
+ this.isLocked = true;
489
+ return await this.manager?.onLock(...p); //events are handled by the manager
490
+ }
491
+ async onUnLock(...p) {
492
+ if (this.isSaved)
493
+ this.isLocked = false;
494
+ return await this.manager?.onUnLock(...p); //events are handled by the manager
495
+ }
496
+ async onLoad(...p) {
497
+ this.isDeleted = false;
498
+ return await this.manager?.onLoad(...p); //events are handled by the manager
499
+ }
500
+ async onSave(...p) {
501
+ if (this.isSaved) {
502
+ this.apply_changes();
503
+ var srObject = this.getSaveResult(true);
504
+ if (this.saveResultHasID(srObject)) {
505
+ /* -------------------------------------------------------------------------- */
506
+ WebObject.LoadIdsFromSaveResult(this, srObject);
507
+ await this.manager?.event_run("on_id_change");
508
+ }
509
+ }
510
+ await this.manager?.onSave(...p); //events are handled by the manager
511
+ await this.onAfterSave();
512
+ return true;
513
+ }
514
+ async onAfterSave(...p) {
515
+ await this.manager?.onAfterSave(...p); //events are handled by the manager
516
+ return true;
517
+ }
518
+ getSaveResult(original = false) {
519
+ let srObject = super.getSaveResult(original);
520
+ if (!srObject)
521
+ return false;
522
+ if (Array.isArray(srObject)) {
523
+ const actual_sr = srObject.find((s) => this.saveResultHasID(s));
524
+ if (actual_sr)
525
+ srObject = actual_sr;
526
+ }
527
+ return srObject;
528
+ }
529
+ async onNew(...p) {
530
+ return await this.manager?.onNew(...p); //events are handled by the manager
531
+ }
532
+ /* -------------------------------------------------------------------------- */
533
+ saveResultHasID(s) {
534
+ return WebObject.saveResultHasID(s);
535
+ }
536
+ static saveResultHasID(s) {
537
+ if (typeof s !== "object" || s == null || !s)
538
+ return false;
539
+ return (s.insertedId ||
540
+ s._id ||
541
+ (s._index_value && !Number.isNaN(s._index_value)));
542
+ }
543
+ /**
544
+ * Load Id and _index_value from the given save result into our object
545
+ * @param o
546
+ * @param srObject
547
+ * @returns
548
+ */
549
+ static LoadIdsFromSaveResult(o, srObject) {
550
+ if (typeof o !== "object" || typeof srObject !== "object")
551
+ return;
552
+ /* -------------------------------------------------------------------------- */
553
+ const srID = srObject.insertedId || srObject._id || WebObject.getID(srObject);
554
+ if (srID) {
555
+ o._id = srID;
556
+ }
557
+ /* -------------------------------------------------------------------------- */
558
+ if (srObject._index_value && !Number.isNaN(srObject._index_value)) {
559
+ o._index_value = Number(srObject._index_value);
560
+ }
561
+ /* -------------------------------------------------------------------------- */
562
+ if (srObject._index_key) {
563
+ o._index_key = srObject._index_key;
564
+ }
565
+ }
566
+ /* -------------------------------------------------------------------------- */
567
+ /**
568
+ * get a single web object
569
+ * default order of parameters : search,readonly,fetchID
570
+ */
571
+ static async get_single(...p) {
572
+ let search = p.shift();
573
+ let readonly = p.shift() ?? false;
574
+ let fetchID = p.shift();
575
+ if (object_isEmpty(search))
576
+ return undefined;
577
+ let result;
578
+ const params = {};
579
+ params.__context = readonly ? "view" : "edit";
580
+ switch (typeof search) {
581
+ case "string":
582
+ case "number":
583
+ search = String(search);
584
+ // const usepath =
585
+ // (await WebObjectPathHelper.get_path(this, "get")) +
586
+ // "/" +
587
+ // search;
588
+ // res = await gfunc.run_action("get", usepath, params, {
589
+ // fetchID: fetchID,
590
+ // });
591
+ result = await this.get_list({ __searchid: search }, readonly, fetchID);
592
+ break;
593
+ case "object":
594
+ default:
595
+ result = await this.get_list(search, readonly, fetchID);
596
+ break;
597
+ }
598
+ if (result)
599
+ result = array_first(result);
600
+ if (!object_isEmpty(result)) {
601
+ result = this.ensure(this, result);
602
+ WebObject.setReadonly(result, readonly);
603
+ }
604
+ return result;
605
+ }
606
+ /**
607
+ * Get a list of web objects
608
+ * default order of parameters : search,readonly,fetchID
609
+ */
610
+ static async get_list(...p) {
611
+ let search = p.shift();
612
+ let readonly = p.shift() ?? false;
613
+ let fetchID = p.shift();
614
+ if (!search)
615
+ search = {};
616
+ const usepath = await WebObjectPathHelper.get_path(this, "get");
617
+ let result_items = await gfunc.run_action("get", usepath, search, { fetchID: fetchID });
618
+ // const selftype = (this.constructor ||
619
+ // Object.getPrototypeOf(this)) as any;
620
+ const res = WebObject.map_rowindex(WebObject.mapto(this, result_items, readonly));
621
+ WebObject.setReadonly(res, readonly);
622
+ return res;
623
+ }
624
+ /**
625
+ * uses `get_list` and then saves the result to `gcache`
626
+ * then uses the `equals` function to return matched results
627
+ * @param search
628
+ * @returns
629
+ */
630
+ static async get_list_cache(search) {
631
+ const all_data = await gcache.get_temp_cache(this.get_webpath(), async () => await this.get_list());
632
+ if (!search)
633
+ return all_data;
634
+ return all_data.filter((s) => this.equals(s, search));
635
+ }
636
+ /**
637
+ * uses `get_list_cache` then the `equals` function to return matched result
638
+ * @param search
639
+ * @returns
640
+ */
641
+ static async get_single_cache(search) {
642
+ return (await this.get_list_cache()).find((s) => this.equals(s, search));
643
+ }
644
+ /**
645
+ * Get a list of web objects and convert them to basic objects
646
+ * can be passed to client components
647
+ * default order of parameters : search,readonly,fetchID
648
+ */
649
+ static async get_basicList(...p) {
650
+ const itemlist = await this.get_list(...p);
651
+ return await Promise.all(itemlist.map(async (r) => await r.get_basicObject()));
652
+ }
653
+ }
654
+ export default WebObject;
@@ -0,0 +1,9 @@
1
+ import WebObject from "./WebObject";
2
+ export declare class WebObjectHelper {
3
+ /**
4
+ * check if the given WebObject is changed or given WebObject array has any changed element
5
+ * @param obj
6
+ */
7
+ static isChangedWebObjectField(obj: WebObject | WebObject[] | any): boolean;
8
+ }
9
+ export default WebObjectHelper;
@@ -0,0 +1,18 @@
1
+ import WebObject from "./WebObject";
2
+ export class WebObjectHelper {
3
+ /**
4
+ * check if the given WebObject is changed or given WebObject array has any changed element
5
+ * @param obj
6
+ */
7
+ static isChangedWebObjectField(obj) {
8
+ if (typeof obj !== "object")
9
+ return false;
10
+ if (Array.isArray(obj)) {
11
+ const arrCheck = obj;
12
+ return (arrCheck.find((r) => r instanceof WebObject && r.isChanged) !=
13
+ undefined);
14
+ }
15
+ return obj instanceof WebObject && obj.isChanged;
16
+ }
17
+ }
18
+ export default WebObjectHelper;
@@ -0,0 +1 @@
1
+ export {};