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); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import { Controller, Get, Injectable, Module, NotFoundException, Param } from "@nestjs/common"; import { MediaModule } from "../media/media.controller.js"; import { MediaService } from "../media/media.service.js"; import { PrismaService } from "../prisma/prisma.service.js"; import { SectionsModule, SectionsService } from "../sections/sections.module.js"; const visible = { isPublished: true, category: { isPublished: true } }; const RELATED_LIMIT = 4; const isAttribute = (a) => !!a && typeof a === "object" && typeof a.name === "string" && typeof a.value === "string"; let PublicService = class PublicService { prisma; media; sections; constructor(prisma, media, sections) { this.prisma = prisma; this.media = media; this.sections = sections; } async site() { const [sections, categories] = await Promise.all([this.sections.getAll(), this.categories()]); return { sections, categories }; } async categories() { const rows = await this.prisma.category.findMany({ where: { isPublished: true }, orderBy: [{ sortOrder: "asc" }, { id: "asc" }], include: { coverImage: true, _count: { select: { products: { where: { isPublished: true } } } }, }, }); return rows.map((c) => ({ slug: c.slug, code: c.code, name: c.name, nameEn: c.nameEn, shortDesc: c.shortDesc, icon: c.icon, coverImage: c.coverImage && this.media.url(c.coverImage.key), productCount: c._count.products, })); } async category(slug) { const c = await this.prisma.category.findFirst({ where: { slug, isPublished: true }, include: { coverImage: true, groups: { orderBy: { sortOrder: "asc" } }, products: { where: { isPublished: true }, orderBy: [{ sortOrder: "asc" }, { id: "asc" }], include: { image: true, group: { select: { slug: true } } }, }, }, }); if (!c) throw new NotFoundException("دسته‌بندی یافت نشد"); const products = c.products.map((p) => this.toPublicProduct(p)); const usedGroups = new Set(products.map((p) => p.group)); return { slug: c.slug, code: c.code, name: c.name, nameEn: c.nameEn, shortDesc: c.shortDesc, fullDesc: c.fullDesc, icon: c.icon, seoTitle: c.seoTitle, seoDescription: c.seoDescription, coverImage: c.coverImage && this.media.url(c.coverImage.key), productCount: products.length, groups: c.groups .filter((g) => usedGroups.has(g.slug)) .map((g) => ({ slug: g.slug, name: g.name, desc: g.desc })), products, }; } async product(slug) { const p = await this.prisma.product.findFirst({ where: { slug, ...visible }, include: { image: true, gallery: { orderBy: { sortOrder: "asc" }, include: { media: true } }, group: true, category: { include: { coverImage: true } }, }, }); if (!p) throw new NotFoundException("محصول یافت نشد"); const media = new Map(); for (const m of [p.image, ...p.gallery.map((g) => g.media)]) if (m) media.set(m.id, m); const siblings = await this.prisma.product.findMany({ where: { categoryId: p.categoryId, isPublished: true, id: { not: p.id } }, orderBy: [{ sortOrder: "asc" }, { id: "asc" }], include: { image: true, group: { select: { slug: true } } }, }); const sameGroup = (s) => p.groupId !== null && s.groupId === p.groupId; const related = [...siblings.filter(sameGroup), ...siblings.filter((s) => !sameGroup(s))] .slice(0, RELATED_LIMIT) .map((s) => this.toPublicProduct(s)); return { ...this.toPublicProduct(p), details: p.details, brand: p.brand, origin: p.origin, sizes: p.sizes, standards: p.standards, features: p.features, applications: p.applications, attributes: Array.isArray(p.attributes) ? p.attributes.filter(isAttribute) : [], packaging: p.packaging, minOrder: p.minOrder, seoTitle: p.seoTitle, seoDescription: p.seoDescription, images: [...media.values()].map((m) => ({ url: this.media.url(m.key), alt: m.alt || p.name, width: m.width, height: m.height, })), groupName: p.group?.name ?? null, category: { slug: p.category.slug, code: p.category.code, name: p.category.name, nameEn: p.category.nameEn, fullDesc: p.category.fullDesc, coverImage: p.category.coverImage && this.media.url(p.category.coverImage.key), }, related, updatedAt: p.updatedAt.toISOString(), }; } async productRefs() { const rows = await this.prisma.product.findMany({ where: visible, orderBy: [{ category: { sortOrder: "asc" } }, { sortOrder: "asc" }], select: { slug: true, updatedAt: true }, }); return rows.map((r) => ({ slug: r.slug, updatedAt: r.updatedAt.toISOString() })); } toPublicProduct(p) { return { code: p.code, slug: p.slug, name: p.name, nameEn: p.nameEn, desc: p.desc, specs: p.specs, variants: p.variants, image: p.image && this.media.url(p.image.key), group: p.group?.slug ?? null, }; } }; PublicService = __decorate([ Injectable(), __metadata("design:paramtypes", [PrismaService, MediaService, SectionsService]) ], PublicService); export { PublicService }; let PublicController = class PublicController { publicData; constructor(publicData) { this.publicData = publicData; } site() { return this.publicData.site(); } categories() { return this.publicData.categories(); } category(slug) { return this.publicData.category(slug); } products() { return this.publicData.productRefs(); } product(slug) { return this.publicData.product(slug); } }; __decorate([ Get("site"), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], PublicController.prototype, "site", null); __decorate([ Get("categories"), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], PublicController.prototype, "categories", null); __decorate([ Get("categories/:slug"), __param(0, Param("slug")), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], PublicController.prototype, "category", null); __decorate([ Get("products"), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], PublicController.prototype, "products", null); __decorate([ Get("products/:slug"), __param(0, Param("slug")), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], PublicController.prototype, "product", null); PublicController = __decorate([ Controller("public"), __metadata("design:paramtypes", [PublicService]) ], PublicController); export { PublicController }; let PublicModule = class PublicModule { }; PublicModule = __decorate([ Module({ imports: [MediaModule, SectionsModule], controllers: [PublicController], providers: [PublicService], }) ], PublicModule); export { PublicModule }; //# sourceMappingURL=public.module.js.map