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.
- package/README.md +194 -129
- package/esm/graphql.js +131 -59
- package/esm/index.js +1 -1
- package/esm/migrations/compare-migration-snapshots.js +61 -0
- package/esm/migrations/generate-migrations.js +68 -0
- package/esm/migrations/index.js +2 -0
- package/esm/migrations/migrate.js +90 -0
- package/esm/migrations/migration-types.js +36 -0
- package/esm/migrations/update-migrations-ts-file.js +115 -0
- package/esm/postgres/postgres-data-provider.js +24 -3
- package/esm/postgres/schema-builder.js +35 -26
- package/esm/remult-better-sqlite3.js +47 -0
- package/esm/remult-bun-sqlite.js +41 -0
- package/esm/remult-knex/index.js +180 -51
- package/esm/remult-mongo.js +2 -2
- package/esm/remult-sql-js.js +3 -78
- package/esm/remult-sqlite-core.js +104 -0
- package/esm/server/expressBridge.js +130 -29
- package/esm/server/initAsyncHooks.js +75 -1
- package/esm/src/CompoundIdField.js +8 -2
- package/esm/src/context.js +20 -24
- package/esm/src/data-api.js +71 -30
- package/esm/src/data-providers/rest-data-provider.js +17 -15
- package/esm/src/data-providers/sql-database.js +32 -7
- package/esm/src/data-providers/web-sql-data-provider.js +1 -9
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +37 -11
- package/esm/src/filter/filter-interfaces.js +229 -17
- package/esm/src/isOfType.js +9 -0
- package/esm/src/remult3/Fields.js +70 -18
- package/esm/src/remult3/RepositoryImplementation.js +47 -21
- package/esm/src/remult3/addValidator.js +15 -0
- package/esm/src/remult3/remult3.js +28 -57
- package/esm/src/server-action.js +4 -4
- package/esm/src/validators.js +6 -3
- package/esm/src/valueConverters.js +1 -1
- package/graphql.js +156 -71
- package/index.d.ts +4 -4
- package/index.js +2 -1
- package/migrations/compare-migration-snapshots.d.ts +27 -0
- package/migrations/compare-migration-snapshots.js +165 -0
- package/migrations/generate-migrations.d.ts +21 -0
- package/migrations/generate-migrations.js +104 -0
- package/migrations/index.d.ts +3 -0
- package/migrations/index.js +7 -0
- package/migrations/migrate.d.ts +27 -0
- package/migrations/migrate.js +175 -0
- package/migrations/migration-types.d.ts +48 -0
- package/migrations/migration-types.js +88 -0
- package/migrations/update-migrations-ts-file.d.ts +1 -0
- package/migrations/update-migrations-ts-file.js +141 -0
- package/package.json +21 -1
- package/postgres/postgres-data-provider.d.ts +8 -3
- package/postgres/postgres-data-provider.js +46 -3
- package/postgres/schema-builder.js +81 -48
- package/remult-better-sqlite3.d.ts +12 -0
- package/remult-better-sqlite3.js +64 -0
- package/remult-bun-sqlite.d.ts +11 -0
- package/remult-bun-sqlite.js +56 -0
- package/remult-knex/index.d.ts +12 -5
- package/remult-knex/index.js +257 -90
- package/remult-mongo.d.ts +2 -2
- package/remult-mongo.js +2 -2
- package/remult-sql-js.d.ts +2 -15
- package/remult-sql-js.js +11 -152
- package/remult-sqlite-core.d.ts +21 -0
- package/remult-sqlite-core.js +217 -0
- package/server/expressBridge.d.ts +30 -1
- package/server/expressBridge.js +140 -32
- package/server/initAsyncHooks.d.ts +16 -0
- package/server/initAsyncHooks.js +128 -2
- package/src/CompoundIdField.js +8 -2
- package/src/column-interfaces.d.ts +9 -3
- package/src/context.d.ts +8 -6
- package/src/context.js +27 -36
- package/src/data-api.d.ts +13 -9
- package/src/data-api.js +184 -135
- package/src/data-providers/rest-data-provider.js +26 -15
- package/src/data-providers/sql-database.d.ts +17 -5
- package/src/data-providers/sql-database.js +31 -7
- package/src/data-providers/web-sql-data-provider.d.ts +1 -2
- package/src/data-providers/web-sql-data-provider.js +4 -8
- package/src/entity.d.ts +64 -6
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +31 -7
- package/src/filter/filter-consumer-bridge-to-sql-request.js +46 -21
- package/src/filter/filter-interfaces.d.ts +106 -39
- package/src/filter/filter-interfaces.js +312 -32
- package/src/isOfType.d.ts +2 -0
- package/src/isOfType.js +14 -0
- package/src/remult3/Fields.d.ts +36 -0
- package/src/remult3/Fields.js +81 -19
- package/src/remult3/RepositoryImplementation.d.ts +7 -3
- package/src/remult3/RepositoryImplementation.js +106 -71
- package/src/remult3/addValidator.d.ts +2 -0
- package/src/remult3/addValidator.js +20 -0
- package/src/remult3/remult3.d.ts +6 -2
- package/src/remult3/remult3.js +28 -57
- package/src/server-action.d.ts +1 -1
- package/src/server-action.js +5 -4
- package/src/sql-command.d.ts +6 -1
- package/src/validators.d.ts +1 -0
- package/src/validators.js +10 -4
- package/src/valueConverters.js +1 -1
|
@@ -12,9 +12,129 @@ var Filter = /** @class */ (function () {
|
|
|
12
12
|
function Filter(apply) {
|
|
13
13
|
this.apply = apply;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
//@internal
|
|
16
|
+
Filter.throwErrorIfFilterIsEmpty = function (where, methodName) {
|
|
17
|
+
if (Filter.isFilterEmpty(where)) {
|
|
18
|
+
throw {
|
|
19
|
+
message: "".concat(methodName, ": requires a filter to protect against accidental delete/update of all rows"),
|
|
20
|
+
httpStatusCode: 400,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//@internal
|
|
25
|
+
Filter.isFilterEmpty = function (where) {
|
|
26
|
+
var e_1, _a, e_2, _b;
|
|
27
|
+
if (where.$and) {
|
|
28
|
+
try {
|
|
29
|
+
for (var _c = tslib_1.__values(where.$and), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
30
|
+
var a = _d.value;
|
|
31
|
+
if (!Filter.isFilterEmpty(a)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
37
|
+
finally {
|
|
38
|
+
try {
|
|
39
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
40
|
+
}
|
|
41
|
+
finally { if (e_1) throw e_1.error; }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (where.$or) {
|
|
45
|
+
try {
|
|
46
|
+
for (var _e = tslib_1.__values(where.$or), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
47
|
+
var a = _f.value;
|
|
48
|
+
if (Filter.isFilterEmpty(a)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
54
|
+
finally {
|
|
55
|
+
try {
|
|
56
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
57
|
+
}
|
|
58
|
+
finally { if (e_2) throw e_2.error; }
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (Object.keys(where).filter(function (x) { return !['$or', '$and'].includes(x); }).length == 0) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Retrieves precise values for each property in a filter for an entity.
|
|
69
|
+
* @template entityType The type of the entity being filtered.
|
|
70
|
+
* @param metadata The metadata of the entity being filtered.
|
|
71
|
+
* @param filter The filter to analyze.
|
|
72
|
+
* @returns A promise that resolves to a FilterPreciseValues object containing the precise values for each property.
|
|
73
|
+
* @example
|
|
74
|
+
* const preciseValues = await Filter.getPreciseValues(meta, {
|
|
75
|
+
* status: { $ne: 'active' },
|
|
76
|
+
* $or: [
|
|
77
|
+
* { customerId: ["1", "2"] },
|
|
78
|
+
* { customerId: "3" }
|
|
79
|
+
* ]
|
|
80
|
+
* });
|
|
81
|
+
* console.log(preciseValues);
|
|
82
|
+
* // Output:
|
|
83
|
+
* // {
|
|
84
|
+
* // "customerId": ["1", "2", "3"], // Precise values inferred from the filter
|
|
85
|
+
* // "status": undefined, // Cannot infer precise values for 'status'
|
|
86
|
+
* // }
|
|
87
|
+
|
|
88
|
+
*/
|
|
89
|
+
Filter.getPreciseValues = function (metadata, filter) {
|
|
90
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
91
|
+
var result;
|
|
92
|
+
return tslib_1.__generator(this, function (_a) {
|
|
93
|
+
switch (_a.label) {
|
|
94
|
+
case 0:
|
|
95
|
+
result = new preciseValuesCollector();
|
|
96
|
+
return [4 /*yield*/, Filter.fromEntityFilter(metadata, filter).__applyToConsumer(result)];
|
|
97
|
+
case 1:
|
|
98
|
+
_a.sent();
|
|
99
|
+
return [2 /*return*/, result.preciseValues];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Retrieves precise values for each property in a filter for an entity.
|
|
106
|
+
* @template entityType The type of the entity being filtered.
|
|
107
|
+
* @param metadata The metadata of the entity being filtered.
|
|
108
|
+
* @param filter The filter to analyze.
|
|
109
|
+
* @returns A promise that resolves to a FilterPreciseValues object containing the precise values for each property.
|
|
110
|
+
* @example
|
|
111
|
+
* const preciseValues = await where.getPreciseValues();
|
|
112
|
+
* console.log(preciseValues);
|
|
113
|
+
* // Output:
|
|
114
|
+
* // {
|
|
115
|
+
* // "customerId": ["1", "2", "3"], // Precise values inferred from the filter
|
|
116
|
+
* // "status": undefined, // Cannot infer precise values for 'status'
|
|
117
|
+
* // }
|
|
118
|
+
|
|
119
|
+
*/
|
|
120
|
+
Filter.prototype.getPreciseValues = function () {
|
|
121
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
122
|
+
var result;
|
|
123
|
+
return tslib_1.__generator(this, function (_a) {
|
|
124
|
+
switch (_a.label) {
|
|
125
|
+
case 0:
|
|
126
|
+
result = new preciseValuesCollector();
|
|
127
|
+
return [4 /*yield*/, this.__applyToConsumer(result)];
|
|
128
|
+
case 1:
|
|
129
|
+
_a.sent();
|
|
130
|
+
return [2 /*return*/, result.preciseValues];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
Filter.createCustom = function (translator, key) {
|
|
16
136
|
if (key === void 0) { key = ''; }
|
|
17
|
-
var rawFilterInfo = { key: key, rawFilterTranslator:
|
|
137
|
+
var rawFilterInfo = { key: key, rawFilterTranslator: translator };
|
|
18
138
|
return Object.assign(function (x) {
|
|
19
139
|
var _a;
|
|
20
140
|
var z = {};
|
|
@@ -206,7 +326,6 @@ var Filter = /** @class */ (function () {
|
|
|
206
326
|
});
|
|
207
327
|
});
|
|
208
328
|
};
|
|
209
|
-
//@internal
|
|
210
329
|
Filter.prototype.toJson = function () {
|
|
211
330
|
var r = new FilterSerializer();
|
|
212
331
|
this.__applyToConsumer(r);
|
|
@@ -317,19 +436,19 @@ var filterHelper = /** @class */ (function () {
|
|
|
317
436
|
filterHelper.prototype.isNotIn = function (values) {
|
|
318
437
|
var _this = this;
|
|
319
438
|
return new Filter(function (add) {
|
|
320
|
-
var
|
|
439
|
+
var e_3, _a;
|
|
321
440
|
try {
|
|
322
441
|
for (var values_1 = tslib_1.__values(values), values_1_1 = values_1.next(); !values_1_1.done; values_1_1 = values_1.next()) {
|
|
323
442
|
var v = values_1_1.value;
|
|
324
443
|
add.isDifferentFrom(_this.metadata, _this.processVal(v));
|
|
325
444
|
}
|
|
326
445
|
}
|
|
327
|
-
catch (
|
|
446
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
328
447
|
finally {
|
|
329
448
|
try {
|
|
330
449
|
if (values_1_1 && !values_1_1.done && (_a = values_1.return)) _a.call(values_1);
|
|
331
450
|
}
|
|
332
|
-
finally { if (
|
|
451
|
+
finally { if (e_3) throw e_3.error; }
|
|
333
452
|
}
|
|
334
453
|
});
|
|
335
454
|
};
|
|
@@ -462,7 +581,7 @@ var AndFilter = /** @class */ (function (_super) {
|
|
|
462
581
|
filters[_i] = arguments[_i];
|
|
463
582
|
}
|
|
464
583
|
var _this = _super.call(this, function (add) {
|
|
465
|
-
var
|
|
584
|
+
var e_4, _a;
|
|
466
585
|
try {
|
|
467
586
|
for (var _b = tslib_1.__values(_this.filters), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
468
587
|
var iterator = _c.value;
|
|
@@ -470,12 +589,12 @@ var AndFilter = /** @class */ (function (_super) {
|
|
|
470
589
|
iterator.__applyToConsumer(add);
|
|
471
590
|
}
|
|
472
591
|
}
|
|
473
|
-
catch (
|
|
592
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
474
593
|
finally {
|
|
475
594
|
try {
|
|
476
595
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
477
596
|
}
|
|
478
|
-
finally { if (
|
|
597
|
+
finally { if (e_4) throw e_4.error; }
|
|
479
598
|
}
|
|
480
599
|
}) || this;
|
|
481
600
|
_this.filters = filters;
|
|
@@ -591,17 +710,30 @@ function entityFilterToJson(entityDefs, where) {
|
|
|
591
710
|
}
|
|
592
711
|
exports.entityFilterToJson = entityFilterToJson;
|
|
593
712
|
function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
594
|
-
var where =
|
|
713
|
+
var where = {};
|
|
714
|
+
function addAnd(what) {
|
|
715
|
+
if (!where.$and) {
|
|
716
|
+
where.$and = [];
|
|
717
|
+
}
|
|
718
|
+
where.$and.push(what);
|
|
719
|
+
}
|
|
720
|
+
function addToFilterObject(key, val) {
|
|
721
|
+
var _a;
|
|
722
|
+
if (where[key] === undefined)
|
|
723
|
+
where[key] = val;
|
|
724
|
+
else {
|
|
725
|
+
addAnd((_a = {}, _a[key] = val, _a));
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
;
|
|
595
729
|
tslib_1.__spreadArray([], tslib_1.__read(entity.fields), false).forEach(function (col) {
|
|
596
|
-
var _a, _b;
|
|
597
730
|
function addFilter(operation, theFilter, jsonArray, asString) {
|
|
598
|
-
var
|
|
731
|
+
var e_5, _a;
|
|
599
732
|
if (jsonArray === void 0) { jsonArray = false; }
|
|
600
733
|
if (asString === void 0) { asString = false; }
|
|
601
734
|
var val = filterInfo.get(col.key + operation);
|
|
602
735
|
if (val !== undefined) {
|
|
603
736
|
var addFilter_1 = function (val) {
|
|
604
|
-
var _a;
|
|
605
737
|
var theVal = val;
|
|
606
738
|
if (jsonArray) {
|
|
607
739
|
var arr = void 0;
|
|
@@ -618,7 +750,7 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
618
750
|
}
|
|
619
751
|
var f = theFilter(theVal);
|
|
620
752
|
if (f !== undefined) {
|
|
621
|
-
|
|
753
|
+
addToFilterObject(col.key, f);
|
|
622
754
|
}
|
|
623
755
|
};
|
|
624
756
|
if (!jsonArray && val instanceof Array) {
|
|
@@ -638,12 +770,12 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
638
770
|
addFilter_1(x);
|
|
639
771
|
}
|
|
640
772
|
}
|
|
641
|
-
catch (
|
|
773
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
642
774
|
finally {
|
|
643
775
|
try {
|
|
644
776
|
if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1);
|
|
645
777
|
}
|
|
646
|
-
finally { if (
|
|
778
|
+
finally { if (e_5) throw e_5.error; }
|
|
647
779
|
}
|
|
648
780
|
}
|
|
649
781
|
}
|
|
@@ -662,10 +794,10 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
662
794
|
case 'y':
|
|
663
795
|
case 'true':
|
|
664
796
|
case 'yes':
|
|
665
|
-
|
|
797
|
+
addToFilterObject(col.key, null);
|
|
666
798
|
break;
|
|
667
799
|
default:
|
|
668
|
-
|
|
800
|
+
addToFilterObject(col.key, { $ne: null });
|
|
669
801
|
break;
|
|
670
802
|
}
|
|
671
803
|
}
|
|
@@ -682,12 +814,19 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
682
814
|
});
|
|
683
815
|
}),
|
|
684
816
|
}); });
|
|
685
|
-
if (or.length == 1)
|
|
686
|
-
where
|
|
687
|
-
|
|
688
|
-
|
|
817
|
+
if (or.length == 1) {
|
|
818
|
+
if (!where.$or) {
|
|
819
|
+
where.$or = or[0].$or;
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
where.$or.push(or[0].$or);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
addAnd({
|
|
689
827
|
$and: or,
|
|
690
828
|
});
|
|
829
|
+
}
|
|
691
830
|
}
|
|
692
831
|
var _loop_3 = function (key) {
|
|
693
832
|
var element = entity.entityType[key];
|
|
@@ -697,10 +836,9 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
697
836
|
var custom = filterInfo.get(exports.customUrlToken + key);
|
|
698
837
|
if (custom !== undefined) {
|
|
699
838
|
var addItem_1 = function (item) {
|
|
700
|
-
var _a;
|
|
701
839
|
if (item[customArrayToken] != undefined)
|
|
702
840
|
item = item[customArrayToken];
|
|
703
|
-
|
|
841
|
+
addToFilterObject(exports.customUrlToken + key, item);
|
|
704
842
|
};
|
|
705
843
|
if (Array.isArray(custom)) {
|
|
706
844
|
custom.forEach(function (item) { return addItem_1(item); });
|
|
@@ -713,11 +851,9 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
713
851
|
for (var key in entity.entityType) {
|
|
714
852
|
_loop_3(key);
|
|
715
853
|
}
|
|
716
|
-
|
|
717
|
-
return where[0];
|
|
718
|
-
return { $and: where };
|
|
854
|
+
return where;
|
|
719
855
|
function separateArrayFromInnerArray(val) {
|
|
720
|
-
var
|
|
856
|
+
var e_6, _a;
|
|
721
857
|
if (!Array.isArray(val))
|
|
722
858
|
return [val];
|
|
723
859
|
var nonArray = [], array = [];
|
|
@@ -731,12 +867,12 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
731
867
|
nonArray.push(v);
|
|
732
868
|
}
|
|
733
869
|
}
|
|
734
|
-
catch (
|
|
870
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
735
871
|
finally {
|
|
736
872
|
try {
|
|
737
873
|
if (val_1_1 && !val_1_1.done && (_a = val_1.return)) _a.call(val_1);
|
|
738
874
|
}
|
|
739
|
-
finally { if (
|
|
875
|
+
finally { if (e_6) throw e_6.error; }
|
|
740
876
|
}
|
|
741
877
|
array.push(nonArray);
|
|
742
878
|
return array;
|
|
@@ -874,5 +1010,149 @@ function __updateEntityBasedOnWhere(entityDefs, where, r) {
|
|
|
874
1010
|
}
|
|
875
1011
|
}
|
|
876
1012
|
exports.__updateEntityBasedOnWhere = __updateEntityBasedOnWhere;
|
|
877
|
-
|
|
878
|
-
|
|
1013
|
+
var preciseValuesCollector = /** @class */ (function () {
|
|
1014
|
+
function preciseValuesCollector() {
|
|
1015
|
+
this.rawValues = {};
|
|
1016
|
+
this.preciseValues = new Proxy(this.rawValues, {
|
|
1017
|
+
get: function (target, prop) {
|
|
1018
|
+
if (prop in target) {
|
|
1019
|
+
var result = target[prop];
|
|
1020
|
+
if (result.bad)
|
|
1021
|
+
return undefined;
|
|
1022
|
+
if (result.values.length > 0) {
|
|
1023
|
+
var relInfo_1 = (0, relationInfoMember_js_1.getRelationFieldInfo)(result.field);
|
|
1024
|
+
if (relInfo_1) {
|
|
1025
|
+
if (relInfo_1.type === 'reference') {
|
|
1026
|
+
return result.values.map(function (x) {
|
|
1027
|
+
return relInfo_1.toRepo.metadata.idMetadata.getIdFilter(x);
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
else
|
|
1031
|
+
throw new Error('Only relations toOne without field are supported.');
|
|
1032
|
+
}
|
|
1033
|
+
return result.values;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
return undefined;
|
|
1037
|
+
},
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
preciseValuesCollector.prototype.ok = function (col) {
|
|
1041
|
+
var _a;
|
|
1042
|
+
var val = [];
|
|
1043
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
1044
|
+
val[_i - 1] = arguments[_i];
|
|
1045
|
+
}
|
|
1046
|
+
var x = this.rawValues[col.key];
|
|
1047
|
+
if (!x) {
|
|
1048
|
+
this.rawValues[col.key] = {
|
|
1049
|
+
field: col,
|
|
1050
|
+
bad: false,
|
|
1051
|
+
values: tslib_1.__spreadArray([], tslib_1.__read(val), false),
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
else {
|
|
1055
|
+
(_a = x.values).push.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(val.filter(function (y) { return !x.values.includes(y); })), false));
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
preciseValuesCollector.prototype.notOk = function (col) {
|
|
1059
|
+
var x = this.rawValues[col.key];
|
|
1060
|
+
if (!x) {
|
|
1061
|
+
this.rawValues[col.key] = {
|
|
1062
|
+
field: col,
|
|
1063
|
+
bad: true,
|
|
1064
|
+
values: [],
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
x.bad = true;
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
preciseValuesCollector.prototype.or = function (orElements) {
|
|
1072
|
+
var e_7, _a, e_8, _b;
|
|
1073
|
+
var result = orElements.map(function (or) {
|
|
1074
|
+
var x = new preciseValuesCollector();
|
|
1075
|
+
or.__applyToConsumer(x);
|
|
1076
|
+
return x;
|
|
1077
|
+
});
|
|
1078
|
+
try {
|
|
1079
|
+
for (var result_1 = tslib_1.__values(result), result_1_1 = result_1.next(); !result_1_1.done; result_1_1 = result_1.next()) {
|
|
1080
|
+
var or = result_1_1.value;
|
|
1081
|
+
for (var key in or.rawValues) {
|
|
1082
|
+
if (Object.prototype.hasOwnProperty.call(or.rawValues, key)) {
|
|
1083
|
+
var element = or.rawValues[key];
|
|
1084
|
+
if (element) {
|
|
1085
|
+
if (element.bad)
|
|
1086
|
+
this.notOk(element.field);
|
|
1087
|
+
else {
|
|
1088
|
+
this.ok.apply(this, tslib_1.__spreadArray([element.field], tslib_1.__read(element.values), false));
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
1096
|
+
finally {
|
|
1097
|
+
try {
|
|
1098
|
+
if (result_1_1 && !result_1_1.done && (_a = result_1.return)) _a.call(result_1);
|
|
1099
|
+
}
|
|
1100
|
+
finally { if (e_7) throw e_7.error; }
|
|
1101
|
+
}
|
|
1102
|
+
for (var key in this.rawValues) {
|
|
1103
|
+
if (Object.prototype.hasOwnProperty.call(this.rawValues, key)) {
|
|
1104
|
+
try {
|
|
1105
|
+
for (var result_2 = (e_8 = void 0, tslib_1.__values(result)), result_2_1 = result_2.next(); !result_2_1.done; result_2_1 = result_2.next()) {
|
|
1106
|
+
var r = result_2_1.value;
|
|
1107
|
+
var element = r.rawValues[key];
|
|
1108
|
+
if (!element)
|
|
1109
|
+
this.notOk(this.rawValues[key].field);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
1113
|
+
finally {
|
|
1114
|
+
try {
|
|
1115
|
+
if (result_2_1 && !result_2_1.done && (_b = result_2.return)) _b.call(result_2);
|
|
1116
|
+
}
|
|
1117
|
+
finally { if (e_8) throw e_8.error; }
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
preciseValuesCollector.prototype.isEqualTo = function (col, val) {
|
|
1123
|
+
this.ok(col, val);
|
|
1124
|
+
};
|
|
1125
|
+
preciseValuesCollector.prototype.isDifferentFrom = function (col, val) {
|
|
1126
|
+
this.notOk(col);
|
|
1127
|
+
};
|
|
1128
|
+
preciseValuesCollector.prototype.isNull = function (col) {
|
|
1129
|
+
this.ok(col, null);
|
|
1130
|
+
};
|
|
1131
|
+
preciseValuesCollector.prototype.isNotNull = function (col) {
|
|
1132
|
+
this.notOk(col);
|
|
1133
|
+
};
|
|
1134
|
+
preciseValuesCollector.prototype.isGreaterOrEqualTo = function (col, val) {
|
|
1135
|
+
this.notOk(col);
|
|
1136
|
+
};
|
|
1137
|
+
preciseValuesCollector.prototype.isGreaterThan = function (col, val) {
|
|
1138
|
+
this.notOk(col);
|
|
1139
|
+
};
|
|
1140
|
+
preciseValuesCollector.prototype.isLessOrEqualTo = function (col, val) {
|
|
1141
|
+
this.notOk(col);
|
|
1142
|
+
};
|
|
1143
|
+
preciseValuesCollector.prototype.isLessThan = function (col, val) {
|
|
1144
|
+
this.notOk(col);
|
|
1145
|
+
};
|
|
1146
|
+
preciseValuesCollector.prototype.containsCaseInsensitive = function (col, val) {
|
|
1147
|
+
this.notOk(col);
|
|
1148
|
+
};
|
|
1149
|
+
preciseValuesCollector.prototype.notContainsCaseInsensitive = function (col, val) {
|
|
1150
|
+
this.notOk(col);
|
|
1151
|
+
};
|
|
1152
|
+
preciseValuesCollector.prototype.isIn = function (col, val) {
|
|
1153
|
+
this.ok.apply(this, tslib_1.__spreadArray([col], tslib_1.__read(val), false));
|
|
1154
|
+
};
|
|
1155
|
+
preciseValuesCollector.prototype.custom = function (key, customItem) { };
|
|
1156
|
+
preciseValuesCollector.prototype.databaseCustom = function (databaseCustom) { };
|
|
1157
|
+
return preciseValuesCollector;
|
|
1158
|
+
}());
|
package/src/isOfType.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cast = exports.isOfType = void 0;
|
|
4
|
+
function isOfType(obj, checkMethod) {
|
|
5
|
+
return typeof obj[checkMethod] !== 'undefined';
|
|
6
|
+
}
|
|
7
|
+
exports.isOfType = isOfType;
|
|
8
|
+
function cast(obj, checkMethod) {
|
|
9
|
+
if (isOfType(obj, checkMethod)) {
|
|
10
|
+
return obj;
|
|
11
|
+
}
|
|
12
|
+
throw new Error("Object is not of type ".concat(checkMethod.toString()));
|
|
13
|
+
}
|
|
14
|
+
exports.cast = cast;
|
package/src/remult3/Fields.d.ts
CHANGED
|
@@ -16,7 +16,43 @@ export declare class Fields {
|
|
|
16
16
|
static createdAt<entityType = any>(...options: (FieldOptions<entityType, Date> | ((options: FieldOptions<entityType, Date>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, Date | undefined>;
|
|
17
17
|
static updatedAt<entityType = any>(...options: (FieldOptions<entityType, Date> | ((options: FieldOptions<entityType, Date>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, Date | undefined>;
|
|
18
18
|
static uuid<entityType = any>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
|
|
19
|
+
/**
|
|
20
|
+
* A CUID (Collision Resistant Unique Identifier) field.
|
|
21
|
+
* This id value is determined on the backend on insert, and can't be updated through the API.
|
|
22
|
+
* The CUID is generated using the `@paralleldrive/cuid2` npm package.
|
|
23
|
+
*/
|
|
19
24
|
static cuid<entityType = any>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Defines a field that can hold a value from a specified set of string literals.
|
|
27
|
+
* @param {() => readonly valueType[]} optionalValues - A function that returns an array of allowed string literals.
|
|
28
|
+
* @returns {ClassFieldDecorator<entityType, valueType | undefined>} - A class field decorator.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
|
|
32
|
+
* class MyEntity {
|
|
33
|
+
* .@Fields.literal(() => ['open', 'closed', 'frozen', 'in progress'] as const)
|
|
34
|
+
* status: 'open' | 'closed' | 'frozen' | 'in progress' = 'open';
|
|
35
|
+
* }
|
|
36
|
+
|
|
37
|
+
*
|
|
38
|
+
* // This defines a field `status` in `MyEntity` that can only hold the values 'open', 'closed', 'frozen', or 'in progress'.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // For better reusability and maintainability:
|
|
42
|
+
|
|
43
|
+
* const statuses = ['open', 'closed', 'frozen', 'in progress'] as const;
|
|
44
|
+
* type StatusType = typeof statuses[number];
|
|
45
|
+
*
|
|
46
|
+
* class MyEntity {
|
|
47
|
+
* .@Fields.literal(() => statuses)
|
|
48
|
+
* status: StatusType = 'open';
|
|
49
|
+
* }
|
|
50
|
+
|
|
51
|
+
*
|
|
52
|
+
* // This approach allows easy management and updates of the allowed values for the `status` field.
|
|
53
|
+
*/
|
|
54
|
+
static literal<entityType = any, valueType extends string = any>(optionalValues: () => readonly valueType[], ...options: (StringFieldOptions<entityType, valueType> | ((options: StringFieldOptions<entityType, valueType>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, valueType | undefined>;
|
|
55
|
+
static enum<entityType = any, theEnum = any>(enumType: () => theEnum, ...options: (FieldOptions<entityType, theEnum[keyof theEnum]> | ((options: FieldOptions<entityType, theEnum[keyof theEnum]>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, theEnum[keyof theEnum] | undefined>;
|
|
20
56
|
static string<entityType = any, valueType = string>(...options: (StringFieldOptions<entityType, valueType> | ((options: StringFieldOptions<entityType, valueType>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, valueType | undefined>;
|
|
21
57
|
static boolean<entityType = any>(...options: (FieldOptions<entityType, boolean> | ((options: FieldOptions<entityType, boolean>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, boolean | undefined>;
|
|
22
58
|
}
|
package/src/remult3/Fields.js
CHANGED
|
@@ -9,6 +9,10 @@ var RepositoryImplementation_js_1 = require("./RepositoryImplementation.js");
|
|
|
9
9
|
var validators_js_1 = require("../validators.js");
|
|
10
10
|
var relationInfoMember_js_1 = require("./relationInfoMember.js");
|
|
11
11
|
var remult_static_js_1 = require("../remult-static.js");
|
|
12
|
+
var addValidator_js_1 = require("./addValidator.js");
|
|
13
|
+
var validateNumber = (0, validators_js_1.createValueValidator)(function (x) {
|
|
14
|
+
return !isNaN(x) && isFinite(x);
|
|
15
|
+
});
|
|
12
16
|
var Fields = /** @class */ (function () {
|
|
13
17
|
function Fields() {
|
|
14
18
|
}
|
|
@@ -63,6 +67,7 @@ var Fields = /** @class */ (function () {
|
|
|
63
67
|
return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; },
|
|
64
68
|
{
|
|
65
69
|
valueConverter: valueConverters_js_1.ValueConverters.Integer,
|
|
70
|
+
validate: validateNumber,
|
|
66
71
|
}], tslib_1.__read(options), false));
|
|
67
72
|
};
|
|
68
73
|
Fields.autoIncrement = function () {
|
|
@@ -82,7 +87,9 @@ var Fields = /** @class */ (function () {
|
|
|
82
87
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
83
88
|
options[_i] = arguments[_i];
|
|
84
89
|
}
|
|
85
|
-
return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; }
|
|
90
|
+
return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; }, {
|
|
91
|
+
validate: validateNumber,
|
|
92
|
+
}], tslib_1.__read(options), false));
|
|
86
93
|
};
|
|
87
94
|
Fields.createdAt = function () {
|
|
88
95
|
var options = [];
|
|
@@ -127,6 +134,11 @@ var Fields = /** @class */ (function () {
|
|
|
127
134
|
},
|
|
128
135
|
}], tslib_1.__read(options), false));
|
|
129
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* A CUID (Collision Resistant Unique Identifier) field.
|
|
139
|
+
* This id value is determined on the backend on insert, and can't be updated through the API.
|
|
140
|
+
* The CUID is generated using the `@paralleldrive/cuid2` npm package.
|
|
141
|
+
*/
|
|
130
142
|
Fields.cuid = function () {
|
|
131
143
|
var options = [];
|
|
132
144
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
@@ -142,6 +154,71 @@ var Fields = /** @class */ (function () {
|
|
|
142
154
|
},
|
|
143
155
|
}], tslib_1.__read(options), false));
|
|
144
156
|
};
|
|
157
|
+
/**
|
|
158
|
+
* Defines a field that can hold a value from a specified set of string literals.
|
|
159
|
+
* @param {() => readonly valueType[]} optionalValues - A function that returns an array of allowed string literals.
|
|
160
|
+
* @returns {ClassFieldDecorator<entityType, valueType | undefined>} - A class field decorator.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
|
|
164
|
+
* class MyEntity {
|
|
165
|
+
* .@Fields.literal(() => ['open', 'closed', 'frozen', 'in progress'] as const)
|
|
166
|
+
* status: 'open' | 'closed' | 'frozen' | 'in progress' = 'open';
|
|
167
|
+
* }
|
|
168
|
+
|
|
169
|
+
*
|
|
170
|
+
* // This defines a field `status` in `MyEntity` that can only hold the values 'open', 'closed', 'frozen', or 'in progress'.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* // For better reusability and maintainability:
|
|
174
|
+
|
|
175
|
+
* const statuses = ['open', 'closed', 'frozen', 'in progress'] as const;
|
|
176
|
+
* type StatusType = typeof statuses[number];
|
|
177
|
+
*
|
|
178
|
+
* class MyEntity {
|
|
179
|
+
* .@Fields.literal(() => statuses)
|
|
180
|
+
* status: StatusType = 'open';
|
|
181
|
+
* }
|
|
182
|
+
|
|
183
|
+
*
|
|
184
|
+
* // This approach allows easy management and updates of the allowed values for the `status` field.
|
|
185
|
+
*/
|
|
186
|
+
Fields.literal = function (optionalValues) {
|
|
187
|
+
var options = [];
|
|
188
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
189
|
+
options[_i - 1] = arguments[_i];
|
|
190
|
+
}
|
|
191
|
+
return Fields.string.apply(Fields, tslib_1.__spreadArray([{
|
|
192
|
+
validate: function (entity, event) { return validators_js_1.Validators.in(optionalValues())(entity, event); }
|
|
193
|
+
}], tslib_1.__read(options), false));
|
|
194
|
+
};
|
|
195
|
+
Fields.enum = function (enumType) {
|
|
196
|
+
var options = [];
|
|
197
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
198
|
+
options[_i - 1] = arguments[_i];
|
|
199
|
+
}
|
|
200
|
+
var valueConverter;
|
|
201
|
+
return Field.apply(void 0, tslib_1.__spreadArray(tslib_1.__spreadArray([function () {
|
|
202
|
+
//@ts-ignore
|
|
203
|
+
return (enumType());
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
validate: function (entity, event) { return validators_js_1.Validators.enum(enumType())(entity, event); }
|
|
207
|
+
}], tslib_1.__read(options), false), [function (options) {
|
|
208
|
+
if (valueConverter === undefined) {
|
|
209
|
+
var enumObj = enumType();
|
|
210
|
+
var enumValues = (0, validators_js_1.getEnumValues)(enumObj);
|
|
211
|
+
valueConverter = enumValues.find(function (x) { return typeof x === "string"; }) ? valueConverters_js_1.ValueConverters.String : valueConverters_js_1.ValueConverters.Integer;
|
|
212
|
+
}
|
|
213
|
+
if (!options.valueConverter) {
|
|
214
|
+
options.valueConverter = valueConverter;
|
|
215
|
+
}
|
|
216
|
+
else if (!options.valueConverter.fieldTypeInDb) {
|
|
217
|
+
//@ts-ignore
|
|
218
|
+
options.valueConverter.fieldTypeInDb = valueConverter.fieldTypeInDb;
|
|
219
|
+
}
|
|
220
|
+
}], false));
|
|
221
|
+
};
|
|
145
222
|
Fields.string = function () {
|
|
146
223
|
var options = [];
|
|
147
224
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
@@ -249,13 +326,13 @@ function Field(valueType) {
|
|
|
249
326
|
var factory = function (remult) {
|
|
250
327
|
var r = (0, RepositoryImplementation_js_1.buildOptions)(options, remult);
|
|
251
328
|
if (r.required) {
|
|
252
|
-
r.validate = addValidator(r.validate, validators_js_1.Validators.required);
|
|
329
|
+
r.validate = (0, addValidator_js_1.addValidator)(r.validate, validators_js_1.Validators.required, true);
|
|
253
330
|
}
|
|
254
331
|
if (r.maxLength) {
|
|
255
|
-
r.validate = addValidator(r.validate, validators_js_1.Validators.maxLength(r.maxLength));
|
|
332
|
+
r.validate = (0, addValidator_js_1.addValidator)(r.validate, validators_js_1.Validators.maxLength(r.maxLength));
|
|
256
333
|
}
|
|
257
334
|
if (r.minLength) {
|
|
258
|
-
r.validate = addValidator(r.validate, validators_js_1.Validators.minLength(r.minLength));
|
|
335
|
+
r.validate = (0, addValidator_js_1.addValidator)(r.validate, validators_js_1.Validators.minLength(r.minLength));
|
|
259
336
|
}
|
|
260
337
|
if (!r.valueType && valueType) {
|
|
261
338
|
r.valueType = valueType();
|
|
@@ -305,18 +382,3 @@ function checkTarget(target) {
|
|
|
305
382
|
throw new Error("Set the 'experimentalDecorators:true' option in your 'tsconfig' or 'jsconfig' (target undefined)");
|
|
306
383
|
}
|
|
307
384
|
exports.checkTarget = checkTarget;
|
|
308
|
-
function addValidator(validators, newValidator, atStart) {
|
|
309
|
-
if (atStart === void 0) { atStart = false; }
|
|
310
|
-
if (!newValidator)
|
|
311
|
-
return;
|
|
312
|
-
var newValidators = Array.isArray(newValidator)
|
|
313
|
-
? newValidator
|
|
314
|
-
: [newValidator];
|
|
315
|
-
var validatorsArray = Array.isArray(validators)
|
|
316
|
-
? validators
|
|
317
|
-
: validators
|
|
318
|
-
? [validators]
|
|
319
|
-
: [];
|
|
320
|
-
return atStart
|
|
321
|
-
? 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);
|
|
322
|
-
}
|