remult 0.23.0-exp.30 → 0.23.0-exp.32

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/esm/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ClassType } from './classType';
2
- export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator as MemberDecorator, ClassFieldDecoratorContextStub, } from './src/remult3/remult3';
2
+ export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
3
+ LifecycleEvent, } from './src/remult3/remult3';
3
4
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
4
5
  export { Entity } from './src/remult3/entity';
5
6
  export { getEntityRef } from './src/remult3/getEntityRef';
@@ -763,7 +763,7 @@ export class EntityQueueStorage {
763
763
  return (this.sync = this.sync.then(() => what()));
764
764
  }
765
765
  async getJobInfo(queuedJobId) {
766
- let q = await this.repo.findId(queuedJobId, { useCache: false });
766
+ let q = await this.repo.findId(queuedJobId);
767
767
  let lastProgress = undefined;
768
768
  return {
769
769
  userId: q.userId,
@@ -992,4 +992,3 @@ JobsInQueueEntity = __decorate([
992
992
  ], JobsInQueueEntity);
993
993
  export { JobsInQueueEntity };
994
994
  allEntities.splice(allEntities.indexOf(JobsInQueueEntity), 1);
995
- //p1 - implement dbname based on related field https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
@@ -37,7 +37,7 @@ export interface FieldOptions<entityType = any, valueType = any> {
37
37
  */
38
38
  validate?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>) | ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>)[];
39
39
  /** Will be fired before this field is saved to the server/database */
40
- saving?: (entity: entityType, e: LifecycleEvent<entityType>, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>;
40
+ saving?: (entity: entityType, fieldRef: FieldRef<entityType, valueType>, e: LifecycleEvent<entityType>) => any | Promise<any>;
41
41
  /** An expression that will determine this fields value on the backend and be provided to the front end*/
42
42
  serverExpression?: (entity: entityType) => valueType | Promise<valueType>;
43
43
  /** The name of the column in the database that holds the data for this field. If no name is set, the key will be used instead.
@@ -286,7 +286,5 @@ class transactionLiveQueryPublisher {
286
286
  }
287
287
  }
288
288
  }
289
- //p1 - seems that after backend methods relations are loaded for some reason - see trempim - intake doRequest backend method
290
- //p1 - reconsider the case in tremping where create user id was updated with some user and not the actual user
291
- //[ ] - when value changes for field with error, clear error - so the user will feel comfortable
289
+ //p2 - when value changes for field with error, clear error - so the user will feel comfortable
292
290
  //y2 - require filter argument - and perform validation checks for it - site, id etc.. changelog, status changes etc...,
@@ -46,7 +46,7 @@ export class Fields {
46
46
  static createdAt(...options) {
47
47
  return Field(() => Date, {
48
48
  allowApiUpdate: false,
49
- saving: (_, { isNew }, ref) => {
49
+ saving: (_, ref, { isNew }) => {
50
50
  if (isNew)
51
51
  ref.value = new Date();
52
52
  },
@@ -55,7 +55,7 @@ export class Fields {
55
55
  static updatedAt(...options) {
56
56
  return Field(() => Date, {
57
57
  allowApiUpdate: false,
58
- saving: (_, _1, ref) => {
58
+ saving: (_, ref) => {
59
59
  ref.value = new Date();
60
60
  },
61
61
  }, ...options);
@@ -64,7 +64,7 @@ export class Fields {
64
64
  return Field(() => String, {
65
65
  allowApiUpdate: false,
66
66
  defaultValue: () => uuid(),
67
- saving: (_, _1, r) => {
67
+ saving: (_, r) => {
68
68
  if (!r.value)
69
69
  r.value = uuid();
70
70
  },
@@ -74,7 +74,7 @@ export class Fields {
74
74
  return Field(() => String, {
75
75
  allowApiUpdate: false,
76
76
  defaultValue: () => createId(),
77
- saving: (_, _1, r) => {
77
+ saving: (_, r) => {
78
78
  if (!r.value)
79
79
  r.value = createId();
80
80
  },
@@ -81,13 +81,17 @@ export class RepositoryImplementation {
81
81
  if (!rel)
82
82
  throw Error(key + ' is not a relation');
83
83
  let repo = this.remult.repo(rel.toType());
84
- let { findOptions } = this.findOptionsBasedOnRelation(rel, field, undefined, item, repo);
84
+ let { findOptions, returnNull, returnUndefined } = this.findOptionsBasedOnRelation(rel, field, undefined, item, repo);
85
85
  const toRepo = new RepositoryImplementation(repo.entity, repo.remult, repo.dataProvider, repo._info, findOptions);
86
86
  if (rel.type === 'toMany')
87
87
  return toRepo;
88
88
  else
89
89
  return {
90
90
  findOne: (options) => {
91
+ if (returnNull)
92
+ return Promise.resolve(null);
93
+ if (returnUndefined)
94
+ return Promise.resolve(undefined);
91
95
  return toRepo.findFirst({}, options);
92
96
  },
93
97
  };
@@ -439,6 +443,8 @@ export class RepositoryImplementation {
439
443
  metadata: toRepo.metadata,
440
444
  }, findOptions)
441
445
  .then((result) => {
446
+ if (result.length == 0 && rel.type == 'toOne')
447
+ return;
442
448
  row[col.key] =
443
449
  rel.type !== 'toMany'
444
450
  ? result.length == 0
@@ -455,6 +461,7 @@ export class RepositoryImplementation {
455
461
  /*@internal */
456
462
  findOptionsBasedOnRelation(rel, field, moreFindOptions, row, otherRepo) {
457
463
  let returnNull = false;
464
+ let returnUndefined = false;
458
465
  let where = [];
459
466
  let findOptions = {};
460
467
  let findOptionsSources = [];
@@ -527,6 +534,8 @@ export class RepositoryImplementation {
527
534
  const val = row[options.field];
528
535
  if (val === null)
529
536
  returnNull = true;
537
+ if (val === undefined)
538
+ returnUndefined = true;
530
539
  else
531
540
  where.push(otherRepo.metadata.idMetadata.getIdFilter(val));
532
541
  }
@@ -552,6 +561,8 @@ export class RepositoryImplementation {
552
561
  : row[field.key];
553
562
  if (val === null)
554
563
  returnNull = true;
564
+ if (val === undefined)
565
+ returnUndefined = true;
555
566
  else if (typeof val === 'object')
556
567
  where.push(otherRepo.metadata.idMetadata.getIdFilter(otherRepo.metadata.idMetadata.getId(val)));
557
568
  else
@@ -562,7 +573,7 @@ export class RepositoryImplementation {
562
573
  findOptions.orderBy // I deduce from this that there may be more than one row and we want only the first
563
574
  )
564
575
  findOptions.limit = 1;
565
- return { findOptions, returnNull };
576
+ return { findOptions, returnNull, returnUndefined };
566
577
  }
567
578
  async mapRawDataToResult(r, loadFields) {
568
579
  if (!r)
@@ -723,7 +734,6 @@ export class RepositoryImplementation {
723
734
  if (typeof id !== 'string' && typeof id !== 'number')
724
735
  throw new Error('id can be either number or string, but got: ' + typeof id);
725
736
  return this.findFirst({}, {
726
- useCache: true,
727
737
  ...options,
728
738
  where: this.metadata.idMetadata.getIdFilter(id),
729
739
  }, true);
@@ -1199,7 +1209,7 @@ export class rowHelperImplementation extends rowHelperBase {
1199
1209
  if (!this.remult.dataProvider.isProxy) {
1200
1210
  for (const col of this.fields) {
1201
1211
  if (col.metadata.options.saving)
1202
- await col.metadata.options.saving(this.instance, e, col);
1212
+ await col.metadata.options.saving(this.instance, col, e);
1203
1213
  }
1204
1214
  if (this.info.entityInfo.saving) {
1205
1215
  await this.info.entityInfo.saving(this.instance, e);
@@ -1355,8 +1365,10 @@ export class rowHelperImplementation extends rowHelperBase {
1355
1365
  wasChanged() {
1356
1366
  this._subscribers?.reportObserved();
1357
1367
  for (const col of this.fields) {
1358
- if (col.valueChanged())
1359
- return true;
1368
+ const rel = getRelationInfo(col.metadata.options);
1369
+ if (!rel || rel.type == 'reference')
1370
+ if (col.valueChanged())
1371
+ return true;
1360
1372
  }
1361
1373
  return false;
1362
1374
  }
@@ -1472,8 +1484,10 @@ export class FieldRefImplementation {
1472
1484
  .relations(this.container)[this.metadata.key].find());
1473
1485
  }
1474
1486
  else {
1475
- return (this.container[this.metadata.key] = await this.helper.repository
1476
- .relations(this.container)[this.metadata.key].findOne());
1487
+ let val = await this.helper.repository
1488
+ .relations(this.container)[this.metadata.key].findOne();
1489
+ if (val)
1490
+ this.container[this.metadata.key] = val;
1477
1491
  }
1478
1492
  }
1479
1493
  else if (lu) {
@@ -1665,6 +1679,14 @@ export class columnDefsImpl {
1665
1679
  return this.settings.dbName;
1666
1680
  return result;
1667
1681
  }
1682
+ const rel = getRelationInfo(this.settings);
1683
+ let field = rel?.type === 'toOne' &&
1684
+ this.settings.field;
1685
+ if (field) {
1686
+ let fInfo = this.entityDefs.fields.find(field);
1687
+ if (fInfo)
1688
+ return fInfo.getDbName();
1689
+ }
1668
1690
  return this.settings.dbName;
1669
1691
  }
1670
1692
  finally {
@@ -551,7 +551,7 @@ export interface ClassDecoratorContextStub<Class extends new (...args: any) => a
551
551
  }
552
552
  export type ClassFieldDecorator<entityType, valueType> = (target: any, context: string | ClassFieldDecoratorContextStub<entityType, valueType | undefined>, c?: any) => void;
553
553
  /**
554
- * //p1 - doc this
554
+ * //p2 - doc this
555
555
  remult.apiClient.httpClient = (
556
556
  input: RequestInfo | URL,
557
557
  init?: RequestInit
@@ -1,21 +1,14 @@
1
1
  export {};
2
- //p1 - include relations in the api docs
3
- //p1 - include Relation options in the api docs
4
- //p1 - fix { allowApiRead: r => r.user.name === 'superman' } } in allowed for instace docs
5
- //p1 - fix seeallowed in ref_entity
6
2
  //p2 - write doc about controlling updates of rows...
7
3
  //p2 - need a way to extract the fields from the relation - for generating relation based sql
8
- //p1 - omit functions from fields and relations
9
- //p1 - active record with include thinks that the row was change!
10
4
  //p2 - add docs for apply changes
11
- //p1 - when the include doesn't find the many to one - it deletes the id!!!
12
5
  //y2 - discuss a default date formatter
13
6
  //[ ] - consider using this in saving etc...
14
7
  //p2 - when subscribe is forbidden - the query still runs after the renew process
15
8
  //p2 - JSON FIELD LOST JSON STORAGE WHEN SET INPUT VALUE
16
9
  //p2 - doc this:
17
10
  /**
18
- * //p1 - doc this
11
+ * //p2 - doc this
19
12
  remult.apiClient.httpClient = (
20
13
  input: RequestInfo | URL,
21
14
  init?: RequestInit
@@ -40,20 +33,24 @@ remult.apiClient.url='localhost:3007/api
40
33
  //p2 - Operator '>' cannot be applied to types 'Number' and 'number'.ts(2365) - change fields to <entityType,number> (now it's Number)
41
34
  //p2 - Field(()=>String) - doesn't play nice with strict mode - it prevents people from extending basic types
42
35
  //p2 - with remult for remultexpress
43
- //p1 - Add a with remult promise to Remult!
44
- //p1 - YONI field didn't appear in intelisence of manyToNe
45
- //p1 - YONI with relation to one, fields doesn't appear well in the overload options when trying to set driver phone on trempim
46
- //p1 - YONI why didn't this._.relations.statusChanges.insert({})work?
47
- //p1 - YONI 'taskid' toOne field parameter did not autocomplete in task app - C:\repos\help-zahal\src\app\events\volunteerInTask.ts 49
36
+ //p2 - Add a with remult promise to Remult!
37
+ //y1 - YONI field didn't appear in intelisence of manyToNe
38
+ //y1 - YONI with relation to one, fields doesn't appear well in the overload options when trying to set driver phone on trempim
39
+ //y1 - YONI why didn't this._.relations.statusChanges.insert({})work?
40
+ //y1 - YONI 'taskid' toOne field parameter did not autocomplete in task app - C:\repos\help-zahal\src\app\events\volunteerInTask.ts 49
41
+ //y1 - YONI omit functions from fields and relations
48
42
  //p2 - filterToRaw should get a dbnames of - and we should create a dbnames of that supports an alias
49
- //p1 - DO NOT BREAK - move fieldref to second parameter, and lifecycle to 3rd consider the breaking signature change of saving on field options - the field becomes the 3rd parameter.
50
- //p1 - test what happens with a many to one relation where the one no longer exist, in all 3 cases (toOne,reference,toone with fields)
51
- //p1 - findid by default has cache - it sucks!
52
43
  //y2 - livequery for findfirst (@JY)
53
44
  //y2 - #239 - (@JY) add a way to get from fieldMetadata back to entity repo (like we have in fieldRef)
54
45
  //p2 - constraints (@JY)
55
46
  //p2 - Add ability to process query that comes from the api
56
47
  //p2 - too much data by mistake
57
48
  //p2 - postgres case sensitive
58
- //y1 - consider http status code for errors
59
49
  //p2 - fix sql log to console to make more sense
50
+ //p2 - type metadata.key - to keyof entity - based on cwis input
51
+ //p2 - processError in remult express
52
+ //y1 - should we change relations to be a static const instead of a class (also for fields maybe) what's the point of doing new Relations
53
+ //y1 - add Class type to index of remult - it is used in repo and is important
54
+ //y2 - Backend methods are transactions, it's not intuitive and maybe should be optional / opt in
55
+ //p2 - get backend methods to work when specifying types for date, and entities as poco's
56
+ //p2 - allow find options preprocessor for api calls, to use for authorization
package/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ClassType } from './classType';
2
- export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator as MemberDecorator, ClassFieldDecoratorContextStub, } from './src/remult3/remult3';
2
+ export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
3
+ LifecycleEvent, } from './src/remult3/remult3';
3
4
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
4
5
  export { Entity } from './src/remult3/entity';
5
6
  export { getEntityRef } from './src/remult3/getEntityRef';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.23.0-exp.30",
3
+ "version": "0.23.0-exp.32",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "types": "index.d.ts",
6
6
  "module": "esm/index.js",
@@ -1125,7 +1125,7 @@ var EntityQueueStorage = /** @class */ (function () {
1125
1125
  var _this = this;
1126
1126
  return tslib_1.__generator(this, function (_a) {
1127
1127
  switch (_a.label) {
1128
- case 0: return [4 /*yield*/, this.repo.findId(queuedJobId, { useCache: false })];
1128
+ case 0: return [4 /*yield*/, this.repo.findId(queuedJobId)];
1129
1129
  case 1:
1130
1130
  q = _a.sent();
1131
1131
  lastProgress = undefined;
@@ -1406,4 +1406,3 @@ var JobsInQueueEntity = /** @class */ (function (_super) {
1406
1406
  }(IdEntity_1.IdEntity));
1407
1407
  exports.JobsInQueueEntity = JobsInQueueEntity;
1408
1408
  context_1.allEntities.splice(context_1.allEntities.indexOf(JobsInQueueEntity), 1);
1409
- //p1 - implement dbname based on related field https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
@@ -37,7 +37,7 @@ export interface FieldOptions<entityType = any, valueType = any> {
37
37
  */
38
38
  validate?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>) | ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>)[];
39
39
  /** Will be fired before this field is saved to the server/database */
40
- saving?: (entity: entityType, e: LifecycleEvent<entityType>, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>;
40
+ saving?: (entity: entityType, fieldRef: FieldRef<entityType, valueType>, e: LifecycleEvent<entityType>) => any | Promise<any>;
41
41
  /** An expression that will determine this fields value on the backend and be provided to the front end*/
42
42
  serverExpression?: (entity: entityType) => valueType | Promise<valueType>;
43
43
  /** The name of the column in the database that holds the data for this field. If no name is set, the key will be used instead.
package/src/context.js CHANGED
@@ -450,7 +450,5 @@ var transactionLiveQueryPublisher = /** @class */ (function () {
450
450
  };
451
451
  return transactionLiveQueryPublisher;
452
452
  }());
453
- //p1 - seems that after backend methods relations are loaded for some reason - see trempim - intake doRequest backend method
454
- //p1 - reconsider the case in tremping where create user id was updated with some user and not the actual user
455
- //[ ] - when value changes for field with error, clear error - so the user will feel comfortable
453
+ //p2 - when value changes for field with error, clear error - so the user will feel comfortable
456
454
  //y2 - require filter argument - and perform validation checks for it - site, id etc.. changelog, status changes etc...,
@@ -86,7 +86,7 @@ var Fields = /** @class */ (function () {
86
86
  return Field.apply(void 0, tslib_1.__spreadArray([function () { return Date; },
87
87
  {
88
88
  allowApiUpdate: false,
89
- saving: function (_, _a, ref) {
89
+ saving: function (_, ref, _a) {
90
90
  var isNew = _a.isNew;
91
91
  if (isNew)
92
92
  ref.value = new Date();
@@ -101,7 +101,7 @@ var Fields = /** @class */ (function () {
101
101
  return Field.apply(void 0, tslib_1.__spreadArray([function () { return Date; },
102
102
  {
103
103
  allowApiUpdate: false,
104
- saving: function (_, _1, ref) {
104
+ saving: function (_, ref) {
105
105
  ref.value = new Date();
106
106
  },
107
107
  }], tslib_1.__read(options), false));
@@ -115,7 +115,7 @@ var Fields = /** @class */ (function () {
115
115
  {
116
116
  allowApiUpdate: false,
117
117
  defaultValue: function () { return (0, uuid_1.v4)(); },
118
- saving: function (_, _1, r) {
118
+ saving: function (_, r) {
119
119
  if (!r.value)
120
120
  r.value = (0, uuid_1.v4)();
121
121
  },
@@ -130,7 +130,7 @@ var Fields = /** @class */ (function () {
130
130
  {
131
131
  allowApiUpdate: false,
132
132
  defaultValue: function () { return (0, cuid2_1.createId)(); },
133
- saving: function (_, _1, r) {
133
+ saving: function (_, r) {
134
134
  if (!r.value)
135
135
  r.value = (0, cuid2_1.createId)();
136
136
  },
@@ -126,13 +126,17 @@ var RepositoryImplementation = /** @class */ (function () {
126
126
  if (!rel)
127
127
  throw Error(key + ' is not a relation');
128
128
  var repo = _this.remult.repo(rel.toType());
129
- var findOptions = _this.findOptionsBasedOnRelation(rel, field, undefined, item, repo).findOptions;
129
+ var _a = _this.findOptionsBasedOnRelation(rel, field, undefined, item, repo), findOptions = _a.findOptions, returnNull = _a.returnNull, returnUndefined = _a.returnUndefined;
130
130
  var toRepo = new RepositoryImplementation(repo.entity, repo.remult, repo.dataProvider, repo._info, findOptions);
131
131
  if (rel.type === 'toMany')
132
132
  return toRepo;
133
133
  else
134
134
  return {
135
135
  findOne: function (options) {
136
+ if (returnNull)
137
+ return Promise.resolve(null);
138
+ if (returnUndefined)
139
+ return Promise.resolve(undefined);
136
140
  return toRepo.findFirst({}, options);
137
141
  },
138
142
  };
@@ -731,6 +735,8 @@ var RepositoryImplementation = /** @class */ (function () {
731
735
  metadata: toRepo_1.metadata,
732
736
  }, findOptions)
733
737
  .then(function (result) {
738
+ if (result.length == 0 && rel.type == 'toOne')
739
+ return;
734
740
  row[col.key] =
735
741
  rel.type !== 'toMany'
736
742
  ? result.length == 0
@@ -778,6 +784,7 @@ var RepositoryImplementation = /** @class */ (function () {
778
784
  RepositoryImplementation.prototype.findOptionsBasedOnRelation = function (rel, field, moreFindOptions, row, otherRepo) {
779
785
  var e_13, _a, e_14, _b, e_15, _c, _d, _e;
780
786
  var returnNull = false;
787
+ var returnUndefined = false;
781
788
  var where = [];
782
789
  var findOptions = {};
783
790
  var findOptionsSources = [];
@@ -880,6 +887,8 @@ var RepositoryImplementation = /** @class */ (function () {
880
887
  var val = row[options.field];
881
888
  if (val === null)
882
889
  returnNull = true;
890
+ if (val === undefined)
891
+ returnUndefined = true;
883
892
  else
884
893
  where.push(otherRepo.metadata.idMetadata.getIdFilter(val));
885
894
  }
@@ -905,6 +914,8 @@ var RepositoryImplementation = /** @class */ (function () {
905
914
  : row[field.key];
906
915
  if (val === null)
907
916
  returnNull = true;
917
+ if (val === undefined)
918
+ returnUndefined = true;
908
919
  else if (typeof val === 'object')
909
920
  where.push(otherRepo.metadata.idMetadata.getIdFilter(otherRepo.metadata.idMetadata.getId(val)));
910
921
  else
@@ -915,7 +926,7 @@ var RepositoryImplementation = /** @class */ (function () {
915
926
  findOptions.orderBy // I deduce from this that there may be more than one row and we want only the first
916
927
  )
917
928
  findOptions.limit = 1;
918
- return { findOptions: findOptions, returnNull: returnNull };
929
+ return { findOptions: findOptions, returnNull: returnNull, returnUndefined: returnUndefined };
919
930
  };
920
931
  RepositoryImplementation.prototype.mapRawDataToResult = function (r, loadFields) {
921
932
  return tslib_1.__awaiter(this, void 0, void 0, function () {
@@ -1157,7 +1168,7 @@ var RepositoryImplementation = /** @class */ (function () {
1157
1168
  return null;
1158
1169
  if (typeof id !== 'string' && typeof id !== 'number')
1159
1170
  throw new Error('id can be either number or string, but got: ' + typeof id);
1160
- return this.findFirst({}, tslib_1.__assign(tslib_1.__assign({ useCache: true }, options), { where: this.metadata.idMetadata.getIdFilter(id) }), true);
1171
+ return this.findFirst({}, tslib_1.__assign(tslib_1.__assign({}, options), { where: this.metadata.idMetadata.getIdFilter(id) }), true);
1161
1172
  };
1162
1173
  /* @internal*/
1163
1174
  RepositoryImplementation.prototype.translateWhereToFilter = function (where) {
@@ -1905,7 +1916,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
1905
1916
  if (!!_c.done) return [3 /*break*/, 7];
1906
1917
  col = _c.value;
1907
1918
  if (!col.metadata.options.saving) return [3 /*break*/, 6];
1908
- return [4 /*yield*/, col.metadata.options.saving(this.instance, e, col)];
1919
+ return [4 /*yield*/, col.metadata.options.saving(this.instance, col, e)];
1909
1920
  case 5:
1910
1921
  _l.sent();
1911
1922
  _l.label = 6;
@@ -2253,8 +2264,10 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2253
2264
  try {
2254
2265
  for (var _c = tslib_1.__values(this.fields), _d = _c.next(); !_d.done; _d = _c.next()) {
2255
2266
  var col = _d.value;
2256
- if (col.valueChanged())
2257
- return true;
2267
+ var rel = (0, relationInfoMember_1.getRelationInfo)(col.metadata.options);
2268
+ if (!rel || rel.type == 'reference')
2269
+ if (col.valueChanged())
2270
+ return true;
2258
2271
  }
2259
2272
  }
2260
2273
  catch (e_36_1) { e_36 = { error: e_36_1 }; }
@@ -2473,9 +2486,9 @@ var FieldRefImplementation = /** @class */ (function () {
2473
2486
  };
2474
2487
  FieldRefImplementation.prototype.load = function () {
2475
2488
  return tslib_1.__awaiter(this, void 0, void 0, function () {
2476
- var lu, rel, _a, _b, _c, _d;
2477
- return tslib_1.__generator(this, function (_e) {
2478
- switch (_e.label) {
2489
+ var lu, rel, _a, _b, val;
2490
+ return tslib_1.__generator(this, function (_c) {
2491
+ switch (_c.label) {
2479
2492
  case 0:
2480
2493
  lu = this.rowBase.lookups.get(this.metadata.key);
2481
2494
  rel = (0, relationInfoMember_1.getRelationInfo)(this.metadata.options);
@@ -2485,23 +2498,24 @@ var FieldRefImplementation = /** @class */ (function () {
2485
2498
  _b = this.metadata.key;
2486
2499
  return [4 /*yield*/, this.helper.repository
2487
2500
  .relations(this.container)[this.metadata.key].find()];
2488
- case 1: return [2 /*return*/, (_a[_b] = _e.sent())];
2489
- case 2:
2490
- _c = this.container;
2491
- _d = this.metadata.key;
2492
- return [4 /*yield*/, this.helper.repository
2493
- .relations(this.container)[this.metadata.key].findOne()];
2494
- case 3: return [2 /*return*/, (_c[_d] = _e.sent())];
2501
+ case 1: return [2 /*return*/, (_a[_b] = _c.sent())];
2502
+ case 2: return [4 /*yield*/, this.helper.repository
2503
+ .relations(this.container)[this.metadata.key].findOne()];
2504
+ case 3:
2505
+ val = _c.sent();
2506
+ if (val)
2507
+ this.container[this.metadata.key] = val;
2508
+ _c.label = 4;
2495
2509
  case 4: return [3 /*break*/, 9];
2496
2510
  case 5:
2497
2511
  if (!lu) return [3 /*break*/, 9];
2498
2512
  if (!this.valueChanged()) return [3 /*break*/, 7];
2499
2513
  return [4 /*yield*/, lu.waitLoadOf(this.rawOriginalValue())];
2500
2514
  case 6:
2501
- _e.sent();
2502
- _e.label = 7;
2515
+ _c.sent();
2516
+ _c.label = 7;
2503
2517
  case 7: return [4 /*yield*/, lu.waitLoad()];
2504
- case 8: return [2 /*return*/, _e.sent()];
2518
+ case 8: return [2 /*return*/, _c.sent()];
2505
2519
  case 9: return [2 /*return*/, this.value];
2506
2520
  }
2507
2521
  });
@@ -2743,7 +2757,7 @@ var columnDefsImpl = /** @class */ (function () {
2743
2757
  };
2744
2758
  columnDefsImpl.prototype.getDbName = function () {
2745
2759
  return tslib_1.__awaiter(this, void 0, void 0, function () {
2746
- var result;
2760
+ var result, rel, field, fInfo;
2747
2761
  return tslib_1.__generator(this, function (_a) {
2748
2762
  switch (_a.label) {
2749
2763
  case 0:
@@ -2762,7 +2776,16 @@ var columnDefsImpl = /** @class */ (function () {
2762
2776
  if (!result)
2763
2777
  return [2 /*return*/, this.settings.dbName];
2764
2778
  return [2 /*return*/, result];
2765
- case 4: return [2 /*return*/, this.settings.dbName];
2779
+ case 4:
2780
+ rel = (0, relationInfoMember_1.getRelationInfo)(this.settings);
2781
+ field = (rel === null || rel === void 0 ? void 0 : rel.type) === 'toOne' &&
2782
+ this.settings.field;
2783
+ if (field) {
2784
+ fInfo = this.entityDefs.fields.find(field);
2785
+ if (fInfo)
2786
+ return [2 /*return*/, fInfo.getDbName()];
2787
+ }
2788
+ return [2 /*return*/, this.settings.dbName];
2766
2789
  case 5: return [7 /*endfinally*/];
2767
2790
  case 6: return [2 /*return*/];
2768
2791
  }
@@ -551,7 +551,7 @@ export interface ClassDecoratorContextStub<Class extends new (...args: any) => a
551
551
  }
552
552
  export type ClassFieldDecorator<entityType, valueType> = (target: any, context: string | ClassFieldDecoratorContextStub<entityType, valueType | undefined>, c?: any) => void;
553
553
  /**
554
- * //p1 - doc this
554
+ * //p2 - doc this
555
555
  remult.apiClient.httpClient = (
556
556
  input: RequestInfo | URL,
557
557
  init?: RequestInit
@@ -1,22 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //p1 - include relations in the api docs
4
- //p1 - include Relation options in the api docs
5
- //p1 - fix { allowApiRead: r => r.user.name === 'superman' } } in allowed for instace docs
6
- //p1 - fix seeallowed in ref_entity
7
3
  //p2 - write doc about controlling updates of rows...
8
4
  //p2 - need a way to extract the fields from the relation - for generating relation based sql
9
- //p1 - omit functions from fields and relations
10
- //p1 - active record with include thinks that the row was change!
11
5
  //p2 - add docs for apply changes
12
- //p1 - when the include doesn't find the many to one - it deletes the id!!!
13
6
  //y2 - discuss a default date formatter
14
7
  //[ ] - consider using this in saving etc...
15
8
  //p2 - when subscribe is forbidden - the query still runs after the renew process
16
9
  //p2 - JSON FIELD LOST JSON STORAGE WHEN SET INPUT VALUE
17
10
  //p2 - doc this:
18
11
  /**
19
- * //p1 - doc this
12
+ * //p2 - doc this
20
13
  remult.apiClient.httpClient = (
21
14
  input: RequestInfo | URL,
22
15
  init?: RequestInit
@@ -41,20 +34,24 @@ remult.apiClient.url='localhost:3007/api
41
34
  //p2 - Operator '>' cannot be applied to types 'Number' and 'number'.ts(2365) - change fields to <entityType,number> (now it's Number)
42
35
  //p2 - Field(()=>String) - doesn't play nice with strict mode - it prevents people from extending basic types
43
36
  //p2 - with remult for remultexpress
44
- //p1 - Add a with remult promise to Remult!
45
- //p1 - YONI field didn't appear in intelisence of manyToNe
46
- //p1 - YONI with relation to one, fields doesn't appear well in the overload options when trying to set driver phone on trempim
47
- //p1 - YONI why didn't this._.relations.statusChanges.insert({})work?
48
- //p1 - YONI 'taskid' toOne field parameter did not autocomplete in task app - C:\repos\help-zahal\src\app\events\volunteerInTask.ts 49
37
+ //p2 - Add a with remult promise to Remult!
38
+ //y1 - YONI field didn't appear in intelisence of manyToNe
39
+ //y1 - YONI with relation to one, fields doesn't appear well in the overload options when trying to set driver phone on trempim
40
+ //y1 - YONI why didn't this._.relations.statusChanges.insert({})work?
41
+ //y1 - YONI 'taskid' toOne field parameter did not autocomplete in task app - C:\repos\help-zahal\src\app\events\volunteerInTask.ts 49
42
+ //y1 - YONI omit functions from fields and relations
49
43
  //p2 - filterToRaw should get a dbnames of - and we should create a dbnames of that supports an alias
50
- //p1 - DO NOT BREAK - move fieldref to second parameter, and lifecycle to 3rd consider the breaking signature change of saving on field options - the field becomes the 3rd parameter.
51
- //p1 - test what happens with a many to one relation where the one no longer exist, in all 3 cases (toOne,reference,toone with fields)
52
- //p1 - findid by default has cache - it sucks!
53
44
  //y2 - livequery for findfirst (@JY)
54
45
  //y2 - #239 - (@JY) add a way to get from fieldMetadata back to entity repo (like we have in fieldRef)
55
46
  //p2 - constraints (@JY)
56
47
  //p2 - Add ability to process query that comes from the api
57
48
  //p2 - too much data by mistake
58
49
  //p2 - postgres case sensitive
59
- //y1 - consider http status code for errors
60
50
  //p2 - fix sql log to console to make more sense
51
+ //p2 - type metadata.key - to keyof entity - based on cwis input
52
+ //p2 - processError in remult express
53
+ //y1 - should we change relations to be a static const instead of a class (also for fields maybe) what's the point of doing new Relations
54
+ //y1 - add Class type to index of remult - it is used in repo and is important
55
+ //y2 - Backend methods are transactions, it's not intuitive and maybe should be optional / opt in
56
+ //p2 - get backend methods to work when specifying types for date, and entities as poco's
57
+ //p2 - allow find options preprocessor for api calls, to use for authorization