remult 0.27.21-next.9 → 0.27.21
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/internals.js +2 -1
- package/esm/remult-sqlite3.js +2 -2
- package/esm/server/get-remult-admin-html.js +1 -1
- package/esm/src/data-providers/sql-relations.js +125 -0
- package/esm/src/remult-static.js +1 -0
- package/esm/src/remult3/RepositoryImplementation.js +74 -47
- package/index.d.ts +1 -1
- package/internals.d.ts +2 -1
- package/internals.js +6 -1
- package/package.json +1 -1
- package/remult-sqlite3.js +3 -3
- package/server/get-remult-admin-html.js +1 -1
- package/src/data-providers/sql-relations.d.ts +40 -0
- package/src/data-providers/sql-relations.js +167 -0
- package/src/remult-static.d.ts +1 -0
- package/src/remult-static.js +1 -0
- package/src/remult3/RepositoryImplementation.d.ts +6 -2
- package/src/remult3/RepositoryImplementation.js +232 -195
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ClassType } from '../../classType.js';
|
|
2
|
+
import { type EntityDbNames } from '../filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
|
+
import type { EntityFilter, EntityOrderBy, ObjectMembersOnly } from '../remult3/remult3.js';
|
|
4
|
+
import type { SqlCommandWithParameters } from '../sql-command.js';
|
|
5
|
+
export declare function sqlRelations<entityType>(forEntity: ClassType<entityType>): SqlRelations<entityType>;
|
|
6
|
+
export type SqlRelations<entityType> = {
|
|
7
|
+
[p in keyof ObjectMembersOnly<entityType>]-?: SqlRelation<ArrayItemType<NonNullable<entityType[p]>>>;
|
|
8
|
+
};
|
|
9
|
+
export type SubQueryWhat<toEntity> = (fieldNamesOfToEntity: EntityDbNames<toEntity>) => string | Promise<string>;
|
|
10
|
+
export type SubQueryOptions<toEntity> = {
|
|
11
|
+
where?: EntityFilter<toEntity>;
|
|
12
|
+
orderBy?: EntityOrderBy<toEntity>;
|
|
13
|
+
first?: boolean;
|
|
14
|
+
c?: SqlCommandWithParameters;
|
|
15
|
+
};
|
|
16
|
+
export type SqlFirst<toEntity> = {
|
|
17
|
+
$subQuery(what: SubQueryWhat<toEntity>): Promise<string>;
|
|
18
|
+
$relations: {
|
|
19
|
+
[P in keyof ObjectMembersOnly<toEntity>]-?: SqlRelation<toEntity[P]>;
|
|
20
|
+
};
|
|
21
|
+
} & {
|
|
22
|
+
[P in keyof toEntity]-?: Promise<string>;
|
|
23
|
+
};
|
|
24
|
+
export type SqlRelation<toEntity> = {
|
|
25
|
+
$count(where?: EntityFilter<toEntity>): Promise<string>;
|
|
26
|
+
$subQuery(what: SubQueryWhat<toEntity>, options?: SubQueryOptions<toEntity>): Promise<string>;
|
|
27
|
+
$relations: {
|
|
28
|
+
[P in keyof ObjectMembersOnly<toEntity>]-?: SqlRelation<toEntity[P]>;
|
|
29
|
+
};
|
|
30
|
+
$first(options?: Pick<SubQueryOptions<toEntity>, 'where' | 'orderBy'>): SqlFirst<toEntity>;
|
|
31
|
+
} & {
|
|
32
|
+
[P in keyof toEntity]-?: Promise<string>;
|
|
33
|
+
};
|
|
34
|
+
export type ArrayItemType<T> = T extends (infer U)[] ? U : T;
|
|
35
|
+
export declare function sqlRelationsFilter<entityType>(forEntity: ClassType<entityType>): { [p in keyof entityType]-?: SqlRelationFilter<entityType, p, ArrayItemType<NonNullable<entityType[p]>>>; };
|
|
36
|
+
export declare class SqlRelationFilter<myEntity, relationKey extends keyof myEntity, toEntity = ArrayItemType<myEntity[relationKey]>> {
|
|
37
|
+
private _tools;
|
|
38
|
+
constructor(myEntity: ClassType<myEntity>, relationField: relationKey);
|
|
39
|
+
some(where?: EntityFilter<toEntity>): EntityFilter<toEntity>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SqlRelationFilter = void 0;
|
|
4
|
+
exports.sqlRelations = sqlRelations;
|
|
5
|
+
exports.sqlRelationsFilter = sqlRelationsFilter;
|
|
6
|
+
var tslib_1 = require("tslib");
|
|
7
|
+
var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consumer-bridge-to-sql-request.js");
|
|
8
|
+
var relationInfoMember_js_1 = require("../remult3/relationInfoMember.js");
|
|
9
|
+
var sql_database_js_1 = require("./sql-database.js");
|
|
10
|
+
var remult_proxy_js_1 = require("../remult-proxy.js");
|
|
11
|
+
function sqlRelations(forEntity) {
|
|
12
|
+
return new Proxy({}, {
|
|
13
|
+
get: function (target, relationField) {
|
|
14
|
+
return new Proxy(new SqlRelationTools(forEntity, relationField), {
|
|
15
|
+
get: function (target, prop) {
|
|
16
|
+
if (prop == '$count')
|
|
17
|
+
return target.$count;
|
|
18
|
+
if (prop == '$subQuery')
|
|
19
|
+
return target.$subQuery;
|
|
20
|
+
if (prop == '$relations')
|
|
21
|
+
return target.___relations();
|
|
22
|
+
if (prop == '$first')
|
|
23
|
+
return target.$first;
|
|
24
|
+
return target.$fields[prop];
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
var SqlRelationTools = /** @class */ (function () {
|
|
31
|
+
function SqlRelationTools(myEntity, relationField) {
|
|
32
|
+
var _this = this;
|
|
33
|
+
this.myEntity = myEntity;
|
|
34
|
+
this.relationField = relationField;
|
|
35
|
+
this.$count = function (where) {
|
|
36
|
+
return _this.$subQuery(function () { return 'count(*)'; }, { where: where });
|
|
37
|
+
};
|
|
38
|
+
this.$first = function (options) {
|
|
39
|
+
return new Proxy(_this, {
|
|
40
|
+
get: function (target, prop) {
|
|
41
|
+
if (prop == '$subQuery')
|
|
42
|
+
return function (what) {
|
|
43
|
+
return target.$subQuery(what, tslib_1.__assign(tslib_1.__assign({}, options), { first: true }));
|
|
44
|
+
};
|
|
45
|
+
if (prop == '$relations')
|
|
46
|
+
return _this.___relations(tslib_1.__assign(tslib_1.__assign({}, options), { first: true }));
|
|
47
|
+
return target.$subQuery(function (fieldNamesOfToEntity) {
|
|
48
|
+
return fieldNamesOfToEntity.$dbNameOf(prop);
|
|
49
|
+
}, tslib_1.__assign(tslib_1.__assign({}, options), { first: true }));
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
this.$fields = new Proxy(this, {
|
|
54
|
+
get: function (target, field) {
|
|
55
|
+
return target.$subQuery(function (fieldNamesOfToEntity) {
|
|
56
|
+
return fieldNamesOfToEntity.$dbNameOf(field);
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
this.$subQuery = function (what, options) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
61
|
+
var rel, relFields, filters, namesOfOtherTable, namesOfMyTable, key, otherTableFilter, result, _a;
|
|
62
|
+
return tslib_1.__generator(this, function (_b) {
|
|
63
|
+
switch (_b.label) {
|
|
64
|
+
case 0:
|
|
65
|
+
rel = (0, relationInfoMember_js_1.getRelationFieldInfo)(remult_proxy_js_1.remult.repo(this.myEntity).fields.find(this.relationField));
|
|
66
|
+
if (!rel)
|
|
67
|
+
throw new Error("".concat(this.relationField, " is not a relation"));
|
|
68
|
+
relFields = rel.getFields();
|
|
69
|
+
filters = [];
|
|
70
|
+
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(rel.toEntity, {
|
|
71
|
+
tableName: true,
|
|
72
|
+
})];
|
|
73
|
+
case 1:
|
|
74
|
+
namesOfOtherTable = _b.sent();
|
|
75
|
+
return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(this.myEntity, { tableName: true })];
|
|
76
|
+
case 2:
|
|
77
|
+
namesOfMyTable = _b.sent();
|
|
78
|
+
for (key in relFields.fields) {
|
|
79
|
+
if (Object.prototype.hasOwnProperty.call(relFields.fields, key)) {
|
|
80
|
+
filters.push("".concat(namesOfOtherTable.$dbNameOf(key), " = ").concat(namesOfMyTable.$dbNameOf(relFields.fields[key])));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return [4 /*yield*/, sql_database_js_1.SqlDatabase.filterToRaw(remult_proxy_js_1.remult.repo(rel.toEntity),
|
|
84
|
+
// eslint-disable-next-line
|
|
85
|
+
options === null || options === void 0 ? void 0 : options.where, undefined, namesOfOtherTable)];
|
|
86
|
+
case 3:
|
|
87
|
+
otherTableFilter = _b.sent();
|
|
88
|
+
if (otherTableFilter)
|
|
89
|
+
filters.push(otherTableFilter);
|
|
90
|
+
_a = "\n( SELECT ".concat;
|
|
91
|
+
return [4 /*yield*/, what(namesOfOtherTable)];
|
|
92
|
+
case 4:
|
|
93
|
+
result = _a.apply("\n( SELECT ", [_b.sent(), " \n FROM "]).concat(namesOfOtherTable, " \n WHERE ").concat(filters.join(' and '));
|
|
94
|
+
if (options === null || options === void 0 ? void 0 : options.orderBy) {
|
|
95
|
+
result += "\n ORDER BY ".concat(Object.keys(options.orderBy)
|
|
96
|
+
.map(function (key) {
|
|
97
|
+
return "".concat(namesOfOtherTable.$dbNameOf(key), " ").concat(options.orderBy[key]);
|
|
98
|
+
})
|
|
99
|
+
.join(', '));
|
|
100
|
+
}
|
|
101
|
+
if (options === null || options === void 0 ? void 0 : options.first) {
|
|
102
|
+
result += "\n LIMIT 1";
|
|
103
|
+
}
|
|
104
|
+
return [2 /*return*/, (result +
|
|
105
|
+
"\n)")];
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}); };
|
|
109
|
+
}
|
|
110
|
+
SqlRelationTools.prototype.___relations = function (options) {
|
|
111
|
+
var _this = this;
|
|
112
|
+
return new Proxy(this, {
|
|
113
|
+
get: function (target, field) {
|
|
114
|
+
var rel1 = (0, relationInfoMember_js_1.getRelationFieldInfo)(remult_proxy_js_1.remult.repo(_this.myEntity).fields.find(_this.relationField));
|
|
115
|
+
return new Proxy(_this, {
|
|
116
|
+
get: function (target, field1) {
|
|
117
|
+
return _this.$subQuery(function () {
|
|
118
|
+
return indent(sqlRelations(rel1.toEntity)[field][field1]);
|
|
119
|
+
}, options);
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
return SqlRelationTools;
|
|
126
|
+
}());
|
|
127
|
+
function sqlRelationsFilter(forEntity) {
|
|
128
|
+
return new Proxy({}, {
|
|
129
|
+
get: function (target, relationField) {
|
|
130
|
+
return new SqlRelationFilter(forEntity, relationField);
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
var SqlRelationFilter = /** @class */ (function () {
|
|
135
|
+
function SqlRelationFilter(myEntity, relationField) {
|
|
136
|
+
this._tools = new SqlRelationTools(myEntity, relationField);
|
|
137
|
+
}
|
|
138
|
+
SqlRelationFilter.prototype.some = function (where) {
|
|
139
|
+
var _this = this;
|
|
140
|
+
//many orms use some, every, none
|
|
141
|
+
return sql_database_js_1.SqlDatabase.rawFilter(function (c) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
142
|
+
var _a;
|
|
143
|
+
return tslib_1.__generator(this, function (_b) {
|
|
144
|
+
switch (_b.label) {
|
|
145
|
+
case 0:
|
|
146
|
+
_a = 'exists ';
|
|
147
|
+
return [4 /*yield*/, this._tools.$subQuery(function () { return '1'; }, {
|
|
148
|
+
where: where,
|
|
149
|
+
c: c,
|
|
150
|
+
})];
|
|
151
|
+
case 1: return [2 /*return*/, (_a +
|
|
152
|
+
(_b.sent()))];
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}); });
|
|
156
|
+
};
|
|
157
|
+
return SqlRelationFilter;
|
|
158
|
+
}());
|
|
159
|
+
exports.SqlRelationFilter = SqlRelationFilter;
|
|
160
|
+
function indent(s) {
|
|
161
|
+
return s.then(function (s) {
|
|
162
|
+
return s
|
|
163
|
+
.split('\n')
|
|
164
|
+
.map(function (x) { return ' ' + x; })
|
|
165
|
+
.join('\n');
|
|
166
|
+
});
|
|
167
|
+
}
|
package/src/remult-static.d.ts
CHANGED
package/src/remult-static.js
CHANGED
|
@@ -73,6 +73,7 @@ export declare class RepositoryImplementation<entityType> implements Repository<
|
|
|
73
73
|
_fromJsonArray(jsonItems: any[], loadOptions: LoadOptions<entityType>): Promise<entityType[]>;
|
|
74
74
|
private _loadManyToOneForManyRows;
|
|
75
75
|
private _populateRelationsForFields;
|
|
76
|
+
private __getRelationAndInclude;
|
|
76
77
|
private _mapRawDataToResult;
|
|
77
78
|
toJson(item: entityType | entityType[] | Promise<entityType> | Promise<entityType[]>): any;
|
|
78
79
|
fromJson(x: any[], isNew?: boolean): entityType[];
|
|
@@ -100,7 +101,7 @@ declare abstract class rowHelperBase<T> {
|
|
|
100
101
|
_error?: string;
|
|
101
102
|
get error(): string | undefined;
|
|
102
103
|
set error(val: string | undefined);
|
|
103
|
-
constructor(fieldsMetadata: FieldMetadata[], instance: T, remult: Remult, isNewRow: boolean);
|
|
104
|
+
constructor(fieldsMetadata: FieldMetadata[], instance: T, remult: Remult, isNewRow: boolean, excludeRelationMembers?: Set<string>);
|
|
104
105
|
_subscribers?: SubscribableImp;
|
|
105
106
|
subscribe(listener: RefSubscriber): Unsubscribe;
|
|
106
107
|
_isLoading: boolean;
|
|
@@ -134,7 +135,7 @@ export declare class rowHelperImplementation<T> extends rowHelperBase<T> impleme
|
|
|
134
135
|
private repo;
|
|
135
136
|
private edp;
|
|
136
137
|
private _isNew;
|
|
137
|
-
constructor(info: EntityFullInfo<T>, instance: T, repo: RepositoryImplementation<T>, edp: EntityDataProvider, remult: Remult, _isNew: boolean);
|
|
138
|
+
constructor(info: EntityFullInfo<T>, instance: T, repo: RepositoryImplementation<T>, edp: EntityDataProvider, remult: Remult, _isNew: boolean, excludeRelationMembers?: Set<string>);
|
|
138
139
|
repository: Repository<unknown>;
|
|
139
140
|
clone(): T;
|
|
140
141
|
get relations(): RepositoryRelations<T>;
|
|
@@ -206,6 +207,9 @@ export declare class FieldRefImplementation<entityType, valueType> implements Fi
|
|
|
206
207
|
__performValidation(): Promise<void>;
|
|
207
208
|
validate(): Promise<boolean>;
|
|
208
209
|
}
|
|
210
|
+
export declare const fieldOptionsEnricher: {
|
|
211
|
+
enrichFieldOptions: (options: FieldOptions) => void;
|
|
212
|
+
};
|
|
209
213
|
export declare const CaptionTransformer: {
|
|
210
214
|
/**
|
|
211
215
|
* Transforms the caption of a column based on custom rules or criteria.
|