remult 3.3.0-next.1 → 3.3.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.
@@ -51,6 +51,7 @@ export function buildEntityInfo(options) {
51
51
  if (relRepo.metadata.apiReadAllowed) {
52
52
  relation = {
53
53
  ...relInfo,
54
+ allowNull: x.allowNull,
54
55
  where,
55
56
  entityKey: relRepo.metadata.key,
56
57
  idField,
@@ -81,6 +82,7 @@ export function buildEntityInfo(options) {
81
82
  caption: x.label,
82
83
  relationToOne: relation,
83
84
  inputType: x.inputType,
85
+ allowNull: x.allowNull,
84
86
  type: x.inputType === InputTypes.json
85
87
  ? 'json'
86
88
  : x.valueType === Number
@@ -316,7 +316,7 @@ export class RemultServerImplementation {
316
316
  //@ts-ignore
317
317
  .get(this.process(async (c, req, res, orig) => dataApiFactory(c).get(res, orig.params.id)))
318
318
  //@ts-ignore
319
- .put(this.process(async (c, req, res, reqInfo, _, orig) => dataApiFactory(c).put(res, reqInfo.params.id, await this.coreOptions.getRequestBody(orig))))
319
+ .put(this.process(async (c, req, res, reqInfo, _, orig) => dataApiFactory(c).put(res, req, reqInfo.params.id, await this.coreOptions.getRequestBody(orig))))
320
320
  //@ts-ignore
321
321
  .delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, orig.params.id)));
322
322
  }
@@ -72,7 +72,7 @@ export class DataApi {
72
72
  case 'query':
73
73
  return res.success(await this.query(res, req, body));
74
74
  default:
75
- return res.created(await this.post(body));
75
+ return res.created(await this.post(body, req));
76
76
  }
77
77
  }
78
78
  catch (err) {
@@ -93,11 +93,11 @@ export class DataApi {
93
93
  include: this.includeNone(),
94
94
  });
95
95
  if (r.length == 0) {
96
- result.push(await this.post({ ...item.where, ...item.set }));
96
+ result.push(await this.post({ ...item.where, ...item.set }, request));
97
97
  }
98
98
  else {
99
99
  if (item.set !== undefined) {
100
- result.push((await this.actualUpdate(r[0], item.set)).toApiJson());
100
+ result.push(await this.actualUpdate(r[0], item.set, request));
101
101
  }
102
102
  else
103
103
  result.push(this.repository.getEntityRef(r[0]).toApiJson());
@@ -154,8 +154,7 @@ export class DataApi {
154
154
  async deleteMany(response, request, body) {
155
155
  try {
156
156
  let deleted = 0;
157
- let where = await this.buildWhere(request, body);
158
- Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
157
+ let where = await this.prepareWhereForManyOperation(body, request);
159
158
  return await doTransaction(this.remult, async () => {
160
159
  for await (const x of this.repository.query({
161
160
  where,
@@ -172,6 +171,14 @@ export class DataApi {
172
171
  response.error(err, this.repository.metadata);
173
172
  }
174
173
  }
174
+ async prepareWhereForManyOperation(body, request) {
175
+ let where = undefined;
176
+ if (body?.where !== 'all') {
177
+ where = await this.buildWhere(request, body);
178
+ Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
179
+ }
180
+ return where;
181
+ }
175
182
  async groupBy(request, body) {
176
183
  if (!this.repository.metadata.apiReadAllowed) {
177
184
  throw new ForbiddenError();
@@ -412,7 +419,7 @@ export class DataApi {
412
419
  async updateManyThroughPutRequest(response, request, body) {
413
420
  const action = request?.get('__action');
414
421
  if (action == 'emptyId') {
415
- return this.put(response, '', body);
422
+ return this.put(response, request, '', body);
416
423
  }
417
424
  return this.updateManyImplementation(response, request, {
418
425
  where: undefined,
@@ -421,8 +428,7 @@ export class DataApi {
421
428
  }
422
429
  async updateManyImplementation(response, request, body) {
423
430
  try {
424
- let where = await this.buildWhere(request, body);
425
- Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
431
+ let where = await this.prepareWhereForManyOperation(body, request);
426
432
  return await doTransaction(this.remult, async () => {
427
433
  let updated = 0;
428
434
  for await (const x of this.repository.query({
@@ -430,7 +436,7 @@ export class DataApi {
430
436
  include: this.includeNone(),
431
437
  aggregate: undefined,
432
438
  })) {
433
- await this.actualUpdate(x, body.set);
439
+ await this.actualUpdate(x, body.set, request);
434
440
  updated++;
435
441
  }
436
442
  response.success({ updated });
@@ -440,20 +446,20 @@ export class DataApi {
440
446
  response.error(err, this.repository.metadata);
441
447
  }
442
448
  }
443
- async actualUpdate(row, body) {
449
+ async actualUpdate(row, body, req) {
444
450
  let ref = this.repository.getEntityRef(row);
445
451
  await ref._updateEntityBasedOnApi(body);
446
452
  if (!ref.apiUpdateAllowed) {
447
453
  throw new ForbiddenError();
448
454
  }
449
- await ref.save();
450
- return ref;
455
+ let options = req.get('_select') === 'none' ? { select: 'none' } : undefined;
456
+ await ref.save(options);
457
+ if (options?.select === 'none')
458
+ return undefined;
459
+ return ref.toApiJson();
451
460
  }
452
- async put(response, id, body) {
453
- await this.doOnId(response, id, async (row) => {
454
- const ref = await this.actualUpdate(row, body);
455
- response.success(ref.toApiJson());
456
- });
461
+ async put(response, req, id, body) {
462
+ await this.doOnId(response, id, async (row) => response.success(await this.actualUpdate(row, body, req)));
457
463
  }
458
464
  async actualDelete(row) {
459
465
  if (!this.repository.getEntityRef(row).apiDeleteAllowed) {
@@ -467,14 +473,17 @@ export class DataApi {
467
473
  response.deleted();
468
474
  });
469
475
  }
470
- async post(body) {
476
+ async post(body, req) {
477
+ let options = req.get('_select') === 'none' ? { select: 'none' } : undefined;
471
478
  const insert = async (what) => {
472
479
  let newr = this.repository.create();
473
480
  await this.repository.getEntityRef(newr)._updateEntityBasedOnApi(what);
474
481
  if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
475
482
  throw new ForbiddenError();
476
483
  }
477
- await this.repository.getEntityRef(newr).save();
484
+ await this.repository.getEntityRef(newr).save(options);
485
+ if (options?.select === 'none')
486
+ return undefined;
478
487
  return this.repository.getEntityRef(newr).toApiJson();
479
488
  };
480
489
  if (Array.isArray(body)) {
@@ -199,37 +199,42 @@ export class RestEntityDataProvider {
199
199
  let url = new UrlBuilder(this.url());
200
200
  let filterObject;
201
201
  if (options) {
202
- if (options.where) {
203
- filterObject = options.where.toJson(); // options.where.__applyToConsumer(new FilterConsumnerBridgeToUrlBuilder(url));
204
- if (options.args === undefined)
205
- if (addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
206
- filterObject = undefined;
202
+ if (options.where === 'all') {
203
+ filterObject = 'all';
207
204
  }
208
- if (options.orderBy && options.orderBy.Segments) {
209
- let sort = '';
210
- let order = '';
211
- let hasDescending = false;
212
- options.orderBy.Segments.forEach((c) => {
213
- if (sort.length > 0) {
214
- sort += ',';
215
- order += ',';
216
- }
217
- sort += c.field.key;
218
- order += c.isDescending ? 'desc' : 'asc';
219
- if (c.isDescending)
220
- hasDescending = true;
221
- });
222
- if (sort)
223
- url.add('_sort', sort);
224
- if (hasDescending)
225
- url.add('_order', order);
226
- }
227
- if (options.limit)
228
- url.add('_limit', options.limit);
229
- if (options.page)
230
- url.add('_page', options.page);
231
- if (options.select) {
232
- url.add('_select', options.select.join(','));
205
+ else {
206
+ if (options.where) {
207
+ filterObject = options.where.toJson();
208
+ if (options.args === undefined)
209
+ if (addFilterToUrlAndReturnTrueIfSuccessful(filterObject, url))
210
+ filterObject = undefined;
211
+ }
212
+ if (options.orderBy && options.orderBy.Segments) {
213
+ let sort = '';
214
+ let order = '';
215
+ let hasDescending = false;
216
+ options.orderBy.Segments.forEach((c) => {
217
+ if (sort.length > 0) {
218
+ sort += ',';
219
+ order += ',';
220
+ }
221
+ sort += c.field.key;
222
+ order += c.isDescending ? 'desc' : 'asc';
223
+ if (c.isDescending)
224
+ hasDescending = true;
225
+ });
226
+ if (sort)
227
+ url.add('_sort', sort);
228
+ if (hasDescending)
229
+ url.add('_order', order);
230
+ }
231
+ if (options.limit)
232
+ url.add('_limit', options.limit);
233
+ if (options.page)
234
+ url.add('_page', options.page);
235
+ if (options.select) {
236
+ url.add('_select', options.select.join(','));
237
+ }
233
238
  }
234
239
  }
235
240
  const run = (action, body) => {
@@ -246,7 +251,7 @@ export class RestEntityDataProvider {
246
251
  else
247
252
  body = { ...body, where: filterObject };
248
253
  }
249
- if (options?.args)
254
+ if (options && 'args' in options)
250
255
  body.args = options.args;
251
256
  if (body && method != 'put')
252
257
  return this.http().post(u.url, body);
@@ -269,10 +274,16 @@ export class RestEntityDataProvider {
269
274
  },
270
275
  };
271
276
  }
272
- update(id, data) {
277
+ update(id, data, options) {
278
+ const urlArgs = [];
279
+ if (id == '')
280
+ urlArgs.push('__action=emptyId');
281
+ if (options?.select === 'none')
282
+ urlArgs.push('_select=$none');
273
283
  return this.http()
274
284
  .put(this.url() +
275
- (id != '' ? '/' + encodeURIComponent(id) : '?__action=emptyId'), this.toJsonOfIncludedKeys(data))
285
+ (id != '' ? '/' + encodeURIComponent(id) : '') +
286
+ (urlArgs.length > 0 ? '?' + urlArgs.join('&') : ''), this.toJsonOfIncludedKeys(data))
276
287
  .then((y) => this.translateFromJson(y));
277
288
  }
278
289
  toJsonOfIncludedKeys(data) {
@@ -290,14 +301,14 @@ export class RestEntityDataProvider {
290
301
  else
291
302
  return this.http().delete(this.url() + '/' + encodeURIComponent(id));
292
303
  }
293
- insert(data) {
304
+ insert(data, options) {
294
305
  return this.http()
295
- .post(this.url(), this.translateToJson(data))
306
+ .post(this.url() + (options?.select === 'none' ? '?_select=$none' : ''), this.translateToJson(data))
296
307
  .then((y) => this.translateFromJson(y));
297
308
  }
298
- insertMany(data) {
309
+ insertMany(data, options) {
299
310
  return this.http()
300
- .post(this.url(), data.map((data) => this.translateToJson(data)))
311
+ .post(this.url() + (options?.select === 'none' ? '?_select=$none' : ''), data.map((data) => this.translateToJson(data)))
301
312
  .then((y) => y.map((y) => this.translateFromJson(y)));
302
313
  }
303
314
  }
@@ -392,7 +392,7 @@ class ActualSQLEntityDataProvider {
392
392
  }
393
393
  return { colKeys, select };
394
394
  }
395
- async update(id, data) {
395
+ async update(id, data, options) {
396
396
  let e = await this.init();
397
397
  let r = this.sql.createCommand();
398
398
  let statement = 'update ' + e.$entityName + ' set ';
@@ -419,6 +419,8 @@ class ActualSQLEntityDataProvider {
419
419
  let returning = true;
420
420
  if (this.sql._getSourceSql().doesNotSupportReturningSyntax)
421
421
  returning = false;
422
+ if (options?.select === 'none')
423
+ returning = false;
422
424
  if (returning &&
423
425
  this.sql._getSourceSql().doesNotSupportReturningSyntaxOnlyForUpdate)
424
426
  returning = false;
@@ -427,6 +429,8 @@ class ActualSQLEntityDataProvider {
427
429
  return r.execute(statement).then((sqlResult) => {
428
430
  this.sql._getSourceSql().afterMutation?.();
429
431
  if (!returning) {
432
+ if (options?.select === 'none')
433
+ return undefined;
430
434
  return getRowAfterUpdate(this.entity, this, data, id, 'update');
431
435
  }
432
436
  if (sqlResult.rows.length != 1)
@@ -448,7 +452,7 @@ class ActualSQLEntityDataProvider {
448
452
  this.sql._getSourceSql().afterMutation?.();
449
453
  });
450
454
  }
451
- async insert(data) {
455
+ async insert(data, options) {
452
456
  let e = await this.init();
453
457
  let r = this.sql.createCommand();
454
458
  let cols = '';
@@ -473,7 +477,8 @@ class ActualSQLEntityDataProvider {
473
477
  }
474
478
  let statement = `insert into ${e.$entityName} (${cols}) values (${vals})`;
475
479
  let { colKeys, select } = await this.buildSelect(e, r, undefined, undefined);
476
- if (!this.sql._getSourceSql().doesNotSupportReturningSyntax)
480
+ if (!this.sql._getSourceSql().doesNotSupportReturningSyntax &&
481
+ !(options?.select === 'none'))
477
482
  statement += ' returning ' + select;
478
483
  return await r.execute(statement).then((sql) => {
479
484
  this.sql._getSourceSql().afterMutation?.();
@@ -483,14 +488,20 @@ class ActualSQLEntityDataProvider {
483
488
  if (typeof id !== 'number')
484
489
  throw new Error('Auto increment, for a database that is does not support returning syntax, should return an array with the single last added id. Instead it returned: ' +
485
490
  JSON.stringify(id));
491
+ if (options?.select === 'none')
492
+ return undefined;
486
493
  return this.find({
487
494
  where: new Filter((x) => x.isEqualTo(this.entity.idMetadata.field, id)),
488
495
  }).then((r) => r[0]);
489
496
  }
490
497
  else {
498
+ if (options?.select === 'none')
499
+ return undefined;
491
500
  return getRowAfterUpdate(this.entity, this, data, undefined, 'insert');
492
501
  }
493
502
  }
503
+ if (options?.select === 'none')
504
+ return undefined;
494
505
  return this.buildResultRow(colKeys, sql.rows[0], sql);
495
506
  });
496
507
  }
@@ -156,10 +156,10 @@ export class RemultProxy {
156
156
  .remultFactory()
157
157
  .repo(...args)
158
158
  .getEntityRef(...args2),
159
- insert: (args2) => self
159
+ insert: (args2, args3) => self
160
160
  .remultFactory()
161
161
  .repo(...args)
162
- .insert(args2),
162
+ .insert(args2, args3),
163
163
  liveQuery: (...args2) => self
164
164
  .remultFactory()
165
165
  .repo(...args)
@@ -179,10 +179,10 @@ export class RemultProxy {
179
179
  .remultFactory()
180
180
  .repo(...args)
181
181
  .upsert(args2),
182
- update: (a, b) => self
182
+ update: (a, b, c) => self
183
183
  .remultFactory()
184
184
  .repo(...args)
185
- .update(a, b),
185
+ .update(a, b, c),
186
186
  };
187
187
  entityCache.set(args[1], result);
188
188
  return result;
@@ -317,7 +317,7 @@ export class RepositoryImplementation {
317
317
  for (const field of this.fields) {
318
318
  }
319
319
  }
320
- async insert(entity) {
320
+ async insert(entity, options) {
321
321
  if (Array.isArray(entity)) {
322
322
  if (this._dataProvider.isProxy) {
323
323
  let refs = [];
@@ -335,27 +335,36 @@ export class RepositoryImplementation {
335
335
  refs.push(ref);
336
336
  raw.push(await ref.buildDtoForInsert());
337
337
  }
338
- return promiseAll(await this._edp.insertMany(raw), (item, i) => refs[i].processInsertResponseDto(item));
338
+ const inserted = await this._edp.insertMany(raw, options);
339
+ if (options?.select === 'none')
340
+ return undefined;
341
+ return promiseAll(inserted, (item, i) => refs[i].processInsertResponseDto(item));
339
342
  }
340
343
  else {
341
344
  let r = [];
342
345
  for (const item of entity) {
343
- r.push(await this.insert(item));
346
+ r.push(await this.insert(item, options));
344
347
  }
348
+ if (options?.select === 'none')
349
+ return undefined;
345
350
  return r;
346
351
  }
347
352
  }
348
353
  else {
349
354
  let ref = getEntityRef(entity, false);
355
+ let result = undefined;
350
356
  if (ref) {
351
357
  if (!ref.isNew())
352
358
  throw 'Item is not new';
353
- return await ref.save();
359
+ result = await ref.save(options);
354
360
  }
355
361
  else {
356
362
  this.__cleanupPartialObject(entity);
357
- return await this.getEntityRef(this.create(entity)).save();
363
+ result = await this.getEntityRef(this.create(entity)).save(options);
358
364
  }
365
+ if (options?.select === 'none')
366
+ return undefined;
367
+ return result;
359
368
  }
360
369
  }
361
370
  get fields() {
@@ -399,7 +408,7 @@ export class RepositoryImplementation {
399
408
  this.__cleanupPartialObject(set);
400
409
  Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
401
410
  if (this._dataProvider.isProxy) {
402
- return this._edp.updateMany(await this._translateWhereToFilter(where), this.__createDto({ ...set }));
411
+ return this._edp.updateMany(where === 'all' ? 'all' : await this._translateWhereToFilter(where), this.__createDto({ ...set }));
403
412
  }
404
413
  else {
405
414
  let updated = 0;
@@ -411,17 +420,22 @@ export class RepositoryImplementation {
411
420
  return updated;
412
421
  }
413
422
  }
414
- async update(id, entity) {
423
+ async update(id, entity, options) {
424
+ function returnResult(result) {
425
+ if (options?.select === 'none')
426
+ return undefined;
427
+ return result;
428
+ }
415
429
  {
416
430
  let ref = getEntityRef(entity, false);
417
431
  if (ref)
418
- return (await ref.save());
432
+ return returnResult((await ref.save(options)));
419
433
  }
420
434
  {
421
435
  let ref = getEntityRef(id, false);
422
436
  if (ref) {
423
437
  assign(id, entity);
424
- return ref.save();
438
+ return returnResult(await ref.save(options));
425
439
  }
426
440
  }
427
441
  this.__cleanupPartialObject(entity);
@@ -433,7 +447,7 @@ export class RepositoryImplementation {
433
447
  else
434
448
  ref = this._getRefForExistingRow(entity, id);
435
449
  if (this._dataProvider.isProxy) {
436
- return await ref.save(Object.keys(entity));
450
+ return returnResult(await ref.save(options, Object.keys(entity)));
437
451
  }
438
452
  else {
439
453
  const r = await ref.reload();
@@ -450,7 +464,7 @@ export class RepositoryImplementation {
450
464
  }
451
465
  }
452
466
  await this._fixTypes(r);
453
- return await ref.save();
467
+ return returnResult(await ref.save(options));
454
468
  }
455
469
  }
456
470
  async upsert(options) {
@@ -855,7 +869,7 @@ export class RepositoryImplementation {
855
869
  async deleteMany({ where, }) {
856
870
  Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
857
871
  if (this._dataProvider.isProxy) {
858
- return this._edp.deleteMany(await this._translateWhereToFilter(where));
872
+ return this._edp.deleteMany(where === 'all' ? 'all' : await this._translateWhereToFilter(where));
859
873
  }
860
874
  else {
861
875
  let deleted = 0;
@@ -1374,6 +1388,15 @@ export class rowHelperImplementation extends rowHelperBase {
1374
1388
  repo;
1375
1389
  edp;
1376
1390
  _isNew;
1391
+ async _updateResultsFromServerAction(rowInfo) {
1392
+ await this._updateEntityBasedOnApi(rowInfo.data, true);
1393
+ if (this._isNew != rowInfo.isNewRow) {
1394
+ this._isNew = rowInfo.isNewRow;
1395
+ this.originalId = rowInfo.id;
1396
+ }
1397
+ if (!rowInfo.wasChanged)
1398
+ this.originalValues = this.copyDataToObject();
1399
+ }
1377
1400
  constructor(info, instance, repo, edp, remult, _isNew, excludeRelationMembers) {
1378
1401
  super(info.fieldsMetadata, instance, remult, _isNew, excludeRelationMembers);
1379
1402
  this.info = info;
@@ -1474,7 +1497,7 @@ export class rowHelperImplementation extends rowHelperBase {
1474
1497
  return this._columns;
1475
1498
  }
1476
1499
  _saving = false;
1477
- async save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
1500
+ async save(options, onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
1478
1501
  try {
1479
1502
  if (this._saving)
1480
1503
  throw new Error('cannot save while entity is already saving');
@@ -1517,13 +1540,13 @@ export class rowHelperImplementation extends rowHelperBase {
1517
1540
  try {
1518
1541
  this._subscribers?.reportChanged();
1519
1542
  if (this.isNew()) {
1520
- if (doNotSave) {
1543
+ if (doNotSave && options?.select !== 'none') {
1521
1544
  updatedRow = (updatedRow = await this.edp.find({
1522
1545
  where: await this.getIdFilter(),
1523
1546
  }))[0];
1524
1547
  }
1525
1548
  else
1526
- updatedRow = await this.edp.insert(d);
1549
+ updatedRow = await this.edp.insert(d, options);
1527
1550
  }
1528
1551
  else {
1529
1552
  let changesOnly = {};
@@ -1542,12 +1565,13 @@ export class rowHelperImplementation extends rowHelperBase {
1542
1565
  if (!wasChanged)
1543
1566
  return this.instance;
1544
1567
  if (doNotSave) {
1545
- updatedRow = (await this.edp.find({ where: await this.getIdFilter() }))[0];
1568
+ if (options?.select !== 'none')
1569
+ updatedRow = (await this.edp.find({ where: await this.getIdFilter() }))[0];
1546
1570
  }
1547
1571
  else {
1548
1572
  if (this.id === undefined)
1549
1573
  throw new Error('Invalid operation, id is undefined');
1550
- updatedRow = await this.edp.update(this.id, changesOnly);
1574
+ updatedRow = await this.edp.update(this.id, changesOnly, options);
1551
1575
  }
1552
1576
  }
1553
1577
  if (updatedRow)
@@ -193,7 +193,7 @@ export function BackendMethod(options) {
193
193
  reg(controllerOptions.key +
194
194
  '/' +
195
195
  (options?.apiPrefix ? options.apiPrefix + '/' : '') +
196
- key, options ? options.queue ?? false : false, options.allowed, async (d, req, res) => {
196
+ key, options ? (options.queue ?? false) : false, options.allowed, async (d, req, res) => {
197
197
  d.args = d.args.map((x) => (isCustomUndefined(x) ? undefined : x));
198
198
  let allowed = options.allowed;
199
199
  try {
@@ -295,7 +295,7 @@ export function BackendMethod(options) {
295
295
  id: defs.getOriginalId(),
296
296
  },
297
297
  }, baseUrl, http);
298
- await defs._updateEntityBasedOnApi(r.rowInfo.data, true);
298
+ await defs._updateResultsFromServerAction(r.rowInfo);
299
299
  return r.result;
300
300
  }
301
301
  catch (err) {
@@ -1,4 +1,5 @@
1
1
  import { InputTypes } from '../inputTypes.js';
2
+ const zeroDate = new Date('0000-01-01');
2
3
  export class ValueConverters {
3
4
  static Date = {
4
5
  toJson: (val) => {
@@ -65,6 +66,8 @@ export class ValueConverters {
65
66
  fromJson: (value) => {
66
67
  if (!value || value == '' || value == '0000-00-00')
67
68
  return null;
69
+ if (value == '0000-01-01')
70
+ return zeroDate;
68
71
  let d = new Date(Date.parse(value));
69
72
  d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
70
73
  return d;
@@ -88,6 +91,8 @@ export class ValueConverters {
88
91
  static DateOnlyString = {
89
92
  ...ValueConverters.DateOnly,
90
93
  toDb: (d) => {
94
+ if (d === zeroDate)
95
+ return '00000000';
91
96
  let val = ValueConverters.DateOnly.toJson(d);
92
97
  if (!val)
93
98
  return undefined;
@@ -98,12 +103,11 @@ export class ValueConverters {
98
103
  return null;
99
104
  if (!val)
100
105
  return undefined;
101
- return new Date(val.substring(0, 4) +
102
- '-' +
103
- val.substring(4, 6) +
104
- '-' +
105
- val.substring(6, 8));
106
+ if (val === '00000000')
107
+ return zeroDate;
108
+ return new Date(Number(val.substring(0, 4)), Number(val.substring(4, 6)) - 1, Number(val.substring(6, 8)));
106
109
  },
110
+ zeroDate,
107
111
  };
108
112
  static Boolean = {
109
113
  toDb: (val) => val,
package/graphql.js CHANGED
@@ -443,7 +443,7 @@ function remultGraphql(options) {
443
443
  setResult((_a = {},
444
444
  _a[toCamelCase(getMetaType(meta))] = y,
445
445
  _a));
446
- } }), arg1.id, arg1.patch)];
446
+ } }), { get: function () { return undefined; } }, arg1.id, arg1.patch)];
447
447
  case 1:
448
448
  _a.sent();
449
449
  return [2 /*return*/];
package/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import type { ClassType } from './classType.js';
2
2
  import type { DataProvider } from './src/data-interfaces.js';
3
3
  export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider.js';
4
4
  export type { ClassType } from './classType.js';
5
- export { ValidateFieldEvent, MembersOnly, NumericKeys, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, UpsertOptions, Repository, GroupByOptions, GroupByResult, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, EntitySelectFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
5
+ export { ValidateFieldEvent, MembersOnly, NumericKeys, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, UpsertOptions, Repository, GroupByOptions, GroupByResult, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, EntitySelectFields, InsertOrUpdateOptions, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
6
6
  LifecycleEvent, FieldsRefBase, FieldsRefForEntityBase, RepositoryRelationsForEntityBase, ControllerRefForControllerBase, ControllerRefBase, ControllerRef, EntityRefForEntityBase, IdMetadata, FindFirstOptionsBase, } from './src/remult3/remult3.js';
7
7
  export { standardSchema } from './src/standard-schema/index.js';
8
8
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, } from './src/remult3/RepositoryImplementation.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.3.0-next.1",
3
+ "version": "3.3.0",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {