remult 0.23.0-exp.2 → 0.23.0-exp.21
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/README.md +26 -27
- package/esm/graphql.js +7 -1
- package/esm/index.d.ts +16 -3
- package/esm/index.js +17 -2
- package/esm/internals.d.ts +2 -1
- package/esm/internals.js +1 -1
- package/esm/remult-express.js +1 -1
- package/esm/remult-knex/index.js +2 -1
- package/esm/remult-mongo.js +2 -1
- package/esm/server/JsonEntityFileStorage.js +1 -1
- package/esm/server/expressBridge.js +1 -1
- package/esm/src/CompoundIdField.d.ts +1 -1
- package/esm/src/CompoundIdField.js +3 -1
- package/esm/src/buildRestDataProvider.d.ts +1 -2
- package/esm/src/column-interfaces.d.ts +19 -7
- package/esm/src/column.d.ts +4 -18
- package/esm/src/column.js +10 -44
- package/esm/src/context.d.ts +1 -1
- package/esm/src/context.js +5 -1
- package/esm/src/data-interfaces.js +1 -2
- package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
- package/esm/src/data-providers/array-entity-data-provider.js +6 -6
- package/esm/src/data-providers/sql-database.js +2 -1
- package/esm/src/data-providers/web-sql-data-provider.js +3 -3
- package/esm/src/entity.d.ts +48 -17
- package/esm/src/filter/filter-interfaces.d.ts +2 -16
- package/esm/src/filter/filter-interfaces.js +87 -6
- package/esm/src/live-query/LiveQueryClient.js +2 -1
- package/esm/src/live-query/SubscriptionChannel.js +4 -3
- package/esm/src/remult-proxy.js +10 -2
- package/esm/src/remult3/Fields.d.ts +140 -21
- package/esm/src/remult3/Fields.js +26 -30
- package/esm/src/remult3/RepositoryImplementation.d.ts +10 -16
- package/esm/src/remult3/RepositoryImplementation.js +165 -48
- package/esm/src/remult3/entity.d.ts +1 -1
- package/esm/src/remult3/entity.js +0 -1
- package/esm/src/remult3/getEntityRef.d.ts +1 -1
- package/esm/src/remult3/getEntityRef.js +1 -1
- package/esm/src/remult3/relation-loader.js +4 -1
- package/esm/src/remult3/remult3.d.ts +132 -7
- package/esm/src/remult3/remult3.js +30 -0
- package/esm/src/remult3/repository-internals.d.ts +14 -0
- package/esm/src/remult3/repository-internals.js +7 -0
- package/esm/src/server-action.js +1 -1
- package/esm/src/sort.d.ts +3 -3
- package/esm/src/sort.js +36 -8
- package/graphql.js +10 -2
- package/index.d.ts +16 -3
- package/index.js +19 -3
- package/internals.d.ts +2 -1
- package/internals.js +3 -1
- package/package.json +1 -1
- package/remult-express.js +1 -1
- package/remult-knex/index.js +2 -1
- package/remult-mongo.js +2 -1
- package/server/JsonEntityFileStorage.js +1 -1
- package/server/expressBridge.js +1 -1
- package/src/CompoundIdField.d.ts +1 -1
- package/src/CompoundIdField.js +3 -0
- package/src/buildRestDataProvider.d.ts +1 -2
- package/src/column-interfaces.d.ts +19 -7
- package/src/column.d.ts +4 -18
- package/src/column.js +10 -56
- package/src/context.d.ts +1 -1
- package/src/context.js +5 -1
- package/src/data-interfaces.js +1 -2
- package/src/data-providers/array-entity-data-provider.d.ts +1 -1
- package/src/data-providers/array-entity-data-provider.js +5 -6
- package/src/data-providers/sql-database.js +2 -1
- package/src/data-providers/web-sql-data-provider.js +3 -3
- package/src/entity.d.ts +48 -17
- package/src/filter/filter-interfaces.d.ts +2 -16
- package/src/filter/filter-interfaces.js +101 -9
- package/src/live-query/LiveQueryClient.js +2 -1
- package/src/live-query/SubscriptionChannel.js +4 -3
- package/src/remult-proxy.js +43 -29
- package/src/remult3/Fields.d.ts +140 -21
- package/src/remult3/Fields.js +32 -32
- package/src/remult3/RepositoryImplementation.d.ts +10 -16
- package/src/remult3/RepositoryImplementation.js +286 -163
- package/src/remult3/entity.d.ts +1 -1
- package/src/remult3/entity.js +0 -1
- package/src/remult3/getEntityRef.d.ts +1 -1
- package/src/remult3/getEntityRef.js +2 -1
- package/src/remult3/relation-loader.js +4 -1
- package/src/remult3/remult3.d.ts +132 -7
- package/src/remult3/remult3.js +30 -0
- package/src/remult3/repository-internals.d.ts +14 -0
- package/src/remult3/repository-internals.js +11 -0
- package/src/server-action.js +1 -1
- package/src/sort.d.ts +3 -3
- package/src/sort.js +43 -11
|
@@ -4,7 +4,6 @@ import { Remult, isBackend, queryConfig, } from '../context';
|
|
|
4
4
|
import { Filter } from '../filter/filter-interfaces';
|
|
5
5
|
import { Sort } from '../sort';
|
|
6
6
|
import { assign } from '../../assign';
|
|
7
|
-
import { filterHelper } from '../filter/filter-interfaces';
|
|
8
7
|
import { ValueConverters } from '../valueConverters';
|
|
9
8
|
import { findOptionsToJson } from '../data-providers/rest-data-provider';
|
|
10
9
|
import { remult as defaultRemult } from '../remult-proxy';
|
|
@@ -12,6 +11,7 @@ import { entityMember, getEntityKey, getEntityRef, getEntitySettings, } from './
|
|
|
12
11
|
import { __updateEntityBasedOnWhere } from './__updateEntityBasedOnWhere';
|
|
13
12
|
import { getRelationInfo, relationInfoMember } from './relationInfoMember';
|
|
14
13
|
import { RelationLoader } from './relation-loader';
|
|
14
|
+
import { getInternalKey } from './repository-internals';
|
|
15
15
|
//import { remult } from "../remult-proxy";
|
|
16
16
|
let classValidatorValidate = undefined;
|
|
17
17
|
// import ("class-validator".toString())
|
|
@@ -37,6 +37,9 @@ export class RepositoryImplementation {
|
|
|
37
37
|
dataProvider;
|
|
38
38
|
_info;
|
|
39
39
|
defaultFindOptions;
|
|
40
|
+
[getInternalKey]() {
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
40
43
|
async createAfterFilter(orderBy, lastRow) {
|
|
41
44
|
let values = new Map();
|
|
42
45
|
for (const s of Sort.translateOrderByToSort(this.metadata, orderBy)
|
|
@@ -56,7 +59,6 @@ export class RepositoryImplementation {
|
|
|
56
59
|
let equalToColumn = [];
|
|
57
60
|
for (const s of Sort.translateOrderByToSort(this.metadata, orderBy)
|
|
58
61
|
.Segments) {
|
|
59
|
-
let ff = new filterHelper(s.field);
|
|
60
62
|
let f = {};
|
|
61
63
|
for (const c of equalToColumn) {
|
|
62
64
|
f[c.key] = values.get(c.key);
|
|
@@ -251,6 +253,8 @@ export class RepositoryImplementation {
|
|
|
251
253
|
for (const key in entity) {
|
|
252
254
|
if (Object.prototype.hasOwnProperty.call(entity, key)) {
|
|
253
255
|
let f = ref.fields[key];
|
|
256
|
+
if (entity[key] === undefined && getRelationInfo(f.metadata.options))
|
|
257
|
+
continue;
|
|
254
258
|
if (f)
|
|
255
259
|
r[key] = entity[key];
|
|
256
260
|
}
|
|
@@ -324,7 +328,6 @@ export class RepositoryImplementation {
|
|
|
324
328
|
async rawFind(options, skipOrderByAndLimit = false, loader) {
|
|
325
329
|
if (!options)
|
|
326
330
|
options = {};
|
|
327
|
-
Remult.onFind(this._info, options);
|
|
328
331
|
if (this.defaultFindOptions) {
|
|
329
332
|
options = { ...this.defaultFindOptions, ...options };
|
|
330
333
|
}
|
|
@@ -333,6 +336,7 @@ export class RepositoryImplementation {
|
|
|
333
336
|
delete opt.orderBy;
|
|
334
337
|
delete opt.limit;
|
|
335
338
|
}
|
|
339
|
+
Remult.onFind(this._info, options);
|
|
336
340
|
const rawRows = await this.edp.find(opt);
|
|
337
341
|
let result = await this.loadManyToOneForManyRows(rawRows, options, loader);
|
|
338
342
|
return result;
|
|
@@ -350,9 +354,12 @@ export class RepositoryImplementation {
|
|
|
350
354
|
options.orderBy = this._info.entityInfo.defaultOrderBy;
|
|
351
355
|
}
|
|
352
356
|
opt.where = await this.translateWhereToFilter(options.where);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
357
|
+
if (options.orderBy !== undefined)
|
|
358
|
+
opt.orderBy = Sort.translateOrderByToSort(this.metadata, options.orderBy);
|
|
359
|
+
if (options.limit !== undefined)
|
|
360
|
+
opt.limit = options.limit;
|
|
361
|
+
if (options.page !== undefined)
|
|
362
|
+
opt.page = options.page;
|
|
356
363
|
return opt;
|
|
357
364
|
}
|
|
358
365
|
async fromJsonArray(jsonItems, loadOptions) {
|
|
@@ -376,13 +383,9 @@ export class RepositoryImplementation {
|
|
|
376
383
|
if (ei) {
|
|
377
384
|
let isRelation = col.options?.[relationInfoMember];
|
|
378
385
|
if (!isRelation) {
|
|
379
|
-
let load =
|
|
380
|
-
? col.options?.defaultIncluded
|
|
381
|
-
: !col.options.lazy;
|
|
386
|
+
let load = !col.options.lazy;
|
|
382
387
|
if (loadFields !== undefined)
|
|
383
388
|
load = loadFields.includes(col);
|
|
384
|
-
if (loadOptions.include)
|
|
385
|
-
load = loadOptions.include[col.key];
|
|
386
389
|
if (load) {
|
|
387
390
|
let repo = this.remult.repo(col.valueType);
|
|
388
391
|
let toLoad = [];
|
|
@@ -391,7 +394,7 @@ export class RepositoryImplementation {
|
|
|
391
394
|
if (val !== undefined &&
|
|
392
395
|
val !== null &&
|
|
393
396
|
!toLoad.includes(val) &&
|
|
394
|
-
!repo.idCache.has(val)) {
|
|
397
|
+
!repo.idCache.has(val + '')) {
|
|
395
398
|
toLoad.push(val);
|
|
396
399
|
}
|
|
397
400
|
}
|
|
@@ -417,7 +420,7 @@ export class RepositoryImplementation {
|
|
|
417
420
|
let rel = getRelationInfo(col.options);
|
|
418
421
|
let incl = col.options
|
|
419
422
|
.defaultIncluded;
|
|
420
|
-
if (loadOptions?.include) {
|
|
423
|
+
if (loadOptions?.include?.[col.key] !== undefined) {
|
|
421
424
|
incl = loadOptions.include[col.key];
|
|
422
425
|
}
|
|
423
426
|
if (rel && incl) {
|
|
@@ -439,7 +442,7 @@ export class RepositoryImplementation {
|
|
|
439
442
|
row[col.key] =
|
|
440
443
|
rel.type !== 'toMany'
|
|
441
444
|
? result.length == 0
|
|
442
|
-
?
|
|
445
|
+
? null
|
|
443
446
|
: result[0]
|
|
444
447
|
: result;
|
|
445
448
|
});
|
|
@@ -455,7 +458,7 @@ export class RepositoryImplementation {
|
|
|
455
458
|
let where = [];
|
|
456
459
|
let findOptions = {};
|
|
457
460
|
let findOptionsSources = [];
|
|
458
|
-
|
|
461
|
+
let options = field.options;
|
|
459
462
|
if (typeof options.findOptions === 'function') {
|
|
460
463
|
findOptionsSources.push(options.findOptions(row));
|
|
461
464
|
}
|
|
@@ -477,11 +480,54 @@ export class RepositoryImplementation {
|
|
|
477
480
|
findOptions[key] = source[key];
|
|
478
481
|
}
|
|
479
482
|
}
|
|
483
|
+
function buildError(what) {
|
|
484
|
+
return Error(`Error for relation: "${field.key}" to "${otherRepo.metadata.key}": ` +
|
|
485
|
+
what);
|
|
486
|
+
}
|
|
487
|
+
let hasFields = () => options.field || options.fields;
|
|
488
|
+
if (rel.type === 'toMany' && !hasFields()) {
|
|
489
|
+
for (const fieldInOtherRepo of otherRepo.fields.toArray()) {
|
|
490
|
+
if (!hasFields()) {
|
|
491
|
+
const reverseRel = getRelationInfo(fieldInOtherRepo.options);
|
|
492
|
+
const relOp = fieldInOtherRepo.options;
|
|
493
|
+
if (reverseRel)
|
|
494
|
+
if (reverseRel.toType() === this.entity)
|
|
495
|
+
if (reverseRel.type === 'reference') {
|
|
496
|
+
options = { ...findOptions, field: fieldInOtherRepo.key };
|
|
497
|
+
}
|
|
498
|
+
else if (reverseRel.type === 'toOne') {
|
|
499
|
+
if (relOp.field) {
|
|
500
|
+
options = { ...options, field: relOp.field };
|
|
501
|
+
}
|
|
502
|
+
else if (relOp.fields) {
|
|
503
|
+
let fields = {};
|
|
504
|
+
for (const key in relOp.fields) {
|
|
505
|
+
if (Object.prototype.hasOwnProperty.call(relOp.fields, key)) {
|
|
506
|
+
const keyInMyTable = relOp.fields[key];
|
|
507
|
+
fields[keyInMyTable] = key;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
options = { ...options, fields };
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (!hasFields())
|
|
516
|
+
throw buildError(`No matching field found on target. Please specify field/fields`);
|
|
517
|
+
}
|
|
518
|
+
function requireField(field, meta) {
|
|
519
|
+
const result = meta.fields.find(field);
|
|
520
|
+
if (!result)
|
|
521
|
+
throw buildError(`Field "${field}" was not found in "${meta.key}".`);
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
480
524
|
if (options.field) {
|
|
481
525
|
if (rel.type === 'toOne') {
|
|
526
|
+
requireField(options.field, this.metadata);
|
|
482
527
|
where.push(otherRepo.metadata.idMetadata.getIdFilter(row[options.field]));
|
|
483
528
|
}
|
|
484
529
|
else {
|
|
530
|
+
requireField(options.field, otherRepo.metadata);
|
|
485
531
|
where.push({
|
|
486
532
|
[options.field]: this.metadata.idMetadata.getId(row),
|
|
487
533
|
});
|
|
@@ -490,13 +536,15 @@ export class RepositoryImplementation {
|
|
|
490
536
|
else if (options.fields) {
|
|
491
537
|
for (const key in options.fields) {
|
|
492
538
|
if (Object.prototype.hasOwnProperty.call(options.fields, key)) {
|
|
539
|
+
requireField(options.fields[key], this.metadata);
|
|
540
|
+
requireField(key, otherRepo.metadata);
|
|
493
541
|
where.push({ [key]: row[options.fields[key]] });
|
|
494
542
|
}
|
|
495
543
|
}
|
|
496
544
|
}
|
|
497
545
|
else if (rel.type === 'toOne' || rel.type === 'reference') {
|
|
498
546
|
let val = rel.type === 'reference'
|
|
499
|
-
? getEntityRef(row).fields.find(field.key).getId()
|
|
547
|
+
? getEntityRef(row).fields.find(requireField(field.key, this.metadata)).getId()
|
|
500
548
|
: row[field.key];
|
|
501
549
|
if (val === null)
|
|
502
550
|
returnNull = true;
|
|
@@ -741,6 +789,7 @@ class rowHelperBase {
|
|
|
741
789
|
columnsInfo;
|
|
742
790
|
instance;
|
|
743
791
|
remult;
|
|
792
|
+
isNewRow;
|
|
744
793
|
_error;
|
|
745
794
|
get error() {
|
|
746
795
|
this._subscribers?.reportObserved();
|
|
@@ -750,10 +799,11 @@ class rowHelperBase {
|
|
|
750
799
|
this._error = val;
|
|
751
800
|
this._subscribers?.reportChanged();
|
|
752
801
|
}
|
|
753
|
-
constructor(columnsInfo, instance, remult) {
|
|
802
|
+
constructor(columnsInfo, instance, remult, isNewRow) {
|
|
754
803
|
this.columnsInfo = columnsInfo;
|
|
755
804
|
this.instance = instance;
|
|
756
805
|
this.remult = remult;
|
|
806
|
+
this.isNewRow = isNewRow;
|
|
757
807
|
{
|
|
758
808
|
let fac = remult;
|
|
759
809
|
if (fac != null && fac.remultFactory) {
|
|
@@ -796,7 +846,38 @@ class rowHelperBase {
|
|
|
796
846
|
});
|
|
797
847
|
lookup.set(val);
|
|
798
848
|
}
|
|
799
|
-
else {
|
|
849
|
+
else if (getRelationInfo(col)?.type === 'toOne') {
|
|
850
|
+
let hasVal = instance.hasOwnProperty(col.key);
|
|
851
|
+
let val = instance[col.key];
|
|
852
|
+
if (isNewRow && !val)
|
|
853
|
+
hasVal = false;
|
|
854
|
+
Object.defineProperty(instance, col.key, {
|
|
855
|
+
get: () => {
|
|
856
|
+
return val;
|
|
857
|
+
},
|
|
858
|
+
set: (newVal) => {
|
|
859
|
+
val = newVal;
|
|
860
|
+
if (newVal === undefined)
|
|
861
|
+
return;
|
|
862
|
+
const op = col;
|
|
863
|
+
if (op.field) {
|
|
864
|
+
this.instance[op.field] = this.remult
|
|
865
|
+
.repo(getRelationInfo(col).toType())
|
|
866
|
+
.metadata.idMetadata.getId(newVal);
|
|
867
|
+
}
|
|
868
|
+
if (op.fields) {
|
|
869
|
+
for (const key in op.fields) {
|
|
870
|
+
if (Object.prototype.hasOwnProperty.call(op.fields, key)) {
|
|
871
|
+
const element = op.fields[key];
|
|
872
|
+
this.instance[element] = newVal[key];
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
},
|
|
877
|
+
enumerable: true,
|
|
878
|
+
});
|
|
879
|
+
if (hasVal)
|
|
880
|
+
instance[col.key] = val;
|
|
800
881
|
}
|
|
801
882
|
}
|
|
802
883
|
}
|
|
@@ -922,7 +1003,9 @@ class rowHelperBase {
|
|
|
922
1003
|
if (val !== undefined && val !== null)
|
|
923
1004
|
val = col.valueConverter.fromJson(JSON.parse(JSON.stringify(val)));
|
|
924
1005
|
}
|
|
925
|
-
|
|
1006
|
+
const rel = getRelationInfo(col);
|
|
1007
|
+
if (!rel || rel.type === 'reference')
|
|
1008
|
+
d[col.key] = val;
|
|
926
1009
|
}
|
|
927
1010
|
return d;
|
|
928
1011
|
}
|
|
@@ -956,7 +1039,7 @@ class rowHelperBase {
|
|
|
956
1039
|
for (const col of this.columnsInfo) {
|
|
957
1040
|
if (!this.remult ||
|
|
958
1041
|
col.includeInApi === undefined ||
|
|
959
|
-
this.remult.
|
|
1042
|
+
this.remult.isAllowedForInstance(this.instance, col.includeInApi)) {
|
|
960
1043
|
let val;
|
|
961
1044
|
let lu = this.lookups.get(col.key);
|
|
962
1045
|
let disable = false;
|
|
@@ -985,13 +1068,14 @@ class rowHelperBase {
|
|
|
985
1068
|
}
|
|
986
1069
|
return result;
|
|
987
1070
|
}
|
|
988
|
-
async _updateEntityBasedOnApi(body) {
|
|
1071
|
+
async _updateEntityBasedOnApi(body, ignoreApiAllowed = false) {
|
|
989
1072
|
let keys = Object.keys(body);
|
|
990
1073
|
for (const col of this.columnsInfo) {
|
|
991
1074
|
if (keys.includes(col.key))
|
|
992
1075
|
if (col.includeInApi === undefined ||
|
|
993
|
-
this.remult.
|
|
1076
|
+
this.remult.isAllowedForInstance(this.instance, col.includeInApi)) {
|
|
994
1077
|
if (!this.remult ||
|
|
1078
|
+
ignoreApiAllowed ||
|
|
995
1079
|
col.allowApiUpdate === undefined ||
|
|
996
1080
|
this.remult.isAllowedForInstance(this.instance, col.allowApiUpdate)) {
|
|
997
1081
|
let lu = this.lookups.get(col.key);
|
|
@@ -1011,7 +1095,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1011
1095
|
edp;
|
|
1012
1096
|
_isNew;
|
|
1013
1097
|
constructor(info, instance, repository, edp, remult, _isNew) {
|
|
1014
|
-
super(info.columnsInfo, instance, remult);
|
|
1098
|
+
super(info.columnsInfo, instance, remult, _isNew);
|
|
1015
1099
|
this.info = info;
|
|
1016
1100
|
this.repository = repository;
|
|
1017
1101
|
this.edp = edp;
|
|
@@ -1033,6 +1117,9 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1033
1117
|
if (Remult.entityRefInit)
|
|
1034
1118
|
Remult.entityRefInit(this, instance);
|
|
1035
1119
|
}
|
|
1120
|
+
get relations() {
|
|
1121
|
+
return this.repository.relations(this.instance);
|
|
1122
|
+
}
|
|
1036
1123
|
get apiUpdateAllowed() {
|
|
1037
1124
|
return this.remult.isAllowedForInstance(this.instance, this.metadata.options.allowApiUpdate);
|
|
1038
1125
|
}
|
|
@@ -1104,12 +1191,15 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1104
1191
|
// no need
|
|
1105
1192
|
await this.__validateEntity();
|
|
1106
1193
|
let doNotSave = false;
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1194
|
+
let e = this.buildLifeCycleEvent(() => (doNotSave = true));
|
|
1195
|
+
if (!this.remult.dataProvider.isProxy) {
|
|
1196
|
+
for (const col of this.fields) {
|
|
1197
|
+
if (col.metadata.options.saving)
|
|
1198
|
+
await col.metadata.options.saving(this.instance, e, col);
|
|
1199
|
+
}
|
|
1200
|
+
if (this.info.entityInfo.saving) {
|
|
1201
|
+
await this.info.entityInfo.saving(this.instance, e);
|
|
1202
|
+
}
|
|
1113
1203
|
}
|
|
1114
1204
|
this.__assertValidity();
|
|
1115
1205
|
let d = this.copyDataToObject();
|
|
@@ -1125,8 +1215,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1125
1215
|
f.value = f.originalValue;
|
|
1126
1216
|
}
|
|
1127
1217
|
}
|
|
1128
|
-
if (this.info.idMetadata.field instanceof CompoundIdField)
|
|
1129
|
-
delete d.id;
|
|
1218
|
+
//if (this.info.idMetadata.field instanceof CompoundIdField) delete d.id
|
|
1130
1219
|
let updatedRow;
|
|
1131
1220
|
let isNew = this.isNew();
|
|
1132
1221
|
try {
|
|
@@ -1157,12 +1246,14 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1157
1246
|
}
|
|
1158
1247
|
}
|
|
1159
1248
|
await this.loadDataFrom(updatedRow);
|
|
1160
|
-
if (this.
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1249
|
+
if (!this.remult.dataProvider.isProxy) {
|
|
1250
|
+
if (this.info.entityInfo.saved)
|
|
1251
|
+
await this.info.entityInfo.saved(this.instance, e);
|
|
1252
|
+
if (this.repository.listeners)
|
|
1253
|
+
for (const listener of this.repository.listeners.filter((x) => x.saved)) {
|
|
1254
|
+
await listener.saved(this.instance, isNew);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1166
1257
|
await this.repository.remult.liveQueryPublisher.itemChanged(this.repository.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }]);
|
|
1167
1258
|
this.saveOriginalData();
|
|
1168
1259
|
this._isNew = false;
|
|
@@ -1178,18 +1269,36 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1178
1269
|
this._saving = false;
|
|
1179
1270
|
}
|
|
1180
1271
|
}
|
|
1272
|
+
buildLifeCycleEvent(preventDefault = () => { }) {
|
|
1273
|
+
const self = this;
|
|
1274
|
+
return {
|
|
1275
|
+
isNew: self.isNew(),
|
|
1276
|
+
fields: self.fields,
|
|
1277
|
+
id: self.getId(),
|
|
1278
|
+
originalId: self.getOriginalId(),
|
|
1279
|
+
metadata: self.repository.metadata,
|
|
1280
|
+
repository: self.repository,
|
|
1281
|
+
preventDefault: () => preventDefault(),
|
|
1282
|
+
relations: self.repository.relations(self.instance),
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1181
1285
|
getIdFilter() {
|
|
1182
1286
|
return Filter.fromEntityFilter(this.metadata, this.repository.metadata.idMetadata.getIdFilter(this.id));
|
|
1183
1287
|
}
|
|
1184
1288
|
async delete() {
|
|
1185
1289
|
this.__clearErrorsAndReportChanged();
|
|
1186
|
-
|
|
1187
|
-
|
|
1290
|
+
let e = this.buildLifeCycleEvent();
|
|
1291
|
+
if (!this.remult.dataProvider.isProxy) {
|
|
1292
|
+
if (this.info.entityInfo.deleting)
|
|
1293
|
+
await this.info.entityInfo.deleting(this.instance, e);
|
|
1294
|
+
}
|
|
1188
1295
|
this.__assertValidity();
|
|
1189
1296
|
try {
|
|
1190
1297
|
await this.edp.delete(this.id);
|
|
1191
|
-
if (this.
|
|
1192
|
-
|
|
1298
|
+
if (!this.remult.dataProvider.isProxy) {
|
|
1299
|
+
if (this.info.entityInfo.deleted)
|
|
1300
|
+
await this.info.entityInfo.deleted(this.instance, e);
|
|
1301
|
+
}
|
|
1193
1302
|
if (this.repository.listeners)
|
|
1194
1303
|
for (const listener of this.repository.listeners.filter((x) => x.deleted)) {
|
|
1195
1304
|
await listener.deleted(this.instance);
|
|
@@ -1228,7 +1337,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1228
1337
|
}
|
|
1229
1338
|
async calcServerExpression() {
|
|
1230
1339
|
if (isBackend())
|
|
1231
|
-
//
|
|
1340
|
+
//y2 should be changed to be based on data provider - consider naming
|
|
1232
1341
|
for (const col of this.info.columnsInfo) {
|
|
1233
1342
|
if (col.serverExpression) {
|
|
1234
1343
|
this.instance[col.key] = await col.serverExpression(this.instance);
|
|
@@ -1254,8 +1363,10 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1254
1363
|
await col.__performValidation();
|
|
1255
1364
|
}
|
|
1256
1365
|
}
|
|
1257
|
-
if (this.info.entityInfo.validation)
|
|
1258
|
-
|
|
1366
|
+
if (this.info.entityInfo.validation) {
|
|
1367
|
+
let e = this.buildLifeCycleEvent(() => { });
|
|
1368
|
+
await this.info.entityInfo.validation(this.instance, e);
|
|
1369
|
+
}
|
|
1259
1370
|
if (this.repository.listeners)
|
|
1260
1371
|
for (const listener of this.repository.listeners.filter((x) => x.validating)) {
|
|
1261
1372
|
await listener.validating(this.instance);
|
|
@@ -1292,7 +1403,7 @@ export function getControllerRef(container, remultArg) {
|
|
|
1292
1403
|
}
|
|
1293
1404
|
export class controllerRefImpl extends rowHelperBase {
|
|
1294
1405
|
constructor(columnsInfo, instance, remult) {
|
|
1295
|
-
super(columnsInfo, instance, remult);
|
|
1406
|
+
super(columnsInfo, instance, remult, false);
|
|
1296
1407
|
let _items = [];
|
|
1297
1408
|
let r = {
|
|
1298
1409
|
find: (c) => r[typeof c === 'string' ? c : c.key],
|
|
@@ -1526,10 +1637,10 @@ export class columnDefsImpl {
|
|
|
1526
1637
|
.getEntityMetadataWithoutBreakingTheEntity(item)
|
|
1527
1638
|
.fields.find(this.key).displayValue;
|
|
1528
1639
|
}
|
|
1529
|
-
|
|
1640
|
+
includedInApi(item) {
|
|
1530
1641
|
if (this.options.includeInApi === undefined)
|
|
1531
1642
|
return true;
|
|
1532
|
-
return this.remult.
|
|
1643
|
+
return this.remult.isAllowedForInstance(item, this.options.includeInApi);
|
|
1533
1644
|
}
|
|
1534
1645
|
toInput(value, inputType) {
|
|
1535
1646
|
return this.valueConverter.toInput(value, inputType);
|
|
@@ -1629,7 +1740,9 @@ class EntityFullInfo {
|
|
|
1629
1740
|
this.fields = r;
|
|
1630
1741
|
this.caption = buildCaption(entityInfo.caption, this.key, remult);
|
|
1631
1742
|
if (entityInfo.id) {
|
|
1632
|
-
let r = entityInfo.id
|
|
1743
|
+
let r = typeof entityInfo.id === 'function'
|
|
1744
|
+
? entityInfo.id(this.fields)
|
|
1745
|
+
: Object.keys(entityInfo.id).map((x) => this.fields.find(x));
|
|
1633
1746
|
if (Array.isArray(r)) {
|
|
1634
1747
|
if (r.length > 1)
|
|
1635
1748
|
this.idMetadata.field = new CompoundIdField(...r);
|
|
@@ -1703,6 +1816,8 @@ class EntityFullInfo {
|
|
|
1703
1816
|
}
|
|
1704
1817
|
idMetadata = {
|
|
1705
1818
|
getId: (item) => {
|
|
1819
|
+
if (item === undefined || item === null)
|
|
1820
|
+
return item;
|
|
1706
1821
|
const ref = getEntityRef(item, false);
|
|
1707
1822
|
if (ref)
|
|
1708
1823
|
return ref.getId();
|
|
@@ -2031,6 +2146,7 @@ class QueryResultImpl {
|
|
|
2031
2146
|
limit: this.options.pageSize,
|
|
2032
2147
|
page: page,
|
|
2033
2148
|
load: this.options.load,
|
|
2149
|
+
include: this.options.include,
|
|
2034
2150
|
});
|
|
2035
2151
|
}
|
|
2036
2152
|
async count() {
|
|
@@ -2055,6 +2171,7 @@ class QueryResultImpl {
|
|
|
2055
2171
|
orderBy: this.options.orderBy,
|
|
2056
2172
|
limit: this.options.pageSize,
|
|
2057
2173
|
load: this.options.load,
|
|
2174
|
+
include: this.options.include,
|
|
2058
2175
|
});
|
|
2059
2176
|
let nextPage = undefined;
|
|
2060
2177
|
let hasNextPage = items.length == this.options.pageSize;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Remult } from '../context';
|
|
2
2
|
import type { EntityOptions } from '../entity';
|
|
3
|
-
import type { ClassDecoratorContextStub } from './
|
|
3
|
+
import type { ClassDecoratorContextStub } from './remult3';
|
|
4
4
|
/**Decorates classes that should be used as entities.
|
|
5
5
|
* Receives a key and an array of EntityOptions.
|
|
6
6
|
* @example
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { allEntities, setControllerSettings } from '../context';
|
|
2
2
|
import { entityInfo, entityInfo_key, getEntitySettings } from './getEntityRef';
|
|
3
|
-
//[ ] YONI - in Typescript 5 I do get the name of the class, what would we like to change because of that?
|
|
4
3
|
/**Decorates classes that should be used as entities.
|
|
5
4
|
* Receives a key and an array of EntityOptions.
|
|
6
5
|
* @example
|
|
@@ -5,5 +5,5 @@ export declare function getEntityRef<entityType>(entity: entityType, throwExcept
|
|
|
5
5
|
export declare const entityMember: unique symbol;
|
|
6
6
|
export declare const entityInfo: unique symbol;
|
|
7
7
|
export declare const entityInfo_key: unique symbol;
|
|
8
|
-
export declare function getEntitySettings<T>(entity: ClassType<T>, throwError?: boolean): EntityOptionsFactory;
|
|
8
|
+
export declare function getEntitySettings<T>(entity: ClassType<T>, throwError?: boolean): EntityOptionsFactory | undefined;
|
|
9
9
|
export declare function getEntityKey(entity: ClassType<any>): string;
|
|
@@ -2,7 +2,7 @@ export function getEntityRef(entity, throwException = true) {
|
|
|
2
2
|
let x = entity[entityMember];
|
|
3
3
|
if (!x && throwException)
|
|
4
4
|
throw new Error('item ' +
|
|
5
|
-
entity.constructor
|
|
5
|
+
(entity.constructor?.name || entity) +
|
|
6
6
|
' was not initialized using a context');
|
|
7
7
|
return x;
|
|
8
8
|
}
|
|
@@ -51,7 +51,10 @@ class QueryVariation {
|
|
|
51
51
|
let w = this.whereVariations.get(whereKey);
|
|
52
52
|
if (!w) {
|
|
53
53
|
const keys = Object.keys(where);
|
|
54
|
-
if (keys.length === 1 &&
|
|
54
|
+
if (keys.length === 1 &&
|
|
55
|
+
typeof where[keys[0]] !== 'object' &&
|
|
56
|
+
!findOptions.limit // because merging calls in that case may bring non more rows than the limit
|
|
57
|
+
) {
|
|
55
58
|
let inVariation = this.pendingInStatements.get(keys[0]);
|
|
56
59
|
if (!inVariation) {
|
|
57
60
|
this.pendingInStatements.set(keys[0], (inVariation = new PendingInStatements(this.rel, keys[0], findOptions)));
|