remult 3.4.0-next.6 → 3.4.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/src/remult3/Fields.js +12 -2
- package/esm/src/remult3/RepositoryImplementation.js +18 -2
- package/package.json +1 -1
- package/src/column-interfaces.d.ts +5 -1
- package/src/remult3/Fields.js +6 -0
- package/src/remult3/RepositoryImplementation.d.ts +3 -0
- package/src/remult3/RepositoryImplementation.js +17 -2
|
@@ -190,7 +190,12 @@ export class Fields {
|
|
|
190
190
|
*/
|
|
191
191
|
static literal(optionalValues, ...options) {
|
|
192
192
|
return Fields.string({
|
|
193
|
-
validate: (entity, event) =>
|
|
193
|
+
validate: (entity, event) => {
|
|
194
|
+
// A value already stored is a fact. Only a new row or a new value has to be in the list.
|
|
195
|
+
if (!event.isNew && !event.valueChanged())
|
|
196
|
+
return;
|
|
197
|
+
return Validators.in(optionalValues())(entity, event);
|
|
198
|
+
},
|
|
194
199
|
//@ts-expect-error as we are adding this to options without it being defined in options
|
|
195
200
|
[fieldOptionalValuesFunctionKey]: optionalValues,
|
|
196
201
|
}, ...options);
|
|
@@ -200,7 +205,12 @@ export class Fields {
|
|
|
200
205
|
return Field(
|
|
201
206
|
//@ts-ignore
|
|
202
207
|
() => enumType(), {
|
|
203
|
-
validate: (entity, event) =>
|
|
208
|
+
validate: (entity, event) => {
|
|
209
|
+
// A value already stored is a fact. Only a new row or a new value has to be in the enum.
|
|
210
|
+
if (!event.isNew && !event.valueChanged())
|
|
211
|
+
return;
|
|
212
|
+
return Validators.enum(enumType())(entity, event);
|
|
213
|
+
},
|
|
204
214
|
[fieldOptionalValuesFunctionKey]: () => getEnumValues(enumType()),
|
|
205
215
|
}, ...options, (options) => {
|
|
206
216
|
;
|
|
@@ -2389,6 +2389,9 @@ export function ValueListFieldType(...options) {
|
|
|
2389
2389
|
if (ref.value && !values.find((v) => v === ref.value)) {
|
|
2390
2390
|
ref.value = values.find((v) => v.id === ref.value.id) || ref.value;
|
|
2391
2391
|
}
|
|
2392
|
+
// A value already stored is a fact. Only a new row or a new value has to be in the list.
|
|
2393
|
+
if (!ref.isNew && !ref.valueChanged())
|
|
2394
|
+
return;
|
|
2392
2395
|
return Validators.in(values)(entity, ref);
|
|
2393
2396
|
};
|
|
2394
2397
|
}, ...options)(type);
|
|
@@ -2407,6 +2410,7 @@ export class ValueListInfo {
|
|
|
2407
2410
|
byIdMap = new Map();
|
|
2408
2411
|
values = [];
|
|
2409
2412
|
isNumeric = false;
|
|
2413
|
+
unknownIdValue;
|
|
2410
2414
|
constructor(valueListType) {
|
|
2411
2415
|
this.valueListType = valueListType;
|
|
2412
2416
|
for (let member in this.valueListType) {
|
|
@@ -2427,7 +2431,9 @@ export class ValueListInfo {
|
|
|
2427
2431
|
var options = this.valueListType[storableMember];
|
|
2428
2432
|
if (options) {
|
|
2429
2433
|
for (const op of options) {
|
|
2430
|
-
if (op
|
|
2434
|
+
if (!op || typeof op === 'function')
|
|
2435
|
+
continue;
|
|
2436
|
+
if (op.getValues) {
|
|
2431
2437
|
this.values.splice(0, this.values.length, ...op.getValues());
|
|
2432
2438
|
this.byIdMap.clear();
|
|
2433
2439
|
this.values.forEach((s) => {
|
|
@@ -2435,6 +2441,8 @@ export class ValueListInfo {
|
|
|
2435
2441
|
this.byIdMap.set(s.id, s);
|
|
2436
2442
|
});
|
|
2437
2443
|
}
|
|
2444
|
+
if ('unknownIdValue' in op)
|
|
2445
|
+
this.unknownIdValue = op.unknownIdValue;
|
|
2438
2446
|
}
|
|
2439
2447
|
if (this.values.find((s) => s.id === undefined))
|
|
2440
2448
|
throw new Error(`ValueType ${this.valueListType} has values without an id`);
|
|
@@ -2452,7 +2460,15 @@ export class ValueListInfo {
|
|
|
2452
2460
|
return this.byIdMap.get(key);
|
|
2453
2461
|
}
|
|
2454
2462
|
fromJson(val) {
|
|
2455
|
-
|
|
2463
|
+
const known = this.byId(val);
|
|
2464
|
+
if (known !== undefined)
|
|
2465
|
+
return known;
|
|
2466
|
+
if (val == null)
|
|
2467
|
+
return undefined;
|
|
2468
|
+
const fallback = this.unknownIdValue;
|
|
2469
|
+
if (typeof fallback !== 'function')
|
|
2470
|
+
return fallback;
|
|
2471
|
+
return fallback(this.isNumeric ? +val : val);
|
|
2456
2472
|
}
|
|
2457
2473
|
toJson(val) {
|
|
2458
2474
|
if (!val)
|
package/package.json
CHANGED
|
@@ -58,7 +58,11 @@ export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
|
58
58
|
* @type {AllowedForInstance<entityType>}
|
|
59
59
|
*/
|
|
60
60
|
allowApiUpdate?: AllowedForInstance<entityType>;
|
|
61
|
-
/** An arrow function that'll be used to perform validations on it
|
|
61
|
+
/** An arrow function that'll be used to perform validations on it.
|
|
62
|
+
*
|
|
63
|
+
* `validate` from several option objects is additive: each one is appended.
|
|
64
|
+
* A function option is the only way to replace validators already set, including a built-in one:
|
|
65
|
+
* `(options) => { options.validate = ... }`.
|
|
62
66
|
* @example
|
|
63
67
|
* @Fields.string({
|
|
64
68
|
* validate: Validators.required
|
package/src/remult3/Fields.js
CHANGED
|
@@ -247,6 +247,9 @@ var Fields = /** @class */ (function () {
|
|
|
247
247
|
}
|
|
248
248
|
return Fields.string.apply(Fields, tslib_1.__spreadArray([(_a = {
|
|
249
249
|
validate: function (entity, event) {
|
|
250
|
+
// A value already stored is a fact. Only a new row or a new value has to be in the list.
|
|
251
|
+
if (!event.isNew && !event.valueChanged())
|
|
252
|
+
return;
|
|
250
253
|
return validators_js_1.Validators.in(optionalValues())(entity, event);
|
|
251
254
|
}
|
|
252
255
|
},
|
|
@@ -265,6 +268,9 @@ var Fields = /** @class */ (function () {
|
|
|
265
268
|
//@ts-ignore
|
|
266
269
|
function () { return enumType(); }, (_a = {
|
|
267
270
|
validate: function (entity, event) {
|
|
271
|
+
// A value already stored is a fact. Only a new row or a new value has to be in the enum.
|
|
272
|
+
if (!event.isNew && !event.valueChanged())
|
|
273
|
+
return;
|
|
268
274
|
return validators_js_1.Validators.enum(enumType())(entity, event);
|
|
269
275
|
}
|
|
270
276
|
},
|
|
@@ -302,6 +302,8 @@ export declare function isAutoIncrement(f: FieldMetadata): boolean;
|
|
|
302
302
|
export declare function ValueListFieldType<valueType extends ValueListItem = ValueListItem>(...options: (ValueListFieldOptions<any, valueType> | ((options: FieldOptions<any, valueType>, remult: Remult) => void))[]): (type: ClassType<valueType>, context?: any) => void;
|
|
303
303
|
export interface ValueListFieldOptions<entityType, valueType> extends FieldOptions<entityType, valueType> {
|
|
304
304
|
getValues?: () => valueType[];
|
|
305
|
+
/** Value used when a stored id is not in the list. A value, or `(id) => value`. @default undefined */
|
|
306
|
+
unknownIdValue?: valueType | ((id: any) => valueType | undefined);
|
|
305
307
|
}
|
|
306
308
|
export declare class ValueListInfo<T extends ValueListItem> implements ValueConverter<T> {
|
|
307
309
|
private valueListType;
|
|
@@ -309,6 +311,7 @@ export declare class ValueListInfo<T extends ValueListItem> implements ValueConv
|
|
|
309
311
|
private byIdMap;
|
|
310
312
|
private values;
|
|
311
313
|
isNumeric: boolean;
|
|
314
|
+
private unknownIdValue?;
|
|
312
315
|
private constructor();
|
|
313
316
|
getValues(): T[];
|
|
314
317
|
byId(key: any): T | undefined;
|
|
@@ -3970,6 +3970,9 @@ function ValueListFieldType() {
|
|
|
3970
3970
|
if (ref.value && !values.find(function (v) { return v === ref.value; })) {
|
|
3971
3971
|
ref.value = values.find(function (v) { return v.id === ref.value.id; }) || ref.value;
|
|
3972
3972
|
}
|
|
3973
|
+
// A value already stored is a fact. Only a new row or a new value has to be in the list.
|
|
3974
|
+
if (!ref.isNew && !ref.valueChanged())
|
|
3975
|
+
return;
|
|
3973
3976
|
return validators_js_1.Validators.in(values)(entity, ref);
|
|
3974
3977
|
};
|
|
3975
3978
|
}], tslib_1.__read(options), false))(type);
|
|
@@ -4003,7 +4006,9 @@ var ValueListInfo = /** @class */ (function () {
|
|
|
4003
4006
|
try {
|
|
4004
4007
|
for (var options_1 = tslib_1.__values(options), options_1_1 = options_1.next(); !options_1_1.done; options_1_1 = options_1.next()) {
|
|
4005
4008
|
var op = options_1_1.value;
|
|
4006
|
-
if (op
|
|
4009
|
+
if (!op || typeof op === 'function')
|
|
4010
|
+
continue;
|
|
4011
|
+
if (op.getValues) {
|
|
4007
4012
|
(_b = this.values).splice.apply(_b, tslib_1.__spreadArray([0, this.values.length], tslib_1.__read(op.getValues()), false));
|
|
4008
4013
|
this.byIdMap.clear();
|
|
4009
4014
|
this.values.forEach(function (s) {
|
|
@@ -4011,6 +4016,8 @@ var ValueListInfo = /** @class */ (function () {
|
|
|
4011
4016
|
_this.byIdMap.set(s.id, s);
|
|
4012
4017
|
});
|
|
4013
4018
|
}
|
|
4019
|
+
if ('unknownIdValue' in op)
|
|
4020
|
+
this.unknownIdValue = op.unknownIdValue;
|
|
4014
4021
|
}
|
|
4015
4022
|
}
|
|
4016
4023
|
catch (e_54_1) { e_54 = { error: e_54_1 }; }
|
|
@@ -4044,7 +4051,15 @@ var ValueListInfo = /** @class */ (function () {
|
|
|
4044
4051
|
return this.byIdMap.get(key);
|
|
4045
4052
|
};
|
|
4046
4053
|
ValueListInfo.prototype.fromJson = function (val) {
|
|
4047
|
-
|
|
4054
|
+
var known = this.byId(val);
|
|
4055
|
+
if (known !== undefined)
|
|
4056
|
+
return known;
|
|
4057
|
+
if (val == null)
|
|
4058
|
+
return undefined;
|
|
4059
|
+
var fallback = this.unknownIdValue;
|
|
4060
|
+
if (typeof fallback !== 'function')
|
|
4061
|
+
return fallback;
|
|
4062
|
+
return fallback(this.isNumeric ? +val : val);
|
|
4048
4063
|
};
|
|
4049
4064
|
ValueListInfo.prototype.toJson = function (val) {
|
|
4050
4065
|
if (!val)
|