@hed-hog/catalog 0.0.285 → 0.0.286

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.
@@ -1,167 +1,167 @@
1
- import { getLocaleText } from '@hed-hog/api-locale';
2
- import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
3
- import { PrismaService } from '@hed-hog/api-prisma';
4
- import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
5
- import { CatalogResourceConfig, catalogResourceMap } from './catalog-resource.config';
6
-
7
- @Injectable()
8
- export class CatalogService {
9
- constructor(
10
- private readonly prisma: PrismaService,
11
- private readonly pagination: PaginationService,
12
- ) {}
13
-
14
- private getConfig(resource: string, locale: string): CatalogResourceConfig {
15
- const config = catalogResourceMap.get(resource);
16
-
17
- if (!config) {
18
- throw new BadRequestException(
19
- getLocaleText('resourceNotSupported', locale, 'Catalog resource is not supported'),
20
- );
21
- }
22
-
23
- return config;
24
- }
25
-
26
- private getModel(resource: string, locale: string) {
27
- const config = this.getConfig(resource, locale);
28
- return this.prisma[config.model];
29
- }
30
-
31
- private normalizeValue(value: unknown) {
32
- if (value === 'true') {
33
- return true;
34
- }
35
-
36
- if (value === 'false') {
37
- return false;
38
- }
39
-
40
- if (typeof value === 'string' && /^-?\d+(\.\d+)?$/.test(value)) {
41
- return value.includes('.') ? Number(value) : Number.parseInt(value, 10);
42
- }
43
-
44
- return value;
45
- }
46
-
47
- private sanitizePayload(config: CatalogResourceConfig, body: Record<string, unknown>) {
48
- const payload: Record<string, unknown> = {};
49
-
50
- for (const field of config.fields) {
51
- if (Object.prototype.hasOwnProperty.call(body, field) && body[field] !== undefined) {
52
- payload[field] = body[field];
53
- }
54
- }
55
-
56
- return payload;
57
- }
58
-
59
- private buildWhere(config: CatalogResourceConfig, paginationParams: PaginationDTO, query: Record<string, unknown>) {
60
- const OR = config.searchFields.length
61
- ? this.prisma.createInsensitiveSearch(config.searchFields, paginationParams)
62
- : [];
63
- const AND: Record<string, unknown>[] = [];
64
-
65
- for (const field of config.filterFields ?? []) {
66
- const rawValue = query[field];
67
-
68
- if (rawValue !== undefined && rawValue !== null && rawValue !== '') {
69
- AND.push({
70
- [field]: this.normalizeValue(rawValue),
71
- });
72
- }
73
- }
74
-
75
- return { OR, AND };
76
- }
77
-
78
- async list(resource: string, locale: string, paginationParams: PaginationDTO, query: Record<string, unknown>) {
79
- const config = this.getConfig(resource, locale);
80
- const model = this.getModel(resource, locale);
81
- const where = this.buildWhere(config, paginationParams, query);
82
-
83
- return this.pagination.paginate(
84
- model,
85
- paginationParams,
86
- {
87
- where,
88
- orderBy: config.defaultOrderBy ?? { id: 'desc' },
89
- },
90
- locale,
91
- );
92
- }
93
-
94
- async stats(resource: string, locale: string) {
95
- const config = this.getConfig(resource, locale);
96
- const model = this.getModel(resource, locale);
97
- const total = await model.count({});
98
- const result: Record<string, unknown> = { total };
99
-
100
- if (config.statusField) {
101
- result.active = await model.count({
102
- where: {
103
- [config.statusField]: 'active',
104
- },
105
- });
106
- }
107
-
108
- return result;
109
- }
110
-
111
- async getById(resource: string, id: number, locale: string) {
112
- const model = this.getModel(resource, locale);
113
- const item = await model.findUnique({ where: { id } });
114
-
115
- if (!item) {
116
- throw new NotFoundException(
117
- getLocaleText('resourceNotFound', locale, 'Catalog resource not found'),
118
- );
119
- }
120
-
121
- return item;
122
- }
123
-
124
- async create(resource: string, body: Record<string, unknown>, locale: string) {
125
- const config = this.getConfig(resource, locale);
126
- const model = this.getModel(resource, locale);
127
-
128
- return model.create({
129
- data: this.sanitizePayload(config, body),
130
- });
131
- }
132
-
133
- async update(resource: string, id: number, body: Record<string, unknown>, locale: string) {
134
- await this.getById(resource, id, locale);
135
- const config = this.getConfig(resource, locale);
136
- const model = this.getModel(resource, locale);
137
-
138
- return model.update({
139
- where: { id },
140
- data: this.sanitizePayload(config, body),
141
- });
142
- }
143
-
144
- async delete(resource: string, id: number, locale: string) {
145
- await this.getById(resource, id, locale);
146
- const model = this.getModel(resource, locale);
147
- return model.delete({ where: { id } });
148
- }
149
-
150
- async listProductImages(productId: number, locale: string, paginationParams: PaginationDTO) {
151
- const model = this.getModel('product-images', locale);
152
-
153
- return this.pagination.paginate(
154
- model,
155
- paginationParams,
156
- {
157
- where: {
158
- product_id: productId,
159
- },
160
- orderBy: {
161
- sort_order: 'asc',
162
- },
163
- },
164
- locale,
165
- );
166
- }
167
- }
1
+ import { getLocaleText } from '@hed-hog/api-locale';
2
+ import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
3
+ import { PrismaService } from '@hed-hog/api-prisma';
4
+ import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
5
+ import { CatalogResourceConfig, catalogResourceMap } from './catalog-resource.config';
6
+
7
+ @Injectable()
8
+ export class CatalogService {
9
+ constructor(
10
+ private readonly prisma: PrismaService,
11
+ private readonly pagination: PaginationService,
12
+ ) {}
13
+
14
+ private getConfig(resource: string, locale: string): CatalogResourceConfig {
15
+ const config = catalogResourceMap.get(resource);
16
+
17
+ if (!config) {
18
+ throw new BadRequestException(
19
+ getLocaleText('resourceNotSupported', locale, 'Catalog resource is not supported'),
20
+ );
21
+ }
22
+
23
+ return config;
24
+ }
25
+
26
+ private getModel(resource: string, locale: string) {
27
+ const config = this.getConfig(resource, locale);
28
+ return this.prisma[config.model];
29
+ }
30
+
31
+ private normalizeValue(value: unknown) {
32
+ if (value === 'true') {
33
+ return true;
34
+ }
35
+
36
+ if (value === 'false') {
37
+ return false;
38
+ }
39
+
40
+ if (typeof value === 'string' && /^-?\d+(\.\d+)?$/.test(value)) {
41
+ return value.includes('.') ? Number(value) : Number.parseInt(value, 10);
42
+ }
43
+
44
+ return value;
45
+ }
46
+
47
+ private sanitizePayload(config: CatalogResourceConfig, body: Record<string, unknown>) {
48
+ const payload: Record<string, unknown> = {};
49
+
50
+ for (const field of config.fields) {
51
+ if (Object.prototype.hasOwnProperty.call(body, field) && body[field] !== undefined) {
52
+ payload[field] = body[field];
53
+ }
54
+ }
55
+
56
+ return payload;
57
+ }
58
+
59
+ private buildWhere(config: CatalogResourceConfig, paginationParams: PaginationDTO, query: Record<string, unknown>) {
60
+ const OR = config.searchFields.length
61
+ ? this.prisma.createInsensitiveSearch(config.searchFields, paginationParams)
62
+ : [];
63
+ const AND: Record<string, unknown>[] = [];
64
+
65
+ for (const field of config.filterFields ?? []) {
66
+ const rawValue = query[field];
67
+
68
+ if (rawValue !== undefined && rawValue !== null && rawValue !== '') {
69
+ AND.push({
70
+ [field]: this.normalizeValue(rawValue),
71
+ });
72
+ }
73
+ }
74
+
75
+ return { OR, AND };
76
+ }
77
+
78
+ async list(resource: string, locale: string, paginationParams: PaginationDTO, query: Record<string, unknown>) {
79
+ const config = this.getConfig(resource, locale);
80
+ const model = this.getModel(resource, locale);
81
+ const where = this.buildWhere(config, paginationParams, query);
82
+
83
+ return this.pagination.paginate(
84
+ model,
85
+ paginationParams,
86
+ {
87
+ where,
88
+ orderBy: config.defaultOrderBy ?? { id: 'desc' },
89
+ },
90
+ locale,
91
+ );
92
+ }
93
+
94
+ async stats(resource: string, locale: string) {
95
+ const config = this.getConfig(resource, locale);
96
+ const model = this.getModel(resource, locale);
97
+ const total = await model.count({});
98
+ const result: Record<string, unknown> = { total };
99
+
100
+ if (config.statusField && config.activeStatusValue) {
101
+ result.active = await model.count({
102
+ where: {
103
+ [config.statusField]: config.activeStatusValue,
104
+ },
105
+ });
106
+ }
107
+
108
+ return result;
109
+ }
110
+
111
+ async getById(resource: string, id: number, locale: string) {
112
+ const model = this.getModel(resource, locale);
113
+ const item = await model.findUnique({ where: { id } });
114
+
115
+ if (!item) {
116
+ throw new NotFoundException(
117
+ getLocaleText('resourceNotFound', locale, 'Catalog resource not found'),
118
+ );
119
+ }
120
+
121
+ return item;
122
+ }
123
+
124
+ async create(resource: string, body: Record<string, unknown>, locale: string) {
125
+ const config = this.getConfig(resource, locale);
126
+ const model = this.getModel(resource, locale);
127
+
128
+ return model.create({
129
+ data: this.sanitizePayload(config, body),
130
+ });
131
+ }
132
+
133
+ async update(resource: string, id: number, body: Record<string, unknown>, locale: string) {
134
+ await this.getById(resource, id, locale);
135
+ const config = this.getConfig(resource, locale);
136
+ const model = this.getModel(resource, locale);
137
+
138
+ return model.update({
139
+ where: { id },
140
+ data: this.sanitizePayload(config, body),
141
+ });
142
+ }
143
+
144
+ async delete(resource: string, id: number, locale: string) {
145
+ await this.getById(resource, id, locale);
146
+ const model = this.getModel(resource, locale);
147
+ return model.delete({ where: { id } });
148
+ }
149
+
150
+ async listProductImages(productId: number, locale: string, paginationParams: PaginationDTO) {
151
+ const model = this.getModel('product-images', locale);
152
+
153
+ return this.pagination.paginate(
154
+ model,
155
+ paginationParams,
156
+ {
157
+ where: {
158
+ product_id: productId,
159
+ },
160
+ orderBy: {
161
+ sort_order: 'asc',
162
+ },
163
+ },
164
+ locale,
165
+ );
166
+ }
167
+ }