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.
Files changed (92) hide show
  1. package/README.md +26 -27
  2. package/esm/graphql.js +7 -1
  3. package/esm/index.d.ts +16 -3
  4. package/esm/index.js +17 -2
  5. package/esm/internals.d.ts +2 -1
  6. package/esm/internals.js +1 -1
  7. package/esm/remult-express.js +1 -1
  8. package/esm/remult-knex/index.js +2 -1
  9. package/esm/remult-mongo.js +2 -1
  10. package/esm/server/JsonEntityFileStorage.js +1 -1
  11. package/esm/server/expressBridge.js +1 -1
  12. package/esm/src/CompoundIdField.d.ts +1 -1
  13. package/esm/src/CompoundIdField.js +3 -1
  14. package/esm/src/buildRestDataProvider.d.ts +1 -2
  15. package/esm/src/column-interfaces.d.ts +19 -7
  16. package/esm/src/column.d.ts +4 -18
  17. package/esm/src/column.js +10 -44
  18. package/esm/src/context.d.ts +1 -1
  19. package/esm/src/context.js +5 -1
  20. package/esm/src/data-interfaces.js +1 -2
  21. package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
  22. package/esm/src/data-providers/array-entity-data-provider.js +6 -6
  23. package/esm/src/data-providers/sql-database.js +2 -1
  24. package/esm/src/data-providers/web-sql-data-provider.js +3 -3
  25. package/esm/src/entity.d.ts +48 -17
  26. package/esm/src/filter/filter-interfaces.d.ts +2 -16
  27. package/esm/src/filter/filter-interfaces.js +87 -6
  28. package/esm/src/live-query/LiveQueryClient.js +2 -1
  29. package/esm/src/live-query/SubscriptionChannel.js +4 -3
  30. package/esm/src/remult-proxy.js +10 -2
  31. package/esm/src/remult3/Fields.d.ts +140 -21
  32. package/esm/src/remult3/Fields.js +26 -30
  33. package/esm/src/remult3/RepositoryImplementation.d.ts +10 -16
  34. package/esm/src/remult3/RepositoryImplementation.js +165 -48
  35. package/esm/src/remult3/entity.d.ts +1 -1
  36. package/esm/src/remult3/entity.js +0 -1
  37. package/esm/src/remult3/getEntityRef.d.ts +1 -1
  38. package/esm/src/remult3/getEntityRef.js +1 -1
  39. package/esm/src/remult3/relation-loader.js +4 -1
  40. package/esm/src/remult3/remult3.d.ts +132 -7
  41. package/esm/src/remult3/remult3.js +30 -0
  42. package/esm/src/remult3/repository-internals.d.ts +14 -0
  43. package/esm/src/remult3/repository-internals.js +7 -0
  44. package/esm/src/server-action.js +1 -1
  45. package/esm/src/sort.d.ts +3 -3
  46. package/esm/src/sort.js +36 -8
  47. package/graphql.js +10 -2
  48. package/index.d.ts +16 -3
  49. package/index.js +19 -3
  50. package/internals.d.ts +2 -1
  51. package/internals.js +3 -1
  52. package/package.json +1 -1
  53. package/remult-express.js +1 -1
  54. package/remult-knex/index.js +2 -1
  55. package/remult-mongo.js +2 -1
  56. package/server/JsonEntityFileStorage.js +1 -1
  57. package/server/expressBridge.js +1 -1
  58. package/src/CompoundIdField.d.ts +1 -1
  59. package/src/CompoundIdField.js +3 -0
  60. package/src/buildRestDataProvider.d.ts +1 -2
  61. package/src/column-interfaces.d.ts +19 -7
  62. package/src/column.d.ts +4 -18
  63. package/src/column.js +10 -56
  64. package/src/context.d.ts +1 -1
  65. package/src/context.js +5 -1
  66. package/src/data-interfaces.js +1 -2
  67. package/src/data-providers/array-entity-data-provider.d.ts +1 -1
  68. package/src/data-providers/array-entity-data-provider.js +5 -6
  69. package/src/data-providers/sql-database.js +2 -1
  70. package/src/data-providers/web-sql-data-provider.js +3 -3
  71. package/src/entity.d.ts +48 -17
  72. package/src/filter/filter-interfaces.d.ts +2 -16
  73. package/src/filter/filter-interfaces.js +101 -9
  74. package/src/live-query/LiveQueryClient.js +2 -1
  75. package/src/live-query/SubscriptionChannel.js +4 -3
  76. package/src/remult-proxy.js +43 -29
  77. package/src/remult3/Fields.d.ts +140 -21
  78. package/src/remult3/Fields.js +32 -32
  79. package/src/remult3/RepositoryImplementation.d.ts +10 -16
  80. package/src/remult3/RepositoryImplementation.js +286 -163
  81. package/src/remult3/entity.d.ts +1 -1
  82. package/src/remult3/entity.js +0 -1
  83. package/src/remult3/getEntityRef.d.ts +1 -1
  84. package/src/remult3/getEntityRef.js +2 -1
  85. package/src/remult3/relation-loader.js +4 -1
  86. package/src/remult3/remult3.d.ts +132 -7
  87. package/src/remult3/remult3.js +30 -0
  88. package/src/remult3/repository-internals.d.ts +14 -0
  89. package/src/remult3/repository-internals.js +11 -0
  90. package/src/server-action.js +1 -1
  91. package/src/sort.d.ts +3 -3
  92. package/src/sort.js +43 -11
@@ -1,6 +1,6 @@
1
1
  import type { ClassType } from '../classType';
2
- import type { Allowed, AllowedForInstance } from './context';
3
- import type { EntityMetadata, FieldRef, OmitEB } from './remult3/remult3';
2
+ import type { AllowedForInstance } from './context';
3
+ import type { EntityMetadata, FieldRef, LifecycleEvent, OmitEB } from './remult3/remult3';
4
4
  export interface FieldOptions<entityType = any, valueType = any> {
5
5
  /** A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
6
6
  * @example
@@ -11,7 +11,7 @@ export interface FieldOptions<entityType = any, valueType = any> {
11
11
  allowNull?: boolean;
12
12
  /** If this field data is included in the api.
13
13
  * @see [allowed](http://remult.dev/docs/allowed.html)*/
14
- includeInApi?: Allowed;
14
+ includeInApi?: AllowedForInstance<entityType>;
15
15
  /** If this field data can be updated in the api.
16
16
  * @see [allowed](http://remult.dev/docs/allowed.html)*/
17
17
  allowApiUpdate?: AllowedForInstance<entityType>;
@@ -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, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>;
40
+ saving?: (entity: entityType, e: LifecycleEvent<entityType>, fieldRef: FieldRef<entityType, valueType>) => 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.
@@ -69,8 +69,20 @@ export interface FieldOptions<entityType = any, valueType = any> {
69
69
  defaultValue?: (entity: entityType) => valueType | Promise<valueType>;
70
70
  /** The html input type for this field */
71
71
  inputType?: string;
72
- /** Determines if the referenced entity will be loaded immediately or on demand.
73
- * @see[Lazy loading of related entities](http://remult.dev/docs/lazy-loading-of-related-entities.html)
72
+ /**
73
+ * @deprecated The 'lazy' option is deprecated and will be removed in future versions.
74
+ * Use 'Relations.toOne' instead.
75
+ *
76
+ * Example usage:
77
+ * ```
78
+ * // Deprecated usage with 'lazy' option
79
+ * @Field(() => Customer, { lazy: true })
80
+ * customer?: Customer;
81
+ *
82
+ * // Preferred usage with 'Relations.toOne'
83
+ * @Relations.toOne(() => Customer)
84
+ * customer?: Customer;
85
+ * ```
74
86
  */
75
87
  lazy?: boolean;
76
88
  /** The value type for this field */
@@ -122,7 +134,7 @@ export interface FieldMetadata<valueType = any, entityType = any> {
122
134
  */
123
135
  displayValue(item: Partial<OmitEB<entityType>>): string;
124
136
  apiUpdateAllowed(item?: Partial<OmitEB<entityType>>): boolean;
125
- readonly includedInApi: boolean;
137
+ includedInApi(item?: Partial<OmitEB<entityType>>): boolean;
126
138
  /** Adapts the value for usage with html input
127
139
  * @example
128
140
  * @Fields.dateOnly()
package/src/column.d.ts CHANGED
@@ -1,32 +1,18 @@
1
- import type { FindOptions, idType, Repository } from './remult3/remult3';
2
- import type { RepositoryImplementation } from './remult3/RepositoryImplementation';
1
+ import type { idType, Repository } from './remult3/remult3';
3
2
  export declare function makeTitle(name: string): string;
4
3
  export declare class LookupColumn<T> {
5
4
  private repository;
6
- private isManyToOneRelation;
5
+ private isReferenceRelation;
7
6
  toJson(): any;
8
7
  setId(val: any): void;
9
8
  waitLoadOf(id: any): Promise<T>;
10
9
  get(id: any): any;
11
- storedItem: {
10
+ storedItem?: {
12
11
  item: T;
13
12
  };
14
13
  set(item: T): void;
15
14
  id: idType<T>;
16
- constructor(repository: RepositoryImplementation<T>, isManyToOneRelation: any);
15
+ constructor(repository: Repository<T>, isReferenceRelation: any);
17
16
  get item(): T;
18
17
  waitLoad(): Promise<T>;
19
18
  }
20
- export declare class OneToMany<T> {
21
- private provider;
22
- private settings?;
23
- constructor(provider: Repository<T>, settings?: {
24
- create?: (newItem: T) => void;
25
- } & FindOptions<T>);
26
- private _items;
27
- private _currentPromise;
28
- get lazyItems(): T[];
29
- load(): Promise<T[]>;
30
- private find;
31
- create(item?: Partial<T>): T;
32
- }
package/src/column.js CHANGED
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OneToMany = exports.LookupColumn = exports.makeTitle = void 0;
3
+ exports.LookupColumn = exports.makeTitle = void 0;
4
4
  var tslib_1 = require("tslib");
5
- var assign_1 = require("../assign");
6
- var __updateEntityBasedOnWhere_1 = require("./remult3/__updateEntityBasedOnWhere");
7
5
  var getEntityRef_1 = require("./remult3/getEntityRef");
6
+ var repository_internals_1 = require("./remult3/repository-internals");
8
7
  function makeTitle(name) {
9
8
  // insert a space before all caps
10
9
  return (name
@@ -16,9 +15,9 @@ function makeTitle(name) {
16
15
  }
17
16
  exports.makeTitle = makeTitle;
18
17
  var LookupColumn = /** @class */ (function () {
19
- function LookupColumn(repository, isManyToOneRelation) {
18
+ function LookupColumn(repository, isReferenceRelation) {
20
19
  this.repository = repository;
21
- this.isManyToOneRelation = isManyToOneRelation;
20
+ this.isReferenceRelation = isReferenceRelation;
22
21
  }
23
22
  LookupColumn.prototype.toJson = function () {
24
23
  if (!this.storedItem)
@@ -35,12 +34,14 @@ var LookupColumn = /** @class */ (function () {
35
34
  LookupColumn.prototype.waitLoadOf = function (id) {
36
35
  if (id === undefined || id === null)
37
36
  return null;
38
- return this.repository.getCachedByIdAsync(id, false);
37
+ return (0, repository_internals_1.getRepositoryInternals)(this.repository).getCachedByIdAsync(id, false);
39
38
  };
40
39
  LookupColumn.prototype.get = function (id) {
41
40
  if (id === undefined || id === null)
42
41
  return null;
43
- return this.repository.getCachedById(id, this.isManyToOneRelation);
42
+ if (this.isReferenceRelation && !this.storedItem)
43
+ return undefined;
44
+ return (0, repository_internals_1.getRepositoryInternals)(this.repository).getCachedById(id, this.isReferenceRelation);
44
45
  };
45
46
  LookupColumn.prototype.set = function (item) {
46
47
  this.storedItem = undefined;
@@ -49,8 +50,8 @@ var LookupColumn = /** @class */ (function () {
49
50
  this.id = item;
50
51
  else {
51
52
  var eo = (0, getEntityRef_1.getEntityRef)(item, false);
52
- if (eo) {
53
- this.repository.addToCache(item);
53
+ if (eo && !this.isReferenceRelation) {
54
+ (0, repository_internals_1.getRepositoryInternals)(this.repository).addToCache(item);
54
55
  this.id = eo.getId();
55
56
  }
56
57
  else {
@@ -85,50 +86,3 @@ var LookupColumn = /** @class */ (function () {
85
86
  return LookupColumn;
86
87
  }());
87
88
  exports.LookupColumn = LookupColumn;
88
- 9000;
89
- var OneToMany = /** @class */ (function () {
90
- function OneToMany(provider, settings) {
91
- this.provider = provider;
92
- this.settings = settings;
93
- }
94
- Object.defineProperty(OneToMany.prototype, "lazyItems", {
95
- get: function () {
96
- this.load();
97
- return this._items;
98
- },
99
- enumerable: false,
100
- configurable: true
101
- });
102
- OneToMany.prototype.load = function () {
103
- return tslib_1.__awaiter(this, void 0, void 0, function () {
104
- var _this = this;
105
- return tslib_1.__generator(this, function (_a) {
106
- if (this._currentPromise != null)
107
- return [2 /*return*/, this._currentPromise];
108
- if (this._items === undefined)
109
- this._items = [];
110
- return [2 /*return*/, (this._currentPromise = this.find().then(function (x) {
111
- var _a;
112
- _this._items.splice(0);
113
- (_a = _this._items).push.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(x), false));
114
- return _this._items;
115
- }))];
116
- });
117
- });
118
- };
119
- OneToMany.prototype.find = function () {
120
- return tslib_1.__awaiter(this, void 0, void 0, function () {
121
- return tslib_1.__generator(this, function (_a) {
122
- return [2 /*return*/, this.provider.find(this.settings)];
123
- });
124
- });
125
- };
126
- OneToMany.prototype.create = function (item) {
127
- var r = this.provider.create();
128
- (0, __updateEntityBasedOnWhere_1.__updateEntityBasedOnWhere)(this.provider.metadata, this.settings.where, r);
129
- (0, assign_1.assign)(r, item);
130
- return r;
131
- };
132
- return OneToMany;
133
- }());
134
- exports.OneToMany = OneToMany;
package/src/context.d.ts CHANGED
@@ -15,7 +15,7 @@ export declare class RemultAsyncLocalStorage {
15
15
  }
16
16
  type myAsyncLocalStorage<T> = {
17
17
  run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R;
18
- getStore(): T;
18
+ getStore(): T | undefined;
19
19
  };
20
20
  export declare function isBackend(): boolean;
21
21
  export declare class Remult {
package/src/context.js CHANGED
@@ -149,7 +149,7 @@ var Remult = /** @class */ (function () {
149
149
  if (typeof roles === 'boolean')
150
150
  return roles;
151
151
  if (typeof roles === 'string')
152
- if (((_c = (_b = this.user) === null || _b === void 0 ? void 0 : _b.roles) === null || _c === void 0 ? void 0 : _c.indexOf(roles.toString())) >= 0)
152
+ if ((_c = (_b = this.user) === null || _b === void 0 ? void 0 : _b.roles) === null || _c === void 0 ? void 0 : _c.includes(roles.toString()))
153
153
  return true;
154
154
  return false;
155
155
  };
@@ -182,6 +182,7 @@ var Remult = /** @class */ (function () {
182
182
  }
183
183
  else
184
184
  return this.isAllowed(allowed);
185
+ return undefined;
185
186
  };
186
187
  //@ts-ignore // type error of typescript regarding args that doesn't appear in my normal development
187
188
  /** Used to call a `backendMethod` using a specific `remult` object
@@ -449,3 +450,6 @@ var transactionLiveQueryPublisher = /** @class */ (function () {
449
450
  };
450
451
  return transactionLiveQueryPublisher;
451
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
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extractSort = void 0;
4
4
  var sort_1 = require("./sort");
5
5
  function extractSort(sort) {
6
- if (sort instanceof sort_1.Sort)
7
- return sort;
8
6
  if (sort instanceof Array) {
9
7
  var r_1 = new sort_1.Sort();
10
8
  sort.forEach(function (i) {
@@ -12,5 +10,6 @@ function extractSort(sort) {
12
10
  });
13
11
  return r_1;
14
12
  }
13
+ return sort;
15
14
  }
16
15
  exports.extractSort = extractSort;
@@ -4,8 +4,8 @@ import { Filter } from '../filter/filter-interfaces';
4
4
  import type { EntityFilter, EntityMetadata } from '../remult3/remult3';
5
5
  export declare class ArrayEntityDataProvider implements EntityDataProvider {
6
6
  private entity;
7
- private rows?;
8
7
  static rawFilter(filter: CustomArrayFilter): EntityFilter<any>;
8
+ private rows;
9
9
  constructor(entity: EntityMetadata, rows?: any[]);
10
10
  __names: EntityDbNamesBase;
11
11
  init(): Promise<EntityDbNamesBase>;
@@ -8,11 +8,10 @@ var filter_interfaces_1 = require("../filter/filter-interfaces");
8
8
  var ArrayEntityDataProvider = /** @class */ (function () {
9
9
  function ArrayEntityDataProvider(entity, rows) {
10
10
  this.entity = entity;
11
- this.rows = rows;
12
- if (!rows)
13
- rows = [];
14
- else {
15
- }
11
+ if (rows === undefined)
12
+ this.rows = [];
13
+ else
14
+ this.rows = rows;
16
15
  }
17
16
  ArrayEntityDataProvider.rawFilter = function (filter) {
18
17
  var _a;
@@ -141,7 +140,7 @@ var ArrayEntityDataProvider = /** @class */ (function () {
141
140
  return [2 /*return*/, rows.map(function (i) {
142
141
  return _this.translateFromJson(i, dbNames);
143
142
  })];
144
- return [2 /*return*/];
143
+ return [2 /*return*/, []];
145
144
  }
146
145
  });
147
146
  });
@@ -9,6 +9,7 @@ var remult_proxy_1 = require("../remult-proxy");
9
9
  var RepositoryImplementation_1 = require("../remult3/RepositoryImplementation");
10
10
  var sort_1 = require("../sort");
11
11
  var valueConverters_1 = require("../valueConverters");
12
+ var repository_internals_1 = require("../remult3/repository-internals");
12
13
  // @dynamic
13
14
  var SqlDatabase = /** @class */ (function () {
14
15
  function SqlDatabase(sql) {
@@ -159,7 +160,7 @@ var SqlDatabase = /** @class */ (function () {
159
160
  case 1:
160
161
  b = new (_a.apply(filter_consumer_bridge_to_sql_request_1.FilterConsumerBridgeToSqlRequest, _b.concat([_c.sent()])))();
161
162
  b._addWhere = false;
162
- return [4 /*yield*/, r.translateWhereToFilter(condition)];
163
+ return [4 /*yield*/, (0, repository_internals_1.getRepositoryInternals)(r).translateWhereToFilter(condition)];
163
164
  case 2: return [4 /*yield*/, (_c.sent()).__applyToConsumer(b)];
164
165
  case 3:
165
166
  _c.sent();
@@ -199,7 +199,7 @@ var WebSqlBridgeToSQLCommand = /** @class */ (function () {
199
199
  });
200
200
  t.executeSql(s, v, function (t1, r) { return resolve(new WebSqlBridgeToSQLQueryResult(r)); }, function (t2, err) {
201
201
  reject(err.message);
202
- return undefined;
202
+ return false;
203
203
  });
204
204
  });
205
205
  });
@@ -217,13 +217,13 @@ var WebSqlBridgeToSQLQueryResult = /** @class */ (function () {
217
217
  }
218
218
  WebSqlBridgeToSQLQueryResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
219
219
  if (this.rows.length == 0)
220
- return undefined;
220
+ throw Error('No rows');
221
221
  var i = 0;
222
222
  for (var m in this.rows[0]) {
223
223
  if (i++ == index)
224
224
  return m;
225
225
  }
226
- return undefined;
226
+ throw Error('index not found');
227
227
  };
228
228
  return WebSqlBridgeToSQLQueryResult;
229
229
  }());
package/src/entity.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Allowed, AllowedForInstance } from './context';
2
2
  import type { FieldMetadata } from './column-interfaces';
3
- import type { EntityFilter, EntityMetadata, EntityOrderBy, EntityRef, FieldsMetadata } from './remult3/remult3';
3
+ import type { EntityFilter, EntityIdFields, EntityMetadata, EntityOrderBy, EntityRef, FieldsMetadata, LifecycleEvent } from './remult3/remult3';
4
4
  export interface EntityOptions<entityType = any> {
5
5
  /**A human readable name for the entity */
6
6
  caption?: string;
@@ -55,20 +55,51 @@ export interface EntityOptions<entityType = any> {
55
55
  * this is the place to run logic that we want to run in any case before an entity is saved.
56
56
  * @example
57
57
  * @Entity<Task>("tasks", {
58
- * saving: async task => {
59
- * task.lastUpdated = new Date()
60
- * }
61
- *})
58
+ * saving: async (task, e) => {
59
+ * if (e.isNew) {
60
+ * task.createdAt = new Date(); // Set the creation date for new tasks.
61
+ * }
62
+ * task.lastUpdated = new Date(); // Update the last updated date.
63
+ * },
64
+ * })
65
+ * @param entity - The instance of the entity being saved.
66
+ * @param event - an @link LifeCycleEvent object
67
+ * @see [Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
62
68
  */
63
- saving?: (row: entityType, proceedWithoutSavingToDb: () => void) => Promise<any> | any;
64
- /** will be called after the Entity was saved to the data source. */
65
- saved?: (row: entityType) => Promise<any> | any;
66
- /** Will be called before an Entity is deleted. */
67
- deleting?: (row: entityType) => Promise<any> | any;
68
- /** Will be called after an Entity is deleted */
69
- deleted?: (row: entityType) => Promise<any> | any;
70
- /** Will be called when the entity is being validated, usually prior to the `saving` event */
71
- validation?: (row: entityType, ref: EntityRef<entityType>) => Promise<any> | any;
69
+ saving?: (entity: entityType, event: LifecycleEvent<entityType>) => Promise<any> | any;
70
+ /**
71
+ * A hook that runs after an entity has been successfully saved.
72
+ *
73
+ * @param entity The instance of the entity that was saved.
74
+ * @param event - an @link LifeCycleEvent object
75
+ * @see [Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
76
+ */
77
+ saved?: (entity: entityType, e: LifecycleEvent<entityType>) => Promise<any> | any;
78
+ /**
79
+ * A hook that runs before an entity is deleted.
80
+ *
81
+ * @param entity The instance of the entity being deleted.
82
+ * @param event - an @link LifeCycleEvent object
83
+ * @see [Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
84
+ */
85
+ deleting?: (entity: entityType, e: LifecycleEvent<entityType>) => Promise<any> | any;
86
+ /**
87
+ * A hook that runs after an entity has been successfully deleted.
88
+ *
89
+ * @param entity The instance of the entity that was deleted.
90
+ * @param event - an @link LifeCycleEvent object
91
+ * @see [Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
92
+ */
93
+ deleted?: (entity: entityType, e: LifecycleEvent<entityType>) => Promise<any> | any;
94
+ /**
95
+ * A hook that runs to perform validation checks on an entity before saving.
96
+ * This hook is also executed on the frontend.
97
+ *
98
+ * @param entity The instance of the entity being validated.
99
+ * @param event - an @link LifeCycleEvent object
100
+ * @see [Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
101
+ */
102
+ validation?: (entity: entityType, ref: LifecycleEvent<entityType>) => Promise<any> | any;
72
103
  /** The name of the table in the database that holds the data for this entity.
73
104
  * If no name is set, the `key` will be used instead.
74
105
  * @example
@@ -84,12 +115,12 @@ export interface EntityOptions<entityType = any> {
84
115
  /** An arrow function that identifies the `id` column to use for this entity
85
116
  * @example
86
117
  * //Single column id
87
- * @Entity<Products>("products", { id:p=>p.productCode })
118
+ * @Entity<Products>("products", { id: {productCode: true} })
88
119
  * @example
89
120
  * //Multiple columns id
90
- * @Entity<OrderDetails>("orderDetails", { id:od=> [od.orderId, od.productCode] })
121
+ * @Entity<OrderDetails>("orderDetails", { id:{ orderId:true, productCode:true} })
91
122
  */
92
- id?: (entity: FieldsMetadata<entityType>) => FieldMetadata | FieldMetadata[];
123
+ id?: EntityIdFields<entityType> | ((entity: FieldsMetadata<entityType>) => FieldMetadata | FieldMetadata[]);
93
124
  entityRefInit?: (ref: EntityRef<entityType>, row: entityType) => void;
94
125
  apiRequireId?: Allowed;
95
126
  }
@@ -2,8 +2,8 @@ import type { FieldMetadata } from '../column-interfaces';
2
2
  import type { Remult } from '../context';
3
3
  import type { EntityFilter, EntityMetadata } from '../remult3/remult3';
4
4
  export declare class Filter {
5
- private apply?;
6
- constructor(apply?: (add: FilterConsumer) => void);
5
+ private apply;
6
+ constructor(apply: (add: FilterConsumer) => void);
7
7
  __applyToConsumer(add: FilterConsumer): void;
8
8
  static resolve<entityType>(filter: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>)): Promise<EntityFilter<entityType>>;
9
9
  static createCustom<entityType>(rawFilterTranslator: (unused: never, r: Remult) => EntityFilter<entityType> | Promise<EntityFilter<entityType>>, key?: string): (() => EntityFilter<entityType>) & customFilterInfo<entityType>;
@@ -14,20 +14,6 @@ export declare class Filter {
14
14
  static entityFilterFromJson<T>(entityDefs: EntityMetadata<T>, packed: any): EntityFilter<T>;
15
15
  static translateCustomWhere<T>(r: Filter, entity: EntityMetadata<T>, remult: Remult): Promise<Filter>;
16
16
  }
17
- export declare class filterHelper {
18
- metadata: FieldMetadata;
19
- constructor(metadata: FieldMetadata);
20
- processVal(val: any): any;
21
- contains(val: string): Filter;
22
- isLessThan(val: any): Filter;
23
- isGreaterOrEqualTo(val: any): Filter;
24
- isNotIn(values: any[]): Filter;
25
- isDifferentFrom(val: any): Filter;
26
- isLessOrEqualTo(val: any): Filter;
27
- isGreaterThan(val: any): Filter;
28
- isEqualTo(val: any): Filter;
29
- isIn(val: any[]): Filter;
30
- }
31
17
  export interface FilterConsumer {
32
18
  or(orElements: Filter[]): any;
33
19
  isEqualTo(col: FieldMetadata, val: any): void;
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.__updateEntityBasedOnWhere = exports.buildFilterFromRequestParameters = exports.entityFilterToJson = exports.FilterSerializer = exports.customDatabaseFilterToken = exports.customUrlToken = exports.OrFilter = exports.AndFilter = exports.filterHelper = exports.Filter = void 0;
3
+ exports.__updateEntityBasedOnWhere = exports.buildFilterFromRequestParameters = exports.entityFilterToJson = exports.FilterSerializer = exports.customDatabaseFilterToken = exports.customUrlToken = exports.OrFilter = exports.AndFilter = exports.Filter = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var getEntityRef_1 = require("../remult3/getEntityRef");
6
+ var relationInfoMember_1 = require("../remult3/relationInfoMember");
6
7
  var Filter = /** @class */ (function () {
7
8
  function Filter(apply) {
8
9
  this.apply = apply;
9
- if (!this.apply) {
10
- this.apply = function () { };
11
- }
12
10
  }
13
11
  Filter.prototype.__applyToConsumer = function (add) {
14
12
  this.apply(add);
@@ -62,7 +60,14 @@ var Filter = /** @class */ (function () {
62
60
  result.push(new Filter(function (x) { return x.databaseCustom(fieldToFilter_1); }));
63
61
  }
64
62
  else {
65
- var fh = new filterHelper(entity.fields[key]);
63
+ var field = entity.fields[key];
64
+ var rel = (0, relationInfoMember_1.getRelationInfo)(field.options);
65
+ var op = field.options;
66
+ var fh = (rel === null || rel === void 0 ? void 0 : rel.type) === 'toOne'
67
+ ? op.fields
68
+ ? new manyToOneFilterHelper(field, entity.fields, op)
69
+ : new toOneFilterHelper(entity.fields[op.field])
70
+ : new filterHelper(field);
66
71
  var found = false;
67
72
  if (fieldToFilter_1 !== undefined && fieldToFilter_1 != null) {
68
73
  if (fieldToFilter_1.$id)
@@ -274,11 +279,97 @@ var filterHelper = /** @class */ (function () {
274
279
  filterHelper.prototype.isIn = function (val) {
275
280
  var _this = this;
276
281
  val = val.map(function (x) { return _this.processVal(x); });
282
+ if ((val === null || val === void 0 ? void 0 : val.length) == 1 && val[0] != undefined && val[0] !== null)
283
+ return new Filter(function (add) { return add.isEqualTo(_this.metadata, val[0]); });
277
284
  return new Filter(function (add) { return add.isIn(_this.metadata, val); });
278
285
  };
279
286
  return filterHelper;
280
287
  }());
281
- exports.filterHelper = filterHelper;
288
+ var toOneFilterHelper = /** @class */ (function (_super) {
289
+ tslib_1.__extends(toOneFilterHelper, _super);
290
+ function toOneFilterHelper() {
291
+ return _super !== null && _super.apply(this, arguments) || this;
292
+ }
293
+ toOneFilterHelper.prototype.processVal = function (val) {
294
+ if (!val)
295
+ return null;
296
+ if (typeof val === 'string' || typeof val === 'number')
297
+ return val;
298
+ return (0, getEntityRef_1.getEntityRef)(val).getId();
299
+ };
300
+ return toOneFilterHelper;
301
+ }(filterHelper));
302
+ var manyToOneFilterHelper = /** @class */ (function () {
303
+ function manyToOneFilterHelper(metadata, fields, relationOptions) {
304
+ this.metadata = metadata;
305
+ this.fields = fields;
306
+ this.relationOptions = relationOptions;
307
+ }
308
+ manyToOneFilterHelper.prototype.processVal = function (val) {
309
+ throw new Error('Invalid for Many To One Relation Field');
310
+ };
311
+ manyToOneFilterHelper.prototype.contains = function (val) {
312
+ throw new Error('Invalid for Many To One Relation Field');
313
+ };
314
+ manyToOneFilterHelper.prototype.isLessThan = function (val) {
315
+ throw new Error('Invalid for Many To One Relation Field');
316
+ };
317
+ manyToOneFilterHelper.prototype.isGreaterOrEqualTo = function (val) {
318
+ throw new Error('Invalid for Many To One Relation Field');
319
+ };
320
+ manyToOneFilterHelper.prototype.isNotIn = function (values) {
321
+ var _this = this;
322
+ return new Filter(function (add) {
323
+ values.forEach(function (v) { return _this.isDifferentFrom(v).__applyToConsumer(add); });
324
+ });
325
+ };
326
+ manyToOneFilterHelper.prototype.isDifferentFrom = function (val) {
327
+ var _this = this;
328
+ return new Filter(function (add) {
329
+ var or = [];
330
+ var _loop_2 = function (key) {
331
+ if (Object.prototype.hasOwnProperty.call(_this.relationOptions.fields, key)) {
332
+ var keyInMyEntity_1 = _this.relationOptions.fields[key];
333
+ or.push(new Filter(function (add) {
334
+ return new filterHelper(_this.fields.find(keyInMyEntity_1))
335
+ .isDifferentFrom(val[key])
336
+ .__applyToConsumer(add);
337
+ }));
338
+ }
339
+ };
340
+ for (var key in _this.relationOptions.fields) {
341
+ _loop_2(key);
342
+ }
343
+ add.or(or);
344
+ });
345
+ };
346
+ manyToOneFilterHelper.prototype.isLessOrEqualTo = function (val) {
347
+ throw new Error('Invalid for Many To One Relation Field');
348
+ };
349
+ manyToOneFilterHelper.prototype.isGreaterThan = function (val) {
350
+ throw new Error('Invalid for Many To One Relation Field');
351
+ };
352
+ manyToOneFilterHelper.prototype.isEqualTo = function (val) {
353
+ var _this = this;
354
+ return new Filter(function (add) {
355
+ for (var key in _this.relationOptions.fields) {
356
+ if (Object.prototype.hasOwnProperty.call(_this.relationOptions.fields, key)) {
357
+ var keyInMyEntity = _this.relationOptions.fields[key];
358
+ new filterHelper(_this.fields.find(keyInMyEntity))
359
+ .isEqualTo(val[key])
360
+ .__applyToConsumer(add);
361
+ }
362
+ }
363
+ });
364
+ };
365
+ manyToOneFilterHelper.prototype.isIn = function (val) {
366
+ var _this = this;
367
+ return new Filter(function (add) {
368
+ add.or(val.map(function (v) { return _this.isEqualTo(v); }));
369
+ });
370
+ };
371
+ return manyToOneFilterHelper;
372
+ }());
282
373
  var AndFilter = /** @class */ (function (_super) {
283
374
  tslib_1.__extends(AndFilter, _super);
284
375
  function AndFilter() {
@@ -470,7 +561,6 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
470
561
  }
471
562
  }
472
563
  }
473
- var c = new filterHelper(col);
474
564
  addFilter('', function (val) { return val; });
475
565
  addFilter('.gt', function (val) { return ({ $gt: val }); });
476
566
  addFilter('.gte', function (val) { return ({ $gte: val }); });
@@ -511,7 +601,7 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
511
601
  $and: or,
512
602
  });
513
603
  }
514
- var _loop_2 = function (key) {
604
+ var _loop_3 = function (key) {
515
605
  var element = entity.entityType[key];
516
606
  if (element &&
517
607
  element.rawFilterInfo &&
@@ -533,7 +623,7 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
533
623
  }
534
624
  };
535
625
  for (var key in entity.entityType) {
536
- _loop_2(key);
626
+ _loop_3(key);
537
627
  }
538
628
  if (where.length == 1)
539
629
  return where[0];
@@ -692,3 +782,5 @@ function __updateEntityBasedOnWhere(entityDefs, where, r) {
692
782
  }
693
783
  }
694
784
  exports.__updateEntityBasedOnWhere = __updateEntityBasedOnWhere;
785
+ // toRaw of default remult threw and exception
786
+ // toRaw didn't respect
@@ -4,6 +4,7 @@ exports.LiveQueryClient = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var buildRestDataProvider_1 = require("../buildRestDataProvider");
6
6
  var rest_data_provider_1 = require("../data-providers/rest-data-provider");
7
+ var repository_internals_1 = require("../remult3/repository-internals");
7
8
  var SubscriptionChannel_1 = require("./SubscriptionChannel");
8
9
  /* @internal*/
9
10
  var LiveQueryClient = /** @class */ (function () {
@@ -100,7 +101,7 @@ var LiveQueryClient = /** @class */ (function () {
100
101
  var onUnsubscribe = function () {
101
102
  alive = false;
102
103
  };
103
- this.runPromise(repo
104
+ this.runPromise((0, repository_internals_1.getRepositoryInternals)(repo)
104
105
  .buildEntityDataProviderFindOptions(options)
105
106
  .then(function (opts) {
106
107
  if (!alive)