remult 0.27.20-next.3 → 0.27.20

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/graphql.js CHANGED
@@ -315,7 +315,7 @@ export function remultGraphql(options) {
315
315
  value: getMetaType(meta),
316
316
  }, argErrorDetail, argClientMutationId);
317
317
  root[createResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
318
- await dApi.httpPost({
318
+ await dApi.post({
319
319
  ...response,
320
320
  created: (y) => {
321
321
  const orig = { ...y };
@@ -324,7 +324,7 @@ export function remultGraphql(options) {
324
324
  [toCamelCase(getMetaType(meta))]: y,
325
325
  });
326
326
  },
327
- }, { get: () => undefined }, arg1.input, undefined);
327
+ }, arg1.input);
328
328
  });
329
329
  resolversMutation[createResolverKey] = (origItem, args, req, gqlInfo) => root[createResolverKey](args, req, gqlInfo);
330
330
  }
@@ -266,9 +266,7 @@ class MongoEntityDataProvider {
266
266
  const { e, collection } = await this.collection();
267
267
  let f = new FilterConsumerBridgeToMongo(e);
268
268
  Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)).__applyToConsumer(f);
269
- await collection.deleteOne(await f.resolveWhere(), {
270
- session: this.session,
271
- });
269
+ collection.deleteOne(await f.resolveWhere(), { session: this.session });
272
270
  }
273
271
  async insert(data) {
274
272
  let { collection, e } = await this.collection();
@@ -258,7 +258,7 @@ export class RemultServerImplementation {
258
258
  if (this.options.logApiEndPoints)
259
259
  console.info('[remult] ' + myRoute);
260
260
  r.route(myRoute)
261
- .get(this.process(async (c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.serializeContext(c))))
261
+ .get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.serializeContext(c))))
262
262
  .put(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).updateManyThroughPutRequest(res, req, await this.coreOptions.getRequestBody(orig))))
263
263
  .delete(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).deleteMany(res, req, undefined)))
264
264
  .post(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).httpPost(res, req, await this.coreOptions.getRequestBody(orig), () => this.serializeContext(c))));
@@ -20,7 +20,7 @@ export class DataApi {
20
20
  case 'count':
21
21
  return this.count(res, req, undefined);
22
22
  case 'groupBy':
23
- return res.success(this.groupBy(req, undefined));
23
+ return this.groupBy(res, req, undefined);
24
24
  }
25
25
  return this.getArray(res, req, undefined);
26
26
  }
@@ -34,90 +34,31 @@ export class DataApi {
34
34
  };
35
35
  }
36
36
  }
37
- try {
38
- if (action?.startsWith(liveQueryAction)) {
39
- validateWhereInBody();
40
- return this.liveQuery(res, req, body, serializeContext, action.substring(liveQueryAction.length));
41
- }
42
- switch (action) {
43
- case 'get':
44
- validateWhereInBody();
45
- return this.getArray(res, req, body);
46
- case 'count':
47
- validateWhereInBody();
48
- return this.count(res, req, body);
49
- case 'groupBy':
50
- return res.success(await this.groupBy(req, body));
51
- case 'deleteMany':
52
- validateWhereInBody();
53
- return this.deleteMany(res, req, body);
54
- case 'updateMany':
55
- validateWhereInBody();
56
- return this.updateManyImplementation(res, req, body);
57
- case 'upsertMany':
58
- return this.upsertMany(res, req, body);
59
- case 'endLiveQuery':
60
- await this.remult.liveQueryStorage.remove(body.id);
61
- res.success('ok');
62
- return;
63
- case 'query':
64
- return res.success(await this.query(res, req, body));
65
- default:
66
- return res.created(await this.post(body));
67
- }
68
- }
69
- catch (err) {
70
- if (err.isForbiddenError)
71
- res.forbidden(err.message);
72
- else
73
- res.error(err, this.repository.metadata);
37
+ if (action?.startsWith(liveQueryAction)) {
38
+ validateWhereInBody();
39
+ return this.liveQuery(res, req, body, serializeContext, action.substring(liveQueryAction.length));
74
40
  }
75
- }
76
- async upsertMany(response, request, body) {
77
- return await doTransaction(this.remult, async () => {
78
- let result = [];
79
- for (const item of body) {
80
- let where = await this.buildWhere(request, { where: item.where });
81
- Filter.throwErrorIfFilterIsEmpty(where, 'upsert');
82
- let r = await this.repository.find({
83
- where,
84
- include: this.includeNone(),
85
- });
86
- if (r.length == 0) {
87
- result.push(await this.post({ ...item.where, ...item.set }));
88
- }
89
- else {
90
- if (item.set !== undefined) {
91
- result.push((await this.actualUpdate(r[0], item.set)).toApiJson());
92
- }
93
- else
94
- result.push(this.repository.getEntityRef(r[0]).toApiJson());
95
- }
96
- }
97
- response.success(result);
98
- });
99
- }
100
- async query(response, request, body) {
101
- if (!this.repository.metadata.apiReadAllowed) {
102
- response.forbidden();
103
- return;
104
- }
105
- try {
106
- let { aggregate, ...rest } = body;
107
- let [{ r }, [aggregates]] = await Promise.all([
108
- this.getArrayImpl(request, rest),
109
- this.groupBy(request, aggregate),
110
- ]);
111
- return {
112
- items: r,
113
- aggregates,
114
- };
115
- }
116
- catch (err) {
117
- if (err.isForbiddenError)
118
- response.forbidden();
119
- else
120
- response.error(err, this.repository.metadata);
41
+ switch (action) {
42
+ case 'get':
43
+ validateWhereInBody();
44
+ return this.getArray(res, req, body);
45
+ case 'count':
46
+ validateWhereInBody();
47
+ return this.count(res, req, body);
48
+ case 'groupBy':
49
+ return this.groupBy(res, req, body);
50
+ case 'deleteMany':
51
+ validateWhereInBody();
52
+ return this.deleteMany(res, req, body);
53
+ case 'updateMany':
54
+ validateWhereInBody();
55
+ return this.updateManyImplementation(res, req, body);
56
+ case 'endLiveQuery':
57
+ await this.remult.liveQueryStorage.remove(body.id);
58
+ res.success('ok');
59
+ return;
60
+ default:
61
+ return this.post(res, body);
121
62
  }
122
63
  }
123
64
  static defaultGetLimit = 0;
@@ -151,7 +92,6 @@ export class DataApi {
151
92
  for await (const x of this.repository.query({
152
93
  where,
153
94
  include: this.includeNone(),
154
- aggregate: undefined,
155
95
  })) {
156
96
  await this.actualDelete(x);
157
97
  deleted++;
@@ -163,7 +103,7 @@ export class DataApi {
163
103
  response.error(err, this.repository.metadata);
164
104
  }
165
105
  }
166
- async groupBy(request, body) {
106
+ async groupBy(response, request, body) {
167
107
  let findOptions = await this.findOptionsFromRequest(request, body);
168
108
  let orderBy = {};
169
109
  if (body?.orderBy) {
@@ -206,9 +146,9 @@ export class DataApi {
206
146
  x[f] = this.repository.fields.find(f).valueConverter.toJson(x[f]);
207
147
  }
208
148
  });
209
- return result;
149
+ response.success(result);
210
150
  }
211
- async getArrayImpl(request, body) {
151
+ async getArrayImpl(response, request, body) {
212
152
  let findOptions = await this.findOptionsFromRequest(request, body);
213
153
  const r = await this.repository.find(findOptions).then(async (r) => {
214
154
  return await Promise.all(r.map(async (y) => this.repository.getEntityRef(y).toApiJson()));
@@ -284,7 +224,7 @@ export class DataApi {
284
224
  return;
285
225
  }
286
226
  try {
287
- const { r } = await this.getArrayImpl(request, body);
227
+ const { r } = await this.getArrayImpl(response, request, body);
288
228
  response.success(r);
289
229
  }
290
230
  catch (err) {
@@ -300,7 +240,7 @@ export class DataApi {
300
240
  return;
301
241
  }
302
242
  try {
303
- const r = await this.getArrayImpl(request, body);
243
+ const r = await this.getArrayImpl(response, request, body);
304
244
  const data = {
305
245
  requestJson: await serializeContext(),
306
246
  findOptionsJson: findOptionsToJson(r.findOptions, this.repository.metadata),
@@ -405,7 +345,6 @@ export class DataApi {
405
345
  for await (const x of this.repository.query({
406
346
  where,
407
347
  include: this.includeNone(),
408
- aggregate: undefined,
409
348
  })) {
410
349
  await this.actualUpdate(x, body.set);
411
350
  updated++;
@@ -444,27 +383,35 @@ export class DataApi {
444
383
  response.deleted();
445
384
  });
446
385
  }
447
- async post(body) {
448
- const insert = async (what) => {
449
- let newr = this.repository.create();
450
- await this.repository.getEntityRef(newr)._updateEntityBasedOnApi(what);
451
- if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
452
- throw new ForbiddenError();
453
- }
454
- await this.repository.getEntityRef(newr).save();
455
- return this.repository.getEntityRef(newr).toApiJson();
456
- };
457
- if (Array.isArray(body)) {
458
- const result = [];
459
- await doTransaction(this.remult, async () => {
460
- for (const item of body) {
461
- result.push(await insert(item));
386
+ async post(response, body) {
387
+ try {
388
+ const insert = async (what) => {
389
+ let newr = this.repository.create();
390
+ await this.repository.getEntityRef(newr)._updateEntityBasedOnApi(what);
391
+ if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
392
+ throw new ForbiddenError();
462
393
  }
463
- });
464
- return result;
394
+ await this.repository.getEntityRef(newr).save();
395
+ return this.repository.getEntityRef(newr).toApiJson();
396
+ };
397
+ if (Array.isArray(body)) {
398
+ const result = [];
399
+ await doTransaction(this.remult, async () => {
400
+ for (const item of body) {
401
+ result.push(await insert(item));
402
+ }
403
+ });
404
+ response.created(result);
405
+ }
406
+ else
407
+ response.created(await insert(body));
408
+ }
409
+ catch (err) {
410
+ if (err.isForbiddenError)
411
+ response.forbidden(err.message);
412
+ else
413
+ response.error(err, this.repository.metadata);
465
414
  }
466
- else
467
- return await insert(body);
468
415
  }
469
416
  }
470
417
  export function determineSort(sortUrlParm, dirUrlParam) {
@@ -103,35 +103,13 @@ export class RestEntityDataProvider {
103
103
  this.http = http;
104
104
  this.entity = entity;
105
105
  }
106
- query(options, aggregateOptions) {
107
- const r = this.buildFindRequest(options);
108
- return r
109
- .run('query', {
110
- aggregate: this.buildAggregateOptions(aggregateOptions),
111
- })
112
- .then(({ items, aggregates }) => ({
113
- items: items.map((x) => this.translateFromJson(x)),
114
- aggregates,
115
- }));
116
- }
117
106
  async groupBy(options) {
118
107
  const { run } = this.buildFindRequest({
119
108
  where: options?.where,
120
109
  limit: options?.limit,
121
110
  page: options?.page,
122
111
  });
123
- const body = this.buildAggregateOptions(options);
124
- const result = await run('groupBy', Object.keys(body).length > 0 ? body : undefined);
125
- if (options?.group)
126
- result.forEach((row) => {
127
- for (const g of options.group) {
128
- row[g.key] = g.valueConverter.fromJson(row[g.key]);
129
- }
130
- });
131
- return result;
132
- }
133
- buildAggregateOptions(options) {
134
- return {
112
+ const body = {
135
113
  groupBy: options?.group?.map((x) => x.key),
136
114
  sum: options?.sum?.map((x) => x.key),
137
115
  avg: options?.avg?.map((x) => x.key),
@@ -140,6 +118,14 @@ export class RestEntityDataProvider {
140
118
  distinctCount: options?.distinctCount?.map((x) => x.key),
141
119
  orderBy: options?.orderBy?.map((x) => ({ ...x, field: x.field?.key })),
142
120
  };
121
+ const result = await run('groupBy', Object.keys(body).length > 0 ? body : undefined);
122
+ if (options?.group)
123
+ result.forEach((row) => {
124
+ for (const g of options.group) {
125
+ row[g.key] = g.valueConverter.fromJson(row[g.key]);
126
+ }
127
+ });
128
+ return result;
143
129
  }
144
130
  translateFromJson(row) {
145
131
  let result = {};
@@ -167,13 +153,6 @@ export class RestEntityDataProvider {
167
153
  const { run } = this.buildFindRequest({ where }, 'put');
168
154
  return run('updateMany', this.toJsonOfIncludedKeys(data)).then((r) => +r.updated);
169
155
  }
170
- async upsertMany(options) {
171
- const { run } = this.buildFindRequest(undefined);
172
- return run('upsertMany', options.map((x) => ({
173
- where: this.toJsonOfIncludedKeys(x.where),
174
- set: x.set !== undefined ? this.toJsonOfIncludedKeys(x.set) : undefined,
175
- }))).then((r) => r.map((x) => this.translateFromJson(x)));
176
- }
177
156
  find(options) {
178
157
  let { run } = this.buildFindRequest(options);
179
158
  return run().then((x) => x.map((y) => this.translateFromJson(y)));
@@ -161,18 +161,14 @@ export class RemultProxy {
161
161
  get metadata() {
162
162
  return remultStatic.remultFactory().repo(...args).metadata;
163
163
  },
164
- query: (options) => self
164
+ query: (...args2) => self
165
165
  .remultFactory()
166
166
  .repo(...args)
167
- .query(options),
167
+ .query(...args2),
168
168
  save: (args2) => self
169
169
  .remultFactory()
170
170
  .repo(...args)
171
171
  .save(args2),
172
- upsert: (args2) => self
173
- .remultFactory()
174
- .repo(...args)
175
- .upsert(args2),
176
172
  update: (a, b) => self
177
173
  .remultFactory()
178
174
  .repo(...args)
@@ -1,6 +1,6 @@
1
1
  import { LookupColumn, makeTitle } from '../column.js';
2
2
  import { CompoundIdField } from '../CompoundIdField.js';
3
- import { Remult, isBackend } from '../context.js';
3
+ import { Remult, isBackend, queryConfig } from '../context.js';
4
4
  import { Filter } from '../filter/filter-interfaces.js';
5
5
  import { Sort } from '../sort.js';
6
6
  import { GroupByForApiKey, } from './remult3.js';
@@ -18,7 +18,6 @@ import { remultStatic } from '../remult-static.js';
18
18
  import { Validators } from '../validators.js';
19
19
  import { addValidator } from './addValidator.js';
20
20
  import { isOfType } from '../isOfType.js';
21
- import { QueryResultImpl } from './QueryResultImpl.js';
22
21
  //import { remult } from "../remult-proxy";
23
22
  let classValidatorValidate = undefined;
24
23
  // import ("class-validator".toString())
@@ -133,23 +132,6 @@ export class RepositoryImplementation {
133
132
  return (await this.groupBy(options))[0];
134
133
  }
135
134
  async groupBy(options) {
136
- var dpOptions = await this.__buildGroupByOptions(options);
137
- const result = await this._edp.groupBy(dpOptions);
138
- //@ts-ignore
139
- if (!options?.[GroupByForApiKey] && options.group) {
140
- const loaderOptions = {
141
- include: {},
142
- };
143
- for (const key of options.group) {
144
- loaderOptions.include[key] = true;
145
- }
146
- const loader = new RelationLoader();
147
- await this._populateRelationsForFields(dpOptions.group, loaderOptions, result, loader);
148
- await loader.resolveAll();
149
- }
150
- return result;
151
- }
152
- async __buildGroupByOptions(options) {
153
135
  let findOptions = await this._buildEntityDataProviderFindOptions({
154
136
  ...options,
155
137
  });
@@ -203,7 +185,20 @@ export class RepositoryImplementation {
203
185
  }
204
186
  }
205
187
  }
206
- return dpOptions;
188
+ const result = await this._edp.groupBy(dpOptions);
189
+ //@ts-ignore
190
+ if (!options?.[GroupByForApiKey] && options.group) {
191
+ const loaderOptions = {
192
+ include: {},
193
+ };
194
+ for (const key of options.group) {
195
+ loaderOptions.include[key] = true;
196
+ }
197
+ const loader = new RelationLoader();
198
+ await this._populateRelationsForFields(dpOptions.group, loaderOptions, result, loader);
199
+ await loader.resolveAll();
200
+ }
201
+ return result;
207
202
  }
208
203
  _idCache = new Map();
209
204
  _getCachedById(id, doNotLoadIfNotFound) {
@@ -350,26 +345,14 @@ export class RepositoryImplementation {
350
345
  }
351
346
  }
352
347
  }
353
- __createDto(basedOn) {
354
- const ref = this.getEntityRef({
355
- ...basedOn,
356
- });
357
- const r = ref.copyDataToObject(false);
358
- const keys = Object.keys(basedOn);
359
- for (const element of this.fields) {
360
- if (element.dbReadOnly || !keys.includes(element.key))
361
- delete r[element.key];
362
- }
363
- return r;
364
- }
365
348
  async updateMany({ where, set, }) {
366
349
  Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
367
350
  if (this._dataProvider.isProxy) {
368
- return this._edp.updateMany(await this._translateWhereToFilter(where), this.__createDto({ ...set }));
351
+ return this._edp.updateMany(await this._translateWhereToFilter(where), set);
369
352
  }
370
353
  else {
371
354
  let updated = 0;
372
- for await (const item of this.query({ where, aggregate: undefined })) {
355
+ for await (const item of this.query({ where })) {
373
356
  assign(item, set);
374
357
  await getEntityRef(item).save();
375
358
  updated++;
@@ -418,40 +401,6 @@ export class RepositoryImplementation {
418
401
  return await ref.save();
419
402
  }
420
403
  }
421
- async upsert(options) {
422
- if (this._dataProvider.isProxy) {
423
- let rawRows = await this._edp.upsertMany((Array.isArray(options) ? options : [options]).map((x) => ({
424
- where: this.__createDto(x.where),
425
- set: x.set ? this.__createDto(x.set) : undefined,
426
- })));
427
- const loader = new RelationLoader();
428
- const result = await this._loadManyToOneForManyRows(rawRows, {}, loader);
429
- await loader.resolveAll();
430
- if (Array.isArray(options))
431
- return result;
432
- else
433
- return result[0];
434
- }
435
- if (Array.isArray(options)) {
436
- return promiseAll(options, (x) => this.upsert(x));
437
- }
438
- let op = options;
439
- var row = await this.findFirst(op.where, { createIfNotFound: true });
440
- var ref = getEntityRef(row, false);
441
- if (ref.isNew()) {
442
- if (op.set) {
443
- assign(row, op.set);
444
- }
445
- return await ref.save();
446
- }
447
- else {
448
- if (op.set) {
449
- assign(row, op.set);
450
- return await ref.save();
451
- }
452
- return row;
453
- }
454
- }
455
404
  _getRefForExistingRow(entity, id) {
456
405
  let ref = getEntityRef(entity, false);
457
406
  if (!ref) {
@@ -516,7 +465,7 @@ export class RepositoryImplementation {
516
465
  },
517
466
  };
518
467
  }
519
- async _rawFind(options, skipOrderByAndLimit = false, loader, actualFind) {
468
+ async _rawFind(options, skipOrderByAndLimit = false, loader) {
520
469
  if (!options)
521
470
  options = {};
522
471
  if (this._defaultFindOptions) {
@@ -528,13 +477,13 @@ export class RepositoryImplementation {
528
477
  delete opt.limit;
529
478
  }
530
479
  Remult.onFind(this._info, options);
531
- const rawRows = await actualFind(opt);
480
+ const rawRows = await this._edp.find(opt);
532
481
  let result = await this._loadManyToOneForManyRows(rawRows, options, loader);
533
482
  return result;
534
483
  }
535
484
  async find(options, skipOrderByAndLimit = false) {
536
485
  const loader = new RelationLoader();
537
- const result = await this._rawFind(options, skipOrderByAndLimit, loader, (x) => this._edp.find(x));
486
+ const result = await this._rawFind(options, skipOrderByAndLimit, loader);
538
487
  await loader.resolveAll();
539
488
  return result;
540
489
  }
@@ -629,7 +578,7 @@ export class RepositoryImplementation {
629
578
  loader
630
579
  .load({
631
580
  entityType,
632
- find: (options) => toRepo._rawFind(options, false, loader, (o) => toRepo._edp.find(o)),
581
+ find: (options) => toRepo._rawFind(options, false, loader),
633
582
  metadata: toRepo.metadata,
634
583
  }, findOptions)
635
584
  .then((result) => {
@@ -780,7 +729,7 @@ export class RepositoryImplementation {
780
729
  }
781
730
  else {
782
731
  let deleted = 0;
783
- for await (const item of this.query({ where, aggregate: undefined })) {
732
+ for await (const item of this.query({ where })) {
784
733
  await getEntityRef(item).delete();
785
734
  deleted++;
786
735
  }
@@ -1506,9 +1455,11 @@ export class rowHelperImplementation extends rowHelperBase {
1506
1455
  await this.__validateEntity();
1507
1456
  this.__assertValidity();
1508
1457
  let d = this.copyDataToObject(this.isNew());
1458
+ let ignoreKeys = [];
1509
1459
  for (const field of this.metadata.fields) {
1510
1460
  if (field.dbReadOnly) {
1511
1461
  d[field.key] = undefined;
1462
+ ignoreKeys.push(field.key);
1512
1463
  let f = this.fields.find(field);
1513
1464
  f.value = f.originalValue;
1514
1465
  }
@@ -2429,6 +2380,116 @@ export class ControllerBase {
2429
2380
  return getControllerRef(this, this.remult);
2430
2381
  }
2431
2382
  }
2383
+ class QueryResultImpl {
2384
+ options;
2385
+ repo;
2386
+ constructor(options, repo) {
2387
+ this.options = options;
2388
+ this.repo = repo;
2389
+ if (!this.options)
2390
+ this.options = {};
2391
+ if (!this.options.pageSize) {
2392
+ this.options.pageSize = queryConfig.defaultPageSize;
2393
+ }
2394
+ }
2395
+ _count = undefined;
2396
+ async getPage(page) {
2397
+ if ((page ?? 0) < 1)
2398
+ page = 1;
2399
+ return this.repo.find({
2400
+ where: this.options.where,
2401
+ orderBy: this.options.orderBy,
2402
+ limit: this.options.pageSize,
2403
+ page: page,
2404
+ load: this.options.load,
2405
+ include: this.options.include,
2406
+ });
2407
+ }
2408
+ async count() {
2409
+ if (this._count === undefined)
2410
+ this._count = await this.repo.count(this.options.where);
2411
+ return this._count;
2412
+ }
2413
+ async forEach(what) {
2414
+ let i = 0;
2415
+ for await (const x of this) {
2416
+ await what(x);
2417
+ i++;
2418
+ }
2419
+ return i;
2420
+ }
2421
+ async paginator(pNextPageFilter) {
2422
+ this.options.orderBy = Sort.createUniqueEntityOrderBy(this.repo.metadata, this.options.orderBy);
2423
+ let items = await this.repo.find({
2424
+ where: {
2425
+ $and: [this.options.where, pNextPageFilter],
2426
+ },
2427
+ orderBy: this.options.orderBy,
2428
+ limit: this.options.pageSize,
2429
+ load: this.options.load,
2430
+ include: this.options.include,
2431
+ });
2432
+ let nextPage = () => {
2433
+ throw new Error('no more pages');
2434
+ };
2435
+ let hasNextPage = items.length == this.options.pageSize;
2436
+ if (hasNextPage) {
2437
+ let nextPageFilter = await this.repo._createAfterFilter(this.options.orderBy, items[items.length - 1]);
2438
+ nextPage = () => this.paginator(nextPageFilter);
2439
+ }
2440
+ return {
2441
+ count: () => this.count(),
2442
+ hasNextPage,
2443
+ items,
2444
+ nextPage,
2445
+ };
2446
+ }
2447
+ [Symbol.asyncIterator]() {
2448
+ if (!this.options.where) {
2449
+ this.options.where = {};
2450
+ }
2451
+ let ob = this.options.orderBy;
2452
+ this.options.orderBy = Sort.createUniqueEntityOrderBy(this.repo.metadata, ob);
2453
+ let itemIndex = -1;
2454
+ let currentPage = undefined;
2455
+ let itStrategy;
2456
+ let j = 0;
2457
+ itStrategy = async () => {
2458
+ if (this.options.progress) {
2459
+ this.options.progress.progress(j++ / (await this.count()));
2460
+ }
2461
+ if (currentPage === undefined || itemIndex == currentPage.items.length) {
2462
+ if (currentPage && !currentPage.hasNextPage)
2463
+ return { value: undefined, done: true };
2464
+ let prev = currentPage;
2465
+ if (currentPage)
2466
+ currentPage = await currentPage.nextPage();
2467
+ else
2468
+ currentPage = await this.paginator();
2469
+ itemIndex = 0;
2470
+ if (currentPage.items.length == 0) {
2471
+ return { value: undefined, done: true };
2472
+ }
2473
+ else {
2474
+ if (prev?.items.length ?? 0 > 0) {
2475
+ if (this.repo.getEntityRef(prev.items[0]).getId() ==
2476
+ this.repo.getEntityRef(currentPage.items[0]).getId())
2477
+ throw new Error('pagination failure, returned same first row');
2478
+ }
2479
+ }
2480
+ }
2481
+ if (itemIndex < currentPage.items.length)
2482
+ return { value: currentPage.items[itemIndex++], done: false };
2483
+ return { done: true, value: undefined };
2484
+ };
2485
+ return {
2486
+ next: async () => {
2487
+ let r = itStrategy();
2488
+ return r;
2489
+ },
2490
+ };
2491
+ }
2492
+ }
2432
2493
  class cacheEntityInfo {
2433
2494
  value = {};
2434
2495
  promise;