remult 0.17.3 → 0.18.0

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 (163) hide show
  1. package/SseSubscriptionServer.d.ts +23 -0
  2. package/SseSubscriptionServer.js +143 -0
  3. package/ably.d.ts +13 -0
  4. package/ably.js +59 -0
  5. package/esm/SseSubscriptionServer.d.ts +23 -0
  6. package/esm/SseSubscriptionServer.js +102 -0
  7. package/esm/ably.d.ts +13 -0
  8. package/esm/ably.js +28 -0
  9. package/esm/index.d.ts +7 -4
  10. package/esm/index.js +4 -2
  11. package/esm/live-query/data-provider-live-query-storage.d.ts +23 -0
  12. package/esm/live-query/data-provider-live-query-storage.js +78 -0
  13. package/esm/myLog.d.ts +1 -0
  14. package/esm/myLog.js +5 -0
  15. package/esm/postgres/postgres-data-provider.d.ts +4 -2
  16. package/esm/postgres/postgres-data-provider.js +18 -6
  17. package/esm/postgres/schema-builder.d.ts +2 -1
  18. package/esm/postgres/schema-builder.js +49 -29
  19. package/esm/remult-knex/index.d.ts +10 -32
  20. package/esm/remult-knex/index.js +75 -51
  21. package/esm/remult-mongo.d.ts +9 -2
  22. package/esm/remult-mongo.js +24 -8
  23. package/esm/remult-next.d.ts +11 -0
  24. package/esm/remult-next.js +27 -0
  25. package/esm/server/core.d.ts +2 -0
  26. package/esm/server/core.js +2 -0
  27. package/esm/server/expressBridge.d.ts +19 -7
  28. package/esm/server/expressBridge.js +135 -31
  29. package/esm/server/index.d.ts +2 -1
  30. package/esm/server/index.js +2 -1
  31. package/esm/server/initDataProvider.d.ts +2 -0
  32. package/esm/server/initDataProvider.js +14 -0
  33. package/esm/src/buildRestDataProvider.d.ts +31 -0
  34. package/esm/src/buildRestDataProvider.js +110 -0
  35. package/esm/src/column-interfaces.d.ts +44 -8
  36. package/esm/src/column.d.ts +3 -3
  37. package/esm/src/context.d.ts +39 -36
  38. package/esm/src/context.js +87 -117
  39. package/esm/src/data-api.d.ts +9 -3
  40. package/esm/src/data-api.js +130 -63
  41. package/esm/src/data-interfaces.d.ts +5 -1
  42. package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
  43. package/esm/src/data-providers/array-entity-data-provider.js +2 -17
  44. package/esm/src/data-providers/rest-data-provider.d.ts +4 -3
  45. package/esm/src/data-providers/rest-data-provider.js +64 -23
  46. package/esm/src/data-providers/sql-database.d.ts +7 -3
  47. package/esm/src/data-providers/sql-database.js +60 -17
  48. package/esm/src/data-providers/web-sql-data-provider.d.ts +3 -0
  49. package/esm/src/data-providers/web-sql-data-provider.js +23 -9
  50. package/esm/src/entity.d.ts +2 -2
  51. package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +16 -16
  52. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +29 -21
  53. package/esm/src/filter/filter-interfaces.d.ts +5 -5
  54. package/esm/src/filter/filter-interfaces.js +31 -26
  55. package/esm/src/live-query/LiveQueryClient.d.ts +1 -0
  56. package/esm/src/live-query/LiveQueryClient.js +184 -0
  57. package/esm/src/live-query/SseSubscriptionClient.d.ts +5 -0
  58. package/esm/src/live-query/SseSubscriptionClient.js +86 -0
  59. package/esm/src/live-query/SubscriptionChannel.d.ts +41 -0
  60. package/esm/src/live-query/SubscriptionChannel.js +121 -0
  61. package/esm/src/live-query/SubscriptionServer.d.ts +38 -0
  62. package/esm/src/live-query/SubscriptionServer.js +108 -0
  63. package/esm/src/remult-proxy.d.ts +1 -1
  64. package/esm/src/remult-proxy.js +52 -7
  65. package/esm/src/remult3/RepositoryImplementation.d.ts +14 -5
  66. package/esm/src/remult3/RepositoryImplementation.js +124 -44
  67. package/esm/src/remult3/getId.d.ts +2 -0
  68. package/esm/src/remult3/getId.js +7 -0
  69. package/esm/src/remult3/remult3.d.ts +67 -10
  70. package/esm/src/remult3/remult3.js +1 -0
  71. package/esm/src/server-action.d.ts +5 -1
  72. package/esm/src/server-action.js +11 -12
  73. package/esm/src/shared-tests/db-tests-setup.d.ts +12 -5
  74. package/esm/src/shared-tests/db-tests-setup.js +14 -6
  75. package/esm/src/shared-tests/db-tests.db-tests.js +71 -10
  76. package/esm/src/sort.d.ts +1 -0
  77. package/esm/src/sort.js +18 -0
  78. package/esm/src/sql-command.d.ts +5 -2
  79. package/esm/src/tests/entityForCustomFilter.d.ts +6 -6
  80. package/esm/src/tests/entityForCustomFilter.js +20 -21
  81. package/esm/src/tests/frontend-database-tests-setup.spec.js +3 -4
  82. package/esm/src/tests/testHelper.spec.d.ts +3 -1
  83. package/esm/src/tests/testHelper.spec.js +63 -60
  84. package/esm/src/valueConverters.js +15 -7
  85. package/index.d.ts +7 -4
  86. package/index.js +7 -3
  87. package/live-query/data-provider-live-query-storage.d.ts +23 -0
  88. package/live-query/data-provider-live-query-storage.js +236 -0
  89. package/myLog.d.ts +1 -0
  90. package/myLog.js +20 -0
  91. package/package.json +18 -1
  92. package/postgres/postgres-data-provider.d.ts +4 -2
  93. package/postgres/postgres-data-provider.js +54 -39
  94. package/postgres/schema-builder.d.ts +2 -1
  95. package/postgres/schema-builder.js +118 -70
  96. package/remult-express.js +1 -1
  97. package/remult-knex/index.d.ts +10 -32
  98. package/remult-knex/index.js +134 -87
  99. package/remult-mongo.d.ts +9 -2
  100. package/remult-mongo.js +39 -7
  101. package/remult-next.d.ts +11 -0
  102. package/remult-next.js +73 -0
  103. package/server/JsonEntityFileStorage.js +2 -2
  104. package/server/core.d.ts +2 -0
  105. package/server/core.js +5 -1
  106. package/server/expressBridge.d.ts +19 -7
  107. package/server/expressBridge.js +283 -69
  108. package/server/index.d.ts +2 -1
  109. package/server/index.js +3 -1
  110. package/server/initDataProvider.d.ts +2 -0
  111. package/server/initDataProvider.js +26 -0
  112. package/src/buildRestDataProvider.d.ts +31 -0
  113. package/src/buildRestDataProvider.js +162 -0
  114. package/src/column-interfaces.d.ts +44 -8
  115. package/src/column.d.ts +3 -3
  116. package/src/context.d.ts +39 -36
  117. package/src/context.js +171 -166
  118. package/src/data-api.d.ts +9 -3
  119. package/src/data-api.js +233 -88
  120. package/src/data-interfaces.d.ts +5 -1
  121. package/src/data-providers/array-entity-data-provider.d.ts +1 -1
  122. package/src/data-providers/array-entity-data-provider.js +2 -17
  123. package/src/data-providers/rest-data-provider.d.ts +4 -3
  124. package/src/data-providers/rest-data-provider.js +105 -39
  125. package/src/data-providers/sql-database.d.ts +7 -3
  126. package/src/data-providers/sql-database.js +89 -16
  127. package/src/data-providers/web-sql-data-provider.d.ts +3 -0
  128. package/src/data-providers/web-sql-data-provider.js +56 -11
  129. package/src/entity.d.ts +2 -2
  130. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +16 -16
  131. package/src/filter/filter-consumer-bridge-to-sql-request.js +59 -50
  132. package/src/filter/filter-interfaces.d.ts +5 -5
  133. package/src/filter/filter-interfaces.js +31 -26
  134. package/src/live-query/LiveQueryClient.d.ts +1 -0
  135. package/src/live-query/LiveQueryClient.js +283 -0
  136. package/src/live-query/SseSubscriptionClient.d.ts +5 -0
  137. package/src/live-query/SseSubscriptionClient.js +150 -0
  138. package/src/live-query/SubscriptionChannel.d.ts +41 -0
  139. package/src/live-query/SubscriptionChannel.js +209 -0
  140. package/src/live-query/SubscriptionServer.d.ts +38 -0
  141. package/src/live-query/SubscriptionServer.js +258 -0
  142. package/src/remult-proxy.d.ts +1 -1
  143. package/src/remult-proxy.js +153 -8
  144. package/src/remult3/RepositoryImplementation.d.ts +14 -5
  145. package/src/remult3/RepositoryImplementation.js +200 -85
  146. package/src/remult3/getId.d.ts +2 -0
  147. package/src/remult3/getId.js +11 -0
  148. package/src/remult3/remult3.d.ts +67 -10
  149. package/src/remult3/remult3.js +1 -0
  150. package/src/server-action.d.ts +5 -1
  151. package/src/server-action.js +11 -11
  152. package/src/shared-tests/db-tests-setup.d.ts +12 -5
  153. package/src/shared-tests/db-tests-setup.js +17 -8
  154. package/src/shared-tests/db-tests.db-tests.js +140 -8
  155. package/src/sort.d.ts +1 -0
  156. package/src/sort.js +18 -0
  157. package/src/sql-command.d.ts +5 -2
  158. package/src/tests/entityForCustomFilter.d.ts +6 -6
  159. package/src/tests/entityForCustomFilter.js +30 -31
  160. package/src/tests/frontend-database-tests-setup.spec.js +5 -6
  161. package/src/tests/testHelper.spec.d.ts +3 -1
  162. package/src/tests/testHelper.spec.js +104 -100
  163. package/src/valueConverters.js +15 -7
@@ -1,7 +1,8 @@
1
1
  import { ClassType } from "../../classType";
2
2
  import { FieldMetadata } from "../column-interfaces";
3
3
  import { Unobserve } from "../context";
4
- import { EntityOptions as EntityOptions } from "../entity";
4
+ import { LiveQueryChange, SubscriptionListener, Unsubscribe } from "../live-query/SubscriptionChannel";
5
+ import { EntityOptions } from "../entity";
5
6
  import { SortSegment } from "../sort";
6
7
  import { entityEventListener } from "../__EntityValueProvider";
7
8
  export interface EntityRef<entityType> extends Subscribable {
@@ -15,7 +16,8 @@ export interface EntityRef<entityType> extends Subscribable {
15
16
  wasDeleted(): boolean;
16
17
  fields: FieldsRef<entityType>;
17
18
  error: string;
18
- getId(): any;
19
+ getId(): idType<entityType>;
20
+ getOriginalId(): idType<entityType>;
19
21
  repository: Repository<entityType>;
20
22
  metadata: EntityMetadata<entityType>;
21
23
  toApiJson(): any;
@@ -94,24 +96,70 @@ export interface IdMetadata<entityType = any> {
94
96
  isIdField(col: FieldMetadata): boolean;
95
97
  createIdInFilter(items: entityType[]): EntityFilter<entityType>;
96
98
  }
99
+ /** Metadata for an `Entity`, this metadata can be used in the user interface to provide a richer UI experience */
97
100
  export interface EntityMetadata<entityType = any> {
98
- readonly idMetadata: IdMetadata<entityType>;
101
+ /** The Entity's key also used as it's url */
99
102
  readonly key: string;
103
+ /** Metadata for the Entity's fields */
100
104
  readonly fields: FieldsMetadata<entityType>;
105
+ /** A human readable caption for the entity. Can be used to achieve a consistent caption for a field throughout the app
106
+ * @example
107
+ * <h1>Create a new item in {taskRepo.metadata.caption}</h1>
108
+ */
101
109
  readonly caption: string;
110
+ /** The options send to the `Entity`'s decorator */
102
111
  readonly options: EntityOptions;
112
+ /** The class type of the entity */
103
113
  readonly entityType: ClassType<entityType>;
114
+ /** true if the current user is allowed to update an entity instance
115
+ * @example
116
+ * const taskRepo = remult.repo(Task);
117
+ * if (taskRepo.metadata.apiUpdateAllowed){
118
+ * //Allow user to edit the entity
119
+ * }
120
+ */
104
121
  readonly apiUpdateAllowed: boolean;
122
+ /** true if the current user is allowed to read from entity
123
+ * @example
124
+ * const taskRepo = remult.repo(Task);
125
+ * if (taskRepo.metadata.apiReadAllowed){
126
+ * taskRepo.find()
127
+ * }
128
+ */
105
129
  readonly apiReadAllowed: boolean;
130
+ /** true if the current user is allowed to delete an entity instance
131
+ * @example
132
+ * const taskRepo = remult.repo(Task);
133
+ * if (taskRepo.metadata.apiDeleteAllowed){
134
+ * //display delete button
135
+ * }
136
+ */
106
137
  readonly apiDeleteAllowed: boolean;
138
+ /** true if the current user is allowed to create an entity instance
139
+ * @example
140
+ * const taskRepo = remult.repo(Task);
141
+ * if (taskRepo.metadata.apiInsertAllowed){
142
+ * //display insert button
143
+ * }
144
+ */
107
145
  readonly apiInsertAllowed: boolean;
146
+ /** Returns the dbName - based on it's `dbName` option and it's `sqlExpression` option */
108
147
  getDbName(): Promise<string>;
148
+ /** Metadata for the Entity's id */
149
+ readonly idMetadata: IdMetadata<entityType>;
109
150
  }
110
151
  export declare type OmitEB<T> = Omit<T, keyof import('./RepositoryImplementation').EntityBase>;
152
+ export declare type idType<entityType> = entityType extends {
153
+ id?: number;
154
+ } ? number : entityType extends {
155
+ id?: string;
156
+ } ? string : (string | number);
111
157
  /**used to perform CRUD operations on an `entityType` */
112
158
  export interface Repository<entityType> {
113
159
  /** returns a result array based on the provided options */
114
160
  find(options?: FindOptions<entityType>): Promise<entityType[]>;
161
+ /** returns a result array based on the provided options */
162
+ liveQuery(options?: FindOptions<entityType>): LiveQuery<entityType>;
115
163
  /** returns the first item that matchers the `where` condition
116
164
  * @example
117
165
  * await taskRepo.findFirst({ completed:false })
@@ -120,16 +168,12 @@ export interface Repository<entityType> {
120
168
  * */
121
169
  findFirst(where?: EntityFilter<entityType>, options?: FindFirstOptions<entityType>): Promise<entityType>;
122
170
  /** returns the items that matches the idm the result is cached unless specified differently in the `options` parameter */
123
- findId(id: entityType extends {
124
- id?: number;
125
- } ? number : entityType extends {
126
- id?: string;
127
- } ? string : (string | number), options?: FindFirstOptionsBase<entityType>): Promise<entityType>;
171
+ findId(id: idType<entityType>, options?: FindFirstOptionsBase<entityType>): Promise<entityType>;
128
172
  /** An alternative form of fetching data from the API server, which is intended for operating on large numbers of entity objects.
129
173
  *
130
174
  * It also has it's own paging mechanism that can be used n paging scenarios.
131
175
  *
132
- * The `query` method doesn't return an array (as the `find` method) and instead returns an `iteratable` `QueryResult` object
176
+ * The `query` method doesn't return an array (as the `find` method) and instead returns an `iterable` `QueryResult` object
133
177
  * which supports iterations using the JavaScript `for await` statement.
134
178
  * @example
135
179
  * for await (const task of taskRepo.query()) {
@@ -179,10 +223,21 @@ export interface Repository<entityType> {
179
223
  fromJson(x: any, isNew?: boolean): Promise<entityType>;
180
224
  /** returns an `entityRef` for an item returned by `create`, `find` etc... */
181
225
  getEntityRef(item: entityType): EntityRef<entityType>;
182
- /**The metadata for the `entity` */
226
+ /**The metadata for the `entity`
227
+ * @See [EntityMetadata](https://remult.dev/docs/ref_entitymetadata.html)
228
+ */
183
229
  metadata: EntityMetadata<entityType>;
184
230
  addEventListener(listener: entityEventListener<entityType>): Unobserve;
185
231
  }
232
+ export interface LiveQuery<entityType> {
233
+ subscribe(next: (info: LiveQueryChangeInfo<entityType>) => void): Unsubscribe;
234
+ subscribe(listener: Partial<SubscriptionListener<LiveQueryChangeInfo<entityType>>>): Unsubscribe;
235
+ }
236
+ export interface LiveQueryChangeInfo<entityType> {
237
+ items: entityType[];
238
+ changes: LiveQueryChange[];
239
+ applyChanges(prevState: entityType[]): entityType[];
240
+ }
186
241
  export interface FindOptions<entityType> extends FindOptionsBase<entityType> {
187
242
  /** Determines the number of rows returned by the request, on the browser the default is 100 rows
188
243
  * @example
@@ -224,6 +279,8 @@ export declare type EntityFilter<entityType> = {
224
279
  export declare type ValueFilter<valueType> = valueType | valueType[] | {
225
280
  $ne?: valueType | valueType[];
226
281
  "!="?: valueType | valueType[];
282
+ $in?: valueType[];
283
+ $nin?: valueType[];
227
284
  };
228
285
  export declare type ComparisonValueFilter<valueType> = ValueFilter<valueType> & {
229
286
  $gt?: valueType;
@@ -1,2 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ ;
@@ -19,6 +19,10 @@ export declare abstract class Action<inParam, outParam> implements ActionInterfa
19
19
  protected abstract execute(info: inParam, req: Remult, res: DataApiResponse): Promise<outParam>;
20
20
  __register(reg: (url: string, queue: boolean, allowed: AllowedForInstance<any>, what: ((data: any, req: Remult, res: DataApiResponse) => void)) => void): void;
21
21
  }
22
+ export declare class ForbiddenError extends Error {
23
+ constructor();
24
+ isForbiddenError: true;
25
+ }
22
26
  export declare class myServerAction extends Action<inArgs, result> {
23
27
  private types;
24
28
  private options;
@@ -38,7 +42,7 @@ export interface BackendMethodOptions<type> {
38
42
  export declare const actionInfo: {
39
43
  allActions: any[];
40
44
  runningOnServer: boolean;
41
- runActionWithoutBlockingUI: (what: () => Promise<any>) => Promise<any>;
45
+ runActionWithoutBlockingUI: <T>(what: () => Promise<T>) => Promise<T>;
42
46
  startBusyWithProgress: () => {
43
47
  progress: (percent: number) => void;
44
48
  close: () => void;
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.classBackendMethodsArray = exports.prepareReceivedArgs = exports.prepareArgsToSend = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.serverActionField = exports.actionInfo = exports.myServerAction = exports.Action = void 0;
3
+ exports.classBackendMethodsArray = exports.prepareReceivedArgs = exports.prepareArgsToSend = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.serverActionField = exports.actionInfo = exports.myServerAction = exports.ForbiddenError = exports.Action = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  require("reflect-metadata");
6
6
  var context_1 = require("./context");
7
+ var buildRestDataProvider_1 = require("./buildRestDataProvider");
7
8
  var sql_database_1 = require("./data-providers/sql-database");
8
9
  var remult3_1 = require("./remult3");
10
+ var remult_proxy_1 = require("./remult-proxy");
9
11
  var Action = /** @class */ (function () {
10
12
  function Action(actionUrl, queue, allowed) {
11
13
  this.actionUrl = actionUrl;
@@ -20,9 +22,9 @@ var Action = /** @class */ (function () {
20
22
  switch (_a.label) {
21
23
  case 0:
22
24
  if (baseUrl === undefined)
23
- baseUrl = remult3_1.RepositoryImplementation.defaultRemult.apiClient.url;
25
+ baseUrl = remult_proxy_1.remult.apiClient.url;
24
26
  if (!http)
25
- http = context_1.buildRestDataProvider(remult3_1.RepositoryImplementation.defaultRemult.apiClient.httpClient);
27
+ http = buildRestDataProvider_1.buildRestDataProvider(remult_proxy_1.remult.apiClient.httpClient);
26
28
  return [4 /*yield*/, http.post(baseUrl + '/' + this.actionUrl, pIn)];
27
29
  case 1:
28
30
  r = _a.sent();
@@ -109,6 +111,7 @@ var ForbiddenError = /** @class */ (function (_super) {
109
111
  }
110
112
  return ForbiddenError;
111
113
  }(Error));
114
+ exports.ForbiddenError = ForbiddenError;
112
115
  var myServerAction = /** @class */ (function (_super) {
113
116
  tslib_1.__extends(myServerAction, _super);
114
117
  function myServerAction(name, types, options, originalMethod) {
@@ -127,12 +130,11 @@ var myServerAction = /** @class */ (function (_super) {
127
130
  case 0:
128
131
  result = { data: {} };
129
132
  ds = remult.dataProvider;
130
- return [4 /*yield*/, ds.transaction(function (ds) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
133
+ return [4 /*yield*/, context_1.doTransaction(remult, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
131
134
  var _a, _b, err_2;
132
135
  return tslib_1.__generator(this, function (_c) {
133
136
  switch (_c.label) {
134
137
  case 0:
135
- remult.dataProvider = (ds);
136
138
  if (!remult.isAllowedForInstance(undefined, this.options.allowed))
137
139
  throw new ForbiddenError();
138
140
  _a = info;
@@ -256,7 +258,7 @@ function BackendMethod(options) {
256
258
  controllerOptions.key = c.repo(constructor).metadata.key;
257
259
  }
258
260
  reg(controllerOptions.key + '/' + key, options ? options.queue : false, options.allowed, function (d, req, res) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
259
- var allowed, remult_1, ds, r_1, err_3;
261
+ var allowed, remult_1, r_1, err_3;
260
262
  var _this = this;
261
263
  return tslib_1.__generator(this, function (_a) {
262
264
  switch (_a.label) {
@@ -267,16 +269,14 @@ function BackendMethod(options) {
267
269
  case 1:
268
270
  _a.trys.push([1, 3, , 4]);
269
271
  remult_1 = req;
270
- ds = remult_1.dataProvider;
271
- return [4 /*yield*/, ds.transaction(function (ds) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
272
+ return [4 /*yield*/, context_1.doTransaction(remult_1, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
272
273
  var _a, repo, y, rowHelper, rows, defs, err_4, y, controllerRef, err_5;
273
274
  var _b, _c, _d;
274
275
  return tslib_1.__generator(this, function (_e) {
275
276
  switch (_e.label) {
276
277
  case 0:
277
- remult_1.dataProvider = (ds);
278
278
  _a = d;
279
- return [4 /*yield*/, prepareReceivedArgs(types, d.args, remult_1, ds, res)];
279
+ return [4 /*yield*/, prepareReceivedArgs(types, d.args, remult_1, remult_1.dataProvider, res)];
280
280
  case 1:
281
281
  _a.args = _e.sent();
282
282
  if (!context_1.allEntities.includes(constructor)) return [3 /*break*/, 13];
@@ -330,7 +330,7 @@ function BackendMethod(options) {
330
330
  throw defs.catchSaveErrors(err_4);
331
331
  case 12: return [3 /*break*/, 20];
332
332
  case 13:
333
- y = new constructor(remult_1, ds);
333
+ y = new constructor(remult_1, remult_1.dataProvider);
334
334
  controllerRef = remult3_1.getControllerRef(y, remult_1);
335
335
  return [4 /*yield*/, controllerRef._updateEntityBasedOnApi(d.fields)];
336
336
  case 14:
@@ -5,15 +5,22 @@ import { Repository } from "../remult3";
5
5
  import { CategoriesForTesting } from "../tests/remult-3-entities";
6
6
  import { Status } from "../tests/testModel/models";
7
7
  export declare function itWithFocus(key: string, what: () => Promise<void>, focus?: boolean): void;
8
- export declare function testAll(key: string, what: dbTestWhatSignature, focus?: boolean): void;
9
- export declare function addDatabaseToTest(tester: dbTestMethodSignature): dbTestMethodSignature;
8
+ export declare function testAll(key: string, what: dbTestWhatSignature, focus?: boolean, options?: {
9
+ exclude?: string[];
10
+ }): void;
11
+ export declare function addDatabaseToTest(tester: dbTestMethodSignature, key?: string): dbTestMethodSignature;
10
12
  export declare function testInMemory(key: string, what: dbTestWhatSignature, focus?: boolean): void;
11
- export declare type dbTestWhatSignature = (db: {
13
+ export declare const TestDbs: {
14
+ restDataProvider: string;
15
+ };
16
+ export declare type dbTestWhatSignature = ((db: {
12
17
  db: DataProvider;
13
18
  remult: Remult;
14
19
  createEntity<entityType>(entity: ClassType<entityType>): Promise<Repository<entityType>>;
15
- }) => Promise<void>;
16
- export declare type dbTestMethodSignature = (key: string, what: dbTestWhatSignature, focus: boolean) => void;
20
+ }) => Promise<void>);
21
+ export declare type dbTestMethodSignature = ((key: string, what: dbTestWhatSignature, focus: boolean) => void) & {
22
+ key?: string;
23
+ };
17
24
  export declare function testAllDbs<T extends CategoriesForTesting>(key: string, doTest: (helper: {
18
25
  remult: Remult;
19
26
  createData: (doInsert?: (insert: (id: number, name: string, description?: string, status?: Status) => Promise<void>) => Promise<void>, entity?: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.testAllDbs = exports.testInMemory = exports.addDatabaseToTest = exports.testAll = exports.itWithFocus = void 0;
3
+ exports.testAllDbs = exports.TestDbs = exports.testInMemory = exports.addDatabaseToTest = exports.testAll = exports.itWithFocus = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var context_1 = require("../context");
6
6
  var in_memory_database_1 = require("../data-providers/in-memory-database");
@@ -14,13 +14,18 @@ function itWithFocus(key, what, focus) {
14
14
  it(key, what);
15
15
  }
16
16
  exports.itWithFocus = itWithFocus;
17
- function testAll(key, what, focus) {
17
+ function testAll(key, what, focus, options) {
18
18
  var e_1, _a;
19
19
  if (focus === void 0) { focus = false; }
20
+ function runTest(m) {
21
+ var _a;
22
+ return !((_a = options === null || options === void 0 ? void 0 : options.exclude) === null || _a === void 0 ? void 0 : _a.includes(m.key));
23
+ }
20
24
  try {
21
25
  for (var databasesTesters_1 = tslib_1.__values(databasesTesters), databasesTesters_1_1 = databasesTesters_1.next(); !databasesTesters_1_1.done; databasesTesters_1_1 = databasesTesters_1.next()) {
22
26
  var test_1 = databasesTesters_1_1.value;
23
- test_1(key, what, focus);
27
+ if (runTest(test_1))
28
+ test_1(key, what, focus);
24
29
  }
25
30
  }
26
31
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -31,14 +36,16 @@ function testAll(key, what, focus) {
31
36
  finally { if (e_1) throw e_1.error; }
32
37
  }
33
38
  loadedTests.push(function (x) {
34
- x(key, what, focus);
39
+ if (runTest(x))
40
+ x(key, what, focus);
35
41
  });
36
42
  }
37
43
  exports.testAll = testAll;
38
44
  var databasesTesters = [];
39
45
  var loadedTests = [];
40
- function addDatabaseToTest(tester) {
46
+ function addDatabaseToTest(tester, key) {
41
47
  var e_2, _a;
48
+ tester.key = key;
42
49
  try {
43
50
  for (var loadedTests_1 = tslib_1.__values(loadedTests), loadedTests_1_1 = loadedTests_1.next(); !loadedTests_1_1.done; loadedTests_1_1 = loadedTests_1.next()) {
44
51
  var test_2 = loadedTests_1_1.value;
@@ -60,14 +67,13 @@ function testInMemory(key, what, focus) {
60
67
  var _this = this;
61
68
  if (focus === void 0) { focus = false; }
62
69
  itWithFocus(key + " - in memory", function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
63
- var remult, db;
70
+ var db, remult;
64
71
  var _this = this;
65
72
  return tslib_1.__generator(this, function (_a) {
66
73
  switch (_a.label) {
67
74
  case 0:
68
- remult = new context_1.Remult();
69
75
  db = new in_memory_database_1.InMemoryDataProvider();
70
- remult.dataProvider = (db);
76
+ remult = new context_1.Remult(db);
71
77
  return [4 /*yield*/, what({ db: db, remult: remult, createEntity: function (x) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
72
78
  return [2 /*return*/, remult.repo(x)];
73
79
  }); }); } })];
@@ -79,6 +85,9 @@ function testInMemory(key, what, focus) {
79
85
  }); }, focus);
80
86
  }
81
87
  exports.testInMemory = testInMemory;
88
+ exports.TestDbs = {
89
+ restDataProvider: "restDataProvider"
90
+ };
82
91
  databasesTesters.push(testInMemory);
83
92
  function testAllDbs(key, doTest, focus) {
84
93
  if (focus === void 0) { focus = false; }
@@ -21,6 +21,9 @@ var entityWithValidationsOnColumn_1 = require("../tests/entityWithValidationsOnC
21
21
  var validators_1 = require("../validators");
22
22
  var models_1 = require("../tests/testModel/models");
23
23
  var id_entity_1 = require("../id-entity");
24
+ var DecoratorReplacer_1 = require("../remult3/DecoratorReplacer");
25
+ var data_provider_live_query_storage_1 = require("../../live-query/data-provider-live-query-storage");
26
+ var uuid_1 = require("uuid");
24
27
  db_tests_setup_1.testAll("what", function (_a) {
25
28
  var remult = _a.remult, createEntity = _a.createEntity;
26
29
  return tslib_1.__awaiter(void 0, void 0, void 0, function () {
@@ -346,7 +349,7 @@ db_tests_setup_1.testAll("put with validations on entity fails", function (_a) {
346
349
  });
347
350
  });
348
351
  });
349
- db_tests_setup_1.testAll("test date with null works", function (_a) {
352
+ db_tests_setup_1.testAll("test date only with null works", function (_a) {
350
353
  var createEntity = _a.createEntity;
351
354
  return tslib_1.__awaiter(void 0, void 0, void 0, function () {
352
355
  var repo, r, _b;
@@ -367,6 +370,60 @@ db_tests_setup_1.testAll("test date with null works", function (_a) {
367
370
  return [4 /*yield*/, repo.count({ d: null })];
368
371
  case 4:
369
372
  _b.apply(void 0, [_c.sent()]).toBe(1);
373
+ r.d = new Date(1976, 5, 16);
374
+ return [4 /*yield*/, r.save()];
375
+ case 5:
376
+ _c.sent();
377
+ expect(r.d.getFullYear()).toBe(1976);
378
+ return [4 /*yield*/, repo.findFirst()];
379
+ case 6:
380
+ r = _c.sent();
381
+ expect(r.d.getFullYear()).toBe(1976);
382
+ r.d = null;
383
+ return [4 /*yield*/, r.save()];
384
+ case 7:
385
+ _c.sent();
386
+ expect(r.d).toBeNull();
387
+ return [2 /*return*/];
388
+ }
389
+ });
390
+ });
391
+ }, false);
392
+ db_tests_setup_1.testAll("test date with null works", function (_a) {
393
+ var createEntity = _a.createEntity;
394
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
395
+ var repo, r, _b;
396
+ return tslib_1.__generator(this, function (_c) {
397
+ switch (_c.label) {
398
+ case 0: return [4 /*yield*/, createEntity(testDateWithNull)];
399
+ case 1:
400
+ repo = _c.sent();
401
+ r = repo.create({ id: 0 });
402
+ return [4 /*yield*/, r.save()];
403
+ case 2:
404
+ _c.sent();
405
+ return [4 /*yield*/, repo.findFirst()];
406
+ case 3:
407
+ r = _c.sent();
408
+ expect(r.fullDate).toBeNull("expected null after");
409
+ _b = expect;
410
+ return [4 /*yield*/, repo.count({ fullDate: null })];
411
+ case 4:
412
+ _b.apply(void 0, [_c.sent()]).toBe(1);
413
+ r.fullDate = new Date(1976, 5, 16);
414
+ return [4 /*yield*/, r.save()];
415
+ case 5:
416
+ _c.sent();
417
+ expect(r.fullDate.getFullYear()).toBe(1976);
418
+ return [4 /*yield*/, repo.findFirst()];
419
+ case 6:
420
+ r = _c.sent();
421
+ expect(r.fullDate.getFullYear()).toBe(1976);
422
+ r.fullDate = null;
423
+ return [4 /*yield*/, r.save()];
424
+ case 7:
425
+ _c.sent();
426
+ expect(r.fullDate).toBeNull();
370
427
  return [2 /*return*/];
371
428
  }
372
429
  });
@@ -393,6 +450,7 @@ var testDateWithNull = /** @class */ (function (_super) {
393
450
  function testDateWithNull() {
394
451
  var _this = _super !== null && _super.apply(this, arguments) || this;
395
452
  _this.id = 0;
453
+ _this.fullDate = null;
396
454
  return _this;
397
455
  }
398
456
  tslib_1.__decorate([
@@ -403,6 +461,10 @@ var testDateWithNull = /** @class */ (function (_super) {
403
461
  remult3_1.Fields.dateOnly({ allowNull: true }),
404
462
  tslib_1.__metadata("design:type", Date)
405
463
  ], testDateWithNull.prototype, "d", void 0);
464
+ tslib_1.__decorate([
465
+ remult3_1.Fields.date({ allowNull: true }),
466
+ tslib_1.__metadata("design:type", Date)
467
+ ], testDateWithNull.prototype, "fullDate", void 0);
406
468
  testDateWithNull = tslib_1.__decorate([
407
469
  remult3_1.Entity('testDateWithNull', { allowApiCrud: true })
408
470
  ], testDateWithNull);
@@ -582,7 +644,7 @@ db_tests_setup_1.testAll("test paging with complex object", function (_a) {
582
644
  }
583
645
  });
584
646
  });
585
- });
647
+ }, false);
586
648
  db_tests_setup_1.testAll("test paging with complex object_2", function (_a) {
587
649
  var remult = _a.remult, createEntity = _a.createEntity;
588
650
  return tslib_1.__awaiter(void 0, void 0, void 0, function () {
@@ -696,7 +758,7 @@ db_tests_setup_1.testAll("test that it works with inheritance", function (_a) {
696
758
  var c, id, _b, _c, _d;
697
759
  return tslib_1.__generator(this, function (_e) {
698
760
  switch (_e.label) {
699
- case 0: return [4 /*yield*/, createEntity(entityForCustomFilter_1.entityForCustomFilter1)];
761
+ case 0: return [4 /*yield*/, createEntity(entityForCustomFilter_1.entityForrawFilter1)];
700
762
  case 1:
701
763
  c = _e.sent();
702
764
  id = 0;
@@ -712,15 +774,15 @@ db_tests_setup_1.testAll("test that it works with inheritance", function (_a) {
712
774
  return [3 /*break*/, 2];
713
775
  case 5:
714
776
  _b = expect;
715
- return [4 /*yield*/, (c.count(entityForCustomFilter_1.entityForCustomFilter1.oneAndThree()))];
777
+ return [4 /*yield*/, (c.count(entityForCustomFilter_1.entityForrawFilter1.oneAndThree()))];
716
778
  case 6:
717
779
  _b.apply(void 0, [_e.sent()]).toBe(2);
718
780
  _c = expect;
719
- return [4 /*yield*/, (c.findFirst(entityForCustomFilter_1.entityForCustomFilter1.testNumericValue(2)))];
781
+ return [4 /*yield*/, (c.findFirst(entityForCustomFilter_1.entityForrawFilter1.testNumericValue(2)))];
720
782
  case 7:
721
783
  _c.apply(void 0, [(_e.sent()).id]).toBe(2);
722
784
  _d = expect;
723
- return [4 /*yield*/, (c.findFirst(entityForCustomFilter_1.entityForCustomFilter1.testObjectValue({ val: 2 })))];
785
+ return [4 /*yield*/, (c.findFirst(entityForCustomFilter_1.entityForrawFilter1.testObjectValue({ val: 2 })))];
724
786
  case 8:
725
787
  _d.apply(void 0, [(_e.sent()).id]).toBe(2);
726
788
  return [2 /*return*/];
@@ -1086,7 +1148,7 @@ db_tests_setup_1.testAllDbs("get array works with filter in body", function (_a)
1086
1148
  return undefined;
1087
1149
  }
1088
1150
  }, {
1089
- status_in: '[1, 2]'
1151
+ "status.in": '[1, 2]'
1090
1152
  })];
1091
1153
  case 2:
1092
1154
  _b.sent();
@@ -1366,7 +1428,7 @@ var testFilter = /** @class */ (function () {
1366
1428
  this.b = '';
1367
1429
  this.c = '';
1368
1430
  }
1369
- testFilter.search = filter_interfaces_1.Filter.createCustom(function (remult, str) { return ({
1431
+ testFilter.search = filter_interfaces_1.Filter.createCustom(function (str, remult) { return ({
1370
1432
  $and: [{
1371
1433
  $or: [
1372
1434
  { a: 'a' },
@@ -1627,3 +1689,73 @@ db_tests_setup_1.testAll("test transaction rollback", function (_a) {
1627
1689
  });
1628
1690
  });
1629
1691
  });
1692
+ db_tests_setup_1.testAll("test date", function (_a) {
1693
+ var createEntity = _a.createEntity;
1694
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
1695
+ var e, r, item;
1696
+ return tslib_1.__generator(this, function (_b) {
1697
+ switch (_b.label) {
1698
+ case 0:
1699
+ e = /** @class */ (function () {
1700
+ function class_4() {
1701
+ this.a = 0;
1702
+ this.d = new Date();
1703
+ }
1704
+ return class_4;
1705
+ }());
1706
+ DecoratorReplacer_1.describeClass(e, remult3_1.Entity("tdate", { allowApiCrud: true }), {
1707
+ a: remult3_1.Fields.number(),
1708
+ d: remult3_1.Fields.date()
1709
+ });
1710
+ return [4 /*yield*/, createEntity(e)];
1711
+ case 1:
1712
+ r = _b.sent();
1713
+ return [4 /*yield*/, r.insert({ a: 1, d: new Date(1976, 5, 16) })];
1714
+ case 2:
1715
+ _b.sent();
1716
+ return [4 /*yield*/, r.findFirst()];
1717
+ case 3:
1718
+ item = _b.sent();
1719
+ expect(item.d.getFullYear()).toBe(1976);
1720
+ return [2 /*return*/];
1721
+ }
1722
+ });
1723
+ });
1724
+ }, false);
1725
+ db_tests_setup_1.testAll("test live query storage", function (_a) {
1726
+ var db = _a.db, remult = _a.remult;
1727
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
1728
+ var x, id, _b;
1729
+ return tslib_1.__generator(this, function (_c) {
1730
+ switch (_c.label) {
1731
+ case 0:
1732
+ x = new data_provider_live_query_storage_1.DataProviderLiveQueryStorage(db);
1733
+ if (!db.ensureSchema) return [3 /*break*/, 2];
1734
+ return [4 /*yield*/, x.ensureSchema()];
1735
+ case 1:
1736
+ _c.sent();
1737
+ _c.label = 2;
1738
+ case 2:
1739
+ id = uuid_1.v4();
1740
+ return [4 /*yield*/, x.add({ id: id, entityKey: 'x', data: "noam" })];
1741
+ case 3:
1742
+ _c.sent();
1743
+ return [4 /*yield*/, x.forEach("x", function (args) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
1744
+ return tslib_1.__generator(this, function (_a) {
1745
+ expect(args.query.data).toBe("noam");
1746
+ return [2 /*return*/];
1747
+ });
1748
+ }); })];
1749
+ case 4:
1750
+ _c.sent();
1751
+ _b = expect;
1752
+ return [4 /*yield*/, x.keepAliveAndReturnUnknownQueryIds([id])];
1753
+ case 5:
1754
+ _b.apply(void 0, [(_c.sent())]).toEqual([]);
1755
+ return [2 /*return*/];
1756
+ }
1757
+ });
1758
+ });
1759
+ }, false, {
1760
+ exclude: [db_tests_setup_1.TestDbs.restDataProvider]
1761
+ });
package/src/sort.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare class Sort {
5
5
  constructor(...segments: SortSegment[]);
6
6
  Segments: SortSegment[];
7
7
  reverse(): Sort;
8
+ compare(a: any, b: any): number;
8
9
  static translateOrderByToSort<T>(entityDefs: EntityMetadata<T>, orderBy: EntityOrderBy<T>): Sort;
9
10
  static createUniqueSort<T>(entityMetadata: EntityMetadata<T>, orderBy: Sort): Sort;
10
11
  static createUniqueEntityOrderBy<T>(entityMetadata: EntityMetadata<T>, orderBy: EntityOrderBy<T>): EntityOrderBy<T>;
package/src/sort.js CHANGED
@@ -51,6 +51,24 @@ var Sort = /** @class */ (function () {
51
51
  }
52
52
  return r;
53
53
  };
54
+ Sort.prototype.compare = function (a, b) {
55
+ var r = 0;
56
+ for (var i = 0; i < this.Segments.length; i++) {
57
+ var seg = this.Segments[i];
58
+ var left = a[seg.field.key];
59
+ var right = b[seg.field.key];
60
+ if (left > right)
61
+ r = 1;
62
+ else if (left < right)
63
+ r = -1;
64
+ if (r != 0) {
65
+ if (seg.isDescending)
66
+ r *= -1;
67
+ return r;
68
+ }
69
+ }
70
+ return r;
71
+ };
54
72
  Sort.translateOrderByToSort = function (entityDefs, orderBy) {
55
73
  if (!orderBy)
56
74
  return undefined;
@@ -4,11 +4,14 @@ export interface SqlImplementation {
4
4
  createCommand(): SqlCommand;
5
5
  transaction(action: (sql: SqlImplementation) => Promise<void>): Promise<void>;
6
6
  entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
7
+ ensureSchema?(entities: EntityMetadata[]): Promise<void>;
7
8
  }
8
- export interface SqlCommand {
9
- addParameterAndReturnSqlToken(val: any): string;
9
+ export interface SqlCommand extends SqlCommandWithParameters {
10
10
  execute(sql: string): Promise<SqlResult>;
11
11
  }
12
+ export interface SqlCommandWithParameters {
13
+ addParameterAndReturnSqlToken(val: any): string;
14
+ }
12
15
  export interface SqlResult {
13
16
  rows: any[];
14
17
  getColumnKeyInResultForIndexInSelect(index: number): string;
@@ -1,16 +1,16 @@
1
1
  import { EntityBase, EntityFilter } from '../remult3';
2
- export declare class entityForCustomFilter extends EntityBase {
2
+ export declare class entityForrawFilter extends EntityBase {
3
3
  id: number;
4
4
  static filter: ((y: {
5
5
  oneAndThree?: boolean;
6
6
  dbOneOrThree?: boolean;
7
7
  two?: boolean;
8
- }) => EntityFilter<entityForCustomFilter>) & import("../filter/filter-interfaces").customFilterInfo<entityForCustomFilter>;
9
- static oneAndThree: (() => EntityFilter<entityForCustomFilter>) & import("../filter/filter-interfaces").customFilterInfo<entityForCustomFilter>;
10
- static testNumericValue: ((y: number) => EntityFilter<entityForCustomFilter>) & import("../filter/filter-interfaces").customFilterInfo<entityForCustomFilter>;
8
+ }) => EntityFilter<entityForrawFilter>) & import("../filter/filter-interfaces").rawFilterInfo<entityForrawFilter>;
9
+ static oneAndThree: (() => EntityFilter<entityForrawFilter>) & import("../filter/filter-interfaces").rawFilterInfo<entityForrawFilter>;
10
+ static testNumericValue: ((y: number) => EntityFilter<entityForrawFilter>) & import("../filter/filter-interfaces").rawFilterInfo<entityForrawFilter>;
11
11
  static testObjectValue: ((y: {
12
12
  val: number;
13
- }) => EntityFilter<entityForCustomFilter>) & import("../filter/filter-interfaces").customFilterInfo<entityForCustomFilter>;
13
+ }) => EntityFilter<entityForrawFilter>) & import("../filter/filter-interfaces").rawFilterInfo<entityForrawFilter>;
14
14
  }
15
- export declare class entityForCustomFilter1 extends entityForCustomFilter {
15
+ export declare class entityForrawFilter1 extends entityForrawFilter {
16
16
  }