@exogee/graphweaver-mikroorm 0.1.0-alpha.1 → 0.1.0-alpha.6
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/lib/base-resolver/assign.d.ts +1 -1
- package/lib/base-resolver/assign.js +160 -0
- package/lib/base-resolver/index.js +18 -0
- package/lib/base-resolver/provider.js +338 -0
- package/lib/config.d.ts +1 -1
- package/lib/config.js +42 -0
- package/lib/database.d.ts +2 -2
- package/lib/database.js +203 -0
- package/lib/entities/audit-change.js +73 -0
- package/lib/entities/audit-related-entity-change.js +57 -0
- package/lib/entities/base-entity.js +36 -0
- package/lib/entities/index.js +20 -0
- package/lib/index.js +24 -947
- package/lib/types/date-type.js +62 -0
- package/lib/types/decimal-type.js +71 -0
- package/lib/types/index.js +19 -0
- package/lib/types/time-type.js +75 -0
- package/lib/utils/authentication-context.js +43 -0
- package/lib/utils/change-tracker.js +112 -0
- package/lib/utils/errors.d.ts +2 -2
- package/lib/utils/errors.js +33 -0
- package/lib/utils/generate-db-schema.js +30 -0
- package/lib/utils/index.js +21 -0
- package/lib/utils/tracked-entity.js +46 -0
- package/lib/utils/untracked-property.js +37 -0
- package/package.json +13 -11
- package/lib/base-resolver/rls/auth-utils.d.ts +0 -17
- package/lib/base-resolver/rls/authorization-context.d.ts +0 -8
- package/lib/base-resolver/rls/database-provider.d.ts +0 -26
- package/lib/base-resolver/rls/index.d.ts +0 -2
- package/lib/entities/common.d.ts +0 -1
- package/lib/entities/hobby.d.ts +0 -8
- package/lib/entities/migration.d.ts +0 -5
- package/lib/entities/session.d.ts +0 -6
- package/lib/entities/skill.d.ts +0 -8
- package/lib/entities/user.d.ts +0 -10
- package/lib/index.js.map +0 -7
|
@@ -3,5 +3,5 @@ interface AssignOptions {
|
|
|
3
3
|
create?: boolean;
|
|
4
4
|
update?: boolean;
|
|
5
5
|
}
|
|
6
|
-
export declare const assign: <T extends Partial<T>>(entity: T, data: EntityData<T>, options?: AssignOptions
|
|
6
|
+
export declare const assign: <T extends Partial<T>>(entity: T, data: EntityData<T>, options?: AssignOptions, visited?: Set<Partial<any>>) => Promise<T>;
|
|
7
7
|
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var assign_exports = {};
|
|
20
|
+
__export(assign_exports, {
|
|
21
|
+
assign: () => assign
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(assign_exports);
|
|
24
|
+
var import_core = require("@mikro-orm/core");
|
|
25
|
+
var import_logger = require("@exogee/logger");
|
|
26
|
+
var import_database = require("../database");
|
|
27
|
+
const assign = async (entity, data, options, visited = /* @__PURE__ */ new Set()) => {
|
|
28
|
+
var _a;
|
|
29
|
+
if (visited.has(entity))
|
|
30
|
+
return entity;
|
|
31
|
+
visited.add(entity);
|
|
32
|
+
const metadata = (0, import_core.wrap)(entity, true).__meta;
|
|
33
|
+
for (const [property, value] of Object.entries(data)) {
|
|
34
|
+
const entityPropertyValue = entity[property];
|
|
35
|
+
const propertyMetadata = metadata.properties[property];
|
|
36
|
+
if ((propertyMetadata == null ? void 0 : propertyMetadata.reference) === import_core.ReferenceType.MANY_TO_MANY || (propertyMetadata == null ? void 0 : propertyMetadata.reference) === import_core.ReferenceType.ONE_TO_MANY) {
|
|
37
|
+
if (!Array.isArray(value))
|
|
38
|
+
throw new Error(
|
|
39
|
+
`Value is not an array while trying to assign to collection property ${property} on entity ${metadata.name}`
|
|
40
|
+
);
|
|
41
|
+
if (!(entityPropertyValue instanceof import_core.Collection)) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Tried to merge array into non-collection property ${property} on entity ${metadata.name}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const visitedEntities = /* @__PURE__ */ new Set();
|
|
47
|
+
for (const subvalue of value) {
|
|
48
|
+
let entity2;
|
|
49
|
+
if (subvalue.id) {
|
|
50
|
+
entity2 = import_database.Database.em.getUnitOfWork().getById(propertyMetadata.type, subvalue.id);
|
|
51
|
+
if (!entity2) {
|
|
52
|
+
if (Object.keys(subvalue).length === 1) {
|
|
53
|
+
entity2 = import_database.Database.em.getReference(propertyMetadata.type, subvalue.id);
|
|
54
|
+
} else {
|
|
55
|
+
import_logger.logger.warn(
|
|
56
|
+
`Doing a full database fetch for ${propertyMetadata.type} with id ${subvalue.id}, this should ideally be prefetched into the Unit of Work before calling assign() for performance`
|
|
57
|
+
);
|
|
58
|
+
entity2 = (_a = await import_database.Database.em.findOne(propertyMetadata.type, {
|
|
59
|
+
id: subvalue.id
|
|
60
|
+
})) != null ? _a : void 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!entity2) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Attempted to assign as an update to '${propertyMetadata.name}' property of ${metadata.name} Entity, but even after a full fetch to the database ${propertyMetadata.type} with ID of ${subvalue.id} could not be found.`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const newEntity = await createOrAssignEntity({
|
|
70
|
+
entity: entity2,
|
|
71
|
+
entityType: propertyMetadata.type,
|
|
72
|
+
data: subvalue,
|
|
73
|
+
options,
|
|
74
|
+
visited
|
|
75
|
+
});
|
|
76
|
+
entityPropertyValue.add(newEntity);
|
|
77
|
+
visitedEntities.add(newEntity);
|
|
78
|
+
}
|
|
79
|
+
entityPropertyValue.remove(
|
|
80
|
+
...entityPropertyValue.getItems().filter((entity2) => !visitedEntities.has(entity2))
|
|
81
|
+
);
|
|
82
|
+
} else if ((propertyMetadata == null ? void 0 : propertyMetadata.reference) == import_core.ReferenceType.MANY_TO_ONE || (propertyMetadata == null ? void 0 : propertyMetadata.reference) === import_core.ReferenceType.ONE_TO_ONE) {
|
|
83
|
+
if (value === null) {
|
|
84
|
+
entity[property] = null;
|
|
85
|
+
} else {
|
|
86
|
+
const valueKeys = Object.keys(value);
|
|
87
|
+
if (valueKeys.length === 1 && valueKeys[0] === "id") {
|
|
88
|
+
entity[property] = import_database.Database.em.getReference(
|
|
89
|
+
propertyMetadata.type,
|
|
90
|
+
value.id
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
if (entityPropertyValue && !import_core.Reference.isReference(entityPropertyValue)) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Trying to merge to related property ${property} on entity ${metadata.name} which is not a reference.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (entityPropertyValue && !entityPropertyValue.isInitialized()) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Trying to merge to related property ${property} on entity ${metadata.name} which is not initialised.`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
const newEntity = await createOrAssignEntity({
|
|
104
|
+
entity: entityPropertyValue == null ? void 0 : entityPropertyValue.unwrap(),
|
|
105
|
+
entityType: propertyMetadata.type,
|
|
106
|
+
data: value,
|
|
107
|
+
options,
|
|
108
|
+
visited
|
|
109
|
+
});
|
|
110
|
+
entity[property] = import_core.Reference.create(newEntity);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
entity[property] = value;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return entity;
|
|
118
|
+
};
|
|
119
|
+
const createOrAssignEntity = ({
|
|
120
|
+
entity,
|
|
121
|
+
entityType,
|
|
122
|
+
data,
|
|
123
|
+
options,
|
|
124
|
+
visited
|
|
125
|
+
}) => {
|
|
126
|
+
var _a, _b;
|
|
127
|
+
const create = (_a = options == null ? void 0 : options.create) != null ? _a : true;
|
|
128
|
+
const update = (_b = options == null ? void 0 : options.update) != null ? _b : true;
|
|
129
|
+
if (data.id) {
|
|
130
|
+
if (!update) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`Updates are disabled, but update value ${JSON.stringify(
|
|
133
|
+
data
|
|
134
|
+
)} was passed which has an ID property.`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (!entity) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Tried to update with data ${JSON.stringify(
|
|
140
|
+
data
|
|
141
|
+
)} but entity could not be located to update.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return assign(entity, data, options, visited);
|
|
145
|
+
} else {
|
|
146
|
+
if (!create) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`Creates are disabled, but update value ${JSON.stringify(
|
|
149
|
+
data
|
|
150
|
+
)} was passed which does not have an ID property.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
const entity2 = import_database.Database.em.create(entityType, {});
|
|
154
|
+
return assign(entity2, data, options, visited);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
158
|
+
0 && (module.exports = {
|
|
159
|
+
assign
|
|
160
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
+
var base_resolver_exports = {};
|
|
17
|
+
module.exports = __toCommonJS(base_resolver_exports);
|
|
18
|
+
__reExport(base_resolver_exports, require("./provider"), module.exports);
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var provider_exports = {};
|
|
20
|
+
__export(provider_exports, {
|
|
21
|
+
MikroBackendProvider: () => MikroBackendProvider,
|
|
22
|
+
gqlToMikro: () => gqlToMikro,
|
|
23
|
+
mapAndAssignKeys: () => mapAndAssignKeys,
|
|
24
|
+
visitPathForPopulate: () => visitPathForPopulate
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(provider_exports);
|
|
27
|
+
var import_logger = require("@exogee/logger");
|
|
28
|
+
var import__ = require("..");
|
|
29
|
+
var import_errors = require("../utils/errors");
|
|
30
|
+
var import_assign = require("./assign");
|
|
31
|
+
const objectOperations = /* @__PURE__ */ new Set(["_and", "_or", "_not"]);
|
|
32
|
+
const mikroObjectOperations = /* @__PURE__ */ new Set(["$and", "$or", "$not"]);
|
|
33
|
+
const nonJoinKeys = /* @__PURE__ */ new Set([
|
|
34
|
+
"$and",
|
|
35
|
+
"$gt",
|
|
36
|
+
"$gte",
|
|
37
|
+
"$in",
|
|
38
|
+
"$lt",
|
|
39
|
+
"$lte",
|
|
40
|
+
"$ne",
|
|
41
|
+
"$nin",
|
|
42
|
+
"$not",
|
|
43
|
+
"$or",
|
|
44
|
+
"$like",
|
|
45
|
+
"$ilike",
|
|
46
|
+
"$null",
|
|
47
|
+
"$notnull",
|
|
48
|
+
"id"
|
|
49
|
+
]);
|
|
50
|
+
const appendPath = (path, newPath) => path.length ? `${path}.${newPath}` : newPath;
|
|
51
|
+
const visitPathForPopulate = (entityName, updateArgBranch, populateBranch = "") => {
|
|
52
|
+
var _a, _b, _c, _d;
|
|
53
|
+
const { properties } = import__.Database.em.getMetadata().get(entityName);
|
|
54
|
+
const collectedPaths = populateBranch ? /* @__PURE__ */ new Set([populateBranch]) : /* @__PURE__ */ new Set([]);
|
|
55
|
+
for (const [key, value] of Object.entries(updateArgBranch != null ? updateArgBranch : {})) {
|
|
56
|
+
if (((_a = properties[key]) == null ? void 0 : _a.reference) === import__.ReferenceType.ONE_TO_ONE || ((_b = properties[key]) == null ? void 0 : _b.reference) === import__.ReferenceType.ONE_TO_MANY || ((_c = properties[key]) == null ? void 0 : _c.reference) === import__.ReferenceType.MANY_TO_ONE || ((_d = properties[key]) == null ? void 0 : _d.reference) === import__.ReferenceType.MANY_TO_MANY) {
|
|
57
|
+
if (Array.isArray(value)) {
|
|
58
|
+
collectedPaths.add(appendPath(populateBranch, key));
|
|
59
|
+
for (const entry of value) {
|
|
60
|
+
const newPaths = visitPathForPopulate(
|
|
61
|
+
properties[key].type,
|
|
62
|
+
entry,
|
|
63
|
+
appendPath(populateBranch, key)
|
|
64
|
+
);
|
|
65
|
+
newPaths.forEach((path) => collectedPaths.add(path));
|
|
66
|
+
}
|
|
67
|
+
} else if (typeof value === "object") {
|
|
68
|
+
const newPaths = visitPathForPopulate(
|
|
69
|
+
properties[key].type,
|
|
70
|
+
value,
|
|
71
|
+
appendPath(populateBranch, key)
|
|
72
|
+
);
|
|
73
|
+
newPaths.forEach((path) => collectedPaths.add(path));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return collectedPaths;
|
|
78
|
+
};
|
|
79
|
+
const gqlToMikro = (filter) => {
|
|
80
|
+
if (Array.isArray(filter)) {
|
|
81
|
+
return filter.map((element) => gqlToMikro(element));
|
|
82
|
+
} else if (typeof filter === "object") {
|
|
83
|
+
for (const key of Object.keys(filter)) {
|
|
84
|
+
if (filter[key] === null)
|
|
85
|
+
continue;
|
|
86
|
+
if (objectOperations.has(key)) {
|
|
87
|
+
filter[key.replace("_", "$")] = gqlToMikro(filter[key]);
|
|
88
|
+
delete filter[key];
|
|
89
|
+
} else if (typeof filter[key] === "object" && !Array.isArray(filter[key])) {
|
|
90
|
+
filter[key] = gqlToMikro(filter[key]);
|
|
91
|
+
} else if (key.indexOf("_") >= 0) {
|
|
92
|
+
const [newKey, operator] = key.split("_");
|
|
93
|
+
const newValue = { [`$${operator}`]: gqlToMikro(filter[key]) };
|
|
94
|
+
if (typeof filter[newKey] !== "undefined") {
|
|
95
|
+
filter[newKey] = { ...filter[newKey], ...newValue };
|
|
96
|
+
} else {
|
|
97
|
+
filter[newKey] = newValue;
|
|
98
|
+
}
|
|
99
|
+
delete filter[key];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return filter;
|
|
104
|
+
};
|
|
105
|
+
const mapAndAssignKeys = (result, entityType, inputArgs) => {
|
|
106
|
+
const cleanInput = JSON.parse(JSON.stringify(inputArgs));
|
|
107
|
+
return (0, import_assign.assign)(result, cleanInput);
|
|
108
|
+
};
|
|
109
|
+
class MikroBackendProvider {
|
|
110
|
+
constructor(mikroType) {
|
|
111
|
+
this.backendId = "mikro-orm";
|
|
112
|
+
this.supportsInFilter = true;
|
|
113
|
+
this.getRepository = () => {
|
|
114
|
+
const repository = import__.Database.em.getRepository(this.entityType);
|
|
115
|
+
if (!repository)
|
|
116
|
+
throw new Error("Could not find repository for " + this.entityType.name);
|
|
117
|
+
return repository;
|
|
118
|
+
};
|
|
119
|
+
this.entityType = mikroType;
|
|
120
|
+
}
|
|
121
|
+
applyWhereClause(where) {
|
|
122
|
+
const query = this.getRepository().createQueryBuilder();
|
|
123
|
+
const joinKeysUsed = /* @__PURE__ */ new Map();
|
|
124
|
+
if (where) {
|
|
125
|
+
const visit = (current, table = "e0") => {
|
|
126
|
+
var _a;
|
|
127
|
+
if (Array.isArray(current)) {
|
|
128
|
+
for (const element of current) {
|
|
129
|
+
visit(element, table);
|
|
130
|
+
}
|
|
131
|
+
} else if (typeof current === "object") {
|
|
132
|
+
for (const key of Object.keys(current)) {
|
|
133
|
+
const shouldJoin = current[key] !== null && typeof current[key] === "object" && Object.keys(current[key]).filter((key2) => !nonJoinKeys.has(key2)).length > 0;
|
|
134
|
+
if (mikroObjectOperations.has(key)) {
|
|
135
|
+
visit(current[key], table);
|
|
136
|
+
} else if (shouldJoin) {
|
|
137
|
+
const keyUseCount = joinKeysUsed.has(key) ? ((_a = joinKeysUsed.get(key)) != null ? _a : 0) + 1 : 1;
|
|
138
|
+
const joinKey = joinKeysUsed.has(key) ? `${key}${keyUseCount}` : key;
|
|
139
|
+
query.leftJoin(`${table}.${key}`, joinKey);
|
|
140
|
+
joinKeysUsed.set(joinKey, keyUseCount);
|
|
141
|
+
visit(current[key], key);
|
|
142
|
+
}
|
|
143
|
+
if (current[key] !== null && typeof current[key] === "object" && Object.keys(current[key]).length === 0) {
|
|
144
|
+
delete current[key];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
visit(where);
|
|
150
|
+
if (Object.keys(where).length > 0) {
|
|
151
|
+
query.andWhere(where);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return query;
|
|
155
|
+
}
|
|
156
|
+
async find(filter, pagination, additionalOptionsForBackend) {
|
|
157
|
+
import_logger.logger.trace(`Running find ${this.entityType.name} with filter`, {
|
|
158
|
+
filter: JSON.stringify(filter)
|
|
159
|
+
});
|
|
160
|
+
const where = filter ? gqlToMikro(JSON.parse(JSON.stringify(filter))) : void 0;
|
|
161
|
+
const query = this.applyWhereClause(where);
|
|
162
|
+
(pagination == null ? void 0 : pagination.limit) && query.limit(pagination.limit);
|
|
163
|
+
(pagination == null ? void 0 : pagination.offset) && query.offset(pagination.offset);
|
|
164
|
+
(pagination == null ? void 0 : pagination.orderBy) && query.orderBy({ ...pagination.orderBy });
|
|
165
|
+
query.setFlag(import__.QueryFlag.DISTINCT);
|
|
166
|
+
const driver = import__.Database.em.getDriver();
|
|
167
|
+
const meta = import__.Database.em.getMetadata().get(this.entityType.name);
|
|
168
|
+
query.populate(driver.autoJoinOneToOneOwner(meta, []));
|
|
169
|
+
if (additionalOptionsForBackend == null ? void 0 : additionalOptionsForBackend.populate) {
|
|
170
|
+
query.populate(additionalOptionsForBackend.populate);
|
|
171
|
+
}
|
|
172
|
+
const result = await query.getResult();
|
|
173
|
+
import_logger.logger.trace(`find ${this.entityType.name} result: ${result.length} rows`);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
async findOne(id) {
|
|
177
|
+
import_logger.logger.trace(`Running findOne ${this.entityType.name} with ID ${id}`);
|
|
178
|
+
const result = await import__.Database.em.findOne(this.entityType, id);
|
|
179
|
+
import_logger.logger.trace(`findOne ${this.entityType.name} result`, { result });
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
async findByRelatedId(entity, relatedField, relatedFieldIds, filter) {
|
|
183
|
+
const queryFilter = {
|
|
184
|
+
$and: [{ [relatedField]: { $in: relatedFieldIds } }, ...[filter != null ? filter : []]]
|
|
185
|
+
};
|
|
186
|
+
const populate = [relatedField];
|
|
187
|
+
const result = await import__.Database.em.find(entity, queryFilter, { populate });
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
async updateOne(id, updateArgs) {
|
|
191
|
+
import_logger.logger.trace(`Running update ${this.entityType.name} with args`, {
|
|
192
|
+
id,
|
|
193
|
+
updateArgs: JSON.stringify(updateArgs)
|
|
194
|
+
});
|
|
195
|
+
const entity = await import__.Database.em.findOne(this.entityType, id, {
|
|
196
|
+
populate: [...visitPathForPopulate(this.entityType.name, updateArgs)]
|
|
197
|
+
});
|
|
198
|
+
if (entity === null) {
|
|
199
|
+
throw new Error(`Unable to locate ${this.entityType.name} with ID: '${id}' for updating.`);
|
|
200
|
+
}
|
|
201
|
+
if (updateArgs == null ? void 0 : updateArgs.version) {
|
|
202
|
+
try {
|
|
203
|
+
await import__.Database.em.lock(entity, import__.LockMode.OPTIMISTIC, updateArgs.version);
|
|
204
|
+
delete updateArgs.version;
|
|
205
|
+
} catch (err) {
|
|
206
|
+
throw new import_errors.OptimisticLockError(err == null ? void 0 : err.message, { entity });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
await mapAndAssignKeys(entity, this.entityType, updateArgs);
|
|
210
|
+
await this.getRepository().persistAndFlush(entity);
|
|
211
|
+
import_logger.logger.trace(`update ${this.entityType.name} entity`, entity);
|
|
212
|
+
return entity;
|
|
213
|
+
}
|
|
214
|
+
async updateMany(updateItems) {
|
|
215
|
+
import_logger.logger.trace(`Running update many ${this.entityType.name} with args`, {
|
|
216
|
+
updateItems: JSON.stringify(updateItems)
|
|
217
|
+
});
|
|
218
|
+
const entities = await import__.Database.transactional(async () => {
|
|
219
|
+
return Promise.all(
|
|
220
|
+
updateItems.map(async (item) => {
|
|
221
|
+
if (!(item == null ? void 0 : item.id))
|
|
222
|
+
throw new Error("You must pass an ID for this entity to update it.");
|
|
223
|
+
const entity = await import__.Database.em.findOneOrFail(this.entityType, item.id, {
|
|
224
|
+
populate: [...visitPathForPopulate(this.entityType.name, item)]
|
|
225
|
+
});
|
|
226
|
+
await mapAndAssignKeys(entity, this.entityType, item);
|
|
227
|
+
import__.Database.em.persist(entity);
|
|
228
|
+
return entity;
|
|
229
|
+
})
|
|
230
|
+
);
|
|
231
|
+
});
|
|
232
|
+
import_logger.logger.trace(`updated ${this.entityType.name} items `, entities);
|
|
233
|
+
return entities;
|
|
234
|
+
}
|
|
235
|
+
async createOrUpdateMany(items) {
|
|
236
|
+
import_logger.logger.trace(`Running create or update many for ${this.entityType.name} with args`, {
|
|
237
|
+
items: JSON.stringify(items)
|
|
238
|
+
});
|
|
239
|
+
const entities = await import__.Database.transactional(async () => {
|
|
240
|
+
return Promise.all(
|
|
241
|
+
items.map(async (item) => {
|
|
242
|
+
let entity;
|
|
243
|
+
const { id } = item;
|
|
244
|
+
if (id) {
|
|
245
|
+
entity = await import__.Database.em.findOneOrFail(this.entityType, id, {
|
|
246
|
+
populate: [...visitPathForPopulate(this.entityType.name, item)]
|
|
247
|
+
});
|
|
248
|
+
import_logger.logger.trace(`Running update on ${this.entityType.name} with item`, {
|
|
249
|
+
item: JSON.stringify(item)
|
|
250
|
+
});
|
|
251
|
+
await mapAndAssignKeys(entity, this.entityType, item);
|
|
252
|
+
} else {
|
|
253
|
+
entity = new this.entityType();
|
|
254
|
+
await mapAndAssignKeys(entity, this.entityType, item);
|
|
255
|
+
import_logger.logger.trace(`Running create on ${this.entityType.name} with item`, {
|
|
256
|
+
item: JSON.stringify(item)
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
import__.Database.em.persist(entity);
|
|
260
|
+
return entity;
|
|
261
|
+
})
|
|
262
|
+
);
|
|
263
|
+
});
|
|
264
|
+
import_logger.logger.trace(`created or updated ${this.entityType.name} items `, entities);
|
|
265
|
+
return entities;
|
|
266
|
+
}
|
|
267
|
+
async createOne(createArgs) {
|
|
268
|
+
import_logger.logger.trace(`Running create ${this.entityType.name} with args`, {
|
|
269
|
+
createArgs: JSON.stringify(createArgs)
|
|
270
|
+
});
|
|
271
|
+
const entity = new this.entityType();
|
|
272
|
+
await mapAndAssignKeys(entity, this.entityType, createArgs);
|
|
273
|
+
await this.getRepository().persistAndFlush(entity);
|
|
274
|
+
import_logger.logger.trace(`create ${this.entityType.name} result`, entity);
|
|
275
|
+
return entity;
|
|
276
|
+
}
|
|
277
|
+
async createMany(createItems) {
|
|
278
|
+
import_logger.logger.trace(`Running create ${this.entityType.name} with args`, {
|
|
279
|
+
createArgs: JSON.stringify(createItems)
|
|
280
|
+
});
|
|
281
|
+
const entities = await import__.Database.transactional(async () => {
|
|
282
|
+
return Promise.all(
|
|
283
|
+
createItems.map(async (item) => {
|
|
284
|
+
const entity = new this.entityType();
|
|
285
|
+
await mapAndAssignKeys(entity, this.entityType, item);
|
|
286
|
+
import__.Database.em.persist(entity);
|
|
287
|
+
return entity;
|
|
288
|
+
})
|
|
289
|
+
);
|
|
290
|
+
});
|
|
291
|
+
import_logger.logger.trace(`created ${this.entityType.name} items `, entities);
|
|
292
|
+
return entities;
|
|
293
|
+
}
|
|
294
|
+
async deleteOne(id) {
|
|
295
|
+
import_logger.logger.trace(`Running delete ${this.entityType.name} with id ${id}`);
|
|
296
|
+
const deletedRows = await this.getRepository().nativeDelete({
|
|
297
|
+
id
|
|
298
|
+
});
|
|
299
|
+
if (deletedRows > 1) {
|
|
300
|
+
throw new Error("Multiple deleted rows");
|
|
301
|
+
}
|
|
302
|
+
import_logger.logger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);
|
|
303
|
+
return deletedRows === 1;
|
|
304
|
+
}
|
|
305
|
+
async deleteMany(ids) {
|
|
306
|
+
import_logger.logger.trace(`Running delete ${this.entityType.name} with ids ${ids}`);
|
|
307
|
+
const deletedRows = await import__.Database.transactional(async () => {
|
|
308
|
+
const deletedCount = await this.getRepository().nativeDelete({
|
|
309
|
+
id: { $in: ids }
|
|
310
|
+
});
|
|
311
|
+
if (deletedCount !== ids.length) {
|
|
312
|
+
throw new Error("We did not delete all the rows, rolling back");
|
|
313
|
+
}
|
|
314
|
+
return deletedCount;
|
|
315
|
+
});
|
|
316
|
+
import_logger.logger.trace(`delete ${this.entityType.name} result: deleted ${deletedRows} row(s)`);
|
|
317
|
+
return deletedRows === ids.length;
|
|
318
|
+
}
|
|
319
|
+
getRelatedEntityId(entity, relatedIdField) {
|
|
320
|
+
if (typeof entity === "string") {
|
|
321
|
+
return entity;
|
|
322
|
+
}
|
|
323
|
+
if (entity.id) {
|
|
324
|
+
return entity.id;
|
|
325
|
+
}
|
|
326
|
+
throw new Error(`Unknown entity without an id: ${JSON.stringify(entity)}`);
|
|
327
|
+
}
|
|
328
|
+
isCollection(entity) {
|
|
329
|
+
return import__.Utils.isCollection(entity);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
333
|
+
0 && (module.exports = {
|
|
334
|
+
MikroBackendProvider,
|
|
335
|
+
gqlToMikro,
|
|
336
|
+
mapAndAssignKeys,
|
|
337
|
+
visitPathForPopulate
|
|
338
|
+
});
|
package/lib/config.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const requireEnvironmentVariable: (envStr: string, warnOnly?: boolean
|
|
1
|
+
export declare const requireEnvironmentVariable: (envStr: string, warnOnly?: boolean) => string | undefined;
|
|
2
2
|
export declare const config: {};
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var config_exports = {};
|
|
20
|
+
__export(config_exports, {
|
|
21
|
+
config: () => config,
|
|
22
|
+
requireEnvironmentVariable: () => requireEnvironmentVariable
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(config_exports);
|
|
25
|
+
var import_logger = require("@exogee/logger");
|
|
26
|
+
const requireEnvironmentVariable = (envStr, warnOnly) => {
|
|
27
|
+
const envVar = process.env[envStr];
|
|
28
|
+
if (!envVar) {
|
|
29
|
+
if (warnOnly) {
|
|
30
|
+
import_logger.logger.warn(`${envStr} is required in environment.`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`${envStr} required but not found.`);
|
|
34
|
+
}
|
|
35
|
+
return envVar;
|
|
36
|
+
};
|
|
37
|
+
const config = {};
|
|
38
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
39
|
+
0 && (module.exports = {
|
|
40
|
+
config,
|
|
41
|
+
requireEnvironmentVariable
|
|
42
|
+
});
|
package/lib/database.d.ts
CHANGED
|
@@ -23,11 +23,11 @@ declare class DatabaseImplementation {
|
|
|
23
23
|
get rawConnection(): import("@mikro-orm/postgresql").PostgreSqlConnection;
|
|
24
24
|
private getConnectionInfo;
|
|
25
25
|
getRepository: <T extends Partial<T>>(entityName: EntityName<T>) => import("@mikro-orm/core").GetRepository<T, import("@mikro-orm/postgresql").EntityRepository<T>>;
|
|
26
|
-
connect: (connectionOptions?: ConnectionOptions
|
|
26
|
+
connect: (connectionOptions?: ConnectionOptions) => Promise<MikroORM<IDatabaseDriver<Connection>>>;
|
|
27
27
|
close: () => Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
export declare const Database: DatabaseImplementation;
|
|
30
30
|
export declare const checkDatabase: () => Promise<any>;
|
|
31
31
|
export declare const getDbSchema: () => Promise<string>;
|
|
32
|
-
export declare const clearDatabaseContext: (req?: any, res?: any, next?: any, connectionOptions?: ConnectionOptions
|
|
32
|
+
export declare const clearDatabaseContext: (req?: any, res?: any, next?: any, connectionOptions?: ConnectionOptions) => Promise<any>;
|
|
33
33
|
export {};
|