@unchainedshop/api 3.0.0-rc9 → 3.0.0
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/api-index.d.ts +3 -2
- package/lib/api-index.d.ts.map +1 -1
- package/lib/api-index.js +3 -2
- package/lib/api-index.js.map +1 -1
- package/lib/context.d.ts +16 -21
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js +2 -2
- package/lib/context.js.map +1 -1
- package/lib/errors.d.ts +1 -0
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +1 -0
- package/lib/errors.js.map +1 -1
- package/lib/express/createBulkImportMiddleware.d.ts.map +1 -1
- package/lib/express/createBulkImportMiddleware.js +3 -3
- package/lib/express/createBulkImportMiddleware.js.map +1 -1
- package/lib/express/createERCMetadataMiddleware.d.ts.map +1 -1
- package/lib/express/createERCMetadataMiddleware.js +9 -8
- package/lib/express/createERCMetadataMiddleware.js.map +1 -1
- package/lib/express/index.d.ts +2 -0
- package/lib/express/index.d.ts.map +1 -1
- package/lib/express/index.js +11 -2
- package/lib/express/index.js.map +1 -1
- package/lib/fastify/ercMetadataHandler.d.ts.map +1 -1
- package/lib/fastify/ercMetadataHandler.js +2 -1
- package/lib/fastify/ercMetadataHandler.js.map +1 -1
- package/lib/fastify/index.d.ts +4 -1
- package/lib/fastify/index.d.ts.map +1 -1
- package/lib/fastify/index.js +47 -15
- package/lib/fastify/index.js.map +1 -1
- package/lib/loaders/index.d.ts +103 -59
- package/lib/loaders/index.d.ts.map +1 -1
- package/lib/loaders/index.js +173 -111
- package/lib/loaders/index.js.map +1 -1
- package/lib/locale-context.d.ts +1 -6
- package/lib/locale-context.d.ts.map +1 -1
- package/lib/locale-context.js +2 -4
- package/lib/locale-context.js.map +1 -1
- package/lib/resolvers/mutations/accounts/createUser.js +1 -1
- package/lib/resolvers/mutations/accounts/createUser.js.map +1 -1
- package/lib/resolvers/mutations/accounts/impersonate.d.ts +9 -0
- package/lib/resolvers/mutations/accounts/impersonate.d.ts.map +1 -0
- package/lib/resolvers/mutations/accounts/impersonate.js +17 -0
- package/lib/resolvers/mutations/accounts/impersonate.js.map +1 -0
- package/lib/resolvers/mutations/accounts/loginAsGuest.js +1 -1
- package/lib/resolvers/mutations/accounts/loginAsGuest.js.map +1 -1
- package/lib/resolvers/mutations/accounts/loginWithPassword.js +1 -1
- package/lib/resolvers/mutations/accounts/loginWithPassword.js.map +1 -1
- package/lib/resolvers/mutations/accounts/loginWithWebAuthn.js +1 -1
- package/lib/resolvers/mutations/accounts/loginWithWebAuthn.js.map +1 -1
- package/lib/resolvers/mutations/accounts/resetPassword.js +1 -1
- package/lib/resolvers/mutations/accounts/resetPassword.js.map +1 -1
- package/lib/resolvers/mutations/accounts/stopImpersonation.d.ts +6 -0
- package/lib/resolvers/mutations/accounts/stopImpersonation.d.ts.map +1 -0
- package/lib/resolvers/mutations/accounts/stopImpersonation.js +14 -0
- package/lib/resolvers/mutations/accounts/stopImpersonation.js.map +1 -0
- package/lib/resolvers/mutations/accounts/verifyEmail.js +1 -1
- package/lib/resolvers/mutations/accounts/verifyEmail.js.map +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortmentProduct.js +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortmentProduct.js.map +1 -1
- package/lib/resolvers/mutations/index.d.ts +2 -0
- package/lib/resolvers/mutations/index.d.ts.map +1 -1
- package/lib/resolvers/mutations/index.js +5 -1
- package/lib/resolvers/mutations/index.js.map +1 -1
- package/lib/resolvers/mutations/products/removeProductReviewVote.d.ts +1 -1
- package/lib/resolvers/mutations/products/removeProductReviewVote.d.ts.map +1 -1
- package/lib/resolvers/mutations/users/addPushSubscription.d.ts.map +1 -1
- package/lib/resolvers/mutations/users/addPushSubscription.js +2 -1
- package/lib/resolvers/mutations/users/addPushSubscription.js.map +1 -1
- package/lib/resolvers/mutations/users/heartbeat.d.ts +1 -1
- package/lib/resolvers/mutations/users/heartbeat.d.ts.map +1 -1
- package/lib/resolvers/mutations/users/heartbeat.js +2 -2
- package/lib/resolvers/mutations/users/heartbeat.js.map +1 -1
- package/lib/resolvers/mutations/users/removePushSubscription.d.ts.map +1 -1
- package/lib/resolvers/mutations/users/removePushSubscription.js +2 -1
- package/lib/resolvers/mutations/users/removePushSubscription.js.map +1 -1
- package/lib/resolvers/queries/index.d.ts +3 -0
- package/lib/resolvers/queries/index.d.ts.map +1 -1
- package/lib/resolvers/queries/index.js +4 -0
- package/lib/resolvers/queries/index.js.map +1 -1
- package/lib/resolvers/queries/users/impersonator.d.ts +3 -0
- package/lib/resolvers/queries/users/impersonator.d.ts.map +1 -0
- package/lib/resolvers/queries/users/impersonator.js +8 -0
- package/lib/resolvers/queries/users/impersonator.js.map +1 -0
- package/lib/resolvers/queries/warehousing/tokens.d.ts +2 -1
- package/lib/resolvers/queries/warehousing/tokens.d.ts.map +1 -1
- package/lib/resolvers/queries/warehousing/tokens.js +2 -2
- package/lib/resolvers/queries/warehousing/tokens.js.map +1 -1
- package/lib/resolvers/queries/warehousing/tokensCount.d.ts +5 -0
- package/lib/resolvers/queries/warehousing/tokensCount.d.ts.map +1 -0
- package/lib/resolvers/queries/warehousing/tokensCount.js +6 -0
- package/lib/resolvers/queries/warehousing/tokensCount.js.map +1 -0
- package/lib/resolvers/type/assortment/assortment-path-link-types.d.ts +7 -9
- package/lib/resolvers/type/assortment/assortment-path-link-types.d.ts.map +1 -1
- package/lib/resolvers/type/assortment/assortment-path-link-types.js +9 -7
- package/lib/resolvers/type/assortment/assortment-path-link-types.js.map +1 -1
- package/lib/resolvers/type/assortment/assortment-types.d.ts +1 -1
- package/lib/resolvers/type/assortment/assortment-types.d.ts.map +1 -1
- package/lib/resolvers/type/assortment/assortment-types.js +9 -2
- package/lib/resolvers/type/assortment/assortment-types.js.map +1 -1
- package/lib/resolvers/type/index.d.ts +14 -8
- package/lib/resolvers/type/index.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-bundle-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-bundle-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-configurable-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-configurable-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-plan-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-plan-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-simple-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-simple-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-tokenized-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-tokenized-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-types.js +9 -2
- package/lib/resolvers/type/product/product-types.js.map +1 -1
- package/lib/resolvers/type/product/product-variation-assignment-vector.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-variation-assignment-vector.js +4 -1
- package/lib/resolvers/type/product/product-variation-assignment-vector.js.map +1 -1
- package/lib/resolvers/type/product/product-variation-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-variation-types.js +5 -2
- package/lib/resolvers/type/product/product-variation-types.js.map +1 -1
- package/lib/roles/all.d.ts.map +1 -1
- package/lib/roles/all.js +2 -0
- package/lib/roles/all.js.map +1 -1
- package/lib/roles/index.d.ts.map +1 -1
- package/lib/roles/index.js +2 -0
- package/lib/roles/index.js.map +1 -1
- package/lib/schema/mutation.d.ts.map +1 -1
- package/lib/schema/mutation.js +10 -0
- package/lib/schema/mutation.js.map +1 -1
- package/lib/schema/query.d.ts.map +1 -1
- package/lib/schema/query.js +11 -1
- package/lib/schema/query.js.map +1 -1
- package/lib/schema/types/user.js +1 -1
- package/package.json +20 -20
- package/src/api-index.ts +5 -4
- package/src/context.ts +31 -17
- package/src/errors.ts +5 -0
- package/src/express/createBulkImportMiddleware.ts +3 -3
- package/src/express/createERCMetadataMiddleware.ts +10 -8
- package/src/express/index.ts +29 -13
- package/src/fastify/ercMetadataHandler.ts +3 -1
- package/src/fastify/index.ts +67 -23
- package/src/loaders/index.ts +273 -228
- package/src/locale-context.ts +1 -10
- package/src/resolvers/mutations/accounts/createUser.ts +1 -1
- package/src/resolvers/mutations/accounts/impersonate.ts +23 -0
- package/src/resolvers/mutations/accounts/loginAsGuest.ts +1 -1
- package/src/resolvers/mutations/accounts/loginWithPassword.ts +1 -1
- package/src/resolvers/mutations/accounts/loginWithWebAuthn.ts +1 -1
- package/src/resolvers/mutations/accounts/resetPassword.ts +1 -1
- package/src/resolvers/mutations/accounts/stopImpersonation.ts +19 -0
- package/src/resolvers/mutations/accounts/verifyEmail.ts +1 -1
- package/src/resolvers/mutations/assortments/removeAssortmentProduct.ts +1 -1
- package/src/resolvers/mutations/index.ts +6 -1
- package/src/resolvers/mutations/users/addPushSubscription.ts +2 -1
- package/src/resolvers/mutations/users/heartbeat.ts +2 -2
- package/src/resolvers/mutations/users/removePushSubscription.ts +3 -1
- package/src/resolvers/queries/index.ts +4 -0
- package/src/resolvers/queries/users/impersonator.ts +13 -0
- package/src/resolvers/queries/warehousing/tokens.ts +3 -1
- package/src/resolvers/queries/warehousing/tokensCount.ts +12 -0
- package/src/resolvers/type/assortment/assortment-path-link-types.ts +14 -19
- package/src/resolvers/type/assortment/assortment-types.ts +17 -5
- package/src/resolvers/type/product/product-types.ts +17 -5
- package/src/resolvers/type/product/product-variation-assignment-vector.ts +4 -1
- package/src/resolvers/type/product/product-variation-types.ts +5 -2
- package/src/roles/all.ts +2 -0
- package/src/roles/index.ts +2 -0
- package/src/schema/mutation.ts +10 -0
- package/src/schema/query.ts +11 -1
- package/src/schema/types/user.ts +1 -1
package/src/loaders/index.ts
CHANGED
|
@@ -12,75 +12,22 @@ import {
|
|
|
12
12
|
AssortmentMediaText,
|
|
13
13
|
} from '@unchainedshop/core-assortments';
|
|
14
14
|
import { File } from '@unchainedshop/core-files';
|
|
15
|
-
export interface UnchainedLoaders {
|
|
16
|
-
loaders: {
|
|
17
|
-
productLoader: InstanceType<typeof DataLoader<{ productId: string }, Product>>;
|
|
18
|
-
productLoaderBySKU: InstanceType<typeof DataLoader<{ sku: string }, Product>>;
|
|
19
|
-
productTextLoader: InstanceType<
|
|
20
|
-
typeof DataLoader<{ productId: string; locale: string }, ProductText>
|
|
21
|
-
>;
|
|
22
|
-
productMediaTextLoader: InstanceType<
|
|
23
|
-
typeof DataLoader<{ productMediaId: string; locale: string }, ProductMediaText>
|
|
24
|
-
>;
|
|
25
|
-
|
|
26
|
-
fileLoader: InstanceType<typeof DataLoader<{ fileId: string }, File>>;
|
|
27
|
-
|
|
28
|
-
filterLoader: InstanceType<typeof DataLoader<{ filterId: string }, Filter>>;
|
|
29
|
-
filterTextLoader: InstanceType<
|
|
30
|
-
typeof DataLoader<{ filterId: string; filterOptionValue?: string; locale: string }, FilterText>
|
|
31
|
-
>;
|
|
32
|
-
|
|
33
|
-
assortmentLoader: InstanceType<typeof DataLoader<{ assortmentId: string }, Assortment>>;
|
|
34
|
-
assortmentTextLoader: InstanceType<
|
|
35
|
-
typeof DataLoader<{ assortmentId: string; locale: string }, AssortmentText>
|
|
36
|
-
>;
|
|
37
|
-
assortmentLinkLoader: InstanceType<
|
|
38
|
-
typeof DataLoader<{ parentAssortmentId: string; childAssortmentId: string }, AssortmentLink>
|
|
39
|
-
>;
|
|
40
|
-
assortmentLinksLoader: InstanceType<
|
|
41
|
-
typeof DataLoader<{ parentAssortmentId?: string; assortmentId?: string }, AssortmentLink[]>
|
|
42
|
-
>;
|
|
43
|
-
assortmentProductLoader: InstanceType<
|
|
44
|
-
typeof DataLoader<{ assortmentId: string; productId: string }, AssortmentProduct>
|
|
45
|
-
>;
|
|
46
|
-
assortmentMediaTextLoader: InstanceType<
|
|
47
|
-
typeof DataLoader<{ assortmentMediaId: string; locale: string }, AssortmentMediaText>
|
|
48
|
-
>;
|
|
49
|
-
|
|
50
|
-
productMediasLoader: InstanceType<typeof DataLoader<{ productId?: string }, ProductMedia[]>>;
|
|
51
|
-
assortmentMediasLoader: InstanceType<
|
|
52
|
-
typeof DataLoader<{ assortmentId?: string }, AssortmentMediaType[]>
|
|
53
|
-
>;
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function getLocaleStrings(localeObj: Intl.Locale) {
|
|
58
|
-
return [localeObj.baseName, localeObj.language, systemLocale.baseName, systemLocale.language];
|
|
59
|
-
}
|
|
60
15
|
|
|
61
|
-
function
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
16
|
+
function getLocaleStrings(locale: string) {
|
|
17
|
+
const localeObj = new Intl.Locale(locale);
|
|
18
|
+
return [
|
|
19
|
+
...new Set([
|
|
20
|
+
localeObj.baseName.toLowerCase(),
|
|
21
|
+
localeObj.language.toLowerCase(),
|
|
22
|
+
systemLocale.baseName.toLowerCase(),
|
|
23
|
+
systemLocale.language.toLowerCase(),
|
|
24
|
+
]),
|
|
25
|
+
];
|
|
66
26
|
}
|
|
67
27
|
|
|
68
|
-
|
|
69
|
-
return queries.map(({ locale, ...queryParams }) => {
|
|
70
|
-
const localeObj = new Intl.Locale(locale);
|
|
71
|
-
|
|
72
|
-
const filteredTexts = texts.filter(filterFn(queryParams));
|
|
73
|
-
if (!filteredTexts.length) return null;
|
|
74
|
-
|
|
75
|
-
const localeStrings = getLocaleStrings(localeObj);
|
|
76
|
-
const filterText = findMatchingText(filteredTexts, localeStrings);
|
|
77
|
-
return filterText || filteredTexts[0];
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['loaders']> => {
|
|
28
|
+
const loaders = async (unchainedAPI: UnchainedCore) => {
|
|
82
29
|
return {
|
|
83
|
-
assortmentLoader: new DataLoader(async (queries) => {
|
|
30
|
+
assortmentLoader: new DataLoader<{ assortmentId: string }, Assortment>(async (queries) => {
|
|
84
31
|
const assortmentIds = [...new Set(queries.map((q) => q.assortmentId).filter(Boolean))];
|
|
85
32
|
|
|
86
33
|
const assortments = await unchainedAPI.modules.assortments.findAssortments({
|
|
@@ -89,35 +36,45 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
|
|
|
89
36
|
includeLeaves: true,
|
|
90
37
|
});
|
|
91
38
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
39
|
+
const assortmentMap = {};
|
|
40
|
+
for (const assortment of assortments) {
|
|
41
|
+
assortmentMap[assortment._id] = assortment;
|
|
42
|
+
}
|
|
43
|
+
return queries.map((q) => assortmentMap[q.assortmentId]);
|
|
98
44
|
}),
|
|
99
45
|
|
|
100
|
-
assortmentTextLoader: new DataLoader
|
|
101
|
-
|
|
46
|
+
assortmentTextLoader: new DataLoader<{ assortmentId: string; locale: string }, AssortmentText>(
|
|
47
|
+
async (queries) => {
|
|
48
|
+
const assortmentIds = [...new Set(queries.map((q) => q.assortmentId).filter(Boolean))];
|
|
102
49
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
50
|
+
const texts = await unchainedAPI.modules.assortments.texts.findTexts(
|
|
51
|
+
{ assortmentId: { $in: assortmentIds } },
|
|
52
|
+
{
|
|
53
|
+
sort: {
|
|
54
|
+
assortmentId: 1,
|
|
55
|
+
},
|
|
108
56
|
},
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
|
|
60
|
+
const textsMap = {};
|
|
61
|
+
const localeMap = Object.fromEntries(
|
|
62
|
+
queryLocales.flatMap((queryLocale) => {
|
|
63
|
+
return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
for (const text of texts) {
|
|
67
|
+
const locale = localeMap[text.locale.toLowerCase()];
|
|
68
|
+
textsMap[locale + text.assortmentId] = text;
|
|
69
|
+
}
|
|
70
|
+
return queries.map((q) => textsMap[q.locale.toLowerCase() + q.assortmentId]);
|
|
71
|
+
},
|
|
72
|
+
),
|
|
73
|
+
|
|
74
|
+
assortmentMediaTextLoader: new DataLoader<
|
|
75
|
+
{ assortmentMediaId: string; locale: string },
|
|
76
|
+
AssortmentMediaText
|
|
77
|
+
>(async (queries) => {
|
|
121
78
|
const assortmentMediaIds = [...new Set(queries.map((q) => q.assortmentMediaId).filter(Boolean))];
|
|
122
79
|
|
|
123
80
|
const texts = await unchainedAPI.modules.assortments.media.texts.findMediaTexts(
|
|
@@ -129,93 +86,150 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
|
|
|
129
86
|
},
|
|
130
87
|
);
|
|
131
88
|
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
89
|
+
const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
|
|
90
|
+
const textsMap = {};
|
|
91
|
+
const localeMap = Object.fromEntries(
|
|
92
|
+
queryLocales.flatMap((queryLocale) => {
|
|
93
|
+
return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
for (const text of texts) {
|
|
97
|
+
const locale = localeMap[text.locale.toLowerCase()];
|
|
98
|
+
textsMap[locale + text.assortmentMediaId] = text;
|
|
99
|
+
}
|
|
100
|
+
return queries.map((q) => textsMap[q.locale.toLowerCase() + q.assortmentMediaId]);
|
|
138
101
|
}),
|
|
139
102
|
|
|
140
|
-
assortmentMediasLoader: new DataLoader
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return queries.map((q) => {
|
|
147
|
-
return assortmentMediaItems.filter((i) => {
|
|
148
|
-
return i.assortmentId === q.assortmentId;
|
|
103
|
+
assortmentMediasLoader: new DataLoader<{ assortmentId?: string }, AssortmentMediaType[]>(
|
|
104
|
+
async (queries) => {
|
|
105
|
+
const assortmentIds = [...new Set(queries.map((q) => q.assortmentId).filter(Boolean))];
|
|
106
|
+
const assortmentMediaItems = await unchainedAPI.modules.assortments.media.findAssortmentMedias({
|
|
107
|
+
assortmentId: { $in: assortmentIds },
|
|
149
108
|
});
|
|
150
|
-
});
|
|
151
|
-
}),
|
|
152
109
|
|
|
153
|
-
|
|
110
|
+
const assortmentMediaMap = {};
|
|
111
|
+
for (const assortmentMedia of assortmentMediaItems) {
|
|
112
|
+
if (!assortmentMediaMap[assortmentMedia.assortmentId]) {
|
|
113
|
+
assortmentMediaMap[assortmentMedia.assortmentId] = [assortmentMedia];
|
|
114
|
+
} else {
|
|
115
|
+
assortmentMediaMap[assortmentMedia.assortmentId].push(assortmentMedia);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return queries.map((q) => assortmentMediaMap[q.assortmentId] || []);
|
|
119
|
+
},
|
|
120
|
+
),
|
|
121
|
+
|
|
122
|
+
assortmentLinkLoader: new DataLoader<
|
|
123
|
+
{ parentAssortmentId: string; childAssortmentId: string },
|
|
124
|
+
AssortmentLink
|
|
125
|
+
>(async (queries) => {
|
|
154
126
|
const parentAssortmentIds = [...new Set(queries.map((q) => q.parentAssortmentId).filter(Boolean))];
|
|
155
127
|
|
|
156
128
|
const links = await unchainedAPI.modules.assortments.links.findLinks({
|
|
157
129
|
parentAssortmentIds,
|
|
158
130
|
});
|
|
159
131
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
132
|
+
const assortmentLinkMap = {};
|
|
133
|
+
for (const link of links) {
|
|
134
|
+
if (!assortmentLinkMap[link.parentAssortmentId]) {
|
|
135
|
+
assortmentLinkMap[link.parentAssortmentId] = [link];
|
|
136
|
+
} else {
|
|
137
|
+
assortmentLinkMap[link.parentAssortmentId].push(link);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return queries.map((q) => {
|
|
142
|
+
if (q.childAssortmentId) {
|
|
143
|
+
return assortmentLinkMap[q.parentAssortmentId].find(
|
|
144
|
+
(link) => link.childAssortmentId === q.childAssortmentId,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return assortmentLinkMap[q.parentAssortmentId][0];
|
|
166
148
|
});
|
|
167
149
|
}),
|
|
168
150
|
|
|
169
|
-
assortmentLinksLoader: new DataLoader
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
(link) => link.parentAssortmentId === parentAssortmentId,
|
|
190
|
-
);
|
|
151
|
+
assortmentLinksLoader: new DataLoader<
|
|
152
|
+
{ parentAssortmentId?: string; childAssortmentId?: string; assortmentId?: string },
|
|
153
|
+
AssortmentLink[]
|
|
154
|
+
>(async (queries) => {
|
|
155
|
+
const parentAssortmentIds = queries.flatMap((q) => q.parentAssortmentId).filter(Boolean);
|
|
156
|
+
const childAssortmentIds = queries.flatMap((q) => q.childAssortmentId).filter(Boolean);
|
|
157
|
+
const assortmentIds = queries.flatMap((q) => q.assortmentId).filter(Boolean);
|
|
158
|
+
|
|
159
|
+
const allLinks = await unchainedAPI.modules.assortments.links.findLinks({
|
|
160
|
+
assortmentIds: [...new Set([...parentAssortmentIds, ...childAssortmentIds, ...assortmentIds])],
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const parentAssortmentLinkMap = {};
|
|
164
|
+
const childAssortmentLinkMap = {};
|
|
165
|
+
|
|
166
|
+
for (const link of allLinks) {
|
|
167
|
+
if (!parentAssortmentLinkMap[link.parentAssortmentId]) {
|
|
168
|
+
parentAssortmentLinkMap[link.parentAssortmentId] = [link];
|
|
169
|
+
} else {
|
|
170
|
+
parentAssortmentLinkMap[link.parentAssortmentId].push(link);
|
|
191
171
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
);
|
|
172
|
+
|
|
173
|
+
if (!childAssortmentLinkMap[link.childAssortmentId]) {
|
|
174
|
+
childAssortmentLinkMap[link.childAssortmentId] = [link];
|
|
175
|
+
} else {
|
|
176
|
+
childAssortmentLinkMap[link.childAssortmentId].push(link);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return queries.map((q) => {
|
|
181
|
+
if (q.parentAssortmentId) {
|
|
182
|
+
return parentAssortmentLinkMap[q.parentAssortmentId] || [];
|
|
183
|
+
} else if (q.childAssortmentId) {
|
|
184
|
+
return childAssortmentLinkMap[q.childAssortmentId] || [];
|
|
197
185
|
}
|
|
198
|
-
return [
|
|
186
|
+
return [
|
|
187
|
+
...(parentAssortmentLinkMap[q.assortmentId] || []),
|
|
188
|
+
...(childAssortmentLinkMap[q.assortmentId] || []),
|
|
189
|
+
];
|
|
199
190
|
});
|
|
200
191
|
}),
|
|
201
192
|
|
|
202
|
-
assortmentProductLoader: new DataLoader
|
|
193
|
+
assortmentProductLoader: new DataLoader<
|
|
194
|
+
{ assortmentId: string; productId: string },
|
|
195
|
+
AssortmentProduct
|
|
196
|
+
>(async (queries) => {
|
|
203
197
|
const assortmentIds = [...new Set(queries.map((q) => q.assortmentId).filter(Boolean))];
|
|
204
198
|
|
|
205
|
-
const assortmentProducts = await unchainedAPI.modules.assortments.products.
|
|
199
|
+
const assortmentProducts = await unchainedAPI.modules.assortments.products.findAssortmentProducts({
|
|
206
200
|
assortmentIds,
|
|
207
201
|
});
|
|
208
202
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
});
|
|
203
|
+
const assortmentProductMap = {};
|
|
204
|
+
for (const assortmentProduct of assortmentProducts) {
|
|
205
|
+
assortmentProductMap[assortmentProduct.assortmentId + assortmentProduct.productId] =
|
|
206
|
+
assortmentProduct;
|
|
207
|
+
}
|
|
208
|
+
return queries.map((q) => assortmentProductMap[q.assortmentId + q.productId]);
|
|
216
209
|
}),
|
|
217
210
|
|
|
218
|
-
|
|
211
|
+
assortmentProductsLoader: new DataLoader<{ productId: string }, AssortmentProduct[]>(
|
|
212
|
+
async (queries) => {
|
|
213
|
+
const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))];
|
|
214
|
+
|
|
215
|
+
const assortmentProducts =
|
|
216
|
+
await unchainedAPI.modules.assortments.products.findAssortmentProducts({
|
|
217
|
+
productIds,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const assortmentProductsMap = {};
|
|
221
|
+
for (const assortmentProduct of assortmentProducts) {
|
|
222
|
+
if (!assortmentProductsMap[assortmentProduct.productId]) {
|
|
223
|
+
assortmentProductsMap[assortmentProduct.productId] = [assortmentProduct];
|
|
224
|
+
} else {
|
|
225
|
+
assortmentProductsMap[assortmentProduct.productId].push(assortmentProduct);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return queries.map((q) => assortmentProductsMap[q.productId] || []);
|
|
229
|
+
},
|
|
230
|
+
),
|
|
231
|
+
|
|
232
|
+
filterLoader: new DataLoader<{ filterId: string }, Filter>(async (queries) => {
|
|
219
233
|
const filterIds = [...new Set(queries.map((q) => q.filterId).filter(Boolean))];
|
|
220
234
|
|
|
221
235
|
const filters = await unchainedAPI.modules.filters.findFilters({
|
|
@@ -223,15 +237,18 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
|
|
|
223
237
|
includeInactive: true,
|
|
224
238
|
});
|
|
225
239
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
240
|
+
const filterMap = {};
|
|
241
|
+
for (const filter of filters) {
|
|
242
|
+
filterMap[filter._id] = filter;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return queries.map((q) => filterMap[q.filterId]);
|
|
232
246
|
}),
|
|
233
247
|
|
|
234
|
-
filterTextLoader: new DataLoader
|
|
248
|
+
filterTextLoader: new DataLoader<
|
|
249
|
+
{ filterId: string; filterOptionValue?: string; locale: string },
|
|
250
|
+
FilterText
|
|
251
|
+
>(async (queries) => {
|
|
235
252
|
const filterIds = [...new Set(queries.map((q) => q.filterId).filter(Boolean))];
|
|
236
253
|
|
|
237
254
|
const texts = await unchainedAPI.modules.filters.texts.findTexts(
|
|
@@ -243,14 +260,21 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
|
|
|
243
260
|
},
|
|
244
261
|
);
|
|
245
262
|
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
263
|
+
const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
|
|
264
|
+
const textsMap = {};
|
|
265
|
+
const localeMap = Object.fromEntries(
|
|
266
|
+
queryLocales.flatMap((queryLocale) => {
|
|
267
|
+
return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
|
|
268
|
+
}),
|
|
269
|
+
);
|
|
270
|
+
for (const text of texts) {
|
|
271
|
+
const locale = localeMap[text.locale.toLowerCase()];
|
|
272
|
+
textsMap[locale + text.filterId + text.filterOptionValue] = text;
|
|
273
|
+
}
|
|
274
|
+
return queries.map((q) => textsMap[q.locale.toLowerCase() + q.filterId + q.filterOptionValue]);
|
|
251
275
|
}),
|
|
252
276
|
|
|
253
|
-
productLoader: new DataLoader(async (queries) => {
|
|
277
|
+
productLoader: new DataLoader<{ productId: string }, Product>(async (queries) => {
|
|
254
278
|
const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))]; // you don't need lodash, _.unique my ass
|
|
255
279
|
|
|
256
280
|
const products = await unchainedAPI.modules.products.findProducts({
|
|
@@ -260,15 +284,15 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
|
|
|
260
284
|
},
|
|
261
285
|
});
|
|
262
286
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
287
|
+
const productMap = {};
|
|
288
|
+
for (const product of products) {
|
|
289
|
+
productMap[product._id] = product;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return queries.map((q) => productMap[q.productId]);
|
|
269
293
|
}),
|
|
270
294
|
|
|
271
|
-
productLoaderBySKU: new DataLoader(async (queries) => {
|
|
295
|
+
productLoaderBySKU: new DataLoader<{ sku: string }, Product>(async (queries) => {
|
|
272
296
|
const skus = [...new Set(queries.map((q) => q.sku).filter(Boolean))]; // you don't need lodash, _.unique my ass
|
|
273
297
|
|
|
274
298
|
const products = await unchainedAPI.modules.products.findProducts({
|
|
@@ -278,81 +302,102 @@ const loaders = async (unchainedAPI: UnchainedCore): Promise<UnchainedLoaders['l
|
|
|
278
302
|
},
|
|
279
303
|
});
|
|
280
304
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
}),
|
|
288
|
-
|
|
289
|
-
productTextLoader: new DataLoader(async (queries) => {
|
|
290
|
-
const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))];
|
|
291
|
-
|
|
292
|
-
const texts = await unchainedAPI.modules.products.texts.findTexts(
|
|
293
|
-
{ productId: { $in: productIds } },
|
|
294
|
-
{
|
|
295
|
-
sort: {
|
|
296
|
-
productId: 1,
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
);
|
|
300
|
-
|
|
301
|
-
const filterFn =
|
|
302
|
-
({ productId }) =>
|
|
303
|
-
(text) =>
|
|
304
|
-
text.productId === productId;
|
|
305
|
+
const productMap = {};
|
|
306
|
+
for (const product of products) {
|
|
307
|
+
productMap[product.warehousing!.sku!] = product;
|
|
308
|
+
}
|
|
305
309
|
|
|
306
|
-
return
|
|
310
|
+
return queries.map((q) => productMap[q.sku]);
|
|
307
311
|
}),
|
|
308
312
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
313
|
+
productTextLoader: new DataLoader<{ productId: string; locale: string }, ProductText>(
|
|
314
|
+
async (queries) => {
|
|
315
|
+
const productIds = [...new Set(queries.map((q) => q.productId))].filter(Boolean);
|
|
316
|
+
const texts = await unchainedAPI.modules.products.texts.findTexts(
|
|
317
|
+
{ productId: { $in: productIds } },
|
|
318
|
+
{
|
|
319
|
+
sort: {
|
|
320
|
+
productId: 1,
|
|
321
|
+
},
|
|
317
322
|
},
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
323
|
+
);
|
|
324
|
+
const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
|
|
325
|
+
const textsMap = {};
|
|
326
|
+
const localeMap = Object.fromEntries(
|
|
327
|
+
queryLocales.flatMap((queryLocale) => {
|
|
328
|
+
return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
|
|
329
|
+
}),
|
|
330
|
+
);
|
|
331
|
+
for (const text of texts) {
|
|
332
|
+
const locale = localeMap[text.locale.toLowerCase()];
|
|
333
|
+
textsMap[locale + text.productId] = text;
|
|
334
|
+
}
|
|
335
|
+
return queries.map((q) => textsMap[q.locale.toLowerCase() + q.productId]);
|
|
336
|
+
},
|
|
337
|
+
),
|
|
338
|
+
|
|
339
|
+
productMediaTextLoader: new DataLoader<{ productMediaId: string; locale: string }, ProductMediaText>(
|
|
340
|
+
async (queries) => {
|
|
341
|
+
const productMediaIds = [...new Set(queries.map((q) => q.productMediaId).filter(Boolean))];
|
|
342
|
+
|
|
343
|
+
const texts = await unchainedAPI.modules.products.media.texts.findMediaTexts(
|
|
344
|
+
{ productMediaId: { $in: productMediaIds } },
|
|
345
|
+
{
|
|
346
|
+
sort: {
|
|
347
|
+
productMediaId: 1,
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
const queryLocales = [...new Set(queries.map((q) => q.locale.toLowerCase()))];
|
|
353
|
+
const textsMap = {};
|
|
354
|
+
const localeMap = Object.fromEntries(
|
|
355
|
+
queryLocales.flatMap((queryLocale) => {
|
|
356
|
+
return getLocaleStrings(queryLocale).map((locale) => [locale, queryLocale]);
|
|
357
|
+
}),
|
|
358
|
+
);
|
|
359
|
+
for (const text of texts) {
|
|
360
|
+
const locale = localeMap[text.locale.toLowerCase()];
|
|
361
|
+
textsMap[locale + text.productMediaId] = text;
|
|
362
|
+
}
|
|
363
|
+
return queries.map((q) => textsMap[q.locale.toLowerCase() + q.productMediaId]);
|
|
364
|
+
},
|
|
365
|
+
),
|
|
328
366
|
|
|
329
|
-
productMediasLoader: new DataLoader(async (queries) => {
|
|
367
|
+
productMediasLoader: new DataLoader<{ productId?: string }, ProductMedia[]>(async (queries) => {
|
|
330
368
|
const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))];
|
|
331
369
|
const productMediaItems = await unchainedAPI.modules.products.media.findProductMedias({
|
|
332
370
|
productId: { $in: productIds },
|
|
333
371
|
});
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
372
|
+
|
|
373
|
+
const productMediaMap = {};
|
|
374
|
+
for (const productMedia of productMediaItems) {
|
|
375
|
+
if (!productMediaMap[productMedia.productId]) {
|
|
376
|
+
productMediaMap[productMedia.productId] = [productMedia];
|
|
377
|
+
} else {
|
|
378
|
+
productMediaMap[productMedia.productId].push(productMedia);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return queries.map((q) => productMediaMap[q.productId] || []);
|
|
339
382
|
}),
|
|
340
383
|
|
|
341
|
-
fileLoader: new DataLoader(async (queries) => {
|
|
384
|
+
fileLoader: new DataLoader<{ fileId: string }, File>(async (queries) => {
|
|
342
385
|
const fileIds = [...new Set(queries.map((q) => q.fileId).filter(Boolean))]; // you don't need lodash, _.unique my ass
|
|
343
386
|
|
|
344
387
|
const files = await unchainedAPI.modules.files.findFiles({
|
|
345
388
|
_id: { $in: fileIds },
|
|
346
389
|
});
|
|
347
390
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
391
|
+
const fileMap = {};
|
|
392
|
+
for (const file of files) {
|
|
393
|
+
fileMap[file._id] = file;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return queries.map((q) => fileMap[q.fileId]);
|
|
354
397
|
}),
|
|
355
398
|
};
|
|
356
399
|
};
|
|
357
400
|
|
|
401
|
+
export type UnchainedLoaders = Awaited<ReturnType<typeof loaders>>;
|
|
402
|
+
|
|
358
403
|
export default loaders;
|
package/src/locale-context.ts
CHANGED
|
@@ -15,9 +15,6 @@ export interface UnchainedLocaleContext {
|
|
|
15
15
|
countryContext: string;
|
|
16
16
|
localeContext: Intl.Locale;
|
|
17
17
|
currencyContext: string;
|
|
18
|
-
remoteAddress?: string;
|
|
19
|
-
remotePort?: string;
|
|
20
|
-
userAgent?: string;
|
|
21
18
|
}
|
|
22
19
|
const { NODE_ENV } = process.env;
|
|
23
20
|
|
|
@@ -76,20 +73,14 @@ export const resolveDefaultContext = pMemoize(
|
|
|
76
73
|
|
|
77
74
|
export const getLocaleContext = async (
|
|
78
75
|
{
|
|
79
|
-
remoteAddress,
|
|
80
|
-
remotePort,
|
|
81
76
|
getHeader,
|
|
82
77
|
}: {
|
|
83
|
-
remoteAddress: string;
|
|
84
|
-
remotePort: number | string;
|
|
85
78
|
getHeader: UnchainedHTTPServerContext['getHeader'];
|
|
86
79
|
},
|
|
87
80
|
unchainedAPI: UnchainedCore,
|
|
88
81
|
): Promise<UnchainedLocaleContext> => {
|
|
89
|
-
|
|
90
|
-
const context = await resolveDefaultContext(
|
|
82
|
+
return resolveDefaultContext(
|
|
91
83
|
{ acceptLang: getHeader('accept-language'), acceptCountry: getHeader('x-shop-country') },
|
|
92
84
|
unchainedAPI,
|
|
93
85
|
);
|
|
94
|
-
return { remoteAddress, remotePort: String(remotePort), userAgent, ...context };
|
|
95
86
|
};
|
|
@@ -37,7 +37,7 @@ export default async function createUser(root: never, params: UserData, context:
|
|
|
37
37
|
user = await context.modules.users.updateHeartbeat(user._id, {
|
|
38
38
|
remoteAddress: context.remoteAddress,
|
|
39
39
|
remotePort: context.remotePort,
|
|
40
|
-
userAgent: context.
|
|
40
|
+
userAgent: context.getHeader('user-agent'),
|
|
41
41
|
locale: context.localeContext.baseName,
|
|
42
42
|
countryCode: context.countryContext,
|
|
43
43
|
});
|