remult 3.3.1 → 3.3.3

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/internals.js CHANGED
@@ -7,3 +7,5 @@ export { __updateEntityBasedOnWhere } from './src/filter/filter-interfaces.js';
7
7
  export const actionInfo = remultStatic.actionInfo;
8
8
  export { isOfType } from './src/isOfType.js';
9
9
  export { flags } from './src/remult3/remult3.js';
10
+ export { DataProviderPromiseWrapper } from './src/data-interfaces.js';
11
+ export { pagedQueryResult } from './src/remult3/pagedQueryResult.js';
@@ -117,7 +117,9 @@ class KnexEntityDataProvider {
117
117
  this.dp = dp;
118
118
  }
119
119
  async groupBy(options) {
120
- return groupByImpl(options, await dbNamesOf(this.entity, this.dp.wrapIdentifier), this.dp.createCommand(), false, (limit, offset) => ' limit ' + limit + ' offset ' + offset);
120
+ return groupByImpl(options, await dbNamesOf(this.entity, this.dp.wrapIdentifier), this.dp.createCommand(), false, (limit, offset) => this.knex.client.config.client?.includes('mssql')
121
+ ? ' offset ' + offset + ' rows fetch next ' + limit + ' rows only'
122
+ : ' limit ' + limit + ' offset ' + offset);
121
123
  }
122
124
  getEntityFrom(e) {
123
125
  if (this.entity.options.sqlExpression)
@@ -78,7 +78,9 @@ export class SqliteCoreDataProvider {
78
78
  addColumnSqlSyntax(x, dbName, isAlterTable) {
79
79
  let result = dbName;
80
80
  const nullNumber = x.allowNull ? '' : ' default 0 not null';
81
- if (x.valueType == Date)
81
+ if (x.valueConverter.fieldTypeInDb)
82
+ result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
83
+ else if (x.valueType == Date)
82
84
  result += ' integer';
83
85
  else if (x.valueType == Boolean)
84
86
  result += ' integer ' + nullNumber;
@@ -29,7 +29,9 @@ export function TestApiDataProvider(options) {
29
29
  if ((result?.statusCode ?? 200) >= 400) {
30
30
  throw { ...result?.data, status: result?.statusCode ?? 500 };
31
31
  }
32
- return result?.data;
32
+ return result?.data
33
+ ? JSON.parse(JSON.stringify(result.data))
34
+ : undefined;
33
35
  });
34
36
  });
35
37
  }
@@ -205,6 +205,8 @@ export class DataApi {
205
205
  }
206
206
  }
207
207
  const group = body?.groupBy?.filter((x) => this.repository.fields.find(x).includedInApi());
208
+ const min = body?.min?.filter((x) => this.repository.fields.find(x).includedInApi());
209
+ const max = body?.max?.filter((x) => this.repository.fields.find(x).includedInApi());
208
210
  let result = await this.repository.groupBy({
209
211
  where: findOptions.where,
210
212
  limit: findOptions.limit,
@@ -214,8 +216,8 @@ export class DataApi {
214
216
  group,
215
217
  sum: body?.sum?.filter((x) => this.repository.fields.find(x).includedInApi()),
216
218
  avg: body?.avg?.filter((x) => this.repository.fields.find(x).includedInApi()),
217
- min: body?.min?.filter((x) => this.repository.fields.find(x).includedInApi()),
218
- max: body?.max?.filter((x) => this.repository.fields.find(x).includedInApi()),
219
+ min,
220
+ max,
219
221
  distinctCount: body?.distinctCount?.filter((x) => this.repository.fields.find(x).includedInApi()),
220
222
  orderBy: orderBy,
221
223
  });
@@ -225,6 +227,17 @@ export class DataApi {
225
227
  x[f] = this.repository.fields.find(f).valueConverter.toJson(x[f]);
226
228
  }
227
229
  });
230
+ const minMax = { min, max };
231
+ for (const element of ['min', 'max']) {
232
+ if (minMax[element])
233
+ result.forEach((x) => {
234
+ for (const f of minMax[element]) {
235
+ x[f][element] = this.repository.fields
236
+ .find(f)
237
+ .valueConverter.toJson(x[f][element]);
238
+ }
239
+ });
240
+ }
228
241
  return result;
229
242
  }
230
243
  async getArrayImpl(request, body) {
@@ -142,6 +142,14 @@ export class RestEntityDataProvider {
142
142
  row[g.key] = g.valueConverter.fromJson(row[g.key]);
143
143
  }
144
144
  });
145
+ for (const element of ['min', 'max']) {
146
+ if (options?.[element])
147
+ result.forEach((row) => {
148
+ for (const f of options[element]) {
149
+ row[f.key][element] = f.valueConverter.fromJson(row[f.key][element]);
150
+ }
151
+ });
152
+ }
145
153
  return result;
146
154
  }
147
155
  buildAggregateOptions(options) {
@@ -581,6 +581,8 @@ export async function groupByImpl(options, e, r, orderByNullFirst, limitSyntax)
581
581
  processResultRow.push((sqlResult, theResult) => {
582
582
  if (turnToNumber)
583
583
  sqlResult = Number(sqlResult);
584
+ if (operator === 'max' || operator === 'min')
585
+ sqlResult = x.valueConverter.fromDb(sqlResult);
584
586
  theResult[x.key] = { ...theResult[x.key], [operator]: sqlResult };
585
587
  });
586
588
  }
@@ -0,0 +1,62 @@
1
+ export function pagedQueryResult(pageSize, getPage, count) {
2
+ const iterator = () => {
3
+ let pageNumber = 1;
4
+ let currentPage = [];
5
+ let itemIndex = 0;
6
+ return {
7
+ next: async () => {
8
+ if (itemIndex >= currentPage.length) {
9
+ currentPage = await getPage(pageNumber);
10
+ if (currentPage.length === 0) {
11
+ return { value: undefined, done: true };
12
+ }
13
+ pageNumber++;
14
+ itemIndex = 0;
15
+ }
16
+ const value = currentPage[itemIndex++];
17
+ return { value, done: false };
18
+ },
19
+ };
20
+ };
21
+ return {
22
+ count,
23
+ getPage,
24
+ forEach: async (what) => {
25
+ let i = 0;
26
+ const it = iterator();
27
+ while (true) {
28
+ const { value, done } = await it.next();
29
+ if (done)
30
+ break;
31
+ await what(value);
32
+ i++;
33
+ }
34
+ return i;
35
+ },
36
+ [Symbol.asyncIterator]: iterator,
37
+ paginator: async () => {
38
+ const createPaginator = async (pageNumber) => {
39
+ const items = await getPage(pageNumber);
40
+ const hasNextPage = items.length === pageSize;
41
+ const emptyPaginator = {
42
+ items: [],
43
+ hasNextPage: false,
44
+ count,
45
+ nextPage: async () => emptyPaginator,
46
+ };
47
+ return {
48
+ items,
49
+ hasNextPage,
50
+ count,
51
+ nextPage: async () => {
52
+ if (!hasNextPage) {
53
+ return emptyPaginator;
54
+ }
55
+ return createPaginator(pageNumber + 1);
56
+ },
57
+ };
58
+ };
59
+ return createPaginator(1);
60
+ },
61
+ };
62
+ }
@@ -90,6 +90,7 @@ export class ValueConverters {
90
90
  };
91
91
  static DateOnlyString = {
92
92
  ...ValueConverters.DateOnly,
93
+ fieldTypeInDb: 'char(8)',
93
94
  toDb: (d) => {
94
95
  if (d === zeroDate)
95
96
  return '00000000';
package/internals.d.ts CHANGED
@@ -15,3 +15,5 @@ export declare const actionInfo: {
15
15
  export { isOfType } from './src/isOfType.js';
16
16
  export type { ClassType } from './classType.js';
17
17
  export { flags } from './src/remult3/remult3.js';
18
+ export { DataProviderPromiseWrapper } from './src/data-interfaces.js';
19
+ export { pagedQueryResult } from './src/remult3/pagedQueryResult.js';
package/internals.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.flags = exports.isOfType = exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.fieldOptionsEnricher = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationFieldInfo = exports.getRelationInfo = exports.sqlRelationsFilter = exports.sqlRelations = void 0;
3
+ exports.pagedQueryResult = exports.DataProviderPromiseWrapper = exports.flags = exports.isOfType = exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.fieldOptionsEnricher = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationFieldInfo = exports.getRelationInfo = exports.sqlRelationsFilter = exports.sqlRelations = void 0;
4
4
  var remult_static_js_1 = require("./src/remult-static.js");
5
5
  var sql_relations_js_1 = require("./src/data-providers/sql-relations.js");
6
6
  Object.defineProperty(exports, "sqlRelations", { enumerable: true, get: function () { return sql_relations_js_1.sqlRelations; } });
@@ -22,3 +22,7 @@ var isOfType_js_1 = require("./src/isOfType.js");
22
22
  Object.defineProperty(exports, "isOfType", { enumerable: true, get: function () { return isOfType_js_1.isOfType; } });
23
23
  var remult3_js_1 = require("./src/remult3/remult3.js");
24
24
  Object.defineProperty(exports, "flags", { enumerable: true, get: function () { return remult3_js_1.flags; } });
25
+ var data_interfaces_js_1 = require("./src/data-interfaces.js");
26
+ Object.defineProperty(exports, "DataProviderPromiseWrapper", { enumerable: true, get: function () { return data_interfaces_js_1.DataProviderPromiseWrapper; } });
27
+ var pagedQueryResult_js_1 = require("./src/remult3/pagedQueryResult.js");
28
+ Object.defineProperty(exports, "pagedQueryResult", { enumerable: true, get: function () { return pagedQueryResult_js_1.pagedQueryResult; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.3.1",
3
+ "version": "3.3.3",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -204,6 +204,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
204
204
  KnexEntityDataProvider.prototype.groupBy = function (options) {
205
205
  return tslib_1.__awaiter(this, void 0, void 0, function () {
206
206
  var _a, _b;
207
+ var _this = this;
207
208
  return tslib_1.__generator(this, function (_c) {
208
209
  switch (_c.label) {
209
210
  case 0:
@@ -212,7 +213,12 @@ var KnexEntityDataProvider = /** @class */ (function () {
212
213
  return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_2.dbNamesOf)(this.entity, this.dp.wrapIdentifier)];
213
214
  case 1: return [2 /*return*/, _a.apply(void 0, _b.concat([_c.sent(), this.dp.createCommand(),
214
215
  false,
215
- function (limit, offset) { return ' limit ' + limit + ' offset ' + offset; }]))];
216
+ function (limit, offset) {
217
+ var _a;
218
+ return ((_a = _this.knex.client.config.client) === null || _a === void 0 ? void 0 : _a.includes('mssql'))
219
+ ? ' offset ' + offset + ' rows fetch next ' + limit + ' rows only'
220
+ : ' limit ' + limit + ' offset ' + offset;
221
+ }]))];
216
222
  }
217
223
  });
218
224
  });
@@ -199,7 +199,9 @@ var SqliteCoreDataProvider = /** @class */ (function () {
199
199
  SqliteCoreDataProvider.prototype.addColumnSqlSyntax = function (x, dbName, isAlterTable) {
200
200
  var result = dbName;
201
201
  var nullNumber = x.allowNull ? '' : ' default 0 not null';
202
- if (x.valueType == Date)
202
+ if (x.valueConverter.fieldTypeInDb)
203
+ result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
204
+ else if (x.valueType == Date)
203
205
  result += ' integer';
204
206
  else if (x.valueType == Boolean)
205
207
  result += ' integer ' + nullNumber;
@@ -55,7 +55,9 @@ function TestApiDataProvider(options) {
55
55
  if (((_c = result === null || result === void 0 ? void 0 : result.statusCode) !== null && _c !== void 0 ? _c : 200) >= 400) {
56
56
  throw tslib_1.__assign(tslib_1.__assign({}, result === null || result === void 0 ? void 0 : result.data), { status: (_d = result === null || result === void 0 ? void 0 : result.statusCode) !== null && _d !== void 0 ? _d : 500 });
57
57
  }
58
- return [2 /*return*/, result === null || result === void 0 ? void 0 : result.data];
58
+ return [2 /*return*/, (result === null || result === void 0 ? void 0 : result.data)
59
+ ? JSON.parse(JSON.stringify(result.data))
60
+ : undefined];
59
61
  }
60
62
  });
61
63
  }); })];
package/src/data-api.js CHANGED
@@ -365,19 +365,19 @@ var DataApi = /** @class */ (function () {
365
365
  };
366
366
  DataApi.prototype.groupBy = function (request, body) {
367
367
  return tslib_1.__awaiter(this, void 0, void 0, function () {
368
- var findOptions, orderBy, _a, _b, element, direction, group, result;
369
- var e_3, _c, _d, _e;
368
+ var findOptions, orderBy, _a, _b, element, direction, group, min, max, result, minMax, _loop_1, _c, _d, element;
369
+ var e_3, _e, _f, _g, e_4, _h;
370
370
  var _this = this;
371
- var _f, _g, _h, _j, _k, _l;
372
- return tslib_1.__generator(this, function (_m) {
373
- switch (_m.label) {
371
+ var _j, _k, _l, _m, _o, _p;
372
+ return tslib_1.__generator(this, function (_q) {
373
+ switch (_q.label) {
374
374
  case 0:
375
375
  if (!this.repository.metadata.apiReadAllowed) {
376
376
  throw new server_action_js_1.ForbiddenError();
377
377
  }
378
378
  return [4 /*yield*/, this.findOptionsFromRequest(request, body)];
379
379
  case 1:
380
- findOptions = _m.sent();
380
+ findOptions = _q.sent();
381
381
  orderBy = {};
382
382
  if (body === null || body === void 0 ? void 0 : body.orderBy) {
383
383
  try {
@@ -392,7 +392,7 @@ var DataApi = /** @class */ (function () {
392
392
  orderBy[remult3_js_1.GroupByCountMember] = direction;
393
393
  break;
394
394
  default:
395
- orderBy[element.field] = tslib_1.__assign(tslib_1.__assign({}, orderBy[element.field]), (_d = {}, _d[element.operation] = direction, _d));
395
+ orderBy[element.field] = tslib_1.__assign(tslib_1.__assign({}, orderBy[element.field]), (_f = {}, _f[element.operation] = direction, _f));
396
396
  break;
397
397
  }
398
398
  }
@@ -400,58 +400,95 @@ var DataApi = /** @class */ (function () {
400
400
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
401
401
  finally {
402
402
  try {
403
- if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
403
+ if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
404
404
  }
405
405
  finally { if (e_3) throw e_3.error; }
406
406
  }
407
407
  }
408
- group = (_f = body === null || body === void 0 ? void 0 : body.groupBy) === null || _f === void 0 ? void 0 : _f.filter(function (x) {
408
+ group = (_j = body === null || body === void 0 ? void 0 : body.groupBy) === null || _j === void 0 ? void 0 : _j.filter(function (x) {
409
409
  return _this.repository.fields.find(x).includedInApi();
410
410
  });
411
- return [4 /*yield*/, this.repository.groupBy((_e = {
411
+ min = (_k = body === null || body === void 0 ? void 0 : body.min) === null || _k === void 0 ? void 0 : _k.filter(function (x) {
412
+ return _this.repository.fields.find(x).includedInApi();
413
+ });
414
+ max = (_l = body === null || body === void 0 ? void 0 : body.max) === null || _l === void 0 ? void 0 : _l.filter(function (x) {
415
+ return _this.repository.fields.find(x).includedInApi();
416
+ });
417
+ return [4 /*yield*/, this.repository.groupBy((_g = {
412
418
  where: findOptions.where,
413
419
  limit: findOptions.limit,
414
420
  page: findOptions.page
415
421
  },
416
422
  //@ts-expect-error internal key
417
- _e[remult3_js_1.GroupByForApiKey] = true,
418
- _e.group = group,
419
- _e.sum = (_g = body === null || body === void 0 ? void 0 : body.sum) === null || _g === void 0 ? void 0 : _g.filter(function (x) {
420
- return _this.repository.fields.find(x).includedInApi();
421
- }),
422
- _e.avg = (_h = body === null || body === void 0 ? void 0 : body.avg) === null || _h === void 0 ? void 0 : _h.filter(function (x) {
423
+ _g[remult3_js_1.GroupByForApiKey] = true,
424
+ _g.group = group,
425
+ _g.sum = (_m = body === null || body === void 0 ? void 0 : body.sum) === null || _m === void 0 ? void 0 : _m.filter(function (x) {
423
426
  return _this.repository.fields.find(x).includedInApi();
424
427
  }),
425
- _e.min = (_j = body === null || body === void 0 ? void 0 : body.min) === null || _j === void 0 ? void 0 : _j.filter(function (x) {
428
+ _g.avg = (_o = body === null || body === void 0 ? void 0 : body.avg) === null || _o === void 0 ? void 0 : _o.filter(function (x) {
426
429
  return _this.repository.fields.find(x).includedInApi();
427
430
  }),
428
- _e.max = (_k = body === null || body === void 0 ? void 0 : body.max) === null || _k === void 0 ? void 0 : _k.filter(function (x) {
431
+ _g.min = min,
432
+ _g.max = max,
433
+ _g.distinctCount = (_p = body === null || body === void 0 ? void 0 : body.distinctCount) === null || _p === void 0 ? void 0 : _p.filter(function (x) {
429
434
  return _this.repository.fields.find(x).includedInApi();
430
435
  }),
431
- _e.distinctCount = (_l = body === null || body === void 0 ? void 0 : body.distinctCount) === null || _l === void 0 ? void 0 : _l.filter(function (x) {
432
- return _this.repository.fields.find(x).includedInApi();
433
- }),
434
- _e.orderBy = orderBy,
435
- _e))];
436
+ _g.orderBy = orderBy,
437
+ _g))];
436
438
  case 2:
437
- result = _m.sent();
439
+ result = _q.sent();
438
440
  if (group)
439
441
  result.forEach(function (x) {
440
- var e_4, _a;
442
+ var e_5, _a;
441
443
  try {
442
444
  for (var group_1 = tslib_1.__values(group), group_1_1 = group_1.next(); !group_1_1.done; group_1_1 = group_1.next()) {
443
445
  var f = group_1_1.value;
444
446
  x[f] = _this.repository.fields.find(f).valueConverter.toJson(x[f]);
445
447
  }
446
448
  }
447
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
449
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
448
450
  finally {
449
451
  try {
450
452
  if (group_1_1 && !group_1_1.done && (_a = group_1.return)) _a.call(group_1);
451
453
  }
452
- finally { if (e_4) throw e_4.error; }
454
+ finally { if (e_5) throw e_5.error; }
453
455
  }
454
456
  });
457
+ minMax = { min: min, max: max };
458
+ _loop_1 = function (element) {
459
+ if (minMax[element])
460
+ result.forEach(function (x) {
461
+ var e_6, _a;
462
+ try {
463
+ for (var _b = (e_6 = void 0, tslib_1.__values(minMax[element])), _c = _b.next(); !_c.done; _c = _b.next()) {
464
+ var f = _c.value;
465
+ x[f][element] = _this.repository.fields
466
+ .find(f)
467
+ .valueConverter.toJson(x[f][element]);
468
+ }
469
+ }
470
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
471
+ finally {
472
+ try {
473
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
474
+ }
475
+ finally { if (e_6) throw e_6.error; }
476
+ }
477
+ });
478
+ };
479
+ try {
480
+ for (_c = tslib_1.__values(['min', 'max']), _d = _c.next(); !_d.done; _d = _c.next()) {
481
+ element = _d.value;
482
+ _loop_1(element);
483
+ }
484
+ }
485
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
486
+ finally {
487
+ try {
488
+ if (_d && !_d.done && (_h = _c.return)) _h.call(_c);
489
+ }
490
+ finally { if (e_4) throw e_4.error; }
491
+ }
455
492
  return [2 /*return*/, result];
456
493
  }
457
494
  });
@@ -564,7 +601,7 @@ var DataApi = /** @class */ (function () {
564
601
  });
565
602
  };
566
603
  DataApi.prototype.includeNone = function () {
567
- var e_5, _a;
604
+ var e_7, _a;
568
605
  var include = {};
569
606
  try {
570
607
  for (var _b = tslib_1.__values(this.repository.metadata.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
@@ -574,12 +611,12 @@ var DataApi = /** @class */ (function () {
574
611
  }
575
612
  }
576
613
  }
577
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
614
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
578
615
  finally {
579
616
  try {
580
617
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
581
618
  }
582
- finally { if (e_5) throw e_5.error; }
619
+ finally { if (e_7) throw e_7.error; }
583
620
  }
584
621
  return include;
585
622
  };
@@ -800,8 +837,8 @@ var DataApi = /** @class */ (function () {
800
837
  case 1:
801
838
  where_2 = _a.sent();
802
839
  return [4 /*yield*/, (0, context_js_1.doTransaction)(this.remult, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
803
- var updated, _a, _b, _c, x, e_6_1;
804
- var _d, e_6, _e, _f;
840
+ var updated, _a, _b, _c, x, e_8_1;
841
+ var _d, e_8, _e, _f;
805
842
  return tslib_1.__generator(this, function (_g) {
806
843
  switch (_g.label) {
807
844
  case 0:
@@ -831,8 +868,8 @@ var DataApi = /** @class */ (function () {
831
868
  return [3 /*break*/, 2];
832
869
  case 6: return [3 /*break*/, 13];
833
870
  case 7:
834
- e_6_1 = _g.sent();
835
- e_6 = { error: e_6_1 };
871
+ e_8_1 = _g.sent();
872
+ e_8 = { error: e_8_1 };
836
873
  return [3 /*break*/, 13];
837
874
  case 8:
838
875
  _g.trys.push([8, , 11, 12]);
@@ -843,7 +880,7 @@ var DataApi = /** @class */ (function () {
843
880
  _g.label = 10;
844
881
  case 10: return [3 /*break*/, 12];
845
882
  case 11:
846
- if (e_6) throw e_6.error;
883
+ if (e_8) throw e_8.error;
847
884
  return [7 /*endfinally*/];
848
885
  case 12: return [7 /*endfinally*/];
849
886
  case 13:
@@ -979,8 +1016,8 @@ var DataApi = /** @class */ (function () {
979
1016
  if (!Array.isArray(body)) return [3 /*break*/, 2];
980
1017
  result_1 = [];
981
1018
  return [4 /*yield*/, (0, context_js_1.doTransaction)(this.remult, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
982
- var body_2, body_2_1, item, _a, _b, e_7_1;
983
- var e_7, _c;
1019
+ var body_2, body_2_1, item, _a, _b, e_9_1;
1020
+ var e_9, _c;
984
1021
  return tslib_1.__generator(this, function (_d) {
985
1022
  switch (_d.label) {
986
1023
  case 0:
@@ -1000,14 +1037,14 @@ var DataApi = /** @class */ (function () {
1000
1037
  return [3 /*break*/, 1];
1001
1038
  case 4: return [3 /*break*/, 7];
1002
1039
  case 5:
1003
- e_7_1 = _d.sent();
1004
- e_7 = { error: e_7_1 };
1040
+ e_9_1 = _d.sent();
1041
+ e_9 = { error: e_9_1 };
1005
1042
  return [3 /*break*/, 7];
1006
1043
  case 6:
1007
1044
  try {
1008
1045
  if (body_2_1 && !body_2_1.done && (_c = body_2.return)) _c.call(body_2);
1009
1046
  }
1010
- finally { if (e_7) throw e_7.error; }
1047
+ finally { if (e_9) throw e_9.error; }
1011
1048
  return [7 /*endfinally*/];
1012
1049
  case 7: return [2 /*return*/];
1013
1050
  }
@@ -151,9 +151,10 @@ var RestEntityDataProvider = /** @class */ (function () {
151
151
  };
152
152
  RestEntityDataProvider.prototype.groupBy = function (options) {
153
153
  return tslib_1.__awaiter(this, void 0, void 0, function () {
154
- var run, body, result;
155
- return tslib_1.__generator(this, function (_a) {
156
- switch (_a.label) {
154
+ var run, body, result, _loop_1, _a, _b, element;
155
+ var e_2, _c;
156
+ return tslib_1.__generator(this, function (_d) {
157
+ switch (_d.label) {
157
158
  case 0:
158
159
  run = this.buildFindRequest({
159
160
  where: options === null || options === void 0 ? void 0 : options.where,
@@ -163,24 +164,56 @@ var RestEntityDataProvider = /** @class */ (function () {
163
164
  body = this.buildAggregateOptions(options);
164
165
  return [4 /*yield*/, run('groupBy', Object.keys(body).length > 0 ? body : undefined)];
165
166
  case 1:
166
- result = _a.sent();
167
+ result = _d.sent();
167
168
  if (options === null || options === void 0 ? void 0 : options.group)
168
169
  result.forEach(function (row) {
169
- var e_2, _a;
170
+ var e_3, _a;
170
171
  try {
171
172
  for (var _b = tslib_1.__values(options.group), _c = _b.next(); !_c.done; _c = _b.next()) {
172
173
  var g = _c.value;
173
174
  row[g.key] = g.valueConverter.fromJson(row[g.key]);
174
175
  }
175
176
  }
176
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
177
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
177
178
  finally {
178
179
  try {
179
180
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
180
181
  }
181
- finally { if (e_2) throw e_2.error; }
182
+ finally { if (e_3) throw e_3.error; }
182
183
  }
183
184
  });
185
+ _loop_1 = function (element) {
186
+ if (options === null || options === void 0 ? void 0 : options[element])
187
+ result.forEach(function (row) {
188
+ var e_4, _a;
189
+ try {
190
+ for (var _b = (e_4 = void 0, tslib_1.__values(options[element])), _c = _b.next(); !_c.done; _c = _b.next()) {
191
+ var f = _c.value;
192
+ row[f.key][element] = f.valueConverter.fromJson(row[f.key][element]);
193
+ }
194
+ }
195
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
196
+ finally {
197
+ try {
198
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
199
+ }
200
+ finally { if (e_4) throw e_4.error; }
201
+ }
202
+ });
203
+ };
204
+ try {
205
+ for (_a = tslib_1.__values(['min', 'max']), _b = _a.next(); !_b.done; _b = _a.next()) {
206
+ element = _b.value;
207
+ _loop_1(element);
208
+ }
209
+ }
210
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
211
+ finally {
212
+ try {
213
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
214
+ }
215
+ finally { if (e_2) throw e_2.error; }
216
+ }
184
217
  return [2 /*return*/, result];
185
218
  }
186
219
  });
@@ -199,7 +232,7 @@ var RestEntityDataProvider = /** @class */ (function () {
199
232
  };
200
233
  };
201
234
  RestEntityDataProvider.prototype.translateFromJson = function (row) {
202
- var e_3, _a;
235
+ var e_5, _a;
203
236
  var result = {};
204
237
  try {
205
238
  for (var _b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
@@ -207,17 +240,17 @@ var RestEntityDataProvider = /** @class */ (function () {
207
240
  result[col.key] = col.valueConverter.fromJson(row[col.key]);
208
241
  }
209
242
  }
210
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
243
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
211
244
  finally {
212
245
  try {
213
246
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
214
247
  }
215
- finally { if (e_3) throw e_3.error; }
248
+ finally { if (e_5) throw e_5.error; }
216
249
  }
217
250
  return result;
218
251
  };
219
252
  RestEntityDataProvider.prototype.translateToJson = function (row) {
220
- var e_4, _a;
253
+ var e_6, _a;
221
254
  var result = {};
222
255
  try {
223
256
  for (var _b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
@@ -225,12 +258,12 @@ var RestEntityDataProvider = /** @class */ (function () {
225
258
  result[col.key] = col.valueConverter.toJson(row[col.key]);
226
259
  }
227
260
  }
228
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
261
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
229
262
  finally {
230
263
  try {
231
264
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
232
265
  }
233
- finally { if (e_4) throw e_4.error; }
266
+ finally { if (e_6) throw e_6.error; }
234
267
  }
235
268
  return result;
236
269
  };
@@ -389,7 +422,7 @@ var RestEntityDataProvider = /** @class */ (function () {
389
422
  .then(function (y) { return _this.translateFromJson(y); });
390
423
  };
391
424
  RestEntityDataProvider.prototype.toJsonOfIncludedKeys = function (data) {
392
- var e_5, _a;
425
+ var e_7, _a;
393
426
  var result = {};
394
427
  var keys = Object.keys(data);
395
428
  try {
@@ -399,12 +432,12 @@ var RestEntityDataProvider = /** @class */ (function () {
399
432
  result[col.key] = col.valueConverter.toJson(data[col.key]);
400
433
  }
401
434
  }
402
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
435
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
403
436
  finally {
404
437
  try {
405
438
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
406
439
  }
407
- finally { if (e_5) throw e_5.error; }
440
+ finally { if (e_7) throw e_7.error; }
408
441
  }
409
442
  return result;
410
443
  };
@@ -453,7 +486,7 @@ function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
453
486
  return false;
454
487
  }
455
488
  }
456
- var _loop_1 = function (key) {
489
+ var _loop_2 = function (key) {
457
490
  if (Object.prototype.hasOwnProperty.call(filter, key)) {
458
491
  var element = filter[key];
459
492
  if (Array.isArray(element)) {
@@ -469,7 +502,7 @@ function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
469
502
  }
470
503
  };
471
504
  for (var key in filter) {
472
- _loop_1(key);
505
+ _loop_2(key);
473
506
  }
474
507
  return true;
475
508
  }
@@ -912,6 +912,8 @@ function groupByImpl(options, e, r, orderByNullFirst, limitSyntax) {
912
912
  var _a;
913
913
  if (turnToNumber)
914
914
  sqlResult = Number(sqlResult);
915
+ if (operator === 'max' || operator === 'min')
916
+ sqlResult = x.valueConverter.fromDb(sqlResult);
915
917
  theResult[x.key] = tslib_1.__assign(tslib_1.__assign({}, theResult[x.key]), (_a = {}, _a[operator] = sqlResult, _a));
916
918
  });
917
919
  return [2 /*return*/];
@@ -0,0 +1,2 @@
1
+ import type { QueryResult } from './remult3.js';
2
+ export declare function pagedQueryResult<T>(pageSize: number, getPage: (pageNumber?: number) => Promise<T[]>, count: () => Promise<number>): QueryResult<T>;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pagedQueryResult = pagedQueryResult;
4
+ var tslib_1 = require("tslib");
5
+ function pagedQueryResult(pageSize, getPage, count) {
6
+ var _a;
7
+ var _this = this;
8
+ var iterator = function () {
9
+ var pageNumber = 1;
10
+ var currentPage = [];
11
+ var itemIndex = 0;
12
+ return {
13
+ next: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
14
+ var value;
15
+ return tslib_1.__generator(this, function (_a) {
16
+ switch (_a.label) {
17
+ case 0:
18
+ if (!(itemIndex >= currentPage.length)) return [3 /*break*/, 2];
19
+ return [4 /*yield*/, getPage(pageNumber)];
20
+ case 1:
21
+ currentPage = _a.sent();
22
+ if (currentPage.length === 0) {
23
+ return [2 /*return*/, { value: undefined, done: true }];
24
+ }
25
+ pageNumber++;
26
+ itemIndex = 0;
27
+ _a.label = 2;
28
+ case 2:
29
+ value = currentPage[itemIndex++];
30
+ return [2 /*return*/, { value: value, done: false }];
31
+ }
32
+ });
33
+ }); },
34
+ };
35
+ };
36
+ return _a = {
37
+ count: count,
38
+ getPage: getPage,
39
+ forEach: function (what) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
40
+ var i, it, _a, value, done;
41
+ return tslib_1.__generator(this, function (_b) {
42
+ switch (_b.label) {
43
+ case 0:
44
+ i = 0;
45
+ it = iterator();
46
+ _b.label = 1;
47
+ case 1:
48
+ if (!true) return [3 /*break*/, 4];
49
+ return [4 /*yield*/, it.next()];
50
+ case 2:
51
+ _a = _b.sent(), value = _a.value, done = _a.done;
52
+ if (done)
53
+ return [3 /*break*/, 4];
54
+ return [4 /*yield*/, what(value)];
55
+ case 3:
56
+ _b.sent();
57
+ i++;
58
+ return [3 /*break*/, 1];
59
+ case 4: return [2 /*return*/, i];
60
+ }
61
+ });
62
+ }); }
63
+ },
64
+ _a[Symbol.asyncIterator] = iterator,
65
+ _a.paginator = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
66
+ var createPaginator;
67
+ var _this = this;
68
+ return tslib_1.__generator(this, function (_a) {
69
+ createPaginator = function (pageNumber) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
70
+ var items, hasNextPage, emptyPaginator;
71
+ var _this = this;
72
+ return tslib_1.__generator(this, function (_a) {
73
+ switch (_a.label) {
74
+ case 0: return [4 /*yield*/, getPage(pageNumber)];
75
+ case 1:
76
+ items = _a.sent();
77
+ hasNextPage = items.length === pageSize;
78
+ emptyPaginator = {
79
+ items: [],
80
+ hasNextPage: false,
81
+ count: count,
82
+ nextPage: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
83
+ return [2 /*return*/, emptyPaginator];
84
+ }); }); },
85
+ };
86
+ return [2 /*return*/, {
87
+ items: items,
88
+ hasNextPage: hasNextPage,
89
+ count: count,
90
+ nextPage: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
91
+ return tslib_1.__generator(this, function (_a) {
92
+ if (!hasNextPage) {
93
+ return [2 /*return*/, emptyPaginator];
94
+ }
95
+ return [2 /*return*/, createPaginator(pageNumber + 1)];
96
+ });
97
+ }); },
98
+ }];
99
+ }
100
+ });
101
+ }); };
102
+ return [2 /*return*/, createPaginator(1)];
103
+ });
104
+ }); },
105
+ _a;
106
+ }
@@ -380,11 +380,11 @@ export type GroupByResult<entityType, groupByFields extends (keyof entityType)[]
380
380
  };
381
381
  } & {
382
382
  [K in minFields[number]]: {
383
- min: number;
383
+ min: entityType[K];
384
384
  };
385
385
  } & {
386
386
  [K in maxFields[number]]: {
387
- max: number;
387
+ max: entityType[K];
388
388
  };
389
389
  } & {
390
390
  [K in distinctCountFields[number]]: {
@@ -94,7 +94,7 @@ var ValueConverters = /** @class */ (function () {
94
94
  return value.toLocaleDateString(undefined);
95
95
  },
96
96
  };
97
- ValueConverters.DateOnlyString = tslib_1.__assign(tslib_1.__assign({}, ValueConverters.DateOnly), { toDb: function (d) {
97
+ ValueConverters.DateOnlyString = tslib_1.__assign(tslib_1.__assign({}, ValueConverters.DateOnly), { fieldTypeInDb: 'char(8)', toDb: function (d) {
98
98
  if (d === zeroDate)
99
99
  return '00000000';
100
100
  var val = ValueConverters.DateOnly.toJson(d);