@unchainedshop/core-assortments 5.0.0-alpha.3 → 5.0.0-alpha.5
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/lib/db/AssortmentsCollection.js +4 -4
- package/lib/module/configureAssortmentFiltersModule.js +2 -2
- package/lib/module/configureAssortmentLinksModule.d.ts +3 -1
- package/lib/module/configureAssortmentLinksModule.js +18 -14
- package/lib/module/configureAssortmentMediaModule.js +2 -2
- package/lib/module/configureAssortmentProductsModule.d.ts +1 -1
- package/lib/module/configureAssortmentProductsModule.js +2 -2
- package/lib/module/configureAssortmentsModule.d.ts +19 -2
- package/lib/module/configureAssortmentsModule.js +73 -41
- package/lib/utils/tree-zipper/zipTreeByDeepness.js +14 -1
- package/package.json +6 -6
|
@@ -37,18 +37,18 @@ export const AssortmentsCollection = async (db) => {
|
|
|
37
37
|
{ index: { locale: 1, assortmentId: 1 } },
|
|
38
38
|
]);
|
|
39
39
|
await buildDbIndexes(AssortmentProducts, [
|
|
40
|
-
{ index: { assortmentId: 1 } },
|
|
40
|
+
{ index: { assortmentId: 1, productId: 1 } },
|
|
41
41
|
{ index: { productId: 1 } },
|
|
42
42
|
{ index: { tags: 1 } },
|
|
43
43
|
{ index: { assortmentId: 1, sortKey: 1 } },
|
|
44
|
-
]);
|
|
44
|
+
], { rebuild: false });
|
|
45
45
|
await buildDbIndexes(AssortmentLinks, [
|
|
46
46
|
{ index: { parentAssortmentId: 1 } },
|
|
47
|
-
{ index: { childAssortmentId: 1 } },
|
|
47
|
+
{ index: { childAssortmentId: 1, sortKey: 1, parentAssortmentId: 1 } },
|
|
48
48
|
{ index: { tags: 1 } },
|
|
49
49
|
{ index: { parentAssortmentId: 1, sortKey: 1 } },
|
|
50
50
|
{ index: { childAssortmentId: 1, parentAssortmentId: 1, sortKey: 1 } },
|
|
51
|
-
]);
|
|
51
|
+
], { rebuild: false });
|
|
52
52
|
await buildDbIndexes(AssortmentFilters, [
|
|
53
53
|
{ index: { assortmentId: 1 } },
|
|
54
54
|
{ index: { filterId: 1 } },
|
|
@@ -18,7 +18,7 @@ export const configureAssortmentFiltersModule = ({ AssortmentFilters, }) => {
|
|
|
18
18
|
},
|
|
19
19
|
findFilterIds: async ({ assortmentId }) => {
|
|
20
20
|
const filters = AssortmentFilters.find({ assortmentId }, {
|
|
21
|
-
sort: { sortKey: 1 },
|
|
21
|
+
sort: { sortKey: 1, _id: 1 },
|
|
22
22
|
projection: { filterId: 1 },
|
|
23
23
|
}).map((filter) => filter.filterId);
|
|
24
24
|
return filters.toArray();
|
|
@@ -41,7 +41,7 @@ export const configureAssortmentFiltersModule = ({ AssortmentFilters, }) => {
|
|
|
41
41
|
created: new Date(),
|
|
42
42
|
};
|
|
43
43
|
if (sortKey === undefined || sortKey === null) {
|
|
44
|
-
const lastAssortmentFilter = (await AssortmentFilters.findOne({ assortmentId }, { sort: { sortKey: -1 } })) || { sortKey: 0 };
|
|
44
|
+
const lastAssortmentFilter = (await AssortmentFilters.findOne({ assortmentId }, { sort: { sortKey: -1, _id: -1 } })) || { sortKey: 0 };
|
|
45
45
|
$setOnInsert.sortKey = lastAssortmentFilter.sortKey + 1;
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
@@ -9,11 +9,13 @@ export declare const configureAssortmentLinksModule: ({ AssortmentLinks, invalid
|
|
|
9
9
|
parentAssortmentId?: string;
|
|
10
10
|
childAssortmentId?: string;
|
|
11
11
|
}) => Promise<mongodb.WithId<AssortmentLink> | null>;
|
|
12
|
-
findLinks: ({ assortmentId, assortmentIds, parentAssortmentId, parentAssortmentIds, }: {
|
|
12
|
+
findLinks: ({ assortmentId, assortmentIds, parentAssortmentId, parentAssortmentIds, childAssortmentId, childAssortmentIds, }: {
|
|
13
13
|
assortmentId?: string;
|
|
14
14
|
assortmentIds?: string[];
|
|
15
15
|
parentAssortmentId?: string;
|
|
16
16
|
parentAssortmentIds?: string[];
|
|
17
|
+
childAssortmentId?: string;
|
|
18
|
+
childAssortmentIds?: string[];
|
|
17
19
|
}, options?: mongodb.FindOptions) => Promise<AssortmentLink[]>;
|
|
18
20
|
create: (doc: Omit<AssortmentLink, "_id" | "created" | "sortKey"> & Pick<Partial<AssortmentLink>, "_id" | "created" | "sortKey">, options?: {
|
|
19
21
|
skipInvalidation?: boolean;
|
|
@@ -15,19 +15,23 @@ export const configureAssortmentLinksModule = ({ AssortmentLinks, invalidateCach
|
|
|
15
15
|
? generateDbFilterById(assortmentLinkId)
|
|
16
16
|
: { parentAssortmentId, childAssortmentId }, {});
|
|
17
17
|
},
|
|
18
|
-
findLinks: async ({ assortmentId, assortmentIds, parentAssortmentId, parentAssortmentIds, }, options) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
};
|
|
18
|
+
findLinks: async ({ assortmentId, assortmentIds, parentAssortmentId, parentAssortmentIds, childAssortmentId, childAssortmentIds, }, options) => {
|
|
19
|
+
const selectors = [];
|
|
20
|
+
const parentIds = parentAssortmentId || (parentAssortmentIds && { $in: parentAssortmentIds });
|
|
21
|
+
const childIds = childAssortmentId || (childAssortmentIds && { $in: childAssortmentIds });
|
|
22
|
+
const bidirectionalIds = assortmentId || (assortmentIds && { $in: assortmentIds });
|
|
23
|
+
if (parentIds)
|
|
24
|
+
selectors.push({ parentAssortmentId: parentIds });
|
|
25
|
+
if (childIds)
|
|
26
|
+
selectors.push({ childAssortmentId: childIds });
|
|
27
|
+
if (bidirectionalIds) {
|
|
28
|
+
selectors.push({ parentAssortmentId: bidirectionalIds }, { childAssortmentId: bidirectionalIds });
|
|
29
|
+
}
|
|
30
|
+
if (!selectors.length)
|
|
31
|
+
return [];
|
|
32
|
+
const selector = selectors.length > 1 ? { $or: selectors } : selectors[0];
|
|
29
33
|
const links = AssortmentLinks.find(selector, options || {
|
|
30
|
-
sort: { sortKey: 1 },
|
|
34
|
+
sort: { sortKey: 1, _id: 1 },
|
|
31
35
|
});
|
|
32
36
|
return links.toArray();
|
|
33
37
|
},
|
|
@@ -37,7 +41,7 @@ export const configureAssortmentLinksModule = ({ AssortmentLinks, invalidateCach
|
|
|
37
41
|
resolveAssortmentLinks: async (id) => {
|
|
38
42
|
return AssortmentLinks.find({ childAssortmentId: id }, {
|
|
39
43
|
projection: { _id: 1, childAssortmentId: 1, parentAssortmentId: 1 },
|
|
40
|
-
sort: { sortKey: 1, parentAssortmentId: 1 },
|
|
44
|
+
sort: { sortKey: 1, parentAssortmentId: 1, _id: 1 },
|
|
41
45
|
}).toArray();
|
|
42
46
|
},
|
|
43
47
|
assortmentId: parentAssortmentId,
|
|
@@ -56,7 +60,7 @@ export const configureAssortmentLinksModule = ({ AssortmentLinks, invalidateCach
|
|
|
56
60
|
created: new Date(),
|
|
57
61
|
};
|
|
58
62
|
if (sortKey === undefined || sortKey === null) {
|
|
59
|
-
const lastAssortmentLink = (await AssortmentLinks.findOne({ parentAssortmentId }, { sort: { sortKey: -1 } })) || { sortKey: 0 };
|
|
63
|
+
const lastAssortmentLink = (await AssortmentLinks.findOne({ parentAssortmentId }, { sort: { sortKey: -1, _id: -1 } })) || { sortKey: 0 };
|
|
60
64
|
$setOnInsert.sortKey = lastAssortmentLink.sortKey + 1;
|
|
61
65
|
}
|
|
62
66
|
else {
|
|
@@ -54,7 +54,7 @@ export const configureAssortmentMediaModule = async ({ db }) => {
|
|
|
54
54
|
const mediaList = AssortmentMedia.find(selector, {
|
|
55
55
|
skip: offset,
|
|
56
56
|
limit,
|
|
57
|
-
sort: { sortKey: 1 },
|
|
57
|
+
sort: { sortKey: 1, _id: 1 },
|
|
58
58
|
...options,
|
|
59
59
|
});
|
|
60
60
|
return mediaList.toArray();
|
|
@@ -64,7 +64,7 @@ export const configureAssortmentMediaModule = async ({ db }) => {
|
|
|
64
64
|
const lastAssortmentMedia = (await AssortmentMedia.findOne({
|
|
65
65
|
assortmentId: doc.assortmentId,
|
|
66
66
|
}, {
|
|
67
|
-
sort: { sortKey: -1 },
|
|
67
|
+
sort: { sortKey: -1, _id: -1 },
|
|
68
68
|
})) || { sortKey: 0 };
|
|
69
69
|
sortKey = lastAssortmentMedia.sortKey + 1;
|
|
70
70
|
}
|
|
@@ -25,7 +25,7 @@ export declare const configureAssortmentProductsModule: ({ AssortmentProducts, i
|
|
|
25
25
|
productId: string;
|
|
26
26
|
assortmentIds: string[];
|
|
27
27
|
}) => Promise<string[]>;
|
|
28
|
-
create: (doc: Omit<AssortmentProduct, "_id" | "created" | "sortKey"> & Partial<Pick<AssortmentProduct, "_id" | "created" | "sortKey">>, options?: {
|
|
28
|
+
create: (doc: Omit<AssortmentProduct, "_id" | "created" | "sortKey" | "tags"> & Partial<Pick<AssortmentProduct, "_id" | "created" | "sortKey" | "tags">>, options?: {
|
|
29
29
|
skipInvalidation?: boolean;
|
|
30
30
|
}) => Promise<mongodb.WithId<AssortmentProduct> | null>;
|
|
31
31
|
delete: (assortmentProductId: string, options?: {
|
|
@@ -46,7 +46,7 @@ export const configureAssortmentProductsModule = ({ AssortmentProducts, invalida
|
|
|
46
46
|
assortmentId: { $in: assortmentIds },
|
|
47
47
|
productId: { $ne: productId },
|
|
48
48
|
}, {
|
|
49
|
-
sort: { sortKey: 1 },
|
|
49
|
+
sort: { sortKey: 1, _id: 1 },
|
|
50
50
|
projection: { productId: 1 },
|
|
51
51
|
}).toArray();
|
|
52
52
|
return assortmentProducts.map((product) => product.productId);
|
|
@@ -69,7 +69,7 @@ export const configureAssortmentProductsModule = ({ AssortmentProducts, invalida
|
|
|
69
69
|
created: new Date(),
|
|
70
70
|
};
|
|
71
71
|
if (sortKey === undefined || sortKey === null) {
|
|
72
|
-
const lastAssortmentProduct = (await AssortmentProducts.findOne({ assortmentId }, { sort: { sortKey: -1 } })) || { sortKey: 0 };
|
|
72
|
+
const lastAssortmentProduct = (await AssortmentProducts.findOne({ assortmentId }, { sort: { sortKey: -1, _id: -1 } })) || { sortKey: 0 };
|
|
73
73
|
$setOnInsert.sortKey = lastAssortmentProduct.sortKey + 1;
|
|
74
74
|
}
|
|
75
75
|
else {
|
|
@@ -52,6 +52,21 @@ export declare const configureAssortmentsModule: (moduleInput: ModuleInput<Assor
|
|
|
52
52
|
skipInvalidation?: boolean;
|
|
53
53
|
}) => Promise<mongodb.WithId<Assortment> | null>;
|
|
54
54
|
invalidateCache: InvalidateCacheFn;
|
|
55
|
+
bulkDelete: (assortmentIds: string[]) => Promise<{
|
|
56
|
+
successIds: string[];
|
|
57
|
+
failedIds: string[];
|
|
58
|
+
}>;
|
|
59
|
+
bulkSetActive: (assortmentIds: string[], isActive: boolean) => Promise<{
|
|
60
|
+
successIds: string[];
|
|
61
|
+
failedIds: string[];
|
|
62
|
+
}>;
|
|
63
|
+
bulkUpdateTags: (assortmentIds: string[], { add, remove }: {
|
|
64
|
+
add?: string[];
|
|
65
|
+
remove?: string[];
|
|
66
|
+
}) => Promise<{
|
|
67
|
+
successIds: string[];
|
|
68
|
+
failedIds: string[];
|
|
69
|
+
}>;
|
|
55
70
|
search: {
|
|
56
71
|
findFilteredAssortments: ({ limit, offset, assortmentIds, assortmentSelector, sort, }: {
|
|
57
72
|
assortmentIds: string[];
|
|
@@ -133,11 +148,13 @@ export declare const configureAssortmentsModule: (moduleInput: ModuleInput<Assor
|
|
|
133
148
|
parentAssortmentId?: string;
|
|
134
149
|
childAssortmentId?: string;
|
|
135
150
|
}) => Promise<mongodb.WithId<AssortmentLink> | null>;
|
|
136
|
-
findLinks: ({ assortmentId, assortmentIds, parentAssortmentId, parentAssortmentIds, }: {
|
|
151
|
+
findLinks: ({ assortmentId, assortmentIds, parentAssortmentId, parentAssortmentIds, childAssortmentId, childAssortmentIds, }: {
|
|
137
152
|
assortmentId?: string;
|
|
138
153
|
assortmentIds?: string[];
|
|
139
154
|
parentAssortmentId?: string;
|
|
140
155
|
parentAssortmentIds?: string[];
|
|
156
|
+
childAssortmentId?: string;
|
|
157
|
+
childAssortmentIds?: string[];
|
|
141
158
|
}, options?: mongodb.FindOptions) => Promise<AssortmentLink[]>;
|
|
142
159
|
create: (doc: Omit<AssortmentLink, "_id" | "created" | "sortKey"> & Pick<Partial<AssortmentLink>, "_id" | "created" | "sortKey">, options?: {
|
|
143
160
|
skipInvalidation?: boolean;
|
|
@@ -182,7 +199,7 @@ export declare const configureAssortmentsModule: (moduleInput: ModuleInput<Assor
|
|
|
182
199
|
productId: string;
|
|
183
200
|
assortmentIds: string[];
|
|
184
201
|
}) => Promise<string[]>;
|
|
185
|
-
create: (doc: Omit<AssortmentProduct, "_id" | "created" | "sortKey"> & Partial<Pick<AssortmentProduct, "_id" | "created" | "sortKey">>, options?: {
|
|
202
|
+
create: (doc: Omit<AssortmentProduct, "_id" | "created" | "sortKey" | "tags"> & Partial<Pick<AssortmentProduct, "_id" | "created" | "sortKey" | "tags">>, options?: {
|
|
186
203
|
skipInvalidation?: boolean;
|
|
187
204
|
}) => Promise<mongodb.WithId<AssortmentProduct> | null>;
|
|
188
205
|
delete: (assortmentProductId: string, options?: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SortDirection } from '@unchainedshop/utils';
|
|
1
|
+
import { executeBulkOperation, SortDirection } from '@unchainedshop/utils';
|
|
2
2
|
import { emit, registerEvents } from '@unchainedshop/events';
|
|
3
3
|
import { generateDbFilterById, findPreservingIds, buildSortOptions, mongodb, generateDbObjectId, } from '@unchainedshop/mongodb';
|
|
4
4
|
import { createLogger } from '@unchainedshop/logger';
|
|
@@ -49,12 +49,12 @@ export const configureAssortmentsModule = async (moduleInput) => {
|
|
|
49
49
|
return AssortmentLinks.find({
|
|
50
50
|
$or: [{ parentAssortmentId: assortment._id }, { childAssortmentId: assortment._id }],
|
|
51
51
|
}, {
|
|
52
|
-
sort: { sortKey: 1 },
|
|
52
|
+
sort: { sortKey: 1, _id: 1 },
|
|
53
53
|
}).toArray();
|
|
54
54
|
};
|
|
55
55
|
const findProductAssignments = async (assortmentId) => {
|
|
56
56
|
return AssortmentProducts.find({ assortmentId }, {
|
|
57
|
-
sort: { sortKey: 1 },
|
|
57
|
+
sort: { sortKey: 1, _id: 1 },
|
|
58
58
|
}).toArray();
|
|
59
59
|
};
|
|
60
60
|
const collectProductIdCacheTree = async (assortment) => {
|
|
@@ -123,6 +123,42 @@ export const configureAssortmentsModule = async (moduleInput) => {
|
|
|
123
123
|
AssortmentTexts,
|
|
124
124
|
});
|
|
125
125
|
const assortmentMedia = await configureAssortmentMediaModule(moduleInput);
|
|
126
|
+
const updateAssortment = async (assortmentId, doc, options) => {
|
|
127
|
+
const assortment = await Assortments.findOneAndUpdate(generateDbFilterById(assortmentId), {
|
|
128
|
+
$set: {
|
|
129
|
+
updated: new Date(),
|
|
130
|
+
...doc,
|
|
131
|
+
},
|
|
132
|
+
}, { returnDocument: 'after' });
|
|
133
|
+
if (!assortment)
|
|
134
|
+
return null;
|
|
135
|
+
await emit('ASSORTMENT_UPDATE', { assortmentId });
|
|
136
|
+
if (!options?.skipInvalidation) {
|
|
137
|
+
await invalidateCache({ assortmentIds: [assortmentId] });
|
|
138
|
+
}
|
|
139
|
+
return assortment;
|
|
140
|
+
};
|
|
141
|
+
const deleteAssortment = async (assortmentId, options) => {
|
|
142
|
+
await assortmentLinks.deleteMany({
|
|
143
|
+
$or: [{ parentAssortmentId: assortmentId }, { childAssortmentId: assortmentId }],
|
|
144
|
+
}, { skipInvalidation: true });
|
|
145
|
+
await assortmentProducts.deleteMany({ assortmentId }, { skipInvalidation: true });
|
|
146
|
+
await assortmentFilters.deleteMany({ assortmentId });
|
|
147
|
+
await assortmentTexts.deleteMany({ assortmentId });
|
|
148
|
+
await assortmentMedia.deleteMediaFiles({ assortmentId });
|
|
149
|
+
const deletedAssortment = await Assortments.findOneAndUpdate(generateDbFilterById(assortmentId), {
|
|
150
|
+
$set: {
|
|
151
|
+
deleted: new Date(),
|
|
152
|
+
},
|
|
153
|
+
}, { returnDocument: 'after' });
|
|
154
|
+
if (!deletedAssortment)
|
|
155
|
+
return null;
|
|
156
|
+
if (!options?.skipInvalidation) {
|
|
157
|
+
await invalidateCache({}, { skipUpstreamTraversal: true });
|
|
158
|
+
}
|
|
159
|
+
await emit('ASSORTMENT_REMOVE', { assortmentId });
|
|
160
|
+
return deletedAssortment;
|
|
161
|
+
};
|
|
126
162
|
return {
|
|
127
163
|
findAssortment: async ({ assortmentId, slug }) => {
|
|
128
164
|
let selector = {};
|
|
@@ -166,7 +202,7 @@ export const configureAssortmentsModule = async (moduleInput) => {
|
|
|
166
202
|
children: async ({ assortmentId, includeInactive, }) => {
|
|
167
203
|
const links = await AssortmentLinks.find({ parentAssortmentId: assortmentId }, {
|
|
168
204
|
projection: { childAssortmentId: 1 },
|
|
169
|
-
sort: { sortKey: 1 },
|
|
205
|
+
sort: { sortKey: 1, _id: 1 },
|
|
170
206
|
}).toArray();
|
|
171
207
|
const assortmentIds = links.map(({ childAssortmentId }) => childAssortmentId);
|
|
172
208
|
const selector = !includeInactive ? { isActive: true } : {};
|
|
@@ -182,12 +218,12 @@ export const configureAssortmentsModule = async (moduleInput) => {
|
|
|
182
218
|
breadcrumbs: async (params, { resolveAssortmentLinks = async (id) => {
|
|
183
219
|
return AssortmentLinks.find({ childAssortmentId: id }, {
|
|
184
220
|
projection: { _id: 1, childAssortmentId: 1, parentAssortmentId: 1 },
|
|
185
|
-
sort: { sortKey: 1, parentAssortmentId: 1 },
|
|
221
|
+
sort: { sortKey: 1, parentAssortmentId: 1, _id: 1 },
|
|
186
222
|
}).toArray();
|
|
187
223
|
}, resolveAssortmentProducts = async (id) => {
|
|
188
224
|
return AssortmentProducts.find({ productId: id }, {
|
|
189
225
|
projection: { _id: true, assortmentId: true, productId: true },
|
|
190
|
-
sort: { sortKey: 1, productId: 1 },
|
|
226
|
+
sort: { sortKey: 1, productId: 1, _id: 1 },
|
|
191
227
|
}).toArray();
|
|
192
228
|
}, }) => {
|
|
193
229
|
const buildBreadcrumbs = makeAssortmentBreadcrumbsBuilder({
|
|
@@ -212,43 +248,39 @@ export const configureAssortmentsModule = async (moduleInput) => {
|
|
|
212
248
|
await emit('ASSORTMENT_CREATE', { assortment });
|
|
213
249
|
return assortment;
|
|
214
250
|
},
|
|
215
|
-
update:
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
},
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
return assortment;
|
|
251
|
+
update: updateAssortment,
|
|
252
|
+
delete: deleteAssortment,
|
|
253
|
+
invalidateCache,
|
|
254
|
+
bulkDelete: async (assortmentIds) => {
|
|
255
|
+
return executeBulkOperation(assortmentIds, async (assortmentId) => {
|
|
256
|
+
const assortment = await Assortments.findOne({ _id: assortmentId, deleted: null }, {});
|
|
257
|
+
if (!assortment)
|
|
258
|
+
throw new Error('not-found');
|
|
259
|
+
if (!(await deleteAssortment(assortmentId))) {
|
|
260
|
+
throw new Error('delete-failed');
|
|
261
|
+
}
|
|
262
|
+
});
|
|
229
263
|
},
|
|
230
|
-
|
|
231
|
-
await
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
await
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return deletedAssortment;
|
|
264
|
+
bulkSetActive: async (assortmentIds, isActive) => executeBulkOperation(assortmentIds, async (assortmentId) => {
|
|
265
|
+
const assortment = await Assortments.findOne({ _id: assortmentId, deleted: null }, {});
|
|
266
|
+
if (!assortment)
|
|
267
|
+
throw new Error('not-found');
|
|
268
|
+
await updateAssortment(assortmentId, { isActive });
|
|
269
|
+
}),
|
|
270
|
+
bulkUpdateTags: async (assortmentIds, { add = [], remove = [] }) => {
|
|
271
|
+
const tagsToRemove = new Set(remove);
|
|
272
|
+
return executeBulkOperation(assortmentIds, async (assortmentId) => {
|
|
273
|
+
const assortment = await Assortments.findOne({ _id: assortmentId, deleted: null }, {});
|
|
274
|
+
if (!assortment)
|
|
275
|
+
throw new Error('not-found');
|
|
276
|
+
const tags = (assortment.tags || []).filter((tag) => !tagsToRemove.has(tag));
|
|
277
|
+
for (const tag of add) {
|
|
278
|
+
if (!tags.includes(tag))
|
|
279
|
+
tags.push(tag);
|
|
280
|
+
}
|
|
281
|
+
await updateAssortment(assortmentId, { tags });
|
|
282
|
+
});
|
|
250
283
|
},
|
|
251
|
-
invalidateCache,
|
|
252
284
|
search: {
|
|
253
285
|
findFilteredAssortments: async ({ limit, offset, assortmentIds, assortmentSelector, sort, }) => {
|
|
254
286
|
const assortments = await findPreservingIds(Assortments)(assortmentSelector, assortmentIds, {
|
|
@@ -59,5 +59,18 @@ export default (tree) => {
|
|
|
59
59
|
const levels = divideTreeByLevels(tree);
|
|
60
60
|
const concattedLevels = concatItemsByLevels(levels);
|
|
61
61
|
const items = shuffleEachLevel(concattedLevels);
|
|
62
|
-
|
|
62
|
+
const result = [];
|
|
63
|
+
const stack = [...items].reverse();
|
|
64
|
+
while (stack.length > 0) {
|
|
65
|
+
const value = stack.pop();
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
for (let i = value.length - 1; i >= 0; i--) {
|
|
68
|
+
stack.push(value[i]);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if (value) {
|
|
72
|
+
result.push(value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
63
76
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/core-assortments",
|
|
3
3
|
"description": "Assortment and category management module for the Unchained Engine",
|
|
4
|
-
"version": "5.0.0-alpha.
|
|
4
|
+
"version": "5.0.0-alpha.5",
|
|
5
5
|
"main": "lib/assortments-index.js",
|
|
6
6
|
"types": "lib/assortments-index.d.ts",
|
|
7
7
|
"type": "module",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@unchainedshop/events": "^5.0.0-alpha.
|
|
39
|
-
"@unchainedshop/logger": "^5.0.0-alpha.
|
|
40
|
-
"@unchainedshop/mongodb": "^5.0.0-alpha.
|
|
41
|
-
"@unchainedshop/utils": "^5.0.0-alpha.
|
|
38
|
+
"@unchainedshop/events": "^5.0.0-alpha.5",
|
|
39
|
+
"@unchainedshop/logger": "^5.0.0-alpha.5",
|
|
40
|
+
"@unchainedshop/mongodb": "^5.0.0-alpha.5",
|
|
41
|
+
"@unchainedshop/utils": "^5.0.0-alpha.5"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^26.2.0",
|
|
45
|
-
"typescript": "^
|
|
45
|
+
"typescript": "^6.0.3"
|
|
46
46
|
}
|
|
47
47
|
}
|