pangea-server 1.0.61 → 1.0.63
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/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# PANGEA
|
|
1
|
+
# PANGEA SERVER
|
|
@@ -9,16 +9,16 @@ type Group = string[];
|
|
|
9
9
|
type Order = Record<string, 'asc' | 'desc'>;
|
|
10
10
|
type FindOneOptions = {
|
|
11
11
|
scopes?: string[];
|
|
12
|
-
attributes?: Attributes;
|
|
13
12
|
order?: Order;
|
|
14
13
|
paranoid?: boolean;
|
|
15
14
|
};
|
|
15
|
+
type AggregateOneOptions = {
|
|
16
|
+
paranoid?: boolean;
|
|
17
|
+
};
|
|
16
18
|
type FindManyOptions<BM extends BaseModel> = {
|
|
17
|
-
attributes?: Attributes;
|
|
18
19
|
where?: Where<BM>;
|
|
19
20
|
searchFields?: string[];
|
|
20
21
|
search?: string | null;
|
|
21
|
-
group?: Group;
|
|
22
22
|
order?: Order;
|
|
23
23
|
paranoid?: boolean;
|
|
24
24
|
};
|
|
@@ -26,18 +26,25 @@ type FindManyPagedOptions<BM extends BaseModel> = FindManyOptions<BM> & {
|
|
|
26
26
|
page?: number | null;
|
|
27
27
|
pageSize?: number | null;
|
|
28
28
|
};
|
|
29
|
+
type AggregateManyConfig = {
|
|
30
|
+
attributes: Attributes;
|
|
31
|
+
group: Group;
|
|
32
|
+
};
|
|
29
33
|
type Target<BM extends BaseModel> = Filters<BM> | BM;
|
|
30
34
|
export declare class Db {
|
|
31
35
|
private __tx?;
|
|
32
36
|
constructor(tx: Tx);
|
|
33
37
|
findOneOrNull<BM extends BaseModel>(model: BaseModelCtor<BM>, filters: Filters<BM>, options?: FindOneOptions): Promise<BM | null>;
|
|
34
38
|
findOne<BM extends BaseModel>(model: BaseModelCtor<BM>, filters: Filters<BM>, options?: FindOneOptions): Promise<BM>;
|
|
39
|
+
aggregateOne<BM extends BaseModel>(model: BaseModelCtor<BM>, attributes: Attributes, options?: AggregateOneOptions): Promise<BM | null>;
|
|
40
|
+
private __getFindOneBaseOptions;
|
|
35
41
|
findMany<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyPagedOptions<BM>): Promise<BM[]>;
|
|
36
42
|
count<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyOptions<BM>): Promise<number>;
|
|
37
43
|
findManyWithCount<BM extends BaseModel>(model: BaseModelCtor<BM>, options?: FindManyPagedOptions<BM>): Promise<{
|
|
38
44
|
instances: BM[];
|
|
39
45
|
totalCount: number;
|
|
40
46
|
}>;
|
|
47
|
+
aggregateMany<BM extends BaseModel>(model: BaseModelCtor<BM>, config: AggregateManyConfig, options?: Omit<FindManyOptions<BM>, 'order'>): Promise<BM[]>;
|
|
41
48
|
private __getFindManyBaseOptions;
|
|
42
49
|
insertOne<BM extends BaseModel>(model: BaseModelCtor<BM>, params: InsertParams<BM>): Promise<BM>;
|
|
43
50
|
insertMany<BM extends BaseModel>(model: BaseModelCtor<BM>, data: InsertParams<BM>[]): Promise<number>;
|
|
@@ -13,20 +13,15 @@ class Db {
|
|
|
13
13
|
}
|
|
14
14
|
// find methods
|
|
15
15
|
findOneOrNull(model, filters, options = {}) {
|
|
16
|
-
const { scopes,
|
|
16
|
+
const { scopes, order, paranoid = true } = options;
|
|
17
17
|
const scopedModel = scopes?.length ? model.scope(...scopes) : model;
|
|
18
|
-
const baseOptions =
|
|
19
|
-
attributes: getFinalAttributes(model, attributes),
|
|
20
|
-
paranoid,
|
|
21
|
-
subQuery: false,
|
|
22
|
-
transaction: this.__tx,
|
|
23
|
-
};
|
|
18
|
+
const baseOptions = this.__getFindOneBaseOptions(paranoid);
|
|
24
19
|
if (typeof filters === 'number') {
|
|
25
20
|
return scopedModel.findByPk(filters, { ...baseOptions, ...getInclude(model) });
|
|
26
21
|
}
|
|
27
22
|
return scopedModel.findOne({
|
|
28
23
|
...baseOptions,
|
|
29
|
-
...getInclude(model, {
|
|
24
|
+
...getInclude(model, { where: filters }),
|
|
30
25
|
order: getFinalOrder(order),
|
|
31
26
|
});
|
|
32
27
|
}
|
|
@@ -36,6 +31,18 @@ class Db {
|
|
|
36
31
|
helpers_1.AppError.ThrowEntityNotFound();
|
|
37
32
|
return instance;
|
|
38
33
|
}
|
|
34
|
+
aggregateOne(model, attributes, options = {}) {
|
|
35
|
+
const { paranoid = true } = options;
|
|
36
|
+
const baseOptions = this.__getFindOneBaseOptions(paranoid);
|
|
37
|
+
return model.findOne({
|
|
38
|
+
...baseOptions,
|
|
39
|
+
attributes: getFinalAttributes(model, attributes),
|
|
40
|
+
...getInclude(model, { attributes }),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
__getFindOneBaseOptions(paranoid) {
|
|
44
|
+
return { paranoid, subQuery: false, transaction: this.__tx };
|
|
45
|
+
}
|
|
39
46
|
async findMany(model, options = {}) {
|
|
40
47
|
const baseOptions = this.__getFindManyBaseOptions(model, options);
|
|
41
48
|
const { page, pageSize } = options;
|
|
@@ -66,8 +73,16 @@ class Db {
|
|
|
66
73
|
const instances = await this.findMany(model, options);
|
|
67
74
|
return { instances, totalCount: instances.length };
|
|
68
75
|
}
|
|
76
|
+
async aggregateMany(model, config, options = {}) {
|
|
77
|
+
const baseOptions = this.__getFindManyBaseOptions(model, options);
|
|
78
|
+
return model.findAll({
|
|
79
|
+
...baseOptions,
|
|
80
|
+
attributes: getFinalAttributes(model, config.attributes),
|
|
81
|
+
...(config.group && { group: config.group.map((field) => formatField(model.name, field)) }),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
69
84
|
__getFindManyBaseOptions(model, options = {}) {
|
|
70
|
-
const {
|
|
85
|
+
const { where, searchFields, search, order, paranoid = true } = options;
|
|
71
86
|
let searchWhere;
|
|
72
87
|
if (searchFields?.length && search) {
|
|
73
88
|
const searchWords = search.split(/\s+/).filter(Boolean);
|
|
@@ -81,12 +96,7 @@ class Db {
|
|
|
81
96
|
};
|
|
82
97
|
}
|
|
83
98
|
return {
|
|
84
|
-
|
|
85
|
-
...getInclude(model, { attributes, where: { ...where, ...searchWhere } }),
|
|
86
|
-
...(group && { group: group.map(pangea_helpers_1.camelToSnake) }),
|
|
87
|
-
...(group && {
|
|
88
|
-
group: group.map((field) => (field.includes('.') ? field : `${model.name}.${(0, pangea_helpers_1.camelToSnake)(field)}`)),
|
|
89
|
-
}),
|
|
99
|
+
...getInclude(model, { where: { ...where, ...searchWhere } }),
|
|
90
100
|
order: getFinalOrder(order),
|
|
91
101
|
paranoid,
|
|
92
102
|
subQuery: false,
|
|
@@ -186,17 +196,22 @@ class Db {
|
|
|
186
196
|
}
|
|
187
197
|
exports.Db = Db;
|
|
188
198
|
// internal functions
|
|
199
|
+
function formatField(modelName, field) {
|
|
200
|
+
if (field.includes('.')) {
|
|
201
|
+
const parts = field.split('.');
|
|
202
|
+
const last = parts.pop();
|
|
203
|
+
return [...parts, (0, pangea_helpers_1.camelToSnake)(last)].join('.');
|
|
204
|
+
}
|
|
205
|
+
return `${modelName}.${(0, pangea_helpers_1.camelToSnake)(field)}`;
|
|
206
|
+
}
|
|
189
207
|
function getFinalAttributes(model, attributes) {
|
|
190
208
|
if (!attributes)
|
|
191
209
|
return;
|
|
192
210
|
return Object.entries(attributes).map(([alias, column]) => {
|
|
193
|
-
if (typeof column === 'string')
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const [op, fieldName] = column;
|
|
198
|
-
const field = fieldName.includes('.') ? fieldName : `${model.name}.${(0, pangea_helpers_1.camelToSnake)(fieldName)}`;
|
|
199
|
-
return [(0, sequelize_1.fn)(op, (0, sequelize_1.col)(field)), alias];
|
|
211
|
+
if (typeof column === 'string')
|
|
212
|
+
return [(0, sequelize_1.col)(formatField(model.name, column)), alias];
|
|
213
|
+
const [op, field] = column;
|
|
214
|
+
return [(0, sequelize_1.fn)(op, (0, sequelize_1.col)(formatField(model.name, field))), alias];
|
|
200
215
|
});
|
|
201
216
|
}
|
|
202
217
|
function convertWhereKeys(obj) {
|
|
@@ -219,7 +234,7 @@ function convertWhereKeys(obj) {
|
|
|
219
234
|
const parts = inner.split('.');
|
|
220
235
|
if (parts.length >= 2) {
|
|
221
236
|
const last = parts.pop();
|
|
222
|
-
newKey = `$${[...parts
|
|
237
|
+
newKey = `$${[...parts, (0, pangea_helpers_1.camelToSnake)(last)].join('.')}$`;
|
|
223
238
|
}
|
|
224
239
|
}
|
|
225
240
|
newObj[newKey] = convertWhereKeys(value);
|
|
@@ -246,7 +261,7 @@ function getInclude(model, config = {}, relDepth = new Map()) {
|
|
|
246
261
|
const relModel = rel.getModelFn();
|
|
247
262
|
includeOptions.push({
|
|
248
263
|
model: relModel,
|
|
249
|
-
as:
|
|
264
|
+
as: relName,
|
|
250
265
|
attributes: !config.attributes ? undefined : [],
|
|
251
266
|
required: rel.required,
|
|
252
267
|
paranoid: rel.paranoid,
|
|
@@ -25,8 +25,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.HasMany = exports.HasOne = exports.BelongsTo = void 0;
|
|
27
27
|
const seq = __importStar(require("sequelize-typescript"));
|
|
28
|
-
// helpers
|
|
29
|
-
const pangea_helpers_1 = require("pangea-helpers");
|
|
30
28
|
exports.BelongsTo = getRelation(seq.BelongsTo);
|
|
31
29
|
exports.HasOne = getRelation(seq.HasOne);
|
|
32
30
|
exports.HasMany = getRelation(seq.HasMany);
|
|
@@ -35,11 +33,10 @@ function getRelation(relationFn) {
|
|
|
35
33
|
return function (getModelFn, options = {}) {
|
|
36
34
|
return function (target, propertyName) {
|
|
37
35
|
const { foreignKey, ...relOptions } = options;
|
|
38
|
-
|
|
39
|
-
relationFn(getModelFn, { as: alias, ...(foreignKey && { foreignKey }) })(target, propertyName);
|
|
36
|
+
relationFn(getModelFn, { as: propertyName, ...(foreignKey && { foreignKey }) })(target, propertyName);
|
|
40
37
|
const model = target.constructor;
|
|
41
38
|
const { eager = relationFn !== seq.HasMany, required = relationFn === seq.BelongsTo ? !model.Columns[`${propertyName}Id`].allowNull : false, paranoid = relationFn !== seq.BelongsTo, joinDepth = 1, ...restOptions } = relOptions;
|
|
42
|
-
model.AddRelation(propertyName, {
|
|
39
|
+
model.AddRelation(propertyName, { getModelFn, eager, required, paranoid, joinDepth, ...restOptions });
|
|
43
40
|
};
|
|
44
41
|
};
|
|
45
42
|
}
|