remult 0.25.8 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +194 -129
  2. package/esm/graphql.js +131 -59
  3. package/esm/index.js +1 -1
  4. package/esm/migrations/compare-migration-snapshots.js +61 -0
  5. package/esm/migrations/generate-migrations.js +68 -0
  6. package/esm/migrations/index.js +2 -0
  7. package/esm/migrations/migrate.js +90 -0
  8. package/esm/migrations/migration-types.js +36 -0
  9. package/esm/migrations/update-migrations-ts-file.js +115 -0
  10. package/esm/postgres/postgres-data-provider.js +24 -3
  11. package/esm/postgres/schema-builder.js +35 -26
  12. package/esm/remult-better-sqlite3.js +47 -0
  13. package/esm/remult-bun-sqlite.js +41 -0
  14. package/esm/remult-knex/index.js +180 -51
  15. package/esm/remult-mongo.js +2 -2
  16. package/esm/remult-sql-js.js +3 -78
  17. package/esm/remult-sqlite-core.js +104 -0
  18. package/esm/server/expressBridge.js +130 -29
  19. package/esm/server/initAsyncHooks.js +75 -1
  20. package/esm/src/CompoundIdField.js +8 -2
  21. package/esm/src/context.js +20 -24
  22. package/esm/src/data-api.js +71 -30
  23. package/esm/src/data-providers/rest-data-provider.js +17 -15
  24. package/esm/src/data-providers/sql-database.js +32 -7
  25. package/esm/src/data-providers/web-sql-data-provider.js +1 -9
  26. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +37 -11
  27. package/esm/src/filter/filter-interfaces.js +229 -17
  28. package/esm/src/isOfType.js +9 -0
  29. package/esm/src/remult3/Fields.js +70 -18
  30. package/esm/src/remult3/RepositoryImplementation.js +47 -21
  31. package/esm/src/remult3/addValidator.js +15 -0
  32. package/esm/src/remult3/remult3.js +28 -57
  33. package/esm/src/server-action.js +4 -4
  34. package/esm/src/validators.js +6 -3
  35. package/esm/src/valueConverters.js +1 -1
  36. package/graphql.js +156 -71
  37. package/index.d.ts +4 -4
  38. package/index.js +2 -1
  39. package/migrations/compare-migration-snapshots.d.ts +27 -0
  40. package/migrations/compare-migration-snapshots.js +165 -0
  41. package/migrations/generate-migrations.d.ts +21 -0
  42. package/migrations/generate-migrations.js +104 -0
  43. package/migrations/index.d.ts +3 -0
  44. package/migrations/index.js +7 -0
  45. package/migrations/migrate.d.ts +27 -0
  46. package/migrations/migrate.js +175 -0
  47. package/migrations/migration-types.d.ts +48 -0
  48. package/migrations/migration-types.js +88 -0
  49. package/migrations/update-migrations-ts-file.d.ts +1 -0
  50. package/migrations/update-migrations-ts-file.js +141 -0
  51. package/package.json +21 -1
  52. package/postgres/postgres-data-provider.d.ts +8 -3
  53. package/postgres/postgres-data-provider.js +46 -3
  54. package/postgres/schema-builder.js +81 -48
  55. package/remult-better-sqlite3.d.ts +12 -0
  56. package/remult-better-sqlite3.js +64 -0
  57. package/remult-bun-sqlite.d.ts +11 -0
  58. package/remult-bun-sqlite.js +56 -0
  59. package/remult-knex/index.d.ts +12 -5
  60. package/remult-knex/index.js +257 -90
  61. package/remult-mongo.d.ts +2 -2
  62. package/remult-mongo.js +2 -2
  63. package/remult-sql-js.d.ts +2 -15
  64. package/remult-sql-js.js +11 -152
  65. package/remult-sqlite-core.d.ts +21 -0
  66. package/remult-sqlite-core.js +217 -0
  67. package/server/expressBridge.d.ts +30 -1
  68. package/server/expressBridge.js +140 -32
  69. package/server/initAsyncHooks.d.ts +16 -0
  70. package/server/initAsyncHooks.js +128 -2
  71. package/src/CompoundIdField.js +8 -2
  72. package/src/column-interfaces.d.ts +9 -3
  73. package/src/context.d.ts +8 -6
  74. package/src/context.js +27 -36
  75. package/src/data-api.d.ts +13 -9
  76. package/src/data-api.js +184 -135
  77. package/src/data-providers/rest-data-provider.js +26 -15
  78. package/src/data-providers/sql-database.d.ts +17 -5
  79. package/src/data-providers/sql-database.js +31 -7
  80. package/src/data-providers/web-sql-data-provider.d.ts +1 -2
  81. package/src/data-providers/web-sql-data-provider.js +4 -8
  82. package/src/entity.d.ts +64 -6
  83. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +31 -7
  84. package/src/filter/filter-consumer-bridge-to-sql-request.js +46 -21
  85. package/src/filter/filter-interfaces.d.ts +106 -39
  86. package/src/filter/filter-interfaces.js +312 -32
  87. package/src/isOfType.d.ts +2 -0
  88. package/src/isOfType.js +14 -0
  89. package/src/remult3/Fields.d.ts +36 -0
  90. package/src/remult3/Fields.js +81 -19
  91. package/src/remult3/RepositoryImplementation.d.ts +7 -3
  92. package/src/remult3/RepositoryImplementation.js +106 -71
  93. package/src/remult3/addValidator.d.ts +2 -0
  94. package/src/remult3/addValidator.js +20 -0
  95. package/src/remult3/remult3.d.ts +6 -2
  96. package/src/remult3/remult3.js +28 -57
  97. package/src/server-action.d.ts +1 -1
  98. package/src/server-action.js +5 -4
  99. package/src/sql-command.d.ts +6 -1
  100. package/src/validators.d.ts +1 -0
  101. package/src/validators.js +10 -4
  102. package/src/valueConverters.js +1 -1
@@ -14,7 +14,7 @@ import { type RepositoryInternal, getInternalKey } from './repository-internals.
14
14
  export declare class RepositoryImplementation<entityType> implements Repository<entityType>, RepositoryInternal<entityType> {
15
15
  private _entity;
16
16
  _remult: Remult;
17
- private _dataProvider;
17
+ _dataProvider: DataProvider;
18
18
  private _info;
19
19
  private _defaultFindOptions?;
20
20
  _notFoundError(id: any): {
@@ -47,7 +47,9 @@ export declare class RepositoryImplementation<entityType> implements Repository<
47
47
  insert(item: Partial<MembersOnly<entityType>>): Promise<entityType>;
48
48
  get fields(): FieldsMetadata<entityType>;
49
49
  validate(entity: Partial<MembersOnly<entityType>>, ...fields: Extract<keyof MembersOnly<entityType>, string>[]): Promise<ErrorInfo<entityType> | undefined>;
50
- updateMany(where: EntityFilter<entityType>, set: Partial<MembersOnly<entityType>>): Promise<number>;
50
+ updateMany({ where }: {
51
+ where: EntityFilter<entityType>;
52
+ }, set: Partial<MembersOnly<entityType>>): Promise<number>;
51
53
  update(id: idType<entityType>, item: Partial<MembersOnly<entityType>>): Promise<entityType>;
52
54
  update(originalItem: Partial<MembersOnly<entityType>>, item: Partial<MembersOnly<entityType>>): Promise<entityType>;
53
55
  private _getRefForExistingRow;
@@ -63,7 +65,9 @@ export declare class RepositoryImplementation<entityType> implements Repository<
63
65
  toJson(item: entityType | entityType[] | Promise<entityType> | Promise<entityType[]>): any;
64
66
  fromJson(json: any, newRow?: boolean): any;
65
67
  count(where?: EntityFilter<entityType>): Promise<number>;
66
- deleteMany(where: EntityFilter<entityType>): Promise<number>;
68
+ deleteMany({ where, }: {
69
+ where: EntityFilter<entityType>;
70
+ }): Promise<number>;
67
71
  private _cache;
68
72
  findOne(options?: FindFirstOptions<entityType>, skipOrderByAndLimit?: boolean): Promise<entityType>;
69
73
  findFirst(where?: EntityFilter<entityType>, options?: FindFirstOptions<entityType>, skipOrderByAndLimit?: boolean): Promise<entityType>;
@@ -18,6 +18,8 @@ var relation_loader_js_1 = require("./relation-loader.js");
18
18
  var repository_internals_js_1 = require("./repository-internals.js");
19
19
  var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consumer-bridge-to-sql-request.js");
20
20
  var remult_static_js_1 = require("../remult-static.js");
21
+ var validators_js_1 = require("../validators.js");
22
+ var addValidator_js_1 = require("./addValidator.js");
21
23
  //import { remult } from "../remult-proxy";
22
24
  var classValidatorValidate = undefined;
23
25
  // import ("class-validator".toString())
@@ -435,51 +437,53 @@ var RepositoryImplementation = /** @class */ (function () {
435
437
  });
436
438
  });
437
439
  };
438
- RepositoryImplementation.prototype.updateMany = function (where, set) {
439
- var _a, e_7, _b, _c;
440
+ RepositoryImplementation.prototype.updateMany = function (_a, set) {
441
+ var _b, e_7, _c, _d;
442
+ var where = _a.where;
440
443
  return tslib_1.__awaiter(this, void 0, void 0, function () {
441
- var _d, _e, updated, _f, _g, _h, item, e_7_1;
442
- return tslib_1.__generator(this, function (_j) {
443
- switch (_j.label) {
444
+ var _e, _f, updated, _g, _h, _j, item, e_7_1;
445
+ return tslib_1.__generator(this, function (_k) {
446
+ switch (_k.label) {
444
447
  case 0:
448
+ filter_interfaces_js_1.Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
445
449
  if (!this._dataProvider.isProxy) return [3 /*break*/, 2];
446
- _e = (_d = this._edp).updateMany;
450
+ _f = (_e = this._edp).updateMany;
447
451
  return [4 /*yield*/, this._translateWhereToFilter(where)];
448
- case 1: return [2 /*return*/, _e.apply(_d, [_j.sent(), set])];
452
+ case 1: return [2 /*return*/, _f.apply(_e, [_k.sent(), set])];
449
453
  case 2:
450
454
  updated = 0;
451
- _j.label = 3;
455
+ _k.label = 3;
452
456
  case 3:
453
- _j.trys.push([3, 9, 10, 15]);
454
- _f = true, _g = tslib_1.__asyncValues(this.query({ where: where }));
455
- _j.label = 4;
456
- case 4: return [4 /*yield*/, _g.next()];
457
+ _k.trys.push([3, 9, 10, 15]);
458
+ _g = true, _h = tslib_1.__asyncValues(this.query({ where: where }));
459
+ _k.label = 4;
460
+ case 4: return [4 /*yield*/, _h.next()];
457
461
  case 5:
458
- if (!(_h = _j.sent(), _a = _h.done, !_a)) return [3 /*break*/, 8];
459
- _c = _h.value;
460
- _f = false;
461
- item = _c;
462
+ if (!(_j = _k.sent(), _b = _j.done, !_b)) return [3 /*break*/, 8];
463
+ _d = _j.value;
464
+ _g = false;
465
+ item = _d;
462
466
  (0, assign_js_1.assign)(item, set);
463
467
  return [4 /*yield*/, (0, getEntityRef_js_1.getEntityRef)(item).save()];
464
468
  case 6:
465
- _j.sent();
469
+ _k.sent();
466
470
  updated++;
467
- _j.label = 7;
471
+ _k.label = 7;
468
472
  case 7:
469
- _f = true;
473
+ _g = true;
470
474
  return [3 /*break*/, 4];
471
475
  case 8: return [3 /*break*/, 15];
472
476
  case 9:
473
- e_7_1 = _j.sent();
477
+ e_7_1 = _k.sent();
474
478
  e_7 = { error: e_7_1 };
475
479
  return [3 /*break*/, 15];
476
480
  case 10:
477
- _j.trys.push([10, , 13, 14]);
478
- if (!(!_f && !_a && (_b = _g.return))) return [3 /*break*/, 12];
479
- return [4 /*yield*/, _b.call(_g)];
481
+ _k.trys.push([10, , 13, 14]);
482
+ if (!(!_g && !_b && (_c = _h.return))) return [3 /*break*/, 12];
483
+ return [4 /*yield*/, _c.call(_h)];
480
484
  case 11:
481
- _j.sent();
482
- _j.label = 12;
485
+ _k.sent();
486
+ _k.label = 12;
483
487
  case 12: return [3 /*break*/, 14];
484
488
  case 13:
485
489
  if (e_7) throw e_7.error;
@@ -1086,50 +1090,52 @@ var RepositoryImplementation = /** @class */ (function () {
1086
1090
  });
1087
1091
  });
1088
1092
  };
1089
- RepositoryImplementation.prototype.deleteMany = function (where) {
1090
- var _a, e_18, _b, _c;
1093
+ RepositoryImplementation.prototype.deleteMany = function (_a) {
1094
+ var _b, e_18, _c, _d;
1095
+ var where = _a.where;
1091
1096
  return tslib_1.__awaiter(this, void 0, void 0, function () {
1092
- var _d, _e, deleted, _f, _g, _h, item, e_18_1;
1093
- return tslib_1.__generator(this, function (_j) {
1094
- switch (_j.label) {
1097
+ var _e, _f, deleted, _g, _h, _j, item, e_18_1;
1098
+ return tslib_1.__generator(this, function (_k) {
1099
+ switch (_k.label) {
1095
1100
  case 0:
1101
+ filter_interfaces_js_1.Filter.throwErrorIfFilterIsEmpty(where, 'deleteMany');
1096
1102
  if (!this._dataProvider.isProxy) return [3 /*break*/, 2];
1097
- _e = (_d = this._edp).deleteMany;
1103
+ _f = (_e = this._edp).deleteMany;
1098
1104
  return [4 /*yield*/, this._translateWhereToFilter(where)];
1099
- case 1: return [2 /*return*/, _e.apply(_d, [_j.sent()])];
1105
+ case 1: return [2 /*return*/, _f.apply(_e, [_k.sent()])];
1100
1106
  case 2:
1101
1107
  deleted = 0;
1102
- _j.label = 3;
1108
+ _k.label = 3;
1103
1109
  case 3:
1104
- _j.trys.push([3, 9, 10, 15]);
1105
- _f = true, _g = tslib_1.__asyncValues(this.query({ where: where }));
1106
- _j.label = 4;
1107
- case 4: return [4 /*yield*/, _g.next()];
1110
+ _k.trys.push([3, 9, 10, 15]);
1111
+ _g = true, _h = tslib_1.__asyncValues(this.query({ where: where }));
1112
+ _k.label = 4;
1113
+ case 4: return [4 /*yield*/, _h.next()];
1108
1114
  case 5:
1109
- if (!(_h = _j.sent(), _a = _h.done, !_a)) return [3 /*break*/, 8];
1110
- _c = _h.value;
1111
- _f = false;
1112
- item = _c;
1115
+ if (!(_j = _k.sent(), _b = _j.done, !_b)) return [3 /*break*/, 8];
1116
+ _d = _j.value;
1117
+ _g = false;
1118
+ item = _d;
1113
1119
  return [4 /*yield*/, (0, getEntityRef_js_1.getEntityRef)(item).delete()];
1114
1120
  case 6:
1115
- _j.sent();
1121
+ _k.sent();
1116
1122
  deleted++;
1117
- _j.label = 7;
1123
+ _k.label = 7;
1118
1124
  case 7:
1119
- _f = true;
1125
+ _g = true;
1120
1126
  return [3 /*break*/, 4];
1121
1127
  case 8: return [3 /*break*/, 15];
1122
1128
  case 9:
1123
- e_18_1 = _j.sent();
1129
+ e_18_1 = _k.sent();
1124
1130
  e_18 = { error: e_18_1 };
1125
1131
  return [3 /*break*/, 15];
1126
1132
  case 10:
1127
- _j.trys.push([10, , 13, 14]);
1128
- if (!(!_f && !_a && (_b = _g.return))) return [3 /*break*/, 12];
1129
- return [4 /*yield*/, _b.call(_g)];
1133
+ _k.trys.push([10, , 13, 14]);
1134
+ if (!(!_g && !_b && (_c = _h.return))) return [3 /*break*/, 12];
1135
+ return [4 /*yield*/, _c.call(_h)];
1130
1136
  case 11:
1131
- _j.sent();
1132
- _j.label = 12;
1137
+ _k.sent();
1138
+ _k.label = 12;
1133
1139
  case 12: return [3 /*break*/, 14];
1134
1140
  case 13:
1135
1141
  if (e_18) throw e_18.error;
@@ -1307,6 +1313,7 @@ var RepositoryImplementation = /** @class */ (function () {
1307
1313
  return tslib_1.__awaiter(this, void 0, void 0, function () {
1308
1314
  var z, z, _c, r;
1309
1315
  var _d;
1316
+ var _this = this;
1310
1317
  return tslib_1.__generator(this, function (_e) {
1311
1318
  switch (_e.label) {
1312
1319
  case 0:
@@ -1318,24 +1325,38 @@ var RepositoryImplementation = /** @class */ (function () {
1318
1325
  $and: [z, (_b = this._defaultFindOptions) === null || _b === void 0 ? void 0 : _b.where],
1319
1326
  };
1320
1327
  }
1321
- if (!(this.metadata.options.backendPrefilter && !this._dataProvider.isProxy)) return [3 /*break*/, 2];
1328
+ if (!!this._dataProvider.isProxy) return [3 /*break*/, 4];
1329
+ if (!this.metadata.options.backendPreprocessFilter) return [3 /*break*/, 2];
1330
+ return [4 /*yield*/, this.metadata.options.backendPreprocessFilter(where, {
1331
+ metadata: this.metadata,
1332
+ getFilterPreciseValues: function (filter) {
1333
+ return filter_interfaces_js_1.Filter.getPreciseValues(_this.metadata, filter || where);
1334
+ },
1335
+ })];
1336
+ case 1:
1337
+ where = _e.sent();
1338
+ _e.label = 2;
1339
+ case 2:
1340
+ if (!this.metadata.options.backendPrefilter) return [3 /*break*/, 4];
1322
1341
  z = where;
1323
1342
  _d = {};
1324
1343
  _c = [z];
1325
1344
  return [4 /*yield*/, filter_interfaces_js_1.Filter.resolve(this.metadata.options.backendPrefilter)];
1326
- case 1:
1327
- where = (_d.$and = _c.concat([_e.sent()]),
1328
- _d);
1329
- _e.label = 2;
1330
- case 2: return [4 /*yield*/, filter_interfaces_js_1.Filter.fromEntityFilter(this.metadata, where)];
1331
1345
  case 3:
1346
+ where = (_d.$and = _c.concat([
1347
+ _e.sent()
1348
+ ]),
1349
+ _d);
1350
+ _e.label = 4;
1351
+ case 4: return [4 /*yield*/, filter_interfaces_js_1.Filter.fromEntityFilter(this.metadata, where)];
1352
+ case 5:
1332
1353
  r = _e.sent();
1333
- if (!(r && !this._dataProvider.isProxy)) return [3 /*break*/, 5];
1354
+ if (!(r && !this._dataProvider.isProxy)) return [3 /*break*/, 7];
1334
1355
  return [4 /*yield*/, filter_interfaces_js_1.Filter.translateCustomWhere(r, this.metadata, this._remult)];
1335
- case 4:
1356
+ case 6:
1336
1357
  r = _e.sent();
1337
- _e.label = 5;
1338
- case 5: return [2 /*return*/, r];
1358
+ _e.label = 7;
1359
+ case 7: return [2 /*return*/, r];
1339
1360
  }
1340
1361
  });
1341
1362
  });
@@ -1954,7 +1975,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
1954
1975
  return _this.instance[y.key];
1955
1976
  };
1956
1977
  if (this.metadata.idMetadata.field instanceof CompoundIdField_js_1.CompoundIdField)
1957
- return this.metadata.idMetadata.field.fields.map(getVal).join(',');
1978
+ return this.metadata.idMetadata.field.getId(getVal);
1958
1979
  return getVal(this.metadata.idMetadata.field);
1959
1980
  };
1960
1981
  rowHelperImplementation.prototype.saveMoreOriginalData = function () {
@@ -2063,7 +2084,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2063
2084
  case 2:
2064
2085
  doNotSave_1 = false;
2065
2086
  e = this.buildLifeCycleEvent(function () { return (doNotSave_1 = true); });
2066
- if (!!this.remult.dataProvider.isProxy) return [3 /*break*/, 12];
2087
+ if (!!this.repository._dataProvider.isProxy) return [3 /*break*/, 12];
2067
2088
  _p.label = 3;
2068
2089
  case 3:
2069
2090
  _p.trys.push([3, 8, 9, 10]);
@@ -2163,7 +2184,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2163
2184
  case 20: return [4 /*yield*/, this.loadDataFrom(updatedRow)];
2164
2185
  case 21:
2165
2186
  _p.sent();
2166
- if (!!this.remult.dataProvider.isProxy) return [3 /*break*/, 31];
2187
+ if (!!this.repository._dataProvider.isProxy) return [3 /*break*/, 31];
2167
2188
  if (!this.info.entityInfo.saved) return [3 /*break*/, 23];
2168
2189
  return [4 /*yield*/, this.info.entityInfo.saved(this.instance, e)];
2169
2190
  case 22:
@@ -2302,7 +2323,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2302
2323
  case 0:
2303
2324
  this.__clearErrorsAndReportChanged();
2304
2325
  e = this.buildLifeCycleEvent();
2305
- if (!!this.remult.dataProvider.isProxy) return [3 /*break*/, 2];
2326
+ if (!!this.repository._dataProvider.isProxy) return [3 /*break*/, 2];
2306
2327
  if (!this.info.entityInfo.deleting) return [3 /*break*/, 2];
2307
2328
  return [4 /*yield*/, this.info.entityInfo.deleting(this.instance, e)];
2308
2329
  case 1:
@@ -2316,7 +2337,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2316
2337
  return [4 /*yield*/, this.edp.delete(this.id)];
2317
2338
  case 4:
2318
2339
  _d.sent();
2319
- if (!!this.remult.dataProvider.isProxy) return [3 /*break*/, 6];
2340
+ if (!!this.repository._dataProvider.isProxy) return [3 /*break*/, 6];
2320
2341
  if (!this.info.entityInfo.deleted) return [3 /*break*/, 6];
2321
2342
  return [4 /*yield*/, this.info.entityInfo.deleted(this.instance, e)];
2322
2343
  case 5:
@@ -3094,9 +3115,13 @@ var EntityFullInfo = /** @class */ (function () {
3094
3115
  }
3095
3116
  if (_this.idMetadata.field instanceof CompoundIdField_js_1.CompoundIdField) {
3096
3117
  var field_1 = _this.idMetadata.field;
3097
- return {
3098
- $or: ids.map(function (x) { return field_1.isEqualTo(x); }),
3099
- };
3118
+ if (ids.length == 1) {
3119
+ return field_1.isEqualTo(ids[0]);
3120
+ }
3121
+ else
3122
+ return {
3123
+ $or: ids.map(function (x) { return field_1.isEqualTo(x); }),
3124
+ };
3100
3125
  }
3101
3126
  if (ids.length == 1)
3102
3127
  return _a = {},
@@ -3245,6 +3270,13 @@ function ValueListFieldType() {
3245
3270
  ;
3246
3271
  (o.valueConverter = ValueListInfo.get(type)),
3247
3272
  (o.displayValue = function (item, val) { return val === null || val === void 0 ? void 0 : val.caption; });
3273
+ o.validate = function (entity, ref) {
3274
+ var values = ValueListInfo.get(type).getValues();
3275
+ if (ref.value && !values.find(function (v) { return v === ref.value; })) {
3276
+ ref.value = values.find(function (v) { return v.id === ref.value.id; }) || ref.value;
3277
+ }
3278
+ return validators_js_1.Validators.in(values)(entity, ref);
3279
+ };
3248
3280
  }], tslib_1.__read(options), false))(type, context);
3249
3281
  };
3250
3282
  }
@@ -3373,8 +3405,11 @@ function buildOptions(options, remult) {
3373
3405
  if (o) {
3374
3406
  if (typeof o === 'function')
3375
3407
  o(r, remult);
3376
- else
3377
- Object.assign(r, o);
3408
+ else {
3409
+ var validate = o.validate, otherOptions = tslib_1.__rest(o, ["validate"]);
3410
+ r.validate = (0, addValidator_js_1.addValidator)(r.validate, validate);
3411
+ Object.assign(r, otherOptions);
3412
+ }
3378
3413
  }
3379
3414
  }
3380
3415
  }
@@ -3392,7 +3427,7 @@ function decorateColumnSettings(settings, remult) {
3392
3427
  if (settings.valueType) {
3393
3428
  var settingsOnTypeLevel = settings.valueType[exports.storableMember];
3394
3429
  if (settingsOnTypeLevel) {
3395
- settings = tslib_1.__assign(tslib_1.__assign({}, buildOptions(settingsOnTypeLevel, remult)), settings);
3430
+ settings = buildOptions(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(settingsOnTypeLevel), false), [settings], false), remult);
3396
3431
  }
3397
3432
  }
3398
3433
  if (settings.valueType == String) {
@@ -0,0 +1,2 @@
1
+ import type { FieldOptions } from '../column-interfaces.js';
2
+ export declare function addValidator(validators: FieldOptions['validate'], newValidator: FieldOptions['validate'], atStart?: boolean): import("../column-interfaces.js").FieldValidator<any, any> | import("../column-interfaces.js").FieldValidator<any, any>[];
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addValidator = void 0;
4
+ var tslib_1 = require("tslib");
5
+ function addValidator(validators, newValidator, atStart) {
6
+ if (atStart === void 0) { atStart = false; }
7
+ if (!newValidator)
8
+ return validators;
9
+ var newValidators = Array.isArray(newValidator)
10
+ ? newValidator
11
+ : [newValidator];
12
+ var validatorsArray = Array.isArray(validators)
13
+ ? validators
14
+ : validators
15
+ ? [validators]
16
+ : [];
17
+ return atStart
18
+ ? tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(newValidators), false), tslib_1.__read(validatorsArray), false) : tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(validatorsArray), false), tslib_1.__read(newValidators), false);
19
+ }
20
+ exports.addValidator = addValidator;
@@ -315,14 +315,18 @@ export interface Repository<entityType> {
315
315
  /**
316
316
  * Updates all items that match the `where` condition.
317
317
  */
318
- updateMany(where: EntityFilter<entityType>, item: Partial<MembersOnly<entityType>>): Promise<number>;
318
+ updateMany(options: {
319
+ where: EntityFilter<entityType>;
320
+ }, item: Partial<MembersOnly<entityType>>): Promise<number>;
319
321
  /** Deletes an Item*/
320
322
  delete(id: idType<entityType>): Promise<void>;
321
323
  delete(item: Partial<MembersOnly<entityType>>): Promise<void>;
322
324
  /**
323
325
  * Deletes all items that match the `where` condition.
324
326
  */
325
- deleteMany(where: EntityFilter<entityType>): Promise<number>;
327
+ deleteMany(options: {
328
+ where: EntityFilter<entityType>;
329
+ }): Promise<number>;
326
330
  /** Creates an instance of an item. It'll not be saved to the data source unless `save` or `insert` will be called for that item */
327
331
  create(item?: Partial<MembersOnly<entityType>>): entityType;
328
332
  toJson(item: Promise<entityType[]>): Promise<any[]>;
@@ -1,60 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- /*y1 - workshop
4
-
5
- * Experiment with doing this with version control - so the students can follow changes
6
- * Prepare stackblitz
7
-
8
-
9
- # influencer:
10
- * review react summit
11
- #
12
-
13
- //y1 - getFields didn't work for kobi in the home component
14
-
15
- //p1 - processError in remult express
16
- //p1 - I think there should be a way to throw a forbidden exception
17
- //p1 - add section to Fields doc, explaining field type in db
18
- //p1 - add section about union type
19
- //p1 - add section about value list field type
3
+ //p1 - add documentation for bun sqlite
4
+ //p2 - fix dark background to also work on groups
5
+ //y1 - JY suggestion of having generate as part of the ensure schema - not sure
6
+ //y1 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
7
+ //y1 - consider changing the sql raw filter to return the sql, instead of setting the sql property
8
+ //p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
9
+ //p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string}
10
+ //p2 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
11
+ //y1 - fix validators cache
12
+ //y2 - should we validate relations
13
+ //y1 - dependency of live query tables
14
+ //p1 - see why mongo tests do not run anymore
15
+ //y1 - consider the bot that updates dependencies
16
+ //y1 - consider replacing all errors with error classes that extend the base Error class
17
+ //y2 - should enforce integer - currently we probably round / truncate it
18
+ //y1 - talk about filter on objects that are not loaded - {
19
+ //category: repo(CompoundId).create({ company: 7, index: 3, name: '' }),
20
+ // }
21
+ //y1 - consider id to also support keyof (id:['company','index'])
22
+ /*y1 - talk about modules in init express with entities/controllers,initRequest,initApi
23
+ - support get with backend method, with url search params as the first parameter, & url as second parameter
24
+ - support returning redirect, and plain html (For sign in scenarios)
20
25
 
26
+ */
27
+ //p1 - in this video I'll use remult to turn a frontend app to a fullstack app
21
28
  /*y1 - Talk JYC - JYC - add some integrity checks on delete
22
29
  - soft delete
23
30
  - delete restrict (implicit, or user selected - and if so, how) (delete & update of id)
24
31
 
25
32
  */
26
- /*y1 currency.ts:10 Uncaught TypeError: Currency_1 is not a constructor
27
- // - ValueListFieldType - the decorator gives an error in react vite project - see langulage yedidya
28
- // happens in target 2022, ts<5.1.6
29
- //typescript 5.1.6
30
- @ValueListFieldType()
31
- export class Currency {
32
- constructor(
33
- public id: number,
34
- public caption: string,
35
- public symbol: string
36
- ) {}
37
- static shekel = new Currency(1, 'Shekel', '₪');
38
- static dollar = new Currency(2, 'Dollar', '$');
39
- static euro = new Currency(3, 'Euro', '€');
40
- static pound = new Currency(4, 'Pound', '£');
41
- static yen = new Currency(5, 'Yen', '¥');
42
- }
43
-
44
- */
45
- //y1 - allow api read to also support instance and filter. - problem with promise
46
- //y1 - admin url1 - pocketbase use /_ for the admin
47
33
  //y1 - consider sql expression gets a dbnames of it's own (that already has the "tableName" defined correctly) maybe also the filter translator
48
- /*y1 - talk about modules in init express with entities/controllers,initRequest,initApi
49
- - support get with backend method, with url search params as the first parameter, & url as second parameter
50
- - support returning redirect, and plain html (For sign in scenarios)
51
-
52
- */
53
34
  //y1 - tried to upgrade vitest, nuxt tests are failing with loading uuid - sounds familiar?
54
35
  //y1 - I think that the tests you've setup don't cover next app router - I added to the setup, but not sure where else
55
36
  //y1 - talk about the parameter issue with backend methods
56
37
  //y1 - select data provider per entity https://discord.com/channels/975754286384418847/976006081748807690/1201415305885397003
57
- //y1 - migrations
58
38
  //y1 - live query refresh of view on table update
59
39
  //y1 - main vs master
60
40
  //y2 - livequery for findfirst (@JY)
@@ -65,11 +45,9 @@ export class Currency {
65
45
  })
66
46
  Description = ""*/
67
47
  //y2 - get backend methods to work when specifying types for date, and entities as poco's
68
- //y2 - conside law-q db based on schema issue - I think that while running the dataProvider function, we should have a valid remult - maybe even have a valid remult, that will be valid until api is run
69
- //y2 - #239 - (@JY) add a way to get from fieldMetadata back to entity repo (like we have in fieldRef)
70
48
  //y2 - constraints (@JY)
71
49
  /*p2 remult admin
72
-
50
+ - when making a change and canceling - the changed value still appears
73
51
  - Small thing, I get SvelteKitError: Not found: /vite.svg
74
52
  - understand the to many relation for the admin, based on the to one
75
53
  - relation from order details to order gave a compound id info - and it is not true - same for the relation to product
@@ -81,11 +59,9 @@ export class Currency {
81
59
  - remult-admin didn't show a update for a table with a uniqua that is numeric
82
60
  */
83
61
  //remult
84
- //p1 - better support union types (status, etc... so it'll work also in filter etc...)
85
62
  //p1 - when a tasks table exists in a different schema - we get many errors
86
63
  //p1 - live query with include
87
64
  //p1 - adjust angular tutorial starter kit for latest angular (as is in tutorial)
88
- //p2 - allow find options preprocessor for api calls, to use for authorization
89
65
  //p2 - when subscribe is forbidden - the query still runs after the renew process
90
66
  //p2 - 'update tasks set where id = $1
91
67
  //p2 - type metadata.key - to keyof entity - based on cwis input
@@ -93,23 +69,18 @@ export class Currency {
93
69
  //p2 - when value changes for field with error, clear error - so the user will feel comfortable
94
70
  //p2 - allowApiUpdate should be false for include in api false
95
71
  //docs
96
- //p2 - make sure that internal members do not appear in the documentation - try running it on the d.ts instead of the code itself.
97
72
  //------
73
+ //y2 - wrap identifier for custom filter & sql expression
74
+ //y2 - Should we create a separate implementation of command - one that the user uses, and another that the database implements (with only the bear necesities) - for example, to provide a second paramter called field for toDb conversions
75
+ //y2 - should we simply inherit from SqlDataProvider - and send the required parameter in the call to the base class - I think that new SqlDatabase(new PostgresDataProvider()) is a bilt combersome
98
76
  //y2 - from the crm-demo(https://crm-demo.up.railway.app/deals), after editing a deal: - _updateEntityBasedOnApi
99
77
  //y2 - Backend methods are transactions, it's not intuitive and maybe should be optional / opt in
100
78
  //y2 - how to run a transaction as a user
101
- //p2 - enum column
102
- //y2 - message for invalid value
103
79
  //y2 - message for relation that is missing
104
80
  //y2 - consider multi tenancies
105
- //p2 - more column types
106
- //p2 - document validators
107
81
  //p2 - and validators to reference
108
82
  //y2 - discuss a default date formatter
109
83
  //y2 - add some api testing framework for user unit tests (will help with codesandbox based discussions)
110
84
  //[ ] V2 - what to do about for relations count?
111
85
  //[ ] V2 - condition? not to fetch if null etc....
112
- //[ ] V3 - all these fields will also appear in the where etc... in the typescript api - but we will not enforce them
113
- //y2 - consider if field types should include validation in them by default (string,number that it's not NaN etc...) and if so, what message?
114
- //y2 - should enforce integer - currently we probably round / truncate it
115
86
  //p1 - adjust react tutorial to esm
@@ -21,7 +21,7 @@ export declare abstract class Action<inParam, outParam> implements ActionInterfa
21
21
  __register(reg: (url: string, queue: boolean, allowed: AllowedForInstance<any>, what: (data: any, req: Remult, res: DataApiResponse) => void) => void): void;
22
22
  }
23
23
  export declare class ForbiddenError extends Error {
24
- constructor();
24
+ constructor(message?: string);
25
25
  isForbiddenError: true;
26
26
  }
27
27
  export declare class myServerAction extends Action<inArgs, result> {
@@ -98,7 +98,7 @@ var Action = /** @class */ (function () {
98
98
  // got a problem in next with instance of ForbiddenError - so replaced it with this bool
99
99
  res.forbidden();
100
100
  else
101
- res.error(err_1);
101
+ res.error(err_1, undefined);
102
102
  return [3 /*break*/, 3];
103
103
  case 3: return [2 /*return*/];
104
104
  }
@@ -111,8 +111,9 @@ var Action = /** @class */ (function () {
111
111
  exports.Action = Action;
112
112
  var ForbiddenError = /** @class */ (function (_super) {
113
113
  tslib_1.__extends(ForbiddenError, _super);
114
- function ForbiddenError() {
115
- var _this = _super.call(this, 'Forbidden') || this;
114
+ function ForbiddenError(message) {
115
+ if (message === void 0) { message = 'Forbidden'; }
116
+ var _this = _super.call(this, message) || this;
116
117
  _this.isForbiddenError = true;
117
118
  return _this;
118
119
  }
@@ -381,7 +382,7 @@ function BackendMethod(options) {
381
382
  // got a problem in next with instance of ForbiddenError - so replaced it with this bool
382
383
  res.forbidden();
383
384
  else
384
- res.error(err_3);
385
+ res.error(err_3, undefined);
385
386
  return [3 /*break*/, 4];
386
387
  case 4: return [2 /*return*/];
387
388
  }
@@ -7,16 +7,21 @@ export interface SqlImplementation extends HasWrapIdentifier {
7
7
  ensureSchema?(entities: EntityMetadata[]): Promise<void>;
8
8
  supportsJsonColumnType?: boolean;
9
9
  orderByNullsFirst?: boolean;
10
+ end(): Promise<void>;
10
11
  afterMutation?: VoidFunction;
11
12
  }
12
13
  export interface HasWrapIdentifier {
13
14
  wrapIdentifier?(name: string): string;
14
15
  }
16
+ export interface SqlCommandFactory extends HasWrapIdentifier {
17
+ createCommand(): SqlCommand;
18
+ execute(sql: string): Promise<SqlResult>;
19
+ }
15
20
  export interface SqlCommand extends SqlCommandWithParameters {
16
21
  execute(sql: string): Promise<SqlResult>;
17
22
  }
18
23
  export interface SqlCommandWithParameters {
19
- /** @deprecated @deprecated use `param` instead*/
24
+ /** @deprecated use `param` instead*/
20
25
  addParameterAndReturnSqlToken(val: any): string;
21
26
  param(val: any): string;
22
27
  }
@@ -47,3 +47,4 @@ export type ValidatorWithArgs<valueType, argsType> = (args: argsType, message?:
47
47
  export declare function createValidatorWithArgs<valueType, argsType>(validate: (entity: any, e: ValidateFieldEvent<any, valueType>, args: argsType) => Promise<boolean | string> | boolean | string, defaultMessage: ValidationMessage<valueType, argsType>): ValidatorWithArgs<valueType, argsType> & {
48
48
  defaultMessage: ValidationMessage<valueType, argsType>;
49
49
  };
50
+ export declare function getEnumValues<theEnum = any>(enumObj: theEnum): any[];
package/src/validators.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createValidatorWithArgs = exports.createValueValidatorWithArgs = exports.createValueValidator = exports.valueValidator = exports.createValidator = exports.Validators = void 0;
3
+ exports.getEnumValues = exports.createValidatorWithArgs = exports.createValueValidatorWithArgs = exports.createValueValidator = exports.valueValidator = exports.createValidator = exports.Validators = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var Validators = /** @class */ (function () {
6
6
  function Validators() {
@@ -48,11 +48,12 @@ var Validators = /** @class */ (function () {
48
48
  });
49
49
  Validators.email = createValueValidator(function (val) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val); }, 'Invalid Email');
50
50
  Validators.url = createValueValidator(function (val) { return !!new URL(val); }, 'Invalid Url');
51
- Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) { return "Value must be one of ".concat(values.join(', ')); });
51
+ Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) { return "Value must be one of ".concat(values.map(function (y) {
52
+ return typeof y === "object" ? y['id'] !== undefined ? y['id'] : y.toString() : y;
53
+ }).join(', ')); });
52
54
  Validators.notNull = createValueValidator(function (val) { return val != null; }, 'Should not be null');
53
55
  Validators.enum = createValueValidatorWithArgs(function (value, enumObj) { return Object.values(enumObj).includes(value); }, function (enumObj) {
54
- return "Value must be one of ".concat(Object.values(enumObj)
55
- .filter(function (x) { return typeof enumObj[x] !== 'number'; })
56
+ return "Value must be one of ".concat(getEnumValues(enumObj)
56
57
  .join(', '));
57
58
  });
58
59
  Validators.relationExists = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
@@ -207,3 +208,8 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
207
208
  },
208
209
  });
209
210
  }
211
+ function getEnumValues(enumObj) {
212
+ return Object.values(enumObj)
213
+ .filter(function (x) { return typeof enumObj[x] !== 'number'; });
214
+ }
215
+ exports.getEnumValues = getEnumValues;