New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@ptc-org/nestjs-query-mongoose

Package Overview
Dependencies
Maintainers
0
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ptc-org/nestjs-query-mongoose - npm Package Compare versions

Comparing version

to
6.1.3

4

package.json
{
"name": "@ptc-org/nestjs-query-mongoose",
"version": "6.1.2",
"version": "6.1.3",
"description": "Mongoose adapter for @ptc-org/nestjs-query-core",

@@ -25,3 +25,3 @@ "author": "doug-martin <doug@dougamartin.com>",

"tslib": "^2.6.2",
"@ptc-org/nestjs-query-core": "6.1.2",
"@ptc-org/nestjs-query-core": "6.1.3",
"reflect-metadata": "0.2.2"

@@ -28,0 +28,0 @@ },

@@ -34,40 +34,6 @@ /// <reference types="mongoose/types/aggregate" />

countRelations<Relation extends Document>(RelationClass: Class<Relation>, relationName: string, dto: Entity, filter: Filter<Relation>): Promise<number>;
findRelation<Relation extends Document>(RelationClass: Class<Relation>, relationName: string, dtos: Entity[], opts?: FindRelationOptions<Relation>): Promise<Map<Entity, Relation | undefined>>;
findRelation<Relation extends Document>(RelationClass: Class<Relation>, relationName: string, dto: Entity, opts?: FindRelationOptions<Relation>): Promise<Relation | undefined>;
/**
* Query for an array of relations for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param dtos - The entities to query relations for.
* @param relationName - The name of relation to query for.
* @param opts - A query to filter, page or sort relations.
* @param withDeleted - Also query the soft deleted records
*/
private batchQueryRelations;
/**
* Query for an array of relations for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param entities - The entities to query relations for.
* @param relationName - The name of relation to query for.
* @param filter - Filter.
* @param query - A query to filter, page or sort relations.
*/
private batchAggregateRelations;
/**
* Count the number of relations for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param entities - The entities to query relations for.
* @param relationName - The name of relation to query for.
* @param filter - The filter to apply to the relation query.
*/
private batchCountRelations;
/**
* Query for a relation for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param dtos - The dto to query relations for.
* @param relationName - The name of relation to query for.
* @param opts - A query to filter, page or sort relations.
*/
private batchFindRelations;
queryRelations<Relation extends Document>(RelationClass: Class<Relation>, relationName: string, entities: Entity[], query: Query<Relation>): Promise<Map<Entity, Relation[]>>;
queryRelations<Relation extends Document>(RelationClass: Class<Relation>, relationName: string, dto: Entity, query: Query<Relation>): Promise<Relation[]>;
findRelation<Relation>(RelationClass: Class<Relation>, relationName: string, dtos: Entity[], opts?: FindRelationOptions<Relation>): Promise<Map<Entity, Relation | undefined>>;
findRelation<Relation>(RelationClass: Class<Relation>, relationName: string, dto: Entity, opts?: FindRelationOptions<Relation>): Promise<Relation | undefined>;
queryRelations<Relation>(RelationClass: Class<Relation>, relationName: string, entities: Entity[], query: Query<Relation>): Promise<Map<Entity, Relation[]>>;
queryRelations<Relation>(RelationClass: Class<Relation>, relationName: string, dto: Entity, query: Query<Relation>): Promise<Relation[]>;
addRelations<Relation extends Document>(relationName: string, id: string, relationIds: (string | number)[], opts?: ModifyRelationOptions<Entity, Relation>): Promise<Entity>;

@@ -84,5 +50,5 @@ setRelations<Relation extends Document>(relationName: string, id: string, relationIds: (string | number)[], opts?: ModifyRelationOptions<Entity, Relation>): Promise<Entity>;

private getReferenceFilter;
private getReferenceIds;
private getReferenceFieldMap;
private getObjectIdReferenceFilter;
private getVirtualReferenceFilter;
private getRefCount;
}

@@ -12,8 +12,12 @@ "use strict";

this.checkForReference('AggregateRelations', relationName);
const relationModel = this.getReferenceModel(relationName);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
if (Array.isArray(dto)) {
return this.batchAggregateRelations(RelationClass, relationName, dto, filter, aggregateQuery);
return dto.reduce(async (mapPromise, entity) => {
const map = await mapPromise;
const refs = await this.aggregateRelations(RelationClass, relationName, entity, filter, aggregateQuery);
return map.set(entity, refs);
}, Promise.resolve(new Map()));
}
const assembler = nestjs_query_core_1.AssemblerFactory.getAssembler(RelationClass, mongoose_1.Document);
const relationModel = this.getReferenceModel(relationName);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
const refFilter = this.getReferenceFilter(relationName, dto, assembler.convertQuery({ filter }).filter);

@@ -34,3 +38,7 @@ if (!refFilter) {

if (Array.isArray(dto)) {
return this.batchCountRelations(RelationClass, relationName, dto, filter);
return dto.reduce(async (mapPromise, entity) => {
const map = await mapPromise;
const refs = await this.countRelations(RelationClass, relationName, entity, filter);
return map.set(entity, refs);
}, Promise.resolve(new Map()));
}

@@ -48,4 +56,9 @@ const assembler = nestjs_query_core_1.AssemblerFactory.getAssembler(RelationClass, mongoose_1.Document);

this.checkForReference('FindRelation', relationName);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
if (Array.isArray(dto)) {
return this.batchFindRelations(RelationClass, relationName, dto, opts);
return dto.reduce(async (prev, curr) => {
const map = await prev;
const ref = await this.findRelation(RelationClass, relationName, curr, opts);
return map.set(curr, ref);
}, Promise.resolve(new Map()));
}

@@ -57,3 +70,2 @@ const foundEntity = await this.Model.findById(dto._id ?? dto.id);

const assembler = nestjs_query_core_1.AssemblerFactory.getAssembler(RelationClass, mongoose_1.Document);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
const filterQuery = referenceQueryBuilder.buildFilterQuery(assembler.convertQuery({ filter: opts?.filter }).filter);

@@ -64,101 +76,11 @@ const populated = await foundEntity.populate({ path: relationName, match: filterQuery });

}
/**
* Query for an array of relations for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param dtos - The entities to query relations for.
* @param relationName - The name of relation to query for.
* @param opts - A query to filter, page or sort relations.
* @param withDeleted - Also query the soft deleted records
*/
async batchQueryRelations(RelationClass, relationName, dtos, opts, withDeleted) {
const assembler = nestjs_query_core_1.AssemblerFactory.getAssembler(RelationClass, mongoose_1.Document);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
const query = assembler.convertQuery(opts);
// If paging is enabled, we need to query each entity individually
if (query.paging) {
const entityRelations = await Promise.all(dtos.map((d) => this.queryRelations(RelationClass, relationName, d, opts)));
return entityRelations.reduce((results, relations, index) => {
const e = dtos[index];
results.set(e, relations);
return results;
}, new Map());
}
const refFilter = this.getReferenceFilter(relationName, dtos, query.filter);
const results = new Map();
if (!refFilter) {
return results;
}
const refFieldMap = this.getReferenceFieldMap(relationName);
if (!refFieldMap) {
return results;
}
const { filterQuery, options } = referenceQueryBuilder.buildQuery({ ...query, filter: refFilter });
const referenceModel = this.getReferenceModel(relationName);
const entityRelations = await referenceModel.find(filterQuery).sort(options.sort).exec();
for (const dto of dtos) {
const referenceIds = this.getReferenceIds(refFieldMap.localField, dto);
const refs = entityRelations.filter((er) => {
return referenceIds.some((rid) => {
const oneOrManyIds = er[refFieldMap.foreignField];
const ids = (Array.isArray(oneOrManyIds) ? oneOrManyIds : [oneOrManyIds]);
return ids.some((id) => id.equals(rid));
});
});
results.set(dto, await assembler.convertToDTOs(refs));
}
return results;
}
/**
* Query for an array of relations for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param entities - The entities to query relations for.
* @param relationName - The name of relation to query for.
* @param filter - Filter.
* @param query - A query to filter, page or sort relations.
*/
async batchAggregateRelations(RelationClass, relationName, entities, filter, query) {
const entityRelations = await Promise.all(entities.map((e) => this.aggregateRelations(RelationClass, relationName, e, filter, query)));
return entityRelations.reduce((results, relationAggregate, index) => {
const e = entities[index];
results.set(e, relationAggregate);
return results;
}, new Map());
}
/**
* Count the number of relations for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param entities - The entities to query relations for.
* @param relationName - The name of relation to query for.
* @param filter - The filter to apply to the relation query.
*/
async batchCountRelations(RelationClass, relationName, entities, filter) {
const entityRelations = await Promise.all(entities.map((e) => this.countRelations(RelationClass, relationName, e, filter)));
return entityRelations.reduce((results, relationCount, index) => {
const e = entities[index];
results.set(e, relationCount);
return results;
}, new Map());
}
/**
* Query for a relation for multiple dtos.
* @param RelationClass - The class to serialize the relations into.
* @param dtos - The dto to query relations for.
* @param relationName - The name of relation to query for.
* @param opts - A query to filter, page or sort relations.
*/
async batchFindRelations(RelationClass, relationName, dtos, opts) {
const batchResults = await this.batchQueryRelations(RelationClass, relationName, dtos, {
filter: opts?.filter
}, opts?.withDeleted);
const results = new Map();
batchResults.forEach((relation, dto) => {
// get just the first one.
results.set(dto, relation[0]);
});
return results;
}
async queryRelations(RelationClass, relationName, dto, query) {
this.checkForReference('QueryRelations', relationName);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
if (Array.isArray(dto)) {
return this.batchQueryRelations(RelationClass, relationName, dto, query);
return dto.reduce(async (mapPromise, entity) => {
const map = await mapPromise;
const refs = await this.queryRelations(RelationClass, relationName, entity, query);
return map.set(entity, refs);
}, Promise.resolve(new Map()));
}

@@ -170,3 +92,2 @@ const foundEntity = await this.Model.findById(dto._id ?? dto.id);

const assembler = nestjs_query_core_1.AssemblerFactory.getAssembler(RelationClass, mongoose_1.Document);
const referenceQueryBuilder = this.getReferenceQueryBuilder(relationName);
const { filterQuery, options } = referenceQueryBuilder.buildQuery(assembler.convertQuery(query));

@@ -283,35 +204,30 @@ const populated = await foundEntity.populate({ path: relationName, match: filterQuery, options });

getReferenceFilter(refName, entity, filter) {
const refFieldMap = this.getReferenceFieldMap(refName);
if (!refFieldMap) {
return undefined;
}
const referenceIds = this.getReferenceIds(refFieldMap.localField, entity);
const refFilter = {
[refFieldMap.foreignField]: { in: referenceIds }
};
return (0, nestjs_query_core_1.mergeFilter)(filter ?? {}, refFilter);
}
getReferenceIds(localField, entity) {
const entities = Array.isArray(entity) ? entity : [entity];
return entities.flatMap((e) => e[localField]).filter((id) => !!id);
}
getReferenceFieldMap(refName) {
if (this.isReferencePath(refName)) {
return {
foreignField: '_id',
localField: refName
};
return this.getObjectIdReferenceFilter(refName, entity, filter);
}
if (this.isVirtualPath(refName)) {
const virtualType = this.Model.schema.virtualpath(refName);
if (!(0, mongoose_types_helper_1.isVirtualTypeWithReferenceOptions)(virtualType)) {
throw new Error(`Unable to lookup reference type for ${refName}`);
if ((0, mongoose_types_helper_1.isVirtualTypeWithReferenceOptions)(virtualType)) {
return this.getVirtualReferenceFilter(virtualType, entity, filter);
}
return {
foreignField: virtualType.options.foreignField,
localField: virtualType.options.localField
};
throw new Error(`Unable to lookup reference type for ${refName}`);
}
return undefined;
}
getObjectIdReferenceFilter(refName, entity, filter) {
const referenceIds = entity[refName];
const refFilter = {
_id: { [Array.isArray(referenceIds) ? 'in' : 'eq']: referenceIds }
};
return (0, nestjs_query_core_1.mergeFilter)(filter ?? {}, refFilter);
}
getVirtualReferenceFilter(virtualType, entity, filter) {
const { foreignField, localField } = virtualType.options;
const refVal = entity[localField];
const isArray = Array.isArray(refVal);
const lookupFilter = {
[foreignField]: { [isArray ? 'in' : 'eq']: refVal }
};
return (0, nestjs_query_core_1.mergeFilter)(filter ?? {}, lookupFilter);
}
getRefCount(relationName, relationIds, filter) {

@@ -318,0 +234,0 @@ const referenceModel = this.getReferenceModel(relationName);

Sorry, the diff of this file is not supported yet