@kenniy/godeye-data-contracts
Version:
Enterprise-grade base repository architecture for GOD-EYE microservices with zero overhead and maximum code reuse
146 lines (145 loc) • 5.89 kB
JavaScript
;
/**
* Base Query DTO - Universal for all entities
* Auto-transforms HTTP parameters to ICriteria format
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseQueryDto = void 0;
const class_validator_1 = require("class-validator");
const class_transformer_1 = require("class-transformer");
const swagger_1 = require("@nestjs/swagger");
class BaseQueryDto {
constructor() {
this.page = 1;
this.limit = 20;
}
/**
* Auto-transform DTO to ICriteria with unified include handling
*/
toICriteria() {
const includeFields = this.parseInclude(this.include);
return {
page: this.page,
limit: this.limit,
relations: includeFields.relations,
select: includeFields.fields,
sort: this.parseSortString(this.sort),
search: this.search ? {
term: this.search
// Backend will auto-discover fields and determine search strategy
} : undefined,
where: this.buildWhereClause()
};
}
/**
* Parse unified include parameter into potential relations and fields
* Repository will validate which items are actual relations using auto-discovery
*/
parseInclude(includeStr) {
if (!includeStr)
return { relations: [], fields: [] };
const items = includeStr.split(',').map(s => s.trim());
// For now, treat all items as potential relations
// Repository will filter out invalid relations using auto-discovery
return {
relations: items.filter(item => this.looksLikeRelation(item)),
fields: items.filter(item => !this.looksLikeRelation(item))
};
}
/**
* Basic heuristic to determine if an item looks like a relation
* Repository auto-discovery will provide final validation
*/
looksLikeRelation(item) {
// Items with dots are likely deep relations (e.g., 'business.owner')
if (item.includes('.'))
return true;
// Common field patterns that are NOT relations
const fieldPatterns = ['id', 'name', 'email', 'createdAt', 'updatedAt', 'status', 'type'];
if (fieldPatterns.includes(item))
return false;
// Assume other items could be relations (repository will validate)
return true;
}
parseSortString(sortStr) {
if (!sortStr)
return undefined;
const sortObj = {};
sortStr.split(',').forEach(item => {
const [field, direction = 'ASC'] = item.split(':');
sortObj[field.trim()] = direction.toUpperCase();
});
return sortObj;
}
buildWhereClause() {
const where = {};
if (this.status) {
where.status = this.status;
}
return Object.keys(where).length > 0 ? where : undefined;
}
}
exports.BaseQueryDto = BaseQueryDto;
__decorate([
(0, swagger_1.ApiPropertyOptional)({ example: 1, description: 'Page number (1-based)' }),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(1),
(0, class_transformer_1.Type)(() => Number),
__metadata("design:type", Number)
], BaseQueryDto.prototype, "page", void 0);
__decorate([
(0, swagger_1.ApiPropertyOptional)({ example: 20, description: 'Items per page', minimum: 1, maximum: 100 }),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsNumber)(),
(0, class_validator_1.Min)(1),
(0, class_validator_1.Max)(100),
(0, class_transformer_1.Type)(() => Number),
__metadata("design:type", Number)
], BaseQueryDto.prototype, "limit", void 0);
__decorate([
(0, swagger_1.ApiPropertyOptional)({
example: 'id,name,email,profile,business',
description: 'Fields and relations to include in response (comma-separated)'
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsString)(),
__metadata("design:type", String)
], BaseQueryDto.prototype, "include", void 0);
__decorate([
(0, swagger_1.ApiPropertyOptional)({
example: 'createdAt:DESC,name:ASC',
description: 'Sort fields with direction (field:ASC/DESC)'
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsString)(),
__metadata("design:type", String)
], BaseQueryDto.prototype, "sort", void 0);
__decorate([
(0, swagger_1.ApiPropertyOptional)({
example: 'john doe',
description: 'Search term - backend automatically determines fields and search strategy'
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsString)(),
__metadata("design:type", String)
], BaseQueryDto.prototype, "search", void 0);
__decorate([
(0, swagger_1.ApiPropertyOptional)({
example: 'active',
enum: ['active', 'inactive', 'deleted'],
description: 'Entity status'
}),
(0, class_validator_1.IsOptional)(),
(0, class_validator_1.IsEnum)(['active', 'inactive', 'deleted']),
__metadata("design:type", String)
], BaseQueryDto.prototype, "status", void 0);