remult 2.7.28 → 2.7.30
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/server/get-remult-admin-html.js +1 -1
- package/esm/server/remult-admin.js +68 -58
- package/esm/server/remult-api-server.js +11 -4
- package/esm/src/filter/filter-interfaces.js +7 -2
- package/esm/src/remult3/getEntityRef.js +2 -0
- package/package.json +1 -1
- package/server/get-remult-admin-html.js +1 -1
- package/server/remult-admin.d.ts +8 -5
- package/server/remult-admin.js +55 -47
- package/server/remult-api-server.d.ts +5 -2
- package/server/remult-api-server.js +14 -6
- package/src/column-interfaces.d.ts +5 -6
- package/src/filter/filter-interfaces.js +7 -2
- package/src/remult3/getEntityRef.js +2 -0
- package/src/remult3/remult3.d.ts +43 -24
package/server/remult-admin.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface EntityUIInfo {
|
|
|
12
12
|
color?: string;
|
|
13
13
|
}
|
|
14
14
|
export interface EntityRelationToManyInfo extends RelationFields {
|
|
15
|
+
key: string;
|
|
16
|
+
caption: string;
|
|
15
17
|
entityKey: string;
|
|
16
18
|
where?: any;
|
|
17
19
|
}
|
|
@@ -35,13 +37,14 @@ export interface FieldRelationToOneInfo extends RelationFields {
|
|
|
35
37
|
captionField: string;
|
|
36
38
|
where?: any;
|
|
37
39
|
}
|
|
38
|
-
export interface
|
|
40
|
+
export interface AdminEntitiesOptions {
|
|
39
41
|
entities: ClassType<any>[];
|
|
40
42
|
remult: Remult;
|
|
41
43
|
}
|
|
42
|
-
export interface
|
|
43
|
-
|
|
44
|
+
export interface AdminDisplayOptions {
|
|
45
|
+
rootPath: string;
|
|
46
|
+
head: string;
|
|
44
47
|
}
|
|
45
|
-
export default function remultAdminHtml(options:
|
|
46
|
-
export declare function buildEntityInfo(options:
|
|
48
|
+
export default function remultAdminHtml(options: AdminDisplayOptions): string;
|
|
49
|
+
export declare function buildEntityInfo(options: AdminEntitiesOptions): EntityUIInfo[];
|
|
47
50
|
export type RelationsToOneValues = Record<string, Map<any, any>>;
|
package/server/remult-admin.js
CHANGED
|
@@ -8,8 +8,10 @@ var filter_interfaces_js_1 = require("../src/filter/filter-interfaces.js");
|
|
|
8
8
|
var get_remult_admin_html_js_1 = require("./get-remult-admin-html.js");
|
|
9
9
|
var RepositoryImplementation_js_1 = require("../src/remult3/RepositoryImplementation.js");
|
|
10
10
|
function remultAdminHtml(options) {
|
|
11
|
-
var
|
|
12
|
-
return (0, get_remult_admin_html_js_1.getHtml)()
|
|
11
|
+
var rootPath = options.rootPath, head = options.head;
|
|
12
|
+
return (0, get_remult_admin_html_js_1.getHtml)()
|
|
13
|
+
.replace('<!--PLACE_HERE_HEAD-->', head)
|
|
14
|
+
.replace('<!--PLACE_HERE_BODY-->', "<script>\n window.optionsFromServer = ".concat(JSON.stringify({ rootPath: rootPath }), "\n</script>"));
|
|
13
15
|
}
|
|
14
16
|
function buildEntityInfo(options) {
|
|
15
17
|
var e_1, _a, e_2, _b, e_3, _c;
|
|
@@ -37,57 +39,63 @@ function buildEntityInfo(options) {
|
|
|
37
39
|
var _loop_1 = function (x) {
|
|
38
40
|
if (!x.includedInApi(undefined))
|
|
39
41
|
return "continue";
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
info.options.findOptions
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (info.type
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
42
|
+
try {
|
|
43
|
+
var relation = void 0;
|
|
44
|
+
var valFieldKey = x.key;
|
|
45
|
+
var info = (0, relationInfoMember_js_1.getRelationFieldInfo)(x);
|
|
46
|
+
if (info) {
|
|
47
|
+
var relInfo = info.getFields();
|
|
48
|
+
var relRepo = options.remult.repo(info.toEntity);
|
|
49
|
+
var where = typeof info.options.findOptions === 'object' &&
|
|
50
|
+
info.options.findOptions.where
|
|
51
|
+
? filter_interfaces_js_1.Filter.entityFilterToJson(relRepo.metadata, info.options.findOptions.where)
|
|
52
|
+
: undefined;
|
|
53
|
+
var idField_1 = relRepo.metadata.idMetadata.field.key;
|
|
54
|
+
if (info.type === 'reference' || info.type === 'toOne') {
|
|
55
|
+
if (info.type == 'toOne') {
|
|
56
|
+
for (var key in relInfo.fields) {
|
|
57
|
+
if (Object.prototype.hasOwnProperty.call(relInfo.fields, key)) {
|
|
58
|
+
var element = relInfo.fields[key];
|
|
59
|
+
valFieldKey = element;
|
|
60
|
+
}
|
|
57
61
|
}
|
|
58
62
|
}
|
|
63
|
+
if (relRepo.metadata.apiReadAllowed) {
|
|
64
|
+
relation = tslib_1.__assign(tslib_1.__assign({}, relInfo), { where: where, entityKey: relRepo.metadata.key, idField: idField_1, captionField: (_d = relRepo.metadata.fields
|
|
65
|
+
.toArray()
|
|
66
|
+
.find(function (x) { return x.key != idField_1 && x.valueType == String; })) === null || _d === void 0 ? void 0 : _d.key });
|
|
67
|
+
}
|
|
59
68
|
}
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
else if (info.type === 'toMany') {
|
|
67
|
-
if (relRepo.metadata.apiReadAllowed) {
|
|
68
|
-
relations.push(tslib_1.__assign(tslib_1.__assign({}, relInfo), { where: where, entityKey: relRepo.metadata.key }));
|
|
69
|
+
else if (info.type === 'toMany') {
|
|
70
|
+
if (relRepo.metadata.apiReadAllowed) {
|
|
71
|
+
relations.push(tslib_1.__assign(tslib_1.__assign({}, relInfo), { where: where, entityKey: relRepo.metadata.key, key: x.key, caption: x.caption }));
|
|
72
|
+
}
|
|
73
|
+
return "continue";
|
|
69
74
|
}
|
|
70
|
-
return "continue";
|
|
71
75
|
}
|
|
76
|
+
fields.push({
|
|
77
|
+
key: x.key,
|
|
78
|
+
readOnly: !x.apiUpdateAllowed(),
|
|
79
|
+
values: (0, RepositoryImplementation_js_1.getValueList)(x),
|
|
80
|
+
valFieldKey: valFieldKey,
|
|
81
|
+
caption: x.caption,
|
|
82
|
+
relationToOne: relation,
|
|
83
|
+
inputType: x.inputType,
|
|
84
|
+
type: x.valueConverter.fieldTypeInDb == 'json'
|
|
85
|
+
? 'json'
|
|
86
|
+
: x.valueType === Number
|
|
87
|
+
? 'number'
|
|
88
|
+
: x.valueType === Boolean
|
|
89
|
+
? 'boolean'
|
|
90
|
+
: x.valueType === Date
|
|
91
|
+
? 'date'
|
|
92
|
+
: 'string',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error("[remult-admin] Error with ".concat(metadata.key, ".").concat(x.key, " field."));
|
|
97
|
+
console.error("[remult-admin]", error);
|
|
72
98
|
}
|
|
73
|
-
fields.push({
|
|
74
|
-
key: x.key,
|
|
75
|
-
readOnly: !x.apiUpdateAllowed(),
|
|
76
|
-
values: (0, RepositoryImplementation_js_1.getValueList)(x),
|
|
77
|
-
valFieldKey: valFieldKey,
|
|
78
|
-
caption: x.caption,
|
|
79
|
-
relationToOne: relation,
|
|
80
|
-
inputType: x.inputType,
|
|
81
|
-
type: x.valueConverter.fieldTypeInDb == 'json'
|
|
82
|
-
? 'json'
|
|
83
|
-
: x.valueType === Number
|
|
84
|
-
? 'number'
|
|
85
|
-
: x.valueType === Boolean
|
|
86
|
-
? 'boolean'
|
|
87
|
-
: x.valueType === Date
|
|
88
|
-
? 'date'
|
|
89
|
-
: 'string',
|
|
90
|
-
});
|
|
91
99
|
};
|
|
92
100
|
try {
|
|
93
101
|
for (var _k = (e_3 = void 0, tslib_1.__values(metadata.fields.toArray())), _l = _k.next(); !_l.done; _l = _k.next()) {
|
|
@@ -52,10 +52,13 @@ export interface RemultServerOptions<RequestType> {
|
|
|
52
52
|
* @example
|
|
53
53
|
* admin: true
|
|
54
54
|
* @example
|
|
55
|
-
* admin: ()=> remult.isAllowed('admin')
|
|
55
|
+
* admin: () => remult.isAllowed('admin')
|
|
56
56
|
* @see [allowed](http://remult.dev/docs/allowed.html)
|
|
57
57
|
*/
|
|
58
|
-
admin?: Allowed
|
|
58
|
+
admin?: Allowed | {
|
|
59
|
+
allow: Allowed;
|
|
60
|
+
customHtmlHead?: (remult: Remult) => string;
|
|
61
|
+
};
|
|
59
62
|
/** Storage to use for backend methods that use queue */
|
|
60
63
|
queueStorage?: QueueStorage;
|
|
61
64
|
/**
|
|
@@ -364,9 +364,13 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
364
364
|
if (this.options.admin !== undefined && this.options.admin !== false) {
|
|
365
365
|
var admin = function () {
|
|
366
366
|
return _this.process(function (remult, req, res, orig, origResponse) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
367
|
-
var
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
var allowed, head;
|
|
368
|
+
var _a, _b, _c;
|
|
369
|
+
return tslib_1.__generator(this, function (_d) {
|
|
370
|
+
allowed = (0, isOfType_js_1.isOfType)(this.options.admin, 'allow')
|
|
371
|
+
? this.options.admin.allow
|
|
372
|
+
: this.options.admin;
|
|
373
|
+
if (remult.isAllowed(allowed)) {
|
|
370
374
|
if (((_a = orig === null || orig === void 0 ? void 0 : orig.params) === null || _a === void 0 ? void 0 : _a.id) === '__entities-metadata') {
|
|
371
375
|
res.success((0, remult_admin_js_1.buildEntityInfo)({
|
|
372
376
|
remult: remult,
|
|
@@ -374,10 +378,14 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
374
378
|
}));
|
|
375
379
|
}
|
|
376
380
|
else {
|
|
381
|
+
head = '<title>Admin</title>';
|
|
382
|
+
if ((0, isOfType_js_1.isOfType)(this.options.admin, 'allow') &&
|
|
383
|
+
this.options.admin.customHtmlHead) {
|
|
384
|
+
head = this.options.admin.customHtmlHead(remult);
|
|
385
|
+
}
|
|
377
386
|
origResponse.send((0, remult_admin_js_1.default)({
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
baseUrl: this.options.rootPath + '/admin',
|
|
387
|
+
rootPath: (_c = this.options.rootPath) !== null && _c !== void 0 ? _c : '/api',
|
|
388
|
+
head: head,
|
|
381
389
|
}));
|
|
382
390
|
}
|
|
383
391
|
}
|
|
@@ -29,6 +29,8 @@ export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
|
29
29
|
/**
|
|
30
30
|
* Determines whether this field can be updated via the API. This setting can also
|
|
31
31
|
* be controlled based on user roles or other access control checks.
|
|
32
|
+
*
|
|
33
|
+
* _It happens after entity level authorization AND if it's allowed._
|
|
32
34
|
* @example
|
|
33
35
|
* // Prevent API from updating this field
|
|
34
36
|
* @Fields.string({ allowApiUpdate: false })
|
|
@@ -122,8 +124,7 @@ export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
|
122
124
|
export interface FieldMetadata<valueType = unknown, entityType = unknown> {
|
|
123
125
|
/** The field's member name in an object.
|
|
124
126
|
* @example
|
|
125
|
-
*
|
|
126
|
-
* console.log(taskRepo.metadata.fields.title.key);
|
|
127
|
+
* console.log(repo(Task).metadata.fields.title.key);
|
|
127
128
|
* // result: title
|
|
128
129
|
*/
|
|
129
130
|
readonly key: entityType extends object ? keyof entityType & string : string;
|
|
@@ -154,8 +155,7 @@ export interface FieldMetadata<valueType = unknown, entityType = unknown> {
|
|
|
154
155
|
readonly allowNull: boolean;
|
|
155
156
|
/** The class that contains this field
|
|
156
157
|
* @example
|
|
157
|
-
*
|
|
158
|
-
* Task == taskRepo.metadata.fields.title.target //will return true
|
|
158
|
+
* Task == repo(Task).metadata.fields.title.target //will return true
|
|
159
159
|
*/
|
|
160
160
|
readonly target: ClassType<valueType>;
|
|
161
161
|
/**
|
|
@@ -179,9 +179,8 @@ export interface FieldMetadata<valueType = unknown, entityType = unknown> {
|
|
|
179
179
|
* Determines if the current user is allowed to update a specific entity instance.
|
|
180
180
|
|
|
181
181
|
* @example
|
|
182
|
-
* const taskRepo = remult.repo(Task);
|
|
183
182
|
* // Check if the current user is allowed to update a specific task
|
|
184
|
-
* if (
|
|
183
|
+
* if (repo(Task).metadata.apiUpdateAllowed(task)){
|
|
185
184
|
* // Allow user to edit the entity
|
|
186
185
|
* }
|
|
187
186
|
* @see {@link FieldOptions#allowApiUpdate} for configuration details
|
|
@@ -936,8 +936,13 @@ function buildFilterFromRequestParameters(entity, filterInfo) {
|
|
|
936
936
|
}
|
|
937
937
|
finally { if (e_5) throw e_5.error; }
|
|
938
938
|
}
|
|
939
|
-
if (not.length == 1
|
|
940
|
-
where
|
|
939
|
+
if (not.length == 1) {
|
|
940
|
+
if (!where.$not) {
|
|
941
|
+
where.$not = not[0].$not;
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
where.$not.push(not[0].$not);
|
|
945
|
+
}
|
|
941
946
|
}
|
|
942
947
|
else {
|
|
943
948
|
addAnd({
|
|
@@ -16,6 +16,8 @@ exports.getEntityKey = getEntityKey;
|
|
|
16
16
|
function getEntityRef(entity, throwException) {
|
|
17
17
|
var _a;
|
|
18
18
|
if (throwException === void 0) { throwException = true; }
|
|
19
|
+
if (entity === undefined)
|
|
20
|
+
throw new Error('entity is undefined');
|
|
19
21
|
var x = entity[exports.entityMember];
|
|
20
22
|
if (!x && throwException)
|
|
21
23
|
throw new Error('item ' +
|
package/src/remult3/remult3.d.ts
CHANGED
|
@@ -212,8 +212,7 @@ export interface EntityMetadata<entityType = unknown> {
|
|
|
212
212
|
/** true if the current user is allowed to update an entity instance
|
|
213
213
|
* @see {@link EntityOptions.allowApiUpdate
|
|
214
214
|
* @example
|
|
215
|
-
*
|
|
216
|
-
* if (taskRepo.metadata.apiUpdateAllowed(task)){
|
|
215
|
+
* if (repo(Task).metadata.apiUpdateAllowed(task)){
|
|
217
216
|
* // Allow user to edit the entity
|
|
218
217
|
* }
|
|
219
218
|
*/
|
|
@@ -221,8 +220,7 @@ export interface EntityMetadata<entityType = unknown> {
|
|
|
221
220
|
/** true if the current user is allowed to read from entity
|
|
222
221
|
* @see {@link EntityOptions.allowApiRead}
|
|
223
222
|
* @example
|
|
224
|
-
*
|
|
225
|
-
* if (taskRepo.metadata.apiReadAllowed){
|
|
223
|
+
* if (repo(Task).metadata.apiReadAllowed){
|
|
226
224
|
* await taskRepo.find()
|
|
227
225
|
* }
|
|
228
226
|
*/
|
|
@@ -230,8 +228,7 @@ export interface EntityMetadata<entityType = unknown> {
|
|
|
230
228
|
/** true if the current user is allowed to delete an entity instance
|
|
231
229
|
* * @see {@link EntityOptions.allowApiDelete}
|
|
232
230
|
* @example
|
|
233
|
-
*
|
|
234
|
-
* if (taskRepo.metadata.apiDeleteAllowed(task)){
|
|
231
|
+
* if (repo(Task).metadata.apiDeleteAllowed(task)){
|
|
235
232
|
* // display delete button
|
|
236
233
|
* }
|
|
237
234
|
*/
|
|
@@ -239,8 +236,7 @@ export interface EntityMetadata<entityType = unknown> {
|
|
|
239
236
|
/** true if the current user is allowed to create an entity instance
|
|
240
237
|
* @see {@link EntityOptions.allowApiInsert}
|
|
241
238
|
* @example
|
|
242
|
-
*
|
|
243
|
-
* if (taskRepo.metadata.apiInsertAllowed(task)){
|
|
239
|
+
* if (repo(Task).metadata.apiInsertAllowed(task)){
|
|
244
240
|
* // display insert button
|
|
245
241
|
* }
|
|
246
242
|
*/
|
|
@@ -389,7 +385,7 @@ export type GroupByResult<entityType, groupByFields extends (keyof entityType)[]
|
|
|
389
385
|
} & {
|
|
390
386
|
$count: number;
|
|
391
387
|
};
|
|
392
|
-
/**used to perform CRUD operations on an `entityType` */
|
|
388
|
+
/** used to perform CRUD operations on an `entityType` */
|
|
393
389
|
export interface Repository<entityType> {
|
|
394
390
|
/** returns a result array based on the provided options */
|
|
395
391
|
find(options?: FindOptions<entityType>): Promise<entityType[]>;
|
|
@@ -611,13 +607,36 @@ export interface Repository<entityType> {
|
|
|
611
607
|
*
|
|
612
608
|
*/
|
|
613
609
|
create(item?: Partial<MembersOnly<entityType>>): entityType;
|
|
610
|
+
/**
|
|
611
|
+
* Translates an entity to a json object.
|
|
612
|
+
* - Ready to be sent to the client _(Date & co are managed)_
|
|
613
|
+
* - Strip out fields that are not allowed to be sent to the client! Check: [Field.includeInApi](http://remult.dev/docs/ref_field#includeinapi)
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* ```ts
|
|
617
|
+
* const tasks = repo(Task).toJson(repo(Task).find())
|
|
618
|
+
* ```
|
|
619
|
+
*
|
|
620
|
+
* @param item Can be an array or a single entity, awaitable or not
|
|
621
|
+
*/
|
|
614
622
|
toJson(item: Promise<entityType[]>): Promise<any[]>;
|
|
615
623
|
toJson(item: entityType[]): any[];
|
|
616
624
|
toJson(item: Promise<entityType>): Promise<any>;
|
|
617
625
|
toJson(item: entityType): any;
|
|
618
|
-
/**
|
|
619
|
-
|
|
620
|
-
|
|
626
|
+
/**
|
|
627
|
+
* Translates a json object to an item instance.
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* ```ts
|
|
631
|
+
* const data = // from the server
|
|
632
|
+
* const tasks = repo(Task).fromJson(data)
|
|
633
|
+
* ```
|
|
634
|
+
*
|
|
635
|
+
* @param data Can be an array or a single element
|
|
636
|
+
* @param isNew To help the creation of the instance
|
|
637
|
+
*/
|
|
638
|
+
fromJson(data: any[], isNew?: boolean): entityType[];
|
|
639
|
+
fromJson(data: any, isNew?: boolean): entityType;
|
|
621
640
|
/** returns an `entityRef` for an item returned by `create`, `find` etc... */
|
|
622
641
|
getEntityRef(item: entityType): EntityRef<entityType>;
|
|
623
642
|
/** Provides information about the fields of the Repository's entity
|
|
@@ -709,26 +728,26 @@ export interface LiveQueryChangeInfo<entityType> {
|
|
|
709
728
|
export interface FindOptions<entityType> extends FindOptionsBase<entityType> {
|
|
710
729
|
/** Determines the number of rows returned by the request, on the browser the default is 100 rows
|
|
711
730
|
* @example
|
|
712
|
-
* await
|
|
713
|
-
*
|
|
714
|
-
*
|
|
731
|
+
* await repo(Products).find({
|
|
732
|
+
* limit: 10,
|
|
733
|
+
* page: 2
|
|
715
734
|
* })
|
|
716
735
|
*/
|
|
717
736
|
limit?: number;
|
|
718
737
|
/** Determines the page number that will be used to extract the data
|
|
719
738
|
* @example
|
|
720
|
-
* await
|
|
721
|
-
*
|
|
722
|
-
* page:2
|
|
739
|
+
* await repo(Products).find({
|
|
740
|
+
* limit: 10,
|
|
741
|
+
* page: 2
|
|
723
742
|
* })
|
|
724
743
|
*/
|
|
725
744
|
page?: number;
|
|
726
745
|
}
|
|
727
746
|
/** Determines the order of items returned .
|
|
728
747
|
* @example
|
|
729
|
-
* await
|
|
748
|
+
* await repo(Products).find({ orderBy: { name: "asc" }})
|
|
730
749
|
* @example
|
|
731
|
-
* await
|
|
750
|
+
* await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
|
|
732
751
|
*/
|
|
733
752
|
export declare type EntityOrderBy<entityType> = {
|
|
734
753
|
[Properties in keyof Partial<MembersOnly<entityType>>]?: 'asc' | 'desc';
|
|
@@ -985,13 +1004,13 @@ export interface LoadOptions<entityType> {
|
|
|
985
1004
|
* Example usage:
|
|
986
1005
|
* ```
|
|
987
1006
|
* // Deprecated usage with 'load' option
|
|
988
|
-
* await
|
|
1007
|
+
* await repo(Order).find({
|
|
989
1008
|
* load: (o) => [o.customer],
|
|
990
1009
|
* });
|
|
991
1010
|
*
|
|
992
1011
|
*
|
|
993
1012
|
* // Preferred usage with 'Relations.toOne' and 'include' option
|
|
994
|
-
* await
|
|
1013
|
+
* await repo(Order).find({
|
|
995
1014
|
* include: { customer: true },
|
|
996
1015
|
* });
|
|
997
1016
|
* ```
|
|
@@ -1029,9 +1048,9 @@ export interface FindOptionsBase<entityType> extends LoadOptions<entityType> {
|
|
|
1029
1048
|
where?: EntityFilter<entityType>;
|
|
1030
1049
|
/** Determines the order of items returned .
|
|
1031
1050
|
* @example
|
|
1032
|
-
* await
|
|
1051
|
+
* await repo(Products).find({ orderBy: { name: "asc" }})
|
|
1033
1052
|
* @example
|
|
1034
|
-
* await
|
|
1053
|
+
* await repo(Products).find({ orderBy: { price: "desc", name: "asc" }})
|
|
1035
1054
|
*/
|
|
1036
1055
|
orderBy?: EntityOrderBy<entityType>;
|
|
1037
1056
|
}
|