remult 0.27.22 → 0.27.23-next.1
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/index.js +1 -0
- package/esm/server/remult-api-server.js +3 -2
- package/esm/src/data-api.js +5 -1
- package/esm/src/data-interfaces.js +10 -0
- package/esm/src/remult3/RepositoryImplementation.js +4 -3
- package/esm/src/remult3/remult3.js +2 -0
- package/esm/src/validators.js +63 -0
- package/index.d.ts +1 -1
- package/index.js +3 -1
- package/package.json +1 -1
- package/server/remult-api-server.js +2 -1
- package/src/data-api.d.ts +1 -1
- package/src/data-api.js +5 -1
- package/src/data-interfaces.d.ts +9 -0
- package/src/data-interfaces.js +12 -0
- package/src/remult3/RepositoryImplementation.d.ts +3 -3
- package/src/remult3/RepositoryImplementation.js +4 -3
- package/src/remult3/remult3.js +2 -0
- package/src/validators.d.ts +80 -1
- package/src/validators.js +63 -0
package/esm/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { getEntityRef } from './src/remult3/getEntityRef.js';
|
|
|
5
5
|
export { Field, Fields, Relations, } from './src/remult3/Fields.js';
|
|
6
6
|
export { IdEntity } from './src/remult3/IdEntity.js';
|
|
7
7
|
export { describeClass, describeBackendMethods, describeEntity, } from './src/remult3/classDescribers.js';
|
|
8
|
+
export { EntityError, } from './src/data-interfaces.js'; //V
|
|
8
9
|
export { RestDataProvider } from './src/data-providers/rest-data-provider.js'; //V
|
|
9
10
|
export { InMemoryDataProvider } from './src/data-providers/in-memory-database.js'; //V
|
|
10
11
|
export { SqlDatabase } from './src/data-providers/sql-database.js'; //V
|
|
@@ -833,10 +833,11 @@ class ResponseBridgeToDataApiResponse {
|
|
|
833
833
|
url: this.genReq?.url,
|
|
834
834
|
method: this.genReq?.method,
|
|
835
835
|
});
|
|
836
|
-
|
|
836
|
+
const json = { ...body, message: body.message };
|
|
837
|
+
this.setStatus(httpStatusCode).json(json);
|
|
837
838
|
};
|
|
838
839
|
await this.handleError?.({
|
|
839
|
-
httpStatusCode,
|
|
840
|
+
httpStatusCode: httpStatusCode,
|
|
840
841
|
req: this.req,
|
|
841
842
|
entity,
|
|
842
843
|
exception,
|
package/esm/src/data-api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { doTransaction } from './context.js';
|
|
2
|
+
import { EntityError } from './data-interfaces.js';
|
|
2
3
|
import { findOptionsToJson, liveQueryAction, } from './data-providers/rest-data-provider.js';
|
|
3
4
|
import { Filter, buildFilterFromRequestParameters, customUrlToken, } from './filter/filter-interfaces.js';
|
|
4
5
|
import { getRelationFieldInfo } from './remult3/relationInfoMember.js';
|
|
@@ -490,7 +491,10 @@ export function determineSort(sortUrlParm, dirUrlParam) {
|
|
|
490
491
|
return result;
|
|
491
492
|
}
|
|
492
493
|
export function serializeError(data) {
|
|
493
|
-
if (data instanceof
|
|
494
|
+
if (data instanceof EntityError) {
|
|
495
|
+
data = { message: data.message, modelState: data.modelState };
|
|
496
|
+
}
|
|
497
|
+
else if (data instanceof Error) {
|
|
494
498
|
data = { message: data.message, stack: data.stack };
|
|
495
499
|
}
|
|
496
500
|
let x = JSON.parse(JSON.stringify(data));
|
|
@@ -9,3 +9,13 @@ export function extractSort(sort) {
|
|
|
9
9
|
}
|
|
10
10
|
return sort;
|
|
11
11
|
}
|
|
12
|
+
export class EntityError extends Error {
|
|
13
|
+
constructor(errorInfo) {
|
|
14
|
+
super(errorInfo.message);
|
|
15
|
+
Object.assign(this, errorInfo);
|
|
16
|
+
}
|
|
17
|
+
modelState;
|
|
18
|
+
stack;
|
|
19
|
+
exception;
|
|
20
|
+
httpStatusCode;
|
|
21
|
+
}
|
|
@@ -5,6 +5,7 @@ import { Filter } from '../filter/filter-interfaces.js';
|
|
|
5
5
|
import { Sort } from '../sort.js';
|
|
6
6
|
import { GroupByForApiKey, } from './remult3.js';
|
|
7
7
|
import { assign } from '../../assign.js';
|
|
8
|
+
import { EntityError, } from '../data-interfaces.js';
|
|
8
9
|
import { ValueConverters } from '../valueConverters.js';
|
|
9
10
|
import { findOptionsToJson } from '../data-providers/rest-data-provider.js';
|
|
10
11
|
import { remult as defaultRemult } from '../remult-proxy.js';
|
|
@@ -1194,7 +1195,7 @@ class rowHelperBase {
|
|
|
1194
1195
|
}
|
|
1195
1196
|
}
|
|
1196
1197
|
}
|
|
1197
|
-
return error;
|
|
1198
|
+
return new EntityError(error);
|
|
1198
1199
|
}
|
|
1199
1200
|
catchSaveErrors(err) {
|
|
1200
1201
|
let e = err;
|
|
@@ -1987,12 +1988,12 @@ export class columnDefsImpl {
|
|
|
1987
1988
|
}
|
|
1988
1989
|
catch (err) {
|
|
1989
1990
|
const error = `${String(prop)} failed for value ${args?.[0]}. Error: ${typeof err === 'string' ? err : err.message}`;
|
|
1990
|
-
throw {
|
|
1991
|
+
throw new EntityError({
|
|
1991
1992
|
message: this.caption + ': ' + error,
|
|
1992
1993
|
modelState: {
|
|
1993
1994
|
[this.key]: error,
|
|
1994
1995
|
},
|
|
1995
|
-
};
|
|
1996
|
+
});
|
|
1996
1997
|
}
|
|
1997
1998
|
};
|
|
1998
1999
|
}
|
|
@@ -17,6 +17,8 @@ const wnn = [
|
|
|
17
17
|
export const flags = {
|
|
18
18
|
error500RetryCount: 4,
|
|
19
19
|
};
|
|
20
|
+
//p1 - make error info an actual error, important for exception handling, and also for auth.js errors that were mistic
|
|
21
|
+
//p1 - add validators min,max,between(range)
|
|
20
22
|
//p1 - allow experimental route registration on remult server, with at least get route, and support redirect, read header and set header - (and the existing get html etc...)
|
|
21
23
|
//p2 - add parameter all to deleteMany, and updateMany
|
|
22
24
|
//p2 filter.apply ApiPreFilter
|
package/esm/src/validators.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { getRelationFieldInfo } from '../internals.js';
|
|
2
|
+
/**
|
|
3
|
+
* Class containing various field validators.
|
|
4
|
+
*/
|
|
2
5
|
export class Validators {
|
|
6
|
+
/**
|
|
7
|
+
* Validator to check if a value is required (not null or empty).
|
|
8
|
+
*/
|
|
3
9
|
static required = createValidator(async (_, e) => !e.valueIsNull() &&
|
|
4
10
|
e.value !== '' &&
|
|
5
11
|
(e.value !== undefined || getRelationFieldInfo(e.metadata) !== undefined), 'Should not be empty');
|
|
12
|
+
/**
|
|
13
|
+
* Validator to ensure a value is unique in the database.
|
|
14
|
+
*/
|
|
6
15
|
static unique = createValidator(async (_, e) => {
|
|
7
16
|
if (!e.entityRef)
|
|
8
17
|
throw 'unique validation may only work on columns that are attached to an entity';
|
|
@@ -16,6 +25,7 @@ export class Validators {
|
|
|
16
25
|
}, 'already exists');
|
|
17
26
|
/**
|
|
18
27
|
* @deprecated use `unique` instead - it also runs only on the backend
|
|
28
|
+
* Validator to ensure a value is unique on the backend.
|
|
19
29
|
*/
|
|
20
30
|
static uniqueOnBackend = createValidator(async (_, e) => {
|
|
21
31
|
if (e.isBackend() && (e.isNew || e.valueChanged())) {
|
|
@@ -26,9 +36,21 @@ export class Validators {
|
|
|
26
36
|
else
|
|
27
37
|
return true;
|
|
28
38
|
}, Validators.unique.defaultMessage);
|
|
39
|
+
/**
|
|
40
|
+
* Validator to check if a value matches a given regular expression.
|
|
41
|
+
*/
|
|
29
42
|
static regex = createValueValidatorWithArgs((val, regex) => regex.test(val));
|
|
43
|
+
/**
|
|
44
|
+
* Validator to check if a value is a valid email address.
|
|
45
|
+
*/
|
|
30
46
|
static email = createValueValidator((val) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val), 'Invalid Email');
|
|
47
|
+
/**
|
|
48
|
+
* Validator to check if a value is a valid URL.
|
|
49
|
+
*/
|
|
31
50
|
static url = createValueValidator((val) => !!new URL(val), 'Invalid Url');
|
|
51
|
+
/**
|
|
52
|
+
* Validator to check if a value is one of the specified values.
|
|
53
|
+
*/
|
|
32
54
|
static in = createValueValidatorWithArgs((val, values) => values.includes(val), (values) => `Value must be one of: ${values
|
|
33
55
|
.map((y) => typeof y === 'object'
|
|
34
56
|
? y?.['id'] !== undefined
|
|
@@ -36,8 +58,17 @@ export class Validators {
|
|
|
36
58
|
: y?.toString()
|
|
37
59
|
: y)
|
|
38
60
|
.join(', ')}`);
|
|
61
|
+
/**
|
|
62
|
+
* Validator to check if a value is not null.
|
|
63
|
+
*/
|
|
39
64
|
static notNull = createValueValidator((val) => val != null, 'Should not be null');
|
|
65
|
+
/**
|
|
66
|
+
* Validator to check if a value exists in a given enum.
|
|
67
|
+
*/
|
|
40
68
|
static enum = createValueValidatorWithArgs((value, enumObj) => Object.values(enumObj).includes(value), (enumObj) => `Value must be one of ${getEnumValues(enumObj).join(', ')}`);
|
|
69
|
+
/**
|
|
70
|
+
* Validator to check if a related value exists in the database.
|
|
71
|
+
*/
|
|
41
72
|
static relationExists = createValidator(async (_, e) => {
|
|
42
73
|
if (e.valueIsNull())
|
|
43
74
|
return true;
|
|
@@ -45,10 +76,27 @@ export class Validators {
|
|
|
45
76
|
return true;
|
|
46
77
|
return Boolean(await e.load());
|
|
47
78
|
}, 'Relation value does not exist');
|
|
79
|
+
/**
|
|
80
|
+
* Validator to check if a value is greater than or equal to a minimum value.
|
|
81
|
+
*/
|
|
82
|
+
static min = createValueValidatorWithArgs((val, minValue) => val >= minValue, (minValue) => `Value must be bigger than or equal to ${minValue}`);
|
|
83
|
+
/**
|
|
84
|
+
* Validator to check if a value is less than or equal to a maximum value.
|
|
85
|
+
*/
|
|
86
|
+
static max = createValueValidatorWithArgs((val, maxValue) => val <= maxValue, (maxValue) => `Value must be smaller than or equal to ${maxValue}`);
|
|
87
|
+
/**
|
|
88
|
+
* Validator to check if a string's length is less than or equal to a maximum length.
|
|
89
|
+
*/
|
|
48
90
|
static maxLength = createValueValidatorWithArgs((val, maxLength) => val.length <= maxLength, (maxLength) => `Value must be at most ${maxLength} characters`);
|
|
91
|
+
/**
|
|
92
|
+
* Validator to check if a string's length is greater than or equal to a minimum length.
|
|
93
|
+
*/
|
|
49
94
|
static minLength = createValueValidatorWithArgs((val, minLength) => val.length >= minLength, (maxLength) => `Value must be at least ${maxLength} characters`);
|
|
50
95
|
static defaultMessage = 'Invalid value';
|
|
51
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Function to create a validator with a custom validation function.
|
|
99
|
+
*/
|
|
52
100
|
export function createValidator(validate, defaultMessage) {
|
|
53
101
|
const validation = async (entity, e, message) => {
|
|
54
102
|
const valid = await validate(entity, e);
|
|
@@ -85,9 +133,15 @@ export function createValidator(validate, defaultMessage) {
|
|
|
85
133
|
withMessage: (message) => async (entity, e) => result(entity, e, message),
|
|
86
134
|
});
|
|
87
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Function to create a value validator.
|
|
138
|
+
*/
|
|
88
139
|
export function valueValidator(validate, defaultMessage) {
|
|
89
140
|
return (entity, e) => validate(e.value) || defaultMessage || false;
|
|
90
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Function to create a value validator with arguments.
|
|
144
|
+
*/
|
|
91
145
|
export function createValueValidator(validate, defaultMessage) {
|
|
92
146
|
return createValidator((_, e) => {
|
|
93
147
|
if (e.value === undefined || e.value === null)
|
|
@@ -95,6 +149,9 @@ export function createValueValidator(validate, defaultMessage) {
|
|
|
95
149
|
return validate(e.value);
|
|
96
150
|
}, defaultMessage);
|
|
97
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Function to create a value validator with arguments and a custom message.
|
|
154
|
+
*/
|
|
98
155
|
export function createValueValidatorWithArgs(validate, defaultMessage) {
|
|
99
156
|
const result = createValidatorWithArgsInternal((_, e, args) => {
|
|
100
157
|
if (e.value === undefined || e.value === null)
|
|
@@ -111,6 +168,9 @@ export function createValueValidatorWithArgs(validate, defaultMessage) {
|
|
|
111
168
|
},
|
|
112
169
|
});
|
|
113
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Function to create a validator with arguments and a custom message.
|
|
173
|
+
*/
|
|
114
174
|
export function createValidatorWithArgs(validate, defaultMessage) {
|
|
115
175
|
return createValidatorWithArgsInternal(validate, defaultMessage);
|
|
116
176
|
}
|
|
@@ -141,6 +201,9 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
|
|
|
141
201
|
},
|
|
142
202
|
});
|
|
143
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Function to get the values of an enum.
|
|
206
|
+
*/
|
|
144
207
|
export function getEnumValues(enumObj) {
|
|
145
208
|
return Object.values(enumObj).filter((x) => typeof enumObj[x] !== 'number');
|
|
146
209
|
}
|
package/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { Field, Fields, StringFieldOptions, Relations, } from './src/remult3/Fie
|
|
|
11
11
|
export { IdEntity } from './src/remult3/IdEntity.js';
|
|
12
12
|
export { describeClass, describeBackendMethods, describeEntity, } from './src/remult3/classDescribers.js';
|
|
13
13
|
export { EntityOptions, PreprocessFilterEvent } from './src/entity.js';
|
|
14
|
-
export { DataProvider, EntityDataProvider, EntityDataProviderGroupByOptions, EntityDataProviderFindOptions, ErrorInfo, RestDataProviderHttpProvider, } from './src/data-interfaces.js';
|
|
14
|
+
export { DataProvider, EntityDataProvider, EntityDataProviderGroupByOptions, EntityDataProviderFindOptions, ErrorInfo, EntityError, RestDataProviderHttpProvider, } from './src/data-interfaces.js';
|
|
15
15
|
export { SqlCommand, SqlCommandWithParameters, SqlImplementation, SqlResult, } from './src/sql-command.js';
|
|
16
16
|
export { FieldMetadata, FieldOptions, FieldValidator, ValueConverter, ValueListItem, // reconsider, maybe it should go to remult angular as the abstraction ?
|
|
17
17
|
ValueOrExpression, } from './src/column-interfaces.js';
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = exports.remult = exports.ValueConverters = exports.createValueValidator = exports.createValueValidatorWithArgs = exports.createValidatorWithArgs = exports.createValidator = exports.valueValidator = exports.Validators = exports.UrlBuilder = exports.Filter = exports.CompoundIdField = exports.Sort = exports.EventSource = exports.isBackend = exports.withRemult = exports.Remult = exports.Allow = exports.ForbiddenError = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.JsonEntityIndexedDbStorage = exports.JsonEntityOpfsStorage = exports.JsonDataProvider = exports.dbNamesOf = exports.CustomSqlFilterBuilder = exports.SqlDatabase = exports.InMemoryDataProvider = exports.RestDataProvider = exports.describeEntity = exports.describeBackendMethods = exports.describeClass = exports.IdEntity = exports.Relations = exports.Fields = exports.Field = exports.getEntityRef = exports.Entity = exports.CaptionTransformer = exports.ValueListInfo = exports.getValueList = exports.ValueListFieldType = exports.getFields = exports.FieldType = exports.ControllerBase = exports.EntityBase = exports.ArrayEntityDataProvider = void 0;
|
|
3
|
+
exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = exports.remult = exports.ValueConverters = exports.createValueValidator = exports.createValueValidatorWithArgs = exports.createValidatorWithArgs = exports.createValidator = exports.valueValidator = exports.Validators = exports.UrlBuilder = exports.Filter = exports.CompoundIdField = exports.Sort = exports.EventSource = exports.isBackend = exports.withRemult = exports.Remult = exports.Allow = exports.ForbiddenError = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.JsonEntityIndexedDbStorage = exports.JsonEntityOpfsStorage = exports.JsonDataProvider = exports.dbNamesOf = exports.CustomSqlFilterBuilder = exports.SqlDatabase = exports.InMemoryDataProvider = exports.RestDataProvider = exports.EntityError = exports.describeEntity = exports.describeBackendMethods = exports.describeClass = exports.IdEntity = exports.Relations = exports.Fields = exports.Field = exports.getEntityRef = exports.Entity = exports.CaptionTransformer = exports.ValueListInfo = exports.getValueList = exports.ValueListFieldType = exports.getFields = exports.FieldType = exports.ControllerBase = exports.EntityBase = exports.ArrayEntityDataProvider = void 0;
|
|
4
4
|
exports.repo = repo;
|
|
5
5
|
var array_entity_data_provider_js_1 = require("./src/data-providers/array-entity-data-provider.js");
|
|
6
6
|
Object.defineProperty(exports, "ArrayEntityDataProvider", { enumerable: true, get: function () { return array_entity_data_provider_js_1.ArrayEntityDataProvider; } });
|
|
@@ -27,6 +27,8 @@ var classDescribers_js_1 = require("./src/remult3/classDescribers.js");
|
|
|
27
27
|
Object.defineProperty(exports, "describeClass", { enumerable: true, get: function () { return classDescribers_js_1.describeClass; } });
|
|
28
28
|
Object.defineProperty(exports, "describeBackendMethods", { enumerable: true, get: function () { return classDescribers_js_1.describeBackendMethods; } });
|
|
29
29
|
Object.defineProperty(exports, "describeEntity", { enumerable: true, get: function () { return classDescribers_js_1.describeEntity; } });
|
|
30
|
+
var data_interfaces_js_1 = require("./src/data-interfaces.js"); //V
|
|
31
|
+
Object.defineProperty(exports, "EntityError", { enumerable: true, get: function () { return data_interfaces_js_1.EntityError; } });
|
|
30
32
|
var rest_data_provider_js_1 = require("./src/data-providers/rest-data-provider.js"); //V
|
|
31
33
|
Object.defineProperty(exports, "RestDataProvider", { enumerable: true, get: function () { return rest_data_provider_js_1.RestDataProvider; } });
|
|
32
34
|
var in_memory_database_js_1 = require("./src/data-providers/in-memory-database.js"); //V
|
package/package.json
CHANGED
|
@@ -1195,7 +1195,8 @@ var ResponseBridgeToDataApiResponse = /** @class */ (function () {
|
|
|
1195
1195
|
url: (_b = _this.genReq) === null || _b === void 0 ? void 0 : _b.url,
|
|
1196
1196
|
method: (_c = _this.genReq) === null || _c === void 0 ? void 0 : _c.method,
|
|
1197
1197
|
});
|
|
1198
|
-
|
|
1198
|
+
var json = tslib_1.__assign(tslib_1.__assign({}, body), { message: body.message });
|
|
1199
|
+
_this.setStatus(httpStatusCode).json(json);
|
|
1199
1200
|
};
|
|
1200
1201
|
return [4 /*yield*/, ((_a = this.handleError) === null || _a === void 0 ? void 0 : _a.call(this, {
|
|
1201
1202
|
httpStatusCode: httpStatusCode,
|
package/src/data-api.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Remult } from './context.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type ErrorInfo } from './data-interfaces.js';
|
|
3
3
|
import { type EntityMetadata, type FindOptions, type Repository } from './remult3/remult3.js';
|
|
4
4
|
import type { rowHelperImplementation } from './remult3/RepositoryImplementation.js';
|
|
5
5
|
export declare class DataApi<T = unknown> {
|
package/src/data-api.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.determineSort = determineSort;
|
|
|
5
5
|
exports.serializeError = serializeError;
|
|
6
6
|
var tslib_1 = require("tslib");
|
|
7
7
|
var context_js_1 = require("./context.js");
|
|
8
|
+
var data_interfaces_js_1 = require("./data-interfaces.js");
|
|
8
9
|
var rest_data_provider_js_1 = require("./data-providers/rest-data-provider.js");
|
|
9
10
|
var filter_interfaces_js_1 = require("./filter/filter-interfaces.js");
|
|
10
11
|
var relationInfoMember_js_1 = require("./remult3/relationInfoMember.js");
|
|
@@ -1005,7 +1006,10 @@ function determineSort(sortUrlParm, dirUrlParam) {
|
|
|
1005
1006
|
return result;
|
|
1006
1007
|
}
|
|
1007
1008
|
function serializeError(data) {
|
|
1008
|
-
if (data instanceof
|
|
1009
|
+
if (data instanceof data_interfaces_js_1.EntityError) {
|
|
1010
|
+
data = { message: data.message, modelState: data.modelState };
|
|
1011
|
+
}
|
|
1012
|
+
else if (data instanceof Error) {
|
|
1009
1013
|
data = { message: data.message, stack: data.stack };
|
|
1010
1014
|
}
|
|
1011
1015
|
var x = JSON.parse(JSON.stringify(data));
|
package/src/data-interfaces.d.ts
CHANGED
|
@@ -67,3 +67,12 @@ export interface ErrorInfo<entityType = unknown> {
|
|
|
67
67
|
exception?: any;
|
|
68
68
|
httpStatusCode?: number;
|
|
69
69
|
}
|
|
70
|
+
export declare class EntityError<entityType = unknown> extends Error implements ErrorInfo<entityType> {
|
|
71
|
+
constructor(errorInfo: ErrorInfo<entityType>);
|
|
72
|
+
modelState?: {
|
|
73
|
+
[Properties in keyof Partial<MembersOnly<entityType>>]?: string;
|
|
74
|
+
};
|
|
75
|
+
stack?: string;
|
|
76
|
+
exception?: any;
|
|
77
|
+
httpStatusCode?: number;
|
|
78
|
+
}
|
package/src/data-interfaces.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityError = void 0;
|
|
3
4
|
exports.extractSort = extractSort;
|
|
5
|
+
var tslib_1 = require("tslib");
|
|
4
6
|
var sort_js_1 = require("./sort.js");
|
|
5
7
|
function extractSort(sort) {
|
|
6
8
|
if (sort instanceof Array) {
|
|
@@ -12,3 +14,13 @@ function extractSort(sort) {
|
|
|
12
14
|
}
|
|
13
15
|
return sort;
|
|
14
16
|
}
|
|
17
|
+
var EntityError = /** @class */ (function (_super) {
|
|
18
|
+
tslib_1.__extends(EntityError, _super);
|
|
19
|
+
function EntityError(errorInfo) {
|
|
20
|
+
var _this = _super.call(this, errorInfo.message) || this;
|
|
21
|
+
Object.assign(_this, errorInfo);
|
|
22
|
+
return _this;
|
|
23
|
+
}
|
|
24
|
+
return EntityError;
|
|
25
|
+
}(Error));
|
|
26
|
+
exports.EntityError = EntityError;
|
|
@@ -7,7 +7,7 @@ import { Filter } from '../filter/filter-interfaces.js';
|
|
|
7
7
|
import { type GroupByOptions, type GroupByResult, type ControllerRef, type ControllerRefForControllerBase, type EntityFilter, type EntityMetadata, type EntityOrderBy, type EntityRef, type EntityRefForEntityBase, type FieldRef, type FieldsMetadata, type FieldsRef, type FieldsRefForEntityBase, type FindFirstOptions, type FindFirstOptionsBase, type FindOptions, type IdMetadata, type LiveQuery, type LoadOptions, type MembersOnly, type NumericKeys, type Repository, type RepositoryRelations, type Subscribable, type idType } from './remult3.js';
|
|
8
8
|
import type { QueryOptions, RefSubscriber, UpsertOptions } from './remult3.js';
|
|
9
9
|
import type { entityEventListener } from '../__EntityValueProvider.js';
|
|
10
|
-
import type
|
|
10
|
+
import { type DataProvider, type EntityDataProvider, type EntityDataProviderGroupByOptions, type EntityDataProviderFindOptions, type ErrorInfo, EntityError } from '../data-interfaces.js';
|
|
11
11
|
import type { Unsubscribe } from '../live-query/SubscriptionChannel.js';
|
|
12
12
|
import { RelationLoader } from './relation-loader.js';
|
|
13
13
|
import { type RepositoryInternal, getInternalKey } from './repository-internals.js';
|
|
@@ -114,7 +114,7 @@ declare abstract class rowHelperBase<T> {
|
|
|
114
114
|
[key: string]: string | undefined;
|
|
115
115
|
};
|
|
116
116
|
protected __assertValidity(): void;
|
|
117
|
-
buildErrorInfoObject():
|
|
117
|
+
buildErrorInfoObject(): EntityError<unknown>;
|
|
118
118
|
abstract get fields(): FieldsRef<T>;
|
|
119
119
|
catchSaveErrors(err: any): any;
|
|
120
120
|
__clearErrorsAndReportChanged(): void;
|
|
@@ -124,7 +124,7 @@ declare abstract class rowHelperBase<T> {
|
|
|
124
124
|
originalValues: any;
|
|
125
125
|
saveOriginalData(): void;
|
|
126
126
|
saveMoreOriginalData(): void;
|
|
127
|
-
validate(): Promise<
|
|
127
|
+
validate(): Promise<EntityError<unknown> | undefined>;
|
|
128
128
|
__validateEntity(): Promise<void>;
|
|
129
129
|
__performColumnAndEntityValidations(): Promise<void>;
|
|
130
130
|
toApiJson(includeRelatedEntities?: boolean, notJustApi?: boolean): any;
|
|
@@ -21,6 +21,7 @@ var filter_interfaces_js_1 = require("../filter/filter-interfaces.js");
|
|
|
21
21
|
var sort_js_1 = require("../sort.js");
|
|
22
22
|
var remult3_js_1 = require("./remult3.js");
|
|
23
23
|
var assign_js_1 = require("../../assign.js");
|
|
24
|
+
var data_interfaces_js_1 = require("../data-interfaces.js");
|
|
24
25
|
var valueConverters_js_1 = require("../valueConverters.js");
|
|
25
26
|
var rest_data_provider_js_1 = require("../data-providers/rest-data-provider.js");
|
|
26
27
|
var remult_proxy_js_1 = require("../remult-proxy.js");
|
|
@@ -1966,7 +1967,7 @@ var rowHelperBase = /** @class */ (function () {
|
|
|
1966
1967
|
finally { if (e_29) throw e_29.error; }
|
|
1967
1968
|
}
|
|
1968
1969
|
}
|
|
1969
|
-
return error;
|
|
1970
|
+
return new data_interfaces_js_1.EntityError(error);
|
|
1970
1971
|
};
|
|
1971
1972
|
rowHelperBase.prototype.catchSaveErrors = function (err) {
|
|
1972
1973
|
var _this = this;
|
|
@@ -3377,12 +3378,12 @@ var columnDefsImpl = /** @class */ (function () {
|
|
|
3377
3378
|
}
|
|
3378
3379
|
catch (err) {
|
|
3379
3380
|
var error = "".concat(String(prop), " failed for value ").concat(args === null || args === void 0 ? void 0 : args[0], ". Error: ").concat(typeof err === 'string' ? err : err.message);
|
|
3380
|
-
throw {
|
|
3381
|
+
throw new data_interfaces_js_1.EntityError({
|
|
3381
3382
|
message: _this.caption + ': ' + error,
|
|
3382
3383
|
modelState: (_a = {},
|
|
3383
3384
|
_a[_this.key] = error,
|
|
3384
3385
|
_a),
|
|
3385
|
-
};
|
|
3386
|
+
});
|
|
3386
3387
|
}
|
|
3387
3388
|
};
|
|
3388
3389
|
}
|
package/src/remult3/remult3.js
CHANGED
|
@@ -20,6 +20,8 @@ var wnn = [
|
|
|
20
20
|
exports.flags = {
|
|
21
21
|
error500RetryCount: 4,
|
|
22
22
|
};
|
|
23
|
+
//p1 - make error info an actual error, important for exception handling, and also for auth.js errors that were mistic
|
|
24
|
+
//p1 - add validators min,max,between(range)
|
|
23
25
|
//p1 - allow experimental route registration on remult server, with at least get route, and support redirect, read header and set header - (and the existing get html etc...)
|
|
24
26
|
//p2 - add parameter all to deleteMany, and updateMany
|
|
25
27
|
//p2 filter.apply ApiPreFilter
|
package/src/validators.d.ts
CHANGED
|
@@ -1,50 +1,129 @@
|
|
|
1
1
|
import type { FieldValidator } from './column-interfaces.js';
|
|
2
2
|
import type { ValidateFieldEvent } from './remult3/remult3.js';
|
|
3
|
+
/**
|
|
4
|
+
* Class containing various field validators.
|
|
5
|
+
*/
|
|
3
6
|
export declare class Validators {
|
|
7
|
+
/**
|
|
8
|
+
* Validator to check if a value is required (not null or empty).
|
|
9
|
+
*/
|
|
4
10
|
static required: Validator<unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Validator to ensure a value is unique in the database.
|
|
13
|
+
*/
|
|
5
14
|
static unique: Validator<unknown>;
|
|
6
15
|
/**
|
|
7
16
|
* @deprecated use `unique` instead - it also runs only on the backend
|
|
17
|
+
* Validator to ensure a value is unique on the backend.
|
|
8
18
|
*/
|
|
9
19
|
static uniqueOnBackend: Validator<unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Validator to check if a value matches a given regular expression.
|
|
22
|
+
*/
|
|
10
23
|
static regex: ValidatorWithArgs<string, RegExp> & {
|
|
11
24
|
defaultMessage: ValueValidationMessage<RegExp>;
|
|
12
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Validator to check if a value is a valid email address.
|
|
28
|
+
*/
|
|
13
29
|
static email: Validator<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Validator to check if a value is a valid URL.
|
|
32
|
+
*/
|
|
14
33
|
static url: Validator<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Validator to check if a value is one of the specified values.
|
|
36
|
+
*/
|
|
15
37
|
static in: <T>(value: readonly T[], withMessage?: ValueValidationMessage<T[]>) => FieldValidator<unknown, T> & {
|
|
16
38
|
withMessage: ValueValidationMessage<T[]>;
|
|
17
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Validator to check if a value is not null.
|
|
42
|
+
*/
|
|
18
43
|
static notNull: Validator<unknown>;
|
|
44
|
+
/**
|
|
45
|
+
* Validator to check if a value exists in a given enum.
|
|
46
|
+
*/
|
|
19
47
|
static enum: ValidatorWithArgs<unknown, unknown> & {
|
|
20
48
|
defaultMessage: ValueValidationMessage<unknown>;
|
|
21
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Validator to check if a related value exists in the database.
|
|
52
|
+
*/
|
|
22
53
|
static relationExists: Validator<unknown>;
|
|
54
|
+
/**
|
|
55
|
+
* Validator to check if a value is greater than or equal to a minimum value.
|
|
56
|
+
*/
|
|
57
|
+
static min: ValidatorWithArgs<number, number> & {
|
|
58
|
+
defaultMessage: ValueValidationMessage<number>;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Validator to check if a value is less than or equal to a maximum value.
|
|
62
|
+
*/
|
|
63
|
+
static max: ValidatorWithArgs<number, number> & {
|
|
64
|
+
defaultMessage: ValueValidationMessage<number>;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Validator to check if a string's length is less than or equal to a maximum length.
|
|
68
|
+
*/
|
|
23
69
|
static maxLength: ValidatorWithArgs<string, number> & {
|
|
24
70
|
defaultMessage: ValueValidationMessage<number>;
|
|
25
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* Validator to check if a string's length is greater than or equal to a minimum length.
|
|
74
|
+
*/
|
|
26
75
|
static minLength: ValidatorWithArgs<string, number> & {
|
|
27
76
|
defaultMessage: ValueValidationMessage<number>;
|
|
28
77
|
};
|
|
29
78
|
static defaultMessage: string;
|
|
30
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Type representing a field validator with an optional message.
|
|
82
|
+
*/
|
|
31
83
|
export type Validator<valueType> = FieldValidator<unknown, valueType> & ((message?: ValidationMessage<valueType, undefined>) => FieldValidator<unknown, valueType>) & {
|
|
32
84
|
defaultMessage: ValidationMessage<valueType, undefined>;
|
|
33
85
|
/**
|
|
34
|
-
* @deprecated
|
|
86
|
+
* @deprecated use (message:string) instead - for example: Validators.required("Is needed")
|
|
35
87
|
*/
|
|
36
88
|
withMessage(message: ValidationMessage<valueType, undefined>): FieldValidator<unknown, valueType>;
|
|
37
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Function to create a validator with a custom validation function.
|
|
92
|
+
*/
|
|
38
93
|
export declare function createValidator<valueType>(validate: (entity: any, e: ValidateFieldEvent<any, valueType>) => Promise<boolean | string> | boolean | string, defaultMessage?: ValidationMessage<valueType, undefined>): Validator<valueType>;
|
|
94
|
+
/**
|
|
95
|
+
* Function to create a value validator.
|
|
96
|
+
*/
|
|
39
97
|
export declare function valueValidator<valueType>(validate: (value: valueType) => boolean | string | Promise<boolean | string>, defaultMessage?: string): (entity: any, e: ValidateFieldEvent<any, valueType>) => string | boolean | Promise<string | boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* Function to create a value validator with arguments.
|
|
100
|
+
*/
|
|
40
101
|
export declare function createValueValidator<valueType>(validate: (value: valueType) => boolean | string | Promise<boolean | string>, defaultMessage?: ValidationMessage<valueType, undefined>): Validator<valueType>;
|
|
102
|
+
/**
|
|
103
|
+
* Function to create a value validator with arguments and a custom message.
|
|
104
|
+
*/
|
|
41
105
|
export declare function createValueValidatorWithArgs<valueType, argsType>(validate: (value: valueType, args: argsType) => boolean | string | Promise<boolean | string>, defaultMessage?: ValueValidationMessage<argsType>): ValidatorWithArgs<valueType, argsType> & {
|
|
42
106
|
defaultMessage: ValueValidationMessage<argsType>;
|
|
43
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Type representing a validation message that can be a string or a function.
|
|
110
|
+
*/
|
|
44
111
|
export type ValueValidationMessage<argsType> = string | ((args: argsType) => string);
|
|
112
|
+
/**
|
|
113
|
+
* Type representing a validation message with additional parameters.
|
|
114
|
+
*/
|
|
45
115
|
export type ValidationMessage<valueType, argsType> = string | ((entity: any, event: ValidateFieldEvent<any, valueType>, args: argsType) => string);
|
|
116
|
+
/**
|
|
117
|
+
* Type representing a validator with arguments.
|
|
118
|
+
*/
|
|
46
119
|
export type ValidatorWithArgs<valueType, argsType> = (args: argsType, message?: ValidationMessage<valueType, argsType>) => FieldValidator<unknown, valueType>;
|
|
120
|
+
/**
|
|
121
|
+
* Function to create a validator with arguments and a custom message.
|
|
122
|
+
*/
|
|
47
123
|
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
124
|
defaultMessage: ValidationMessage<valueType, argsType>;
|
|
49
125
|
};
|
|
126
|
+
/**
|
|
127
|
+
* Function to get the values of an enum.
|
|
128
|
+
*/
|
|
50
129
|
export declare function getEnumValues<theEnum>(enumObj: theEnum): any[];
|
package/src/validators.js
CHANGED
|
@@ -9,11 +9,17 @@ exports.createValidatorWithArgs = createValidatorWithArgs;
|
|
|
9
9
|
exports.getEnumValues = getEnumValues;
|
|
10
10
|
var tslib_1 = require("tslib");
|
|
11
11
|
var internals_js_1 = require("../internals.js");
|
|
12
|
+
/**
|
|
13
|
+
* Class containing various field validators.
|
|
14
|
+
*/
|
|
12
15
|
var Validators = /** @class */ (function () {
|
|
13
16
|
function Validators() {
|
|
14
17
|
}
|
|
15
18
|
var _a;
|
|
16
19
|
_a = Validators;
|
|
20
|
+
/**
|
|
21
|
+
* Validator to check if a value is required (not null or empty).
|
|
22
|
+
*/
|
|
17
23
|
Validators.required = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
18
24
|
return tslib_1.__generator(_a, function (_b) {
|
|
19
25
|
return [2 /*return*/, !e.valueIsNull() &&
|
|
@@ -21,6 +27,9 @@ var Validators = /** @class */ (function () {
|
|
|
21
27
|
(e.value !== undefined || (0, internals_js_1.getRelationFieldInfo)(e.metadata) !== undefined)];
|
|
22
28
|
});
|
|
23
29
|
}); }, 'Should not be empty');
|
|
30
|
+
/**
|
|
31
|
+
* Validator to ensure a value is unique in the database.
|
|
32
|
+
*/
|
|
24
33
|
Validators.unique = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
25
34
|
var _b;
|
|
26
35
|
return tslib_1.__generator(_a, function (_c) {
|
|
@@ -39,6 +48,7 @@ var Validators = /** @class */ (function () {
|
|
|
39
48
|
}); }, 'already exists');
|
|
40
49
|
/**
|
|
41
50
|
* @deprecated use `unique` instead - it also runs only on the backend
|
|
51
|
+
* Validator to ensure a value is unique on the backend.
|
|
42
52
|
*/
|
|
43
53
|
Validators.uniqueOnBackend = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
44
54
|
var _b;
|
|
@@ -54,11 +64,23 @@ var Validators = /** @class */ (function () {
|
|
|
54
64
|
}
|
|
55
65
|
});
|
|
56
66
|
}); }, _a.unique.defaultMessage);
|
|
67
|
+
/**
|
|
68
|
+
* Validator to check if a value matches a given regular expression.
|
|
69
|
+
*/
|
|
57
70
|
Validators.regex = createValueValidatorWithArgs(function (val, regex) {
|
|
58
71
|
return regex.test(val);
|
|
59
72
|
});
|
|
73
|
+
/**
|
|
74
|
+
* Validator to check if a value is a valid email address.
|
|
75
|
+
*/
|
|
60
76
|
Validators.email = createValueValidator(function (val) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val); }, 'Invalid Email');
|
|
77
|
+
/**
|
|
78
|
+
* Validator to check if a value is a valid URL.
|
|
79
|
+
*/
|
|
61
80
|
Validators.url = createValueValidator(function (val) { return !!new URL(val); }, 'Invalid Url');
|
|
81
|
+
/**
|
|
82
|
+
* Validator to check if a value is one of the specified values.
|
|
83
|
+
*/
|
|
62
84
|
Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) {
|
|
63
85
|
return "Value must be one of: ".concat(values
|
|
64
86
|
.map(function (y) {
|
|
@@ -70,10 +92,19 @@ var Validators = /** @class */ (function () {
|
|
|
70
92
|
})
|
|
71
93
|
.join(', '));
|
|
72
94
|
});
|
|
95
|
+
/**
|
|
96
|
+
* Validator to check if a value is not null.
|
|
97
|
+
*/
|
|
73
98
|
Validators.notNull = createValueValidator(function (val) { return val != null; }, 'Should not be null');
|
|
99
|
+
/**
|
|
100
|
+
* Validator to check if a value exists in a given enum.
|
|
101
|
+
*/
|
|
74
102
|
Validators.enum = createValueValidatorWithArgs(function (value, enumObj) { return Object.values(enumObj).includes(value); }, function (enumObj) {
|
|
75
103
|
return "Value must be one of ".concat(getEnumValues(enumObj).join(', '));
|
|
76
104
|
});
|
|
105
|
+
/**
|
|
106
|
+
* Validator to check if a related value exists in the database.
|
|
107
|
+
*/
|
|
77
108
|
Validators.relationExists = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
78
109
|
var _b;
|
|
79
110
|
return tslib_1.__generator(_a, function (_c) {
|
|
@@ -89,12 +120,29 @@ var Validators = /** @class */ (function () {
|
|
|
89
120
|
}
|
|
90
121
|
});
|
|
91
122
|
}); }, 'Relation value does not exist');
|
|
123
|
+
/**
|
|
124
|
+
* Validator to check if a value is greater than or equal to a minimum value.
|
|
125
|
+
*/
|
|
126
|
+
Validators.min = createValueValidatorWithArgs(function (val, minValue) { return val >= minValue; }, function (minValue) { return "Value must be bigger than or equal to ".concat(minValue); });
|
|
127
|
+
/**
|
|
128
|
+
* Validator to check if a value is less than or equal to a maximum value.
|
|
129
|
+
*/
|
|
130
|
+
Validators.max = createValueValidatorWithArgs(function (val, maxValue) { return val <= maxValue; }, function (maxValue) { return "Value must be smaller than or equal to ".concat(maxValue); });
|
|
131
|
+
/**
|
|
132
|
+
* Validator to check if a string's length is less than or equal to a maximum length.
|
|
133
|
+
*/
|
|
92
134
|
Validators.maxLength = createValueValidatorWithArgs(function (val, maxLength) { return val.length <= maxLength; }, function (maxLength) { return "Value must be at most ".concat(maxLength, " characters"); });
|
|
135
|
+
/**
|
|
136
|
+
* Validator to check if a string's length is greater than or equal to a minimum length.
|
|
137
|
+
*/
|
|
93
138
|
Validators.minLength = createValueValidatorWithArgs(function (val, minLength) { return val.length >= minLength; }, function (maxLength) { return "Value must be at least ".concat(maxLength, " characters"); });
|
|
94
139
|
Validators.defaultMessage = 'Invalid value';
|
|
95
140
|
return Validators;
|
|
96
141
|
}());
|
|
97
142
|
exports.Validators = Validators;
|
|
143
|
+
/**
|
|
144
|
+
* Function to create a validator with a custom validation function.
|
|
145
|
+
*/
|
|
98
146
|
function createValidator(validate, defaultMessage) {
|
|
99
147
|
var _this = this;
|
|
100
148
|
var validation = function (entity, e, message) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
@@ -149,11 +197,17 @@ function createValidator(validate, defaultMessage) {
|
|
|
149
197
|
},
|
|
150
198
|
});
|
|
151
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Function to create a value validator.
|
|
202
|
+
*/
|
|
152
203
|
function valueValidator(validate, defaultMessage) {
|
|
153
204
|
return function (entity, e) {
|
|
154
205
|
return validate(e.value) || defaultMessage || false;
|
|
155
206
|
};
|
|
156
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Function to create a value validator with arguments.
|
|
210
|
+
*/
|
|
157
211
|
function createValueValidator(validate, defaultMessage) {
|
|
158
212
|
return createValidator(function (_, e) {
|
|
159
213
|
if (e.value === undefined || e.value === null)
|
|
@@ -161,6 +215,9 @@ function createValueValidator(validate, defaultMessage) {
|
|
|
161
215
|
return validate(e.value);
|
|
162
216
|
}, defaultMessage);
|
|
163
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Function to create a value validator with arguments and a custom message.
|
|
220
|
+
*/
|
|
164
221
|
function createValueValidatorWithArgs(validate, defaultMessage) {
|
|
165
222
|
var result = createValidatorWithArgsInternal(function (_, e, args) {
|
|
166
223
|
if (e.value === undefined || e.value === null)
|
|
@@ -179,6 +236,9 @@ function createValueValidatorWithArgs(validate, defaultMessage) {
|
|
|
179
236
|
},
|
|
180
237
|
});
|
|
181
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Function to create a validator with arguments and a custom message.
|
|
241
|
+
*/
|
|
182
242
|
function createValidatorWithArgs(validate, defaultMessage) {
|
|
183
243
|
return createValidatorWithArgsInternal(validate, defaultMessage);
|
|
184
244
|
}
|
|
@@ -221,6 +281,9 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
|
|
|
221
281
|
},
|
|
222
282
|
});
|
|
223
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* Function to get the values of an enum.
|
|
286
|
+
*/
|
|
224
287
|
function getEnumValues(enumObj) {
|
|
225
288
|
return Object.values(enumObj).filter(function (x) { return typeof enumObj[x] !== 'number'; });
|
|
226
289
|
}
|