remult 0.27.21-next.13 → 0.27.21-next.14
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
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { remultStatic } from './src/remult-static.js';
|
|
2
|
+
export { sqlRelations, SqlRelationFilter, } from '../core/src/data-providers/sql-relations.js';
|
|
2
3
|
export { getRelationInfo, getRelationFieldInfo, } from './src/remult3/relationInfoMember.js';
|
|
3
4
|
export { decorateColumnSettings, controllerRefImpl, getControllerRef, } from './src/remult3/RepositoryImplementation.js';
|
|
4
5
|
export { getEntitySettings } from './src/remult3/getEntityRef.js';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { dbNamesOf, repo, SqlDatabase,
|
|
2
|
+
// } from 'remult'
|
|
3
|
+
} from '../../index.js'; // comment in the from `remult`
|
|
4
|
+
import { getRelationFieldInfo } from '../../internals.js'; // comment in the from `remult`
|
|
5
|
+
// import { getRelationFieldInfo } from 'remult/internals'
|
|
6
|
+
export function sqlRelations(forEntity) {
|
|
7
|
+
return new Proxy({}, {
|
|
8
|
+
get: (target, relationField) => new Proxy(new SqlRelationTools(forEntity, relationField), {
|
|
9
|
+
get: (target, prop) => {
|
|
10
|
+
if (prop == '$count')
|
|
11
|
+
return target.$count;
|
|
12
|
+
if (prop == '$subQuery')
|
|
13
|
+
return target.$subQuery;
|
|
14
|
+
if (prop == '$relations')
|
|
15
|
+
return target.___relations();
|
|
16
|
+
if (prop == '$first')
|
|
17
|
+
return target.$first;
|
|
18
|
+
return target.$fields[prop];
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
class SqlRelationTools {
|
|
24
|
+
myEntity;
|
|
25
|
+
relationField;
|
|
26
|
+
constructor(myEntity, relationField) {
|
|
27
|
+
this.myEntity = myEntity;
|
|
28
|
+
this.relationField = relationField;
|
|
29
|
+
}
|
|
30
|
+
$count = (where) => {
|
|
31
|
+
return this.$subQuery(() => 'count(*)', { where });
|
|
32
|
+
};
|
|
33
|
+
$first = (options) => {
|
|
34
|
+
return new Proxy(this, {
|
|
35
|
+
get: (target, prop) => {
|
|
36
|
+
if (prop == '$subQuery')
|
|
37
|
+
return (what) => target.$subQuery(what, { ...options, first: true });
|
|
38
|
+
if (prop == '$relations')
|
|
39
|
+
return this.___relations({ ...options, first: true });
|
|
40
|
+
return target.$subQuery((fieldNamesOfToEntity) => fieldNamesOfToEntity.$dbNameOf(prop), { ...options, first: true });
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
$fields = new Proxy(this, {
|
|
45
|
+
get: (target, field) => {
|
|
46
|
+
return target.$subQuery((fieldNamesOfToEntity) => fieldNamesOfToEntity.$dbNameOf(field));
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
$subQuery = async (what, options) => {
|
|
50
|
+
const rel = getRelationFieldInfo(repo(this.myEntity).fields.find(this.relationField));
|
|
51
|
+
if (!rel)
|
|
52
|
+
throw new Error(`${this.relationField} is not a relation`);
|
|
53
|
+
const relFields = rel.getFields();
|
|
54
|
+
const filters = [];
|
|
55
|
+
const namesOfOtherTable = await dbNamesOf(rel.toEntity, {
|
|
56
|
+
tableName: true,
|
|
57
|
+
});
|
|
58
|
+
const namesOfMyTable = await dbNamesOf(this.myEntity, { tableName: true });
|
|
59
|
+
for (const key in relFields.fields) {
|
|
60
|
+
if (Object.prototype.hasOwnProperty.call(relFields.fields, key)) {
|
|
61
|
+
filters.push(`${namesOfOtherTable.$dbNameOf(key)} = ${namesOfMyTable.$dbNameOf(relFields.fields[key])}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const otherTableFilter = await SqlDatabase.filterToRaw(repo(rel.toEntity),
|
|
65
|
+
// eslint-disable-next-line
|
|
66
|
+
options?.where, undefined, namesOfOtherTable);
|
|
67
|
+
if (otherTableFilter)
|
|
68
|
+
filters.push(otherTableFilter);
|
|
69
|
+
let result = `
|
|
70
|
+
( SELECT ${await what(namesOfOtherTable)}
|
|
71
|
+
FROM ${namesOfOtherTable}
|
|
72
|
+
WHERE ${filters.join(' and ')}`;
|
|
73
|
+
if (options?.orderBy) {
|
|
74
|
+
result += `
|
|
75
|
+
ORDER BY ${Object.keys(options.orderBy)
|
|
76
|
+
.map((key) => `${namesOfOtherTable.$dbNameOf(key)} ${options.orderBy[key]}`)
|
|
77
|
+
.join(', ')}`;
|
|
78
|
+
}
|
|
79
|
+
if (options?.first) {
|
|
80
|
+
result += `
|
|
81
|
+
LIMIT 1`;
|
|
82
|
+
}
|
|
83
|
+
return (result +
|
|
84
|
+
`
|
|
85
|
+
)`);
|
|
86
|
+
};
|
|
87
|
+
___relations(options) {
|
|
88
|
+
return new Proxy(this, {
|
|
89
|
+
get: (target, field) => {
|
|
90
|
+
const rel1 = getRelationFieldInfo(repo(this.myEntity).fields.find(this.relationField));
|
|
91
|
+
return new Proxy(this, {
|
|
92
|
+
get: (target, field1) => {
|
|
93
|
+
return this.$subQuery(() => indent(sqlRelations(rel1.toEntity)[field][field1]), options);
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export function sqlRelationsFilter(forEntity) {
|
|
101
|
+
return new Proxy({}, {
|
|
102
|
+
get: (target, relationField) => new SqlRelationFilter(forEntity, relationField),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export class SqlRelationFilter {
|
|
106
|
+
_tools;
|
|
107
|
+
constructor(myEntity, relationField) {
|
|
108
|
+
this._tools = new SqlRelationTools(myEntity, relationField);
|
|
109
|
+
}
|
|
110
|
+
some(where) {
|
|
111
|
+
//many orms use some, every, none
|
|
112
|
+
return SqlDatabase.rawFilter(async (c) => {
|
|
113
|
+
return ('exists ' +
|
|
114
|
+
(await this._tools.$subQuery(() => '1', {
|
|
115
|
+
where,
|
|
116
|
+
c,
|
|
117
|
+
})));
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function indent(s) {
|
|
122
|
+
return s.then((s) => s
|
|
123
|
+
.split('\n')
|
|
124
|
+
.map((x) => ' ' + x)
|
|
125
|
+
.join('\n'));
|
|
126
|
+
}
|
package/internals.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { sqlRelations, SqlRelationFilter, } from '../core/src/data-providers/sql-relations.js';
|
|
1
2
|
export { getRelationInfo, getRelationFieldInfo, type RelationFieldInfo, type RelationInfo, type RelationFields, } from './src/remult3/relationInfoMember.js';
|
|
2
3
|
export { decorateColumnSettings, controllerRefImpl, getControllerRef, } from './src/remult3/RepositoryImplementation.js';
|
|
3
4
|
export { getEntitySettings } from './src/remult3/getEntityRef.js';
|
package/internals.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.flags = exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationFieldInfo = exports.getRelationInfo = void 0;
|
|
3
|
+
exports.flags = exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationFieldInfo = exports.getRelationInfo = exports.SqlRelationFilter = exports.sqlRelations = void 0;
|
|
4
4
|
var remult_static_js_1 = require("./src/remult-static.js");
|
|
5
|
+
var sql_relations_js_1 = require("../core/src/data-providers/sql-relations.js");
|
|
6
|
+
Object.defineProperty(exports, "sqlRelations", { enumerable: true, get: function () { return sql_relations_js_1.sqlRelations; } });
|
|
7
|
+
Object.defineProperty(exports, "SqlRelationFilter", { enumerable: true, get: function () { return sql_relations_js_1.SqlRelationFilter; } });
|
|
5
8
|
var relationInfoMember_js_1 = require("./src/remult3/relationInfoMember.js");
|
|
6
9
|
Object.defineProperty(exports, "getRelationInfo", { enumerable: true, get: function () { return relationInfoMember_js_1.getRelationInfo; } });
|
|
7
10
|
Object.defineProperty(exports, "getRelationFieldInfo", { enumerable: true, get: function () { return relationInfoMember_js_1.getRelationFieldInfo; } });
|
package/package.json
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ClassType, type EntityDbNames, type EntityFilter, type EntityOrderBy, type ObjectMembersOnly, type SqlCommandWithParameters } from '../../index.js';
|
|
2
|
+
export declare function sqlRelations<entityType>(forEntity: ClassType<entityType>): SqlRelations<entityType>;
|
|
3
|
+
export type SqlRelations<entityType> = {
|
|
4
|
+
[p in keyof ObjectMembersOnly<entityType>]-?: SqlRelation<ArrayItemType<NonNullable<entityType[p]>>>;
|
|
5
|
+
};
|
|
6
|
+
export type SubQueryWhat<toEntity> = (fieldNamesOfToEntity: EntityDbNames<toEntity>) => string | Promise<string>;
|
|
7
|
+
export type SubQueryOptions<toEntity> = {
|
|
8
|
+
where?: EntityFilter<toEntity>;
|
|
9
|
+
orderBy?: EntityOrderBy<toEntity>;
|
|
10
|
+
first?: boolean;
|
|
11
|
+
c?: SqlCommandWithParameters;
|
|
12
|
+
};
|
|
13
|
+
export type SqlFirst<toEntity> = {
|
|
14
|
+
$subQuery(what: SubQueryWhat<toEntity>): Promise<string>;
|
|
15
|
+
$relations: {
|
|
16
|
+
[P in keyof ObjectMembersOnly<toEntity>]-?: SqlRelation<toEntity[P]>;
|
|
17
|
+
};
|
|
18
|
+
} & {
|
|
19
|
+
[P in keyof toEntity]-?: Promise<string>;
|
|
20
|
+
};
|
|
21
|
+
export type SqlRelation<toEntity> = {
|
|
22
|
+
$count(where?: EntityFilter<toEntity>): Promise<string>;
|
|
23
|
+
$subQuery(what: SubQueryWhat<toEntity>, options?: SubQueryOptions<toEntity>): Promise<string>;
|
|
24
|
+
$relations: {
|
|
25
|
+
[P in keyof ObjectMembersOnly<toEntity>]-?: SqlRelation<toEntity[P]>;
|
|
26
|
+
};
|
|
27
|
+
$first(options?: Pick<SubQueryOptions<toEntity>, 'where' | 'orderBy'>): SqlFirst<toEntity>;
|
|
28
|
+
} & {
|
|
29
|
+
[P in keyof toEntity]-?: Promise<string>;
|
|
30
|
+
};
|
|
31
|
+
export type ArrayItemType<T> = T extends (infer U)[] ? U : T;
|
|
32
|
+
export declare function sqlRelationsFilter<entityType>(forEntity: ClassType<entityType>): { [p in keyof entityType]-?: SqlRelationFilter<entityType, p, ArrayItemType<NonNullable<entityType[p]>>>; };
|
|
33
|
+
export declare class SqlRelationFilter<myEntity, relationKey extends keyof myEntity, toEntity = ArrayItemType<myEntity[relationKey]>> {
|
|
34
|
+
private _tools;
|
|
35
|
+
constructor(myEntity: ClassType<myEntity>, relationField: relationKey);
|
|
36
|
+
some(where?: EntityFilter<toEntity>): EntityFilter<toEntity>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
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 index_js_1 = require("../../index.js"); // comment in the from `remult`
|
|
8
|
+
var internals_js_1 = require("../../internals.js"); // comment in the from `remult`
|
|
9
|
+
// import { getRelationFieldInfo } from 'remult/internals'
|
|
10
|
+
function sqlRelations(forEntity) {
|
|
11
|
+
return new Proxy({}, {
|
|
12
|
+
get: function (target, relationField) {
|
|
13
|
+
return new Proxy(new SqlRelationTools(forEntity, relationField), {
|
|
14
|
+
get: function (target, prop) {
|
|
15
|
+
if (prop == '$count')
|
|
16
|
+
return target.$count;
|
|
17
|
+
if (prop == '$subQuery')
|
|
18
|
+
return target.$subQuery;
|
|
19
|
+
if (prop == '$relations')
|
|
20
|
+
return target.___relations();
|
|
21
|
+
if (prop == '$first')
|
|
22
|
+
return target.$first;
|
|
23
|
+
return target.$fields[prop];
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
var SqlRelationTools = /** @class */ (function () {
|
|
30
|
+
function SqlRelationTools(myEntity, relationField) {
|
|
31
|
+
var _this = this;
|
|
32
|
+
this.myEntity = myEntity;
|
|
33
|
+
this.relationField = relationField;
|
|
34
|
+
this.$count = function (where) {
|
|
35
|
+
return _this.$subQuery(function () { return 'count(*)'; }, { where: where });
|
|
36
|
+
};
|
|
37
|
+
this.$first = function (options) {
|
|
38
|
+
return new Proxy(_this, {
|
|
39
|
+
get: function (target, prop) {
|
|
40
|
+
if (prop == '$subQuery')
|
|
41
|
+
return function (what) {
|
|
42
|
+
return target.$subQuery(what, tslib_1.__assign(tslib_1.__assign({}, options), { first: true }));
|
|
43
|
+
};
|
|
44
|
+
if (prop == '$relations')
|
|
45
|
+
return _this.___relations(tslib_1.__assign(tslib_1.__assign({}, options), { first: true }));
|
|
46
|
+
return target.$subQuery(function (fieldNamesOfToEntity) {
|
|
47
|
+
return fieldNamesOfToEntity.$dbNameOf(prop);
|
|
48
|
+
}, tslib_1.__assign(tslib_1.__assign({}, options), { first: true }));
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
this.$fields = new Proxy(this, {
|
|
53
|
+
get: function (target, field) {
|
|
54
|
+
return target.$subQuery(function (fieldNamesOfToEntity) {
|
|
55
|
+
return fieldNamesOfToEntity.$dbNameOf(field);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
this.$subQuery = function (what, options) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
60
|
+
var rel, relFields, filters, namesOfOtherTable, namesOfMyTable, key, otherTableFilter, result, _a;
|
|
61
|
+
return tslib_1.__generator(this, function (_b) {
|
|
62
|
+
switch (_b.label) {
|
|
63
|
+
case 0:
|
|
64
|
+
rel = (0, internals_js_1.getRelationFieldInfo)((0, index_js_1.repo)(this.myEntity).fields.find(this.relationField));
|
|
65
|
+
if (!rel)
|
|
66
|
+
throw new Error("".concat(this.relationField, " is not a relation"));
|
|
67
|
+
relFields = rel.getFields();
|
|
68
|
+
filters = [];
|
|
69
|
+
return [4 /*yield*/, (0, index_js_1.dbNamesOf)(rel.toEntity, {
|
|
70
|
+
tableName: true,
|
|
71
|
+
})];
|
|
72
|
+
case 1:
|
|
73
|
+
namesOfOtherTable = _b.sent();
|
|
74
|
+
return [4 /*yield*/, (0, index_js_1.dbNamesOf)(this.myEntity, { tableName: true })];
|
|
75
|
+
case 2:
|
|
76
|
+
namesOfMyTable = _b.sent();
|
|
77
|
+
for (key in relFields.fields) {
|
|
78
|
+
if (Object.prototype.hasOwnProperty.call(relFields.fields, key)) {
|
|
79
|
+
filters.push("".concat(namesOfOtherTable.$dbNameOf(key), " = ").concat(namesOfMyTable.$dbNameOf(relFields.fields[key])));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return [4 /*yield*/, index_js_1.SqlDatabase.filterToRaw((0, index_js_1.repo)(rel.toEntity),
|
|
83
|
+
// eslint-disable-next-line
|
|
84
|
+
options === null || options === void 0 ? void 0 : options.where, undefined, namesOfOtherTable)];
|
|
85
|
+
case 3:
|
|
86
|
+
otherTableFilter = _b.sent();
|
|
87
|
+
if (otherTableFilter)
|
|
88
|
+
filters.push(otherTableFilter);
|
|
89
|
+
_a = "\n( SELECT ".concat;
|
|
90
|
+
return [4 /*yield*/, what(namesOfOtherTable)];
|
|
91
|
+
case 4:
|
|
92
|
+
result = _a.apply("\n( SELECT ", [_b.sent(), " \n FROM "]).concat(namesOfOtherTable, " \n WHERE ").concat(filters.join(' and '));
|
|
93
|
+
if (options === null || options === void 0 ? void 0 : options.orderBy) {
|
|
94
|
+
result += "\n ORDER BY ".concat(Object.keys(options.orderBy)
|
|
95
|
+
.map(function (key) {
|
|
96
|
+
return "".concat(namesOfOtherTable.$dbNameOf(key), " ").concat(options.orderBy[key]);
|
|
97
|
+
})
|
|
98
|
+
.join(', '));
|
|
99
|
+
}
|
|
100
|
+
if (options === null || options === void 0 ? void 0 : options.first) {
|
|
101
|
+
result += "\n LIMIT 1";
|
|
102
|
+
}
|
|
103
|
+
return [2 /*return*/, (result +
|
|
104
|
+
"\n)")];
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}); };
|
|
108
|
+
}
|
|
109
|
+
SqlRelationTools.prototype.___relations = function (options) {
|
|
110
|
+
var _this = this;
|
|
111
|
+
return new Proxy(this, {
|
|
112
|
+
get: function (target, field) {
|
|
113
|
+
var rel1 = (0, internals_js_1.getRelationFieldInfo)((0, index_js_1.repo)(_this.myEntity).fields.find(_this.relationField));
|
|
114
|
+
return new Proxy(_this, {
|
|
115
|
+
get: function (target, field1) {
|
|
116
|
+
return _this.$subQuery(function () {
|
|
117
|
+
return indent(sqlRelations(rel1.toEntity)[field][field1]);
|
|
118
|
+
}, options);
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
return SqlRelationTools;
|
|
125
|
+
}());
|
|
126
|
+
function sqlRelationsFilter(forEntity) {
|
|
127
|
+
return new Proxy({}, {
|
|
128
|
+
get: function (target, relationField) {
|
|
129
|
+
return new SqlRelationFilter(forEntity, relationField);
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
var SqlRelationFilter = /** @class */ (function () {
|
|
134
|
+
function SqlRelationFilter(myEntity, relationField) {
|
|
135
|
+
this._tools = new SqlRelationTools(myEntity, relationField);
|
|
136
|
+
}
|
|
137
|
+
SqlRelationFilter.prototype.some = function (where) {
|
|
138
|
+
var _this = this;
|
|
139
|
+
//many orms use some, every, none
|
|
140
|
+
return index_js_1.SqlDatabase.rawFilter(function (c) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
141
|
+
var _a;
|
|
142
|
+
return tslib_1.__generator(this, function (_b) {
|
|
143
|
+
switch (_b.label) {
|
|
144
|
+
case 0:
|
|
145
|
+
_a = 'exists ';
|
|
146
|
+
return [4 /*yield*/, this._tools.$subQuery(function () { return '1'; }, {
|
|
147
|
+
where: where,
|
|
148
|
+
c: c,
|
|
149
|
+
})];
|
|
150
|
+
case 1: return [2 /*return*/, (_a +
|
|
151
|
+
(_b.sent()))];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}); });
|
|
155
|
+
};
|
|
156
|
+
return SqlRelationFilter;
|
|
157
|
+
}());
|
|
158
|
+
exports.SqlRelationFilter = SqlRelationFilter;
|
|
159
|
+
function indent(s) {
|
|
160
|
+
return s.then(function (s) {
|
|
161
|
+
return s
|
|
162
|
+
.split('\n')
|
|
163
|
+
.map(function (x) { return ' ' + x; })
|
|
164
|
+
.join('\n');
|
|
165
|
+
});
|
|
166
|
+
}
|