remult 0.22.2 → 0.22.4

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.
@@ -192,7 +192,7 @@ class KnexEntityDataProvider {
192
192
  let insert = this.knex(e.$entityName).insert(insertObject);
193
193
  if (isAutoIncrement(this.entity.idMetadata.field)) {
194
194
  let newId;
195
- if (this.knex.client.config.client === 'mysql2') {
195
+ if (this.knex.client.config.client === 'mysql2' || this.knex.client.config.client === 'mysql') {
196
196
  let result = await insert;
197
197
  newId = result[0];
198
198
  }
@@ -380,7 +380,7 @@ export class KnexSchemaBuilder {
380
380
  KnexSchemaBuilder.logToConsole = true;
381
381
  function supportsJson(knex) {
382
382
  const client = knex.client.config.client;
383
- if (client?.includes('sqlite3') || client?.includes('mssql'))
383
+ if (client?.includes('sqlite3') || client?.includes('mssql') || client?.includes('mysql'))
384
384
  return false;
385
385
  return true;
386
386
  }
@@ -64,6 +64,16 @@ export const mySqlTest = addDatabaseToTest(testKnexSqlImpl(Knex.default({
64
64
  database: 'test',
65
65
  },
66
66
  }), 'mysql2'));
67
+ addDatabaseToTest(testKnexSqlImpl(Knex.default({
68
+ client: 'mysql',
69
+ connection: {
70
+ user: 'root',
71
+ password: 'MASTERKEY',
72
+ host: '127.0.0.1',
73
+ database: 'test',
74
+ port: 3307
75
+ },
76
+ }), 'mysql'));
67
77
  let pg = createPostgresConnection();
68
78
  export function testPostgresImplementation(key, what, focus = false) {
69
79
  itWithFocus(key + ' - postgres', async () => {
@@ -124,7 +124,7 @@ export declare class rowHelperImplementation<T> extends rowHelperBase<T> impleme
124
124
  private _columns;
125
125
  get fields(): FieldsRef<T>;
126
126
  private _saving;
127
- save(): Promise<T>;
127
+ save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject?: string[]): Promise<T>;
128
128
  private getIdFilter;
129
129
  delete(): Promise<void>;
130
130
  loadDataFrom(data: any, loadItems?: FieldMetadata[]): Promise<void>;
@@ -190,8 +190,28 @@ export class RepositoryImplementation {
190
190
  }
191
191
  }
192
192
  async update(id, entity) {
193
+ {
194
+ let ref = getEntityRef(entity, false);
195
+ if (ref)
196
+ return (await ref.save());
197
+ }
193
198
  let ref = this.getRefForExistingRow(entity, id);
194
- return (await ref.save());
199
+ if (this.dataProvider.isProxy) {
200
+ return await ref.save(Object.keys(entity));
201
+ }
202
+ else {
203
+ const r = await this.findId(ref.id, { useCache: false });
204
+ if (!r)
205
+ throw new Error('Not Found');
206
+ for (const key in entity) {
207
+ if (Object.prototype.hasOwnProperty.call(entity, key)) {
208
+ let f = ref.fields[key];
209
+ if (f)
210
+ r[key] = f.value;
211
+ }
212
+ }
213
+ return await getEntityRef(r).save();
214
+ }
195
215
  }
196
216
  getRefForExistingRow(entity, id) {
197
217
  let ref = getEntityRef(entity, false);
@@ -909,7 +929,7 @@ export class rowHelperImplementation extends rowHelperBase {
909
929
  }
910
930
  return this._columns;
911
931
  }
912
- async save() {
932
+ async save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
913
933
  try {
914
934
  if (this._saving)
915
935
  throw new Error('cannot save while entity is already saving');
@@ -917,7 +937,8 @@ export class rowHelperImplementation extends rowHelperBase {
917
937
  if (this.wasDeleted())
918
938
  throw new Error('cannot save a deleted row');
919
939
  this.isLoading = true;
920
- await this.__validateEntity();
940
+ if (onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject === undefined) // no need
941
+ await this.__validateEntity();
921
942
  let doNotSave = false;
922
943
  for (const col of this.fields) {
923
944
  if (col.metadata.options.saving)
@@ -930,7 +951,9 @@ export class rowHelperImplementation extends rowHelperBase {
930
951
  let d = this.copyDataToObject();
931
952
  let ignoreKeys = [];
932
953
  for (const field of this.metadata.fields) {
933
- if (field.dbReadOnly) {
954
+ if (field.dbReadOnly ||
955
+ (onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject !== undefined &&
956
+ !onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject.includes(field.key))) {
934
957
  d[field.key] = undefined;
935
958
  ignoreKeys.push(field.key);
936
959
  let f = this.fields.find(field);
@@ -1834,11 +1857,13 @@ export function decorateColumnSettings(settings, remult) {
1834
1857
  isIdNumeric =
1835
1858
  remult.repo(settings.valueType).metadata.idMetadata.field
1836
1859
  .valueType === Number;
1837
- for (const key of [
1838
- 'fieldTypeInDb',
1839
- ]) {
1840
- //@ts-ignore
1841
- target[key] = ValueConverters.Integer[key];
1860
+ if (isIdNumeric) {
1861
+ for (const key of [
1862
+ 'fieldTypeInDb',
1863
+ ]) {
1864
+ //@ts-ignore
1865
+ target[key] = ValueConverters.Integer[key];
1866
+ }
1842
1867
  }
1843
1868
  }
1844
1869
  }
@@ -1082,3 +1082,95 @@ testAll('test relation to number id', async ({ createEntity }) => {
1082
1082
  expect(await taskRepo.count({ category: cat[1] })).toBe(1);
1083
1083
  expect(await taskRepo.count({ category: { $id: cat[0].id } })).toBe(2);
1084
1084
  }, false, { exclude: [TestDbs.mongo, TestDbs.mongoNoTrans] });
1085
+ testAll('test relation to string id', async ({ createEntity }) => {
1086
+ const category = class {
1087
+ constructor() {
1088
+ this.id = '';
1089
+ this.name = '';
1090
+ }
1091
+ };
1092
+ describeClass(category, Entity('rel_ID_string_categories', { allowApiCrud: true }), {
1093
+ id: Fields.cuid(),
1094
+ name: Fields.string(),
1095
+ });
1096
+ const task = class {
1097
+ constructor() {
1098
+ this.id = 0;
1099
+ this.title = '';
1100
+ }
1101
+ };
1102
+ describeClass(task, Entity('rel_ID_string_task', { allowApiCrud: true }), {
1103
+ id: Fields.autoIncrement(),
1104
+ title: Fields.string(),
1105
+ category: Field(() => category),
1106
+ });
1107
+ const catRepo = await createEntity(category);
1108
+ const taskRepo = await createEntity(task);
1109
+ const cat = await catRepo.insert([{ name: 'cat0' }, { name: 'cat1' }]);
1110
+ await taskRepo.insert([
1111
+ { title: 't1', category: cat[0] },
1112
+ { title: 't2', category: cat[0] },
1113
+ { title: 't3', category: cat[1] },
1114
+ ]);
1115
+ expect(taskRepo.fields.category.valueConverter.fieldTypeInDb).toBeUndefined();
1116
+ expect(await taskRepo.count({ category: cat[0] })).toBe(2);
1117
+ expect(await taskRepo.count({ category: cat[1] })).toBe(1);
1118
+ expect(await taskRepo.count({ category: { $id: cat[0].id } })).toBe(2);
1119
+ }, false, { exclude: [TestDbs.mongo, TestDbs.mongoNoTrans] });
1120
+ testAll("test update doesn't override other values", async ({ createEntity, remult }) => {
1121
+ const catRepo = await createEntity(Categories);
1122
+ const cat = await catRepo.insert({ id: 1, categoryName: 'cat' });
1123
+ const task = class {
1124
+ constructor() {
1125
+ this.id = 0;
1126
+ this.title = '';
1127
+ this.completed = false;
1128
+ }
1129
+ };
1130
+ describeClass(task, Entity('tasks', { allowApiCrud: true }), {
1131
+ id: Fields.integer(),
1132
+ title: Fields.string(),
1133
+ cat: Field(() => Categories),
1134
+ completed: Fields.boolean(),
1135
+ });
1136
+ const taskRepo = await createEntity(task);
1137
+ await taskRepo.insert({ id: 1, cat, title: 'noam' });
1138
+ {
1139
+ const aTask = await taskRepo.findFirst({}, { useCache: false });
1140
+ expect(aTask.title).toBe('noam');
1141
+ expect(aTask.cat.categoryName).toBe('cat');
1142
+ expect(aTask.completed).toBe(false);
1143
+ }
1144
+ await taskRepo.update(1, { completed: true });
1145
+ {
1146
+ const aTask = await taskRepo.findFirst({}, { useCache: false });
1147
+ expect(aTask.id).toBe(1);
1148
+ expect(aTask.title).toBe('noam');
1149
+ expect(aTask.cat.categoryName).toBe('cat');
1150
+ expect(aTask.completed).toBe(true);
1151
+ }
1152
+ }, false);
1153
+ testAll("test update doesn't validate non included fields", async ({ createEntity, remult }) => {
1154
+ const catRepo = await createEntity(Categories);
1155
+ const cat = await catRepo.insert({ id: 1, categoryName: 'cat' });
1156
+ const task = class {
1157
+ constructor() {
1158
+ this.id = 0;
1159
+ this.title = '';
1160
+ this.completed = false;
1161
+ }
1162
+ };
1163
+ describeClass(task, Entity('tasks', { allowApiCrud: true }), {
1164
+ id: Fields.integer(),
1165
+ title: Fields.string({ validate: Validators.required }),
1166
+ cat: Field(() => Categories),
1167
+ completed: Fields.boolean(),
1168
+ });
1169
+ const taskRepo = await createEntity(task);
1170
+ await taskRepo.insert({ id: 1, cat, title: 'noam' });
1171
+ await taskRepo.update(1, { completed: true });
1172
+ {
1173
+ const aTask = await taskRepo.findId(1, { useCache: false });
1174
+ expect(aTask.completed).toBe(true);
1175
+ }
1176
+ }, false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.22.2",
3
+ "version": "0.22.4",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "types": "index.d.ts",
6
6
  "module": "esm/index.js",
@@ -375,7 +375,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
375
375
  case 10:
376
376
  insert = this.knex(e.$entityName).insert(insertObject);
377
377
  if (!remult3_1.isAutoIncrement(this.entity.idMetadata.field)) return [3 /*break*/, 15];
378
- if (!(this.knex.client.config.client === 'mysql2')) return [3 /*break*/, 12];
378
+ if (!(this.knex.client.config.client === 'mysql2' || this.knex.client.config.client === 'mysql')) return [3 /*break*/, 12];
379
379
  return [4 /*yield*/, insert];
380
380
  case 11:
381
381
  result = _d.sent();
@@ -825,7 +825,7 @@ var KnexSchemaBuilder = /** @class */ (function () {
825
825
  exports.KnexSchemaBuilder = KnexSchemaBuilder;
826
826
  function supportsJson(knex) {
827
827
  var client = knex.client.config.client;
828
- if ((client === null || client === void 0 ? void 0 : client.includes('sqlite3')) || (client === null || client === void 0 ? void 0 : client.includes('mssql')))
828
+ if ((client === null || client === void 0 ? void 0 : client.includes('sqlite3')) || (client === null || client === void 0 ? void 0 : client.includes('mssql')) || (client === null || client === void 0 ? void 0 : client.includes('mysql')))
829
829
  return false;
830
830
  return true;
831
831
  }
@@ -92,6 +92,16 @@ exports.mySqlTest = db_tests_setup_1.addDatabaseToTest(testKnexSqlImpl(Knex.defa
92
92
  database: 'test',
93
93
  },
94
94
  }), 'mysql2'));
95
+ db_tests_setup_1.addDatabaseToTest(testKnexSqlImpl(Knex.default({
96
+ client: 'mysql',
97
+ connection: {
98
+ user: 'root',
99
+ password: 'MASTERKEY',
100
+ host: '127.0.0.1',
101
+ database: 'test',
102
+ port: 3307
103
+ },
104
+ }), 'mysql'));
95
105
  var pg = postgres_1.createPostgresConnection();
96
106
  function testPostgresImplementation(key, what, focus) {
97
107
  var _this = this;
@@ -124,7 +124,7 @@ export declare class rowHelperImplementation<T> extends rowHelperBase<T> impleme
124
124
  private _columns;
125
125
  get fields(): FieldsRef<T>;
126
126
  private _saving;
127
- save(): Promise<T>;
127
+ save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject?: string[]): Promise<T>;
128
128
  private getIdFilter;
129
129
  delete(): Promise<void>;
130
130
  loadDataFrom(data: any, loadItems?: FieldMetadata[]): Promise<void>;
@@ -324,13 +324,33 @@ var RepositoryImplementation = /** @class */ (function () {
324
324
  };
325
325
  RepositoryImplementation.prototype.update = function (id, entity) {
326
326
  return tslib_1.__awaiter(this, void 0, void 0, function () {
327
- var ref;
327
+ var ref_1, ref, r, key, f;
328
328
  return tslib_1.__generator(this, function (_a) {
329
329
  switch (_a.label) {
330
330
  case 0:
331
- ref = this.getRefForExistingRow(entity, id);
332
- return [4 /*yield*/, ref.save()];
331
+ ref_1 = getEntityRef(entity, false);
332
+ if (!ref_1) return [3 /*break*/, 2];
333
+ return [4 /*yield*/, ref_1.save()];
333
334
  case 1: return [2 /*return*/, (_a.sent())];
335
+ case 2:
336
+ ref = this.getRefForExistingRow(entity, id);
337
+ if (!this.dataProvider.isProxy) return [3 /*break*/, 4];
338
+ return [4 /*yield*/, ref.save(Object.keys(entity))];
339
+ case 3: return [2 /*return*/, _a.sent()];
340
+ case 4: return [4 /*yield*/, this.findId(ref.id, { useCache: false })];
341
+ case 5:
342
+ r = _a.sent();
343
+ if (!r)
344
+ throw new Error('Not Found');
345
+ for (key in entity) {
346
+ if (Object.prototype.hasOwnProperty.call(entity, key)) {
347
+ f = ref.fields[key];
348
+ if (f)
349
+ r[key] = f.value;
350
+ }
351
+ }
352
+ return [4 /*yield*/, getEntityRef(r).save()];
353
+ case 6: return [2 /*return*/, _a.sent()];
334
354
  }
335
355
  });
336
356
  });
@@ -1525,7 +1545,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
1525
1545
  enumerable: false,
1526
1546
  configurable: true
1527
1547
  });
1528
- rowHelperImplementation.prototype.save = function () {
1548
+ rowHelperImplementation.prototype.save = function (onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
1529
1549
  var _a;
1530
1550
  return tslib_1.__awaiter(this, void 0, void 0, function () {
1531
1551
  var doNotSave_1, _b, _c, col, e_25_1, d, ignoreKeys, _d, _e, field, f, updatedRow, isNew, changesOnly, wasChanged, key, element, _f, _g, listener, e_26_1, err_1;
@@ -1533,58 +1553,63 @@ var rowHelperImplementation = /** @class */ (function (_super) {
1533
1553
  return tslib_1.__generator(this, function (_l) {
1534
1554
  switch (_l.label) {
1535
1555
  case 0:
1536
- _l.trys.push([0, , 34, 35]);
1556
+ _l.trys.push([0, , 35, 36]);
1537
1557
  if (this._saving)
1538
1558
  throw new Error('cannot save while entity is already saving');
1539
1559
  this._saving = true;
1540
1560
  if (this.wasDeleted())
1541
1561
  throw new Error('cannot save a deleted row');
1542
1562
  this.isLoading = true;
1563
+ if (!(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject === undefined)) return [3 /*break*/, 2];
1543
1564
  return [4 /*yield*/, this.__validateEntity()];
1544
1565
  case 1:
1545
1566
  _l.sent();
1546
- doNotSave_1 = false;
1547
1567
  _l.label = 2;
1548
1568
  case 2:
1549
- _l.trys.push([2, 7, 8, 9]);
1550
- _b = tslib_1.__values(this.fields), _c = _b.next();
1569
+ doNotSave_1 = false;
1551
1570
  _l.label = 3;
1552
1571
  case 3:
1553
- if (!!_c.done) return [3 /*break*/, 6];
1572
+ _l.trys.push([3, 8, 9, 10]);
1573
+ _b = tslib_1.__values(this.fields), _c = _b.next();
1574
+ _l.label = 4;
1575
+ case 4:
1576
+ if (!!_c.done) return [3 /*break*/, 7];
1554
1577
  col = _c.value;
1555
- if (!col.metadata.options.saving) return [3 /*break*/, 5];
1578
+ if (!col.metadata.options.saving) return [3 /*break*/, 6];
1556
1579
  return [4 /*yield*/, col.metadata.options.saving(this.instance, col)];
1557
- case 4:
1558
- _l.sent();
1559
- _l.label = 5;
1560
1580
  case 5:
1581
+ _l.sent();
1582
+ _l.label = 6;
1583
+ case 6:
1561
1584
  _c = _b.next();
1562
- return [3 /*break*/, 3];
1563
- case 6: return [3 /*break*/, 9];
1564
- case 7:
1585
+ return [3 /*break*/, 4];
1586
+ case 7: return [3 /*break*/, 10];
1587
+ case 8:
1565
1588
  e_25_1 = _l.sent();
1566
1589
  e_25 = { error: e_25_1 };
1567
- return [3 /*break*/, 9];
1568
- case 8:
1590
+ return [3 /*break*/, 10];
1591
+ case 9:
1569
1592
  try {
1570
1593
  if (_c && !_c.done && (_h = _b.return)) _h.call(_b);
1571
1594
  }
1572
1595
  finally { if (e_25) throw e_25.error; }
1573
1596
  return [7 /*endfinally*/];
1574
- case 9:
1575
- if (!this.info.entityInfo.saving) return [3 /*break*/, 11];
1576
- return [4 /*yield*/, this.info.entityInfo.saving(this.instance, function () { return (doNotSave_1 = true); })];
1577
1597
  case 10:
1578
- _l.sent();
1579
- _l.label = 11;
1598
+ if (!this.info.entityInfo.saving) return [3 /*break*/, 12];
1599
+ return [4 /*yield*/, this.info.entityInfo.saving(this.instance, function () { return (doNotSave_1 = true); })];
1580
1600
  case 11:
1601
+ _l.sent();
1602
+ _l.label = 12;
1603
+ case 12:
1581
1604
  this.__assertValidity();
1582
1605
  d = this.copyDataToObject();
1583
1606
  ignoreKeys = [];
1584
1607
  try {
1585
1608
  for (_d = tslib_1.__values(this.metadata.fields), _e = _d.next(); !_e.done; _e = _d.next()) {
1586
1609
  field = _e.value;
1587
- if (field.dbReadOnly) {
1610
+ if (field.dbReadOnly ||
1611
+ (onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject !== undefined &&
1612
+ !onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject.includes(field.key))) {
1588
1613
  d[field.key] = undefined;
1589
1614
  ignoreKeys.push(field.key);
1590
1615
  f = this.fields.find(field);
@@ -1603,16 +1628,16 @@ var rowHelperImplementation = /** @class */ (function (_super) {
1603
1628
  delete d.id;
1604
1629
  updatedRow = void 0;
1605
1630
  isNew = this.isNew();
1606
- _l.label = 12;
1607
- case 12:
1608
- _l.trys.push([12, 31, , 33]);
1631
+ _l.label = 13;
1632
+ case 13:
1633
+ _l.trys.push([13, 32, , 34]);
1609
1634
  (_a = this._subscribers) === null || _a === void 0 ? void 0 : _a.reportChanged();
1610
- if (!this.isNew()) return [3 /*break*/, 14];
1635
+ if (!this.isNew()) return [3 /*break*/, 15];
1611
1636
  return [4 /*yield*/, this.edp.insert(d)];
1612
- case 13:
1613
- updatedRow = _l.sent();
1614
- return [3 /*break*/, 18];
1615
1637
  case 14:
1638
+ updatedRow = _l.sent();
1639
+ return [3 /*break*/, 19];
1640
+ case 15:
1616
1641
  changesOnly = {};
1617
1642
  wasChanged = false;
1618
1643
  for (key in d) {
@@ -1627,70 +1652,70 @@ var rowHelperImplementation = /** @class */ (function (_super) {
1627
1652
  }
1628
1653
  if (!wasChanged)
1629
1654
  return [2 /*return*/, this.instance];
1630
- if (!doNotSave_1) return [3 /*break*/, 16];
1655
+ if (!doNotSave_1) return [3 /*break*/, 17];
1631
1656
  return [4 /*yield*/, this.edp.find({ where: this.getIdFilter() })];
1632
- case 15:
1657
+ case 16:
1633
1658
  updatedRow = (_l.sent())[0];
1634
- return [3 /*break*/, 18];
1635
- case 16: return [4 /*yield*/, this.edp.update(this.id, changesOnly)];
1636
- case 17:
1659
+ return [3 /*break*/, 19];
1660
+ case 17: return [4 /*yield*/, this.edp.update(this.id, changesOnly)];
1661
+ case 18:
1637
1662
  updatedRow = _l.sent();
1638
- _l.label = 18;
1639
- case 18: return [4 /*yield*/, this.loadDataFrom(updatedRow)];
1640
- case 19:
1641
- _l.sent();
1642
- if (!this.info.entityInfo.saved) return [3 /*break*/, 21];
1643
- return [4 /*yield*/, this.info.entityInfo.saved(this.instance)];
1663
+ _l.label = 19;
1664
+ case 19: return [4 /*yield*/, this.loadDataFrom(updatedRow)];
1644
1665
  case 20:
1645
1666
  _l.sent();
1646
- _l.label = 21;
1667
+ if (!this.info.entityInfo.saved) return [3 /*break*/, 22];
1668
+ return [4 /*yield*/, this.info.entityInfo.saved(this.instance)];
1647
1669
  case 21:
1648
- if (!this.repository.listeners) return [3 /*break*/, 29];
1670
+ _l.sent();
1649
1671
  _l.label = 22;
1650
1672
  case 22:
1651
- _l.trys.push([22, 27, 28, 29]);
1652
- _f = tslib_1.__values(this.repository.listeners.filter(function (x) { return x.saved; })), _g = _f.next();
1673
+ if (!this.repository.listeners) return [3 /*break*/, 30];
1653
1674
  _l.label = 23;
1654
1675
  case 23:
1655
- if (!!_g.done) return [3 /*break*/, 26];
1676
+ _l.trys.push([23, 28, 29, 30]);
1677
+ _f = tslib_1.__values(this.repository.listeners.filter(function (x) { return x.saved; })), _g = _f.next();
1678
+ _l.label = 24;
1679
+ case 24:
1680
+ if (!!_g.done) return [3 /*break*/, 27];
1656
1681
  listener = _g.value;
1657
1682
  return [4 /*yield*/, listener.saved(this.instance, isNew)];
1658
- case 24:
1659
- _l.sent();
1660
- _l.label = 25;
1661
1683
  case 25:
1684
+ _l.sent();
1685
+ _l.label = 26;
1686
+ case 26:
1662
1687
  _g = _f.next();
1663
- return [3 /*break*/, 23];
1664
- case 26: return [3 /*break*/, 29];
1665
- case 27:
1688
+ return [3 /*break*/, 24];
1689
+ case 27: return [3 /*break*/, 30];
1690
+ case 28:
1666
1691
  e_26_1 = _l.sent();
1667
1692
  e_26 = { error: e_26_1 };
1668
- return [3 /*break*/, 29];
1669
- case 28:
1693
+ return [3 /*break*/, 30];
1694
+ case 29:
1670
1695
  try {
1671
1696
  if (_g && !_g.done && (_k = _f.return)) _k.call(_f);
1672
1697
  }
1673
1698
  finally { if (e_26) throw e_26.error; }
1674
1699
  return [7 /*endfinally*/];
1675
- case 29: return [4 /*yield*/, this.repository.remult.liveQueryPublisher.itemChanged(this.repository.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }])];
1676
- case 30:
1700
+ case 30: return [4 /*yield*/, this.repository.remult.liveQueryPublisher.itemChanged(this.repository.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }])];
1701
+ case 31:
1677
1702
  _l.sent();
1678
1703
  this.saveOriginalData();
1679
1704
  this._isNew = false;
1680
1705
  return [2 /*return*/, this.instance];
1681
- case 31:
1706
+ case 32:
1682
1707
  err_1 = _l.sent();
1683
1708
  return [4 /*yield*/, this.catchSaveErrors(err_1)];
1684
- case 32:
1709
+ case 33:
1685
1710
  _l.sent();
1686
- return [3 /*break*/, 33];
1687
- case 33: return [3 /*break*/, 35];
1688
- case 34:
1711
+ return [3 /*break*/, 34];
1712
+ case 34: return [3 /*break*/, 36];
1713
+ case 35:
1689
1714
  this.isLoading = false;
1690
1715
  this._reportChangedToEntityAndFields();
1691
1716
  this._saving = false;
1692
1717
  return [7 /*endfinally*/];
1693
- case 35: return [2 /*return*/];
1718
+ case 36: return [2 /*return*/];
1694
1719
  }
1695
1720
  });
1696
1721
  });
@@ -3018,21 +3043,23 @@ function decorateColumnSettings(settings, remult) {
3018
3043
  isIdNumeric_1 =
3019
3044
  remult.repo(settings.valueType).metadata.idMetadata.field
3020
3045
  .valueType === Number;
3021
- try {
3022
- for (var _b = tslib_1.__values([
3023
- 'fieldTypeInDb',
3024
- ]), _c = _b.next(); !_c.done; _c = _b.next()) {
3025
- var key = _c.value;
3026
- //@ts-ignore
3027
- target[key] = valueConverters_1.ValueConverters.Integer[key];
3028
- }
3029
- }
3030
- catch (e_40_1) { e_40 = { error: e_40_1 }; }
3031
- finally {
3046
+ if (isIdNumeric_1) {
3032
3047
  try {
3033
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3048
+ for (var _b = tslib_1.__values([
3049
+ 'fieldTypeInDb',
3050
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
3051
+ var key = _c.value;
3052
+ //@ts-ignore
3053
+ target[key] = valueConverters_1.ValueConverters.Integer[key];
3054
+ }
3055
+ }
3056
+ catch (e_40_1) { e_40 = { error: e_40_1 }; }
3057
+ finally {
3058
+ try {
3059
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3060
+ }
3061
+ finally { if (e_40) throw e_40.error; }
3034
3062
  }
3035
- finally { if (e_40) throw e_40.error; }
3036
3063
  }
3037
3064
  }
3038
3065
  }
@@ -2377,3 +2377,164 @@ db_tests_setup_1.testAll('test relation to number id', function (_a) {
2377
2377
  });
2378
2378
  });
2379
2379
  }, false, { exclude: [db_tests_setup_1.TestDbs.mongo, db_tests_setup_1.TestDbs.mongoNoTrans] });
2380
+ db_tests_setup_1.testAll('test relation to string id', function (_a) {
2381
+ var createEntity = _a.createEntity;
2382
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
2383
+ var category, task, catRepo, taskRepo, cat, _b, _c, _d;
2384
+ return tslib_1.__generator(this, function (_e) {
2385
+ switch (_e.label) {
2386
+ case 0:
2387
+ category = /** @class */ (function () {
2388
+ function class_12() {
2389
+ this.id = '';
2390
+ this.name = '';
2391
+ }
2392
+ return class_12;
2393
+ }());
2394
+ DecoratorReplacer_1.describeClass(category, remult3_1.Entity('rel_ID_string_categories', { allowApiCrud: true }), {
2395
+ id: remult3_1.Fields.cuid(),
2396
+ name: remult3_1.Fields.string(),
2397
+ });
2398
+ task = /** @class */ (function () {
2399
+ function class_13() {
2400
+ this.id = 0;
2401
+ this.title = '';
2402
+ }
2403
+ return class_13;
2404
+ }());
2405
+ DecoratorReplacer_1.describeClass(task, remult3_1.Entity('rel_ID_string_task', { allowApiCrud: true }), {
2406
+ id: remult3_1.Fields.autoIncrement(),
2407
+ title: remult3_1.Fields.string(),
2408
+ category: remult3_1.Field(function () { return category; }),
2409
+ });
2410
+ return [4 /*yield*/, createEntity(category)];
2411
+ case 1:
2412
+ catRepo = _e.sent();
2413
+ return [4 /*yield*/, createEntity(task)];
2414
+ case 2:
2415
+ taskRepo = _e.sent();
2416
+ return [4 /*yield*/, catRepo.insert([{ name: 'cat0' }, { name: 'cat1' }])];
2417
+ case 3:
2418
+ cat = _e.sent();
2419
+ return [4 /*yield*/, taskRepo.insert([
2420
+ { title: 't1', category: cat[0] },
2421
+ { title: 't2', category: cat[0] },
2422
+ { title: 't3', category: cat[1] },
2423
+ ])];
2424
+ case 4:
2425
+ _e.sent();
2426
+ expect(taskRepo.fields.category.valueConverter.fieldTypeInDb).toBeUndefined();
2427
+ _b = expect;
2428
+ return [4 /*yield*/, taskRepo.count({ category: cat[0] })];
2429
+ case 5:
2430
+ _b.apply(void 0, [_e.sent()]).toBe(2);
2431
+ _c = expect;
2432
+ return [4 /*yield*/, taskRepo.count({ category: cat[1] })];
2433
+ case 6:
2434
+ _c.apply(void 0, [_e.sent()]).toBe(1);
2435
+ _d = expect;
2436
+ return [4 /*yield*/, taskRepo.count({ category: { $id: cat[0].id } })];
2437
+ case 7:
2438
+ _d.apply(void 0, [_e.sent()]).toBe(2);
2439
+ return [2 /*return*/];
2440
+ }
2441
+ });
2442
+ });
2443
+ }, false, { exclude: [db_tests_setup_1.TestDbs.mongo, db_tests_setup_1.TestDbs.mongoNoTrans] });
2444
+ db_tests_setup_1.testAll("test update doesn't override other values", function (_a) {
2445
+ var createEntity = _a.createEntity, remult = _a.remult;
2446
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
2447
+ var catRepo, cat, task, taskRepo, aTask, aTask;
2448
+ return tslib_1.__generator(this, function (_b) {
2449
+ switch (_b.label) {
2450
+ case 0: return [4 /*yield*/, createEntity(remult_3_entities_1.Categories)];
2451
+ case 1:
2452
+ catRepo = _b.sent();
2453
+ return [4 /*yield*/, catRepo.insert({ id: 1, categoryName: 'cat' })];
2454
+ case 2:
2455
+ cat = _b.sent();
2456
+ task = /** @class */ (function () {
2457
+ function class_14() {
2458
+ this.id = 0;
2459
+ this.title = '';
2460
+ this.completed = false;
2461
+ }
2462
+ return class_14;
2463
+ }());
2464
+ DecoratorReplacer_1.describeClass(task, remult3_1.Entity('tasks', { allowApiCrud: true }), {
2465
+ id: remult3_1.Fields.integer(),
2466
+ title: remult3_1.Fields.string(),
2467
+ cat: remult3_1.Field(function () { return remult_3_entities_1.Categories; }),
2468
+ completed: remult3_1.Fields.boolean(),
2469
+ });
2470
+ return [4 /*yield*/, createEntity(task)];
2471
+ case 3:
2472
+ taskRepo = _b.sent();
2473
+ return [4 /*yield*/, taskRepo.insert({ id: 1, cat: cat, title: 'noam' })];
2474
+ case 4:
2475
+ _b.sent();
2476
+ return [4 /*yield*/, taskRepo.findFirst({}, { useCache: false })];
2477
+ case 5:
2478
+ aTask = _b.sent();
2479
+ expect(aTask.title).toBe('noam');
2480
+ expect(aTask.cat.categoryName).toBe('cat');
2481
+ expect(aTask.completed).toBe(false);
2482
+ return [4 /*yield*/, taskRepo.update(1, { completed: true })];
2483
+ case 6:
2484
+ _b.sent();
2485
+ return [4 /*yield*/, taskRepo.findFirst({}, { useCache: false })];
2486
+ case 7:
2487
+ aTask = _b.sent();
2488
+ expect(aTask.id).toBe(1);
2489
+ expect(aTask.title).toBe('noam');
2490
+ expect(aTask.cat.categoryName).toBe('cat');
2491
+ expect(aTask.completed).toBe(true);
2492
+ return [2 /*return*/];
2493
+ }
2494
+ });
2495
+ });
2496
+ }, false);
2497
+ db_tests_setup_1.testAll("test update doesn't validate non included fields", function (_a) {
2498
+ var createEntity = _a.createEntity, remult = _a.remult;
2499
+ return tslib_1.__awaiter(void 0, void 0, void 0, function () {
2500
+ var catRepo, cat, task, taskRepo, aTask;
2501
+ return tslib_1.__generator(this, function (_b) {
2502
+ switch (_b.label) {
2503
+ case 0: return [4 /*yield*/, createEntity(remult_3_entities_1.Categories)];
2504
+ case 1:
2505
+ catRepo = _b.sent();
2506
+ return [4 /*yield*/, catRepo.insert({ id: 1, categoryName: 'cat' })];
2507
+ case 2:
2508
+ cat = _b.sent();
2509
+ task = /** @class */ (function () {
2510
+ function class_15() {
2511
+ this.id = 0;
2512
+ this.title = '';
2513
+ this.completed = false;
2514
+ }
2515
+ return class_15;
2516
+ }());
2517
+ DecoratorReplacer_1.describeClass(task, remult3_1.Entity('tasks', { allowApiCrud: true }), {
2518
+ id: remult3_1.Fields.integer(),
2519
+ title: remult3_1.Fields.string({ validate: validators_1.Validators.required }),
2520
+ cat: remult3_1.Field(function () { return remult_3_entities_1.Categories; }),
2521
+ completed: remult3_1.Fields.boolean(),
2522
+ });
2523
+ return [4 /*yield*/, createEntity(task)];
2524
+ case 3:
2525
+ taskRepo = _b.sent();
2526
+ return [4 /*yield*/, taskRepo.insert({ id: 1, cat: cat, title: 'noam' })];
2527
+ case 4:
2528
+ _b.sent();
2529
+ return [4 /*yield*/, taskRepo.update(1, { completed: true })];
2530
+ case 5:
2531
+ _b.sent();
2532
+ return [4 /*yield*/, taskRepo.findId(1, { useCache: false })];
2533
+ case 6:
2534
+ aTask = _b.sent();
2535
+ expect(aTask.completed).toBe(true);
2536
+ return [2 /*return*/];
2537
+ }
2538
+ });
2539
+ });
2540
+ }, false);