@unchainedshop/api 2.0.0-beta6 → 2.0.0-beta8
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 +4 -7
- package/lib/api-index.js +24 -14
- package/lib/api-index.js.map +1 -1
- package/lib/context.d.ts +0 -1
- package/lib/context.js +0 -11
- package/lib/context.js.map +1 -1
- package/lib/createGraphQLServer.d.ts +2 -2
- package/lib/createGraphQLServer.js +12 -53
- package/lib/createGraphQLServer.js.map +1 -1
- package/lib/errors.js +8 -3
- package/lib/errors.js.map +1 -1
- package/lib/express/createApolloMiddleware.d.ts +4 -0
- package/lib/express/createApolloMiddleware.js +34 -0
- package/lib/express/createApolloMiddleware.js.map +1 -0
- package/lib/express/createBulkImportMiddleware.d.ts +2 -0
- package/lib/express/createBulkImportMiddleware.js +79 -0
- package/lib/express/createBulkImportMiddleware.js.map +1 -0
- package/lib/express/createERCMetadataMiddleware.d.ts +3 -0
- package/lib/express/createERCMetadataMiddleware.js +56 -0
- package/lib/express/createERCMetadataMiddleware.js.map +1 -0
- package/lib/express/createSingleSignOnMiddleware.d.ts +6 -0
- package/lib/express/createSingleSignOnMiddleware.js +71 -0
- package/lib/express/createSingleSignOnMiddleware.js.map +1 -0
- package/lib/express/index.d.ts +6 -0
- package/lib/express/index.js +27 -0
- package/lib/express/index.js.map +1 -0
- package/lib/loaders/index.js +50 -0
- package/lib/loaders/index.js.map +1 -1
- package/lib/resolvers/index.js +1 -1
- package/lib/resolvers/index.js.map +1 -1
- package/lib/resolvers/mutations/accounts/changePassword.d.ts +0 -2
- package/lib/resolvers/mutations/accounts/changePassword.js +2 -2
- package/lib/resolvers/mutations/accounts/changePassword.js.map +1 -1
- package/lib/resolvers/mutations/accounts/createUser.js +2 -2
- package/lib/resolvers/mutations/accounts/createUser.js.map +1 -1
- package/lib/resolvers/mutations/accounts/enrollUser.js +1 -1
- package/lib/resolvers/mutations/accounts/enrollUser.js.map +1 -1
- package/lib/resolvers/mutations/accounts/loginWithPassword.d.ts +0 -1
- package/lib/resolvers/mutations/accounts/loginWithPassword.js +3 -3
- package/lib/resolvers/mutations/accounts/loginWithPassword.js.map +1 -1
- package/lib/resolvers/mutations/accounts/resetPassword.d.ts +0 -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/setPassword.d.ts +0 -1
- package/lib/resolvers/mutations/accounts/setPassword.js +1 -1
- package/lib/resolvers/mutations/accounts/setPassword.js.map +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortment.js +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortment.js.map +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortmentFilter.js +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortmentFilter.js.map +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortmentLink.js +1 -1
- package/lib/resolvers/mutations/assortments/removeAssortmentLink.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/enrollments/updateEnrollment.d.ts +1 -1
- package/lib/resolvers/mutations/filters/removeFilter.js +1 -1
- package/lib/resolvers/mutations/filters/removeFilter.js.map +1 -1
- package/lib/resolvers/mutations/filters/updateFilter.js +2 -1
- package/lib/resolvers/mutations/filters/updateFilter.js.map +1 -1
- package/lib/resolvers/mutations/index.d.ts +1 -1
- package/lib/resolvers/mutations/pageView.d.ts +1 -1
- package/lib/resolvers/mutations/pageView.js +2 -2
- package/lib/resolvers/mutations/pageView.js.map +1 -1
- package/lib/resolvers/mutations/products/removeProduct.d.ts +1 -1
- package/lib/resolvers/mutations/products/removeProduct.js +5 -8
- package/lib/resolvers/mutations/products/removeProduct.js.map +1 -1
- package/lib/resolvers/queries/products/product.js +1 -1
- package/lib/resolvers/queries/products/productCatalogPrices.d.ts +1 -1
- package/lib/resolvers/queries/products/productCatalogPrices.js +5 -2
- package/lib/resolvers/queries/products/productCatalogPrices.js.map +1 -1
- package/lib/resolvers/queries/products/products.js +1 -1
- package/lib/resolvers/queries/products/products.js.map +1 -1
- package/lib/resolvers/scalars/LowerCaseString.d.ts +1 -1
- package/lib/resolvers/scalars/index.d.ts +1 -1
- package/lib/resolvers/type/assortment/assortment-filter-types.d.ts +2 -2
- package/lib/resolvers/type/assortment/assortment-filter-types.js +13 -6
- package/lib/resolvers/type/assortment/assortment-filter-types.js.map +1 -1
- package/lib/resolvers/type/assortment/assortment-link-types.d.ts +2 -2
- package/lib/resolvers/type/assortment/assortment-link-types.js +14 -6
- package/lib/resolvers/type/assortment/assortment-link-types.js.map +1 -1
- package/lib/resolvers/type/assortment/assortment-media-types.d.ts +1 -1
- package/lib/resolvers/type/assortment/assortment-path-link-types.d.ts +1 -4
- package/lib/resolvers/type/assortment/assortment-path-link-types.js +0 -7
- package/lib/resolvers/type/assortment/assortment-path-link-types.js.map +1 -1
- package/lib/resolvers/type/assortment/assortment-product-types.d.ts +2 -2
- package/lib/resolvers/type/assortment/assortment-product-types.js +14 -6
- package/lib/resolvers/type/assortment/assortment-product-types.js.map +1 -1
- package/lib/resolvers/type/assortment/assortment-types.d.ts +1 -1
- package/lib/resolvers/type/bookmark-types.d.ts +1 -1
- package/lib/resolvers/type/bookmark-types.js +6 -2
- package/lib/resolvers/type/bookmark-types.js.map +1 -1
- package/lib/resolvers/type/country-types.d.ts +1 -1
- package/lib/resolvers/type/delivery-provider-types.d.ts +1 -1
- package/lib/resolvers/type/enrollment/enrollment-delivery-types.d.ts +2 -2
- package/lib/resolvers/type/enrollment/enrollment-payment-types.d.ts +2 -2
- package/lib/resolvers/type/enrollment/enrollment-period-types.d.ts +2 -2
- package/lib/resolvers/type/enrollment/enrollment-plan-tyes.d.ts +2 -2
- package/lib/resolvers/type/enrollment/enrollment-plan-tyes.js +6 -2
- package/lib/resolvers/type/enrollment/enrollment-plan-tyes.js.map +1 -1
- package/lib/resolvers/type/enrollment/enrollment-types.d.ts +2 -2
- package/lib/resolvers/type/event-types.d.ts +1 -1
- package/lib/resolvers/type/filter/filter-option-types.d.ts +2 -2
- package/lib/resolvers/type/filter/filter-types.d.ts +2 -2
- package/lib/resolvers/type/order/order-delivery-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-delivery-pickup-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-delivery-shipping-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-global-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-item-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-item-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-item-types.js +13 -6
- package/lib/resolvers/type/order/order-item-types.js.map +1 -1
- package/lib/resolvers/type/order/order-payment-card-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-generic-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-invoice-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-types.d.ts +1 -1
- package/lib/resolvers/type/price-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-bundle-item-types.js +4 -2
- package/lib/resolvers/type/product/product-bundle-item-types.js.map +1 -1
- package/lib/resolvers/type/product/product-discount.d.ts +1 -1
- package/lib/resolvers/type/product/product-review-types.d.ts +1 -1
- package/lib/resolvers/type/product/product-review-types.js +6 -2
- package/lib/resolvers/type/product/product-review-types.js.map +1 -1
- package/lib/resolvers/type/product/product-tokenized-types.js +1 -0
- package/lib/resolvers/type/product/product-tokenized-types.js.map +1 -1
- package/lib/resolvers/type/product/product-variation-assignment-types.js +4 -2
- package/lib/resolvers/type/product/product-variation-assignment-types.js.map +1 -1
- package/lib/resolvers/type/quotation-types.d.ts +2 -2
- package/lib/resolvers/type/quotation-types.js +7 -3
- package/lib/resolvers/type/quotation-types.js.map +1 -1
- package/lib/resolvers/type/shop-types.d.ts +1 -1
- package/lib/resolvers/type/token-types.d.ts +1 -1
- package/lib/resolvers/type/user-types.d.ts +1 -3
- package/lib/resolvers/type/user-types.js +0 -12
- package/lib/resolvers/type/user-types.js.map +1 -1
- package/lib/resolvers/type/webauthn-credentials-types.d.ts +1 -1
- package/lib/resolvers/type/work-types.d.ts +1 -1
- package/lib/schema/{types/log.d.ts → directives.d.ts} +0 -0
- package/lib/schema/directives.js +15 -0
- package/lib/schema/directives.js.map +1 -0
- package/lib/schema/index.js +2 -1
- package/lib/schema/index.js.map +1 -1
- package/lib/schema/inputTypes.js +0 -15
- package/lib/schema/inputTypes.js.map +1 -1
- package/lib/schema/mutation.js +4 -23
- package/lib/schema/mutation.js.map +1 -1
- package/lib/schema/query.js +28 -10
- package/lib/schema/query.js.map +1 -1
- package/lib/schema/types/assortment.js +9 -10
- package/lib/schema/types/assortment.js.map +1 -1
- package/lib/schema/types/color.js +1 -1
- package/lib/schema/types/country.js +1 -1
- package/lib/schema/types/currency.js +1 -1
- package/lib/schema/types/delivery.js +3 -2
- package/lib/schema/types/delivery.js.map +1 -1
- package/lib/schema/types/dimensions.js +1 -1
- package/lib/schema/types/discount.js +1 -1
- package/lib/schema/types/dispatch.js +1 -0
- package/lib/schema/types/dispatch.js.map +1 -1
- package/lib/schema/types/filter.js +5 -8
- package/lib/schema/types/filter.js.map +1 -1
- package/lib/schema/types/geo-position.js +1 -1
- package/lib/schema/types/language.js +1 -1
- package/lib/schema/types/media.js +1 -1
- package/lib/schema/types/payment.js +3 -3
- package/lib/schema/types/price.js +2 -2
- package/lib/schema/types/product/bundle-product.js +2 -3
- package/lib/schema/types/product/bundle-product.js.map +1 -1
- package/lib/schema/types/product/configurable-product.js +7 -7
- package/lib/schema/types/product/plan-product.js +4 -3
- package/lib/schema/types/product/plan-product.js.map +1 -1
- package/lib/schema/types/product/product.js +11 -11
- package/lib/schema/types/product/simple-product.js +5 -4
- package/lib/schema/types/product/simple-product.js.map +1 -1
- package/lib/schema/types/product/tokenized-product.js +6 -3
- package/lib/schema/types/product/tokenized-product.js.map +1 -1
- package/lib/schema/types/search.js +3 -8
- package/lib/schema/types/search.js.map +1 -1
- package/lib/schema/types/shop.js +2 -2
- package/lib/schema/types/stock.js +1 -0
- package/lib/schema/types/stock.js.map +1 -1
- package/lib/schema/types/types.js +1 -1
- package/lib/schema/types/user.js +1 -3
- package/lib/schema/types/user.js.map +1 -1
- package/lib/schema/types/warehousing.js +3 -3
- package/package.json +31 -19
- package/src/api-index.ts +25 -29
- package/src/context.ts +0 -19
- package/src/createGraphQLServer.ts +11 -56
- package/src/errors.ts +8 -3
- package/src/express/createApolloMiddleware.ts +40 -0
- package/src/express/createBulkImportMiddleware.ts +90 -0
- package/src/express/createERCMetadataMiddleware.ts +72 -0
- package/src/express/createSingleSignOnMiddleware.ts +83 -0
- package/src/express/index.ts +48 -0
- package/src/loaders/index.ts +63 -3
- package/src/resolvers/index.ts +1 -1
- package/src/resolvers/mutations/accounts/changePassword.ts +2 -4
- package/src/resolvers/mutations/accounts/createUser.ts +2 -2
- package/src/resolvers/mutations/accounts/enrollUser.ts +1 -1
- package/src/resolvers/mutations/accounts/loginWithPassword.ts +3 -4
- package/src/resolvers/mutations/accounts/resetPassword.ts +2 -2
- package/src/resolvers/mutations/accounts/setPassword.ts +2 -2
- package/src/resolvers/mutations/assortments/removeAssortment.ts +1 -1
- package/src/resolvers/mutations/assortments/removeAssortmentFilter.ts +1 -1
- package/src/resolvers/mutations/assortments/removeAssortmentLink.ts +1 -1
- package/src/resolvers/mutations/assortments/removeAssortmentProduct.ts +1 -1
- package/src/resolvers/mutations/filters/removeFilter.ts +1 -1
- package/src/resolvers/mutations/filters/updateFilter.ts +3 -1
- package/src/resolvers/mutations/pageView.ts +2 -2
- package/src/resolvers/mutations/products/removeProduct.ts +6 -8
- package/src/resolvers/queries/products/product.ts +1 -1
- package/src/resolvers/queries/products/productCatalogPrices.ts +5 -2
- package/src/resolvers/queries/products/products.ts +1 -1
- package/src/resolvers/type/assortment/assortment-filter-types.ts +11 -6
- package/src/resolvers/type/assortment/assortment-link-types.ts +12 -6
- package/src/resolvers/type/assortment/assortment-path-link-types.ts +0 -11
- package/src/resolvers/type/assortment/assortment-product-types.ts +12 -6
- package/src/resolvers/type/bookmark-types.ts +7 -2
- package/src/resolvers/type/enrollment/enrollment-plan-tyes.ts +6 -2
- package/src/resolvers/type/order/order-item-types.ts +13 -6
- package/src/resolvers/type/product/product-bundle-item-types.ts +4 -2
- package/src/resolvers/type/product/product-review-types.ts +6 -2
- package/src/resolvers/type/product/product-tokenized-types.ts +1 -0
- package/src/resolvers/type/product/product-variation-assignment-types.ts +4 -2
- package/src/resolvers/type/quotation-types.ts +6 -3
- package/src/resolvers/type/user-types.ts +0 -15
- package/src/schema/directives.js +14 -0
- package/src/schema/index.js +2 -1
- package/src/schema/inputTypes.js +0 -15
- package/src/schema/mutation.js +4 -23
- package/src/schema/query.js +28 -10
- package/src/schema/types/assortment.js +9 -10
- package/src/schema/types/color.js +1 -1
- package/src/schema/types/country.js +1 -1
- package/src/schema/types/currency.js +1 -1
- package/src/schema/types/delivery.js +3 -2
- package/src/schema/types/dimensions.js +1 -1
- package/src/schema/types/discount.js +1 -1
- package/src/schema/types/dispatch.js +1 -0
- package/src/schema/types/filter.js +5 -8
- package/src/schema/types/geo-position.js +1 -1
- package/src/schema/types/language.js +1 -1
- package/src/schema/types/media.js +1 -1
- package/src/schema/types/payment.js +3 -3
- package/src/schema/types/price.js +2 -2
- package/src/schema/types/product/bundle-product.js +2 -3
- package/src/schema/types/product/configurable-product.js +7 -7
- package/src/schema/types/product/plan-product.js +4 -3
- package/src/schema/types/product/product.js +11 -11
- package/src/schema/types/product/simple-product.js +5 -4
- package/src/schema/types/product/tokenized-product.js +6 -3
- package/src/schema/types/search.js +3 -8
- package/src/schema/types/shop.js +2 -2
- package/src/schema/types/stock.js +1 -0
- package/src/schema/types/types.js +1 -1
- package/src/schema/types/user.js +1 -3
- package/src/schema/types/warehousing.js +3 -3
- package/tsconfig.json +1 -0
- package/lib/createBulkImportServer.d.ts +0 -2
- package/lib/createBulkImportServer.js +0 -81
- package/lib/createBulkImportServer.js.map +0 -1
- package/lib/createERCMetadataServer.d.ts +0 -2
- package/lib/createERCMetadataServer.js +0 -59
- package/lib/createERCMetadataServer.js.map +0 -1
- package/lib/schema/types/log.js +0 -16
- package/lib/schema/types/log.js.map +0 -1
- package/src/createBulkImportServer.ts +0 -95
- package/src/createERCMetadataServer.ts +0 -78
- package/src/schema/types/log.js +0 -15
package/src/api-index.ts
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
import { UnchainedServerOptions } from '@unchainedshop/types/api';
|
|
2
|
-
import { ApolloServer } from 'apollo
|
|
3
|
-
import
|
|
2
|
+
import type { ApolloServer } from '@apollo/server';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
4
5
|
import createGraphQLServer from './createGraphQLServer';
|
|
5
|
-
import { createContextResolver,
|
|
6
|
-
import createERCMetadataServer from './createERCMetadataServer';
|
|
6
|
+
import { createContextResolver, setCurrentContextResolver, getCurrentContextResolver } from './context';
|
|
7
7
|
|
|
8
8
|
export * from './context';
|
|
9
9
|
export * as acl from './acl';
|
|
10
10
|
export * as errors from './errors';
|
|
11
|
+
export * as express from './express';
|
|
11
12
|
export { hashPassword } from './hashPassword';
|
|
12
13
|
export * as roles from './roles';
|
|
13
|
-
|
|
14
14
|
export { createContextResolver, getCurrentContextResolver, setCurrentContextResolver };
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const loadJSON = (filename) => {
|
|
17
|
+
try {
|
|
18
|
+
const base = typeof __filename !== 'undefined' && __filename;
|
|
19
|
+
if (!base)
|
|
20
|
+
return {
|
|
21
|
+
version: process.env.npm_package_version,
|
|
22
|
+
};
|
|
23
|
+
const absolutePath = path.resolve(path.dirname(base), filename);
|
|
24
|
+
const data = JSON.parse(fs.readFileSync(absolutePath, 'utf-8'));
|
|
25
|
+
return data;
|
|
26
|
+
} catch (e) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const packageJson = loadJSON('../package.json');
|
|
31
|
+
|
|
32
|
+
const UNCHAINED_API_VERSION = process.env.UNCHAINED_API_VERSION || packageJson?.version || '1.2.x';
|
|
17
33
|
|
|
18
|
-
export const startAPIServer = (
|
|
19
|
-
|
|
20
|
-
): {
|
|
21
|
-
apolloGraphQLServer: ApolloServer;
|
|
22
|
-
bulkImportServer: any;
|
|
23
|
-
ercMetadataServer: any;
|
|
24
|
-
} => {
|
|
25
|
-
const {
|
|
26
|
-
unchainedAPI,
|
|
27
|
-
roles,
|
|
28
|
-
expressApp,
|
|
29
|
-
context: customContext,
|
|
30
|
-
...apolloServerOptions
|
|
31
|
-
} = options || {};
|
|
34
|
+
export const startAPIServer = async (options: UnchainedServerOptions): Promise<ApolloServer> => {
|
|
35
|
+
const { unchainedAPI, roles, context: customContext, ...apolloServerOptions } = options || {};
|
|
32
36
|
|
|
33
37
|
const contextResolver = createContextResolver(unchainedAPI, roles, UNCHAINED_API_VERSION);
|
|
34
38
|
|
|
@@ -40,13 +44,5 @@ export const startAPIServer = (
|
|
|
40
44
|
: contextResolver,
|
|
41
45
|
);
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
const bulkImportServer = createBulkImportServer(expressApp);
|
|
45
|
-
const ercMetadataServer = createERCMetadataServer(expressApp);
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
apolloGraphQLServer,
|
|
49
|
-
bulkImportServer,
|
|
50
|
-
ercMetadataServer,
|
|
51
|
-
};
|
|
47
|
+
return createGraphQLServer(apolloServerOptions);
|
|
52
48
|
};
|
package/src/context.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { UnchainedContextResolver } from '@unchainedshop/types/api';
|
|
2
2
|
import { UnchainedCore } from '@unchainedshop/types/core';
|
|
3
|
-
import { IncomingMessage, OutgoingMessage } from 'http';
|
|
4
3
|
import instantiateLoaders from './loaders';
|
|
5
4
|
import { getLocaleContext } from './locale-context';
|
|
6
5
|
import { getUserContext } from './user-context';
|
|
@@ -32,21 +31,3 @@ export const createContextResolver =
|
|
|
32
31
|
version,
|
|
33
32
|
};
|
|
34
33
|
};
|
|
35
|
-
|
|
36
|
-
export const useMiddlewareWithCurrentContext = (expressApp, path, middleware) => {
|
|
37
|
-
expressApp.use(
|
|
38
|
-
path,
|
|
39
|
-
async function middlewareWithContext(
|
|
40
|
-
req: IncomingMessage & { unchainedContext?: UnchainedCore },
|
|
41
|
-
res: OutgoingMessage,
|
|
42
|
-
next,
|
|
43
|
-
) {
|
|
44
|
-
try {
|
|
45
|
-
req.unchainedContext = await context({ req, res });
|
|
46
|
-
await middleware(req, res, next);
|
|
47
|
-
} catch (error) {
|
|
48
|
-
next(error);
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
};
|
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
import { ApolloServer
|
|
2
|
-
import {
|
|
1
|
+
import { ApolloServer } from '@apollo/server';
|
|
2
|
+
import { GraphQLError } from 'graphql';
|
|
3
3
|
import { log, LogLevel } from '@unchainedshop/logger';
|
|
4
4
|
import typeDefs from './schema';
|
|
5
5
|
import resolvers from './resolvers';
|
|
6
|
-
import { getCurrentContextResolver } from './context';
|
|
7
6
|
|
|
8
7
|
const { APOLLO_ENGINE_KEY } = process.env;
|
|
9
8
|
|
|
10
|
-
const handleUploads = (options) => async (req, res, next) => {
|
|
11
|
-
const contentType = req.headers['content-type'];
|
|
12
|
-
const isUpload = contentType && contentType.startsWith('multipart/form-data');
|
|
13
|
-
if (isUpload) {
|
|
14
|
-
req.body = await processRequest(req, res, options);
|
|
15
|
-
}
|
|
16
|
-
next();
|
|
17
|
-
};
|
|
18
|
-
|
|
19
9
|
const logGraphQLServerError = (error) => {
|
|
20
10
|
try {
|
|
21
11
|
const {
|
|
@@ -35,21 +25,17 @@ const logGraphQLServerError = (error) => {
|
|
|
35
25
|
} catch (e) {} // eslint-disable-line
|
|
36
26
|
};
|
|
37
27
|
|
|
38
|
-
export default (
|
|
28
|
+
export default async (options) => {
|
|
39
29
|
const {
|
|
40
|
-
corsOrigins = null, // no cookie handling
|
|
41
30
|
typeDefs: additionalTypeDefs = [],
|
|
42
31
|
resolvers: additionalResolvers = [],
|
|
43
32
|
engine = {},
|
|
44
33
|
...apolloServerOptions
|
|
45
34
|
} = options || {};
|
|
46
35
|
|
|
47
|
-
const context = getCurrentContextResolver();
|
|
48
36
|
const server = new ApolloServer({
|
|
49
37
|
typeDefs: [...typeDefs, ...additionalTypeDefs],
|
|
50
38
|
resolvers: [resolvers, ...additionalResolvers],
|
|
51
|
-
context,
|
|
52
|
-
uploads: false,
|
|
53
39
|
formatError: (error) => {
|
|
54
40
|
logGraphQLServerError(error);
|
|
55
41
|
const {
|
|
@@ -57,18 +43,20 @@ export default (expressApp, options) => {
|
|
|
57
43
|
path,
|
|
58
44
|
extensions: { exception, code, ...extensions }, // eslint-disable-line
|
|
59
45
|
} = error;
|
|
60
|
-
const apolloError = new
|
|
61
|
-
|
|
62
|
-
|
|
46
|
+
const apolloError = new GraphQLError(message, {
|
|
47
|
+
extensions: {
|
|
48
|
+
code,
|
|
49
|
+
...extensions,
|
|
50
|
+
},
|
|
63
51
|
});
|
|
64
52
|
// eslint-disable-next-line
|
|
65
53
|
// @ts-ignore
|
|
66
54
|
apolloError.path = path;
|
|
67
55
|
return apolloError;
|
|
68
56
|
},
|
|
69
|
-
|
|
57
|
+
apollo: APOLLO_ENGINE_KEY
|
|
70
58
|
? {
|
|
71
|
-
|
|
59
|
+
key: APOLLO_ENGINE_KEY,
|
|
72
60
|
privateVariables: ['email', 'plainPassword', 'oldPlainPassword', 'newPlainPassword'],
|
|
73
61
|
...engine,
|
|
74
62
|
}
|
|
@@ -76,40 +64,7 @@ export default (expressApp, options) => {
|
|
|
76
64
|
...apolloServerOptions,
|
|
77
65
|
});
|
|
78
66
|
|
|
79
|
-
|
|
80
|
-
corsOrigins && Array.isArray(corsOrigins)
|
|
81
|
-
? (origin, callback) => {
|
|
82
|
-
if (corsOrigins.length === 0 || !origin) {
|
|
83
|
-
callback(null, true);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (corsOrigins.indexOf(origin) !== -1) {
|
|
87
|
-
callback(null, true);
|
|
88
|
-
} else {
|
|
89
|
-
callback(new Error('Not allowed by CORS'));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
: corsOrigins;
|
|
93
|
-
|
|
94
|
-
// server.start().then(() => {
|
|
95
|
-
//
|
|
96
|
-
// });
|
|
97
|
-
|
|
98
|
-
const middleware = server.getMiddleware({
|
|
99
|
-
path: '/graphql',
|
|
100
|
-
cors: !originFn
|
|
101
|
-
? undefined
|
|
102
|
-
: {
|
|
103
|
-
origin: originFn,
|
|
104
|
-
credentials: true,
|
|
105
|
-
},
|
|
106
|
-
bodyParserConfig: {
|
|
107
|
-
limit: '5mb',
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
expressApp.use(handleUploads({ maxFileSize: 10000000, maxFiles: 10 }));
|
|
112
|
-
expressApp.use(middleware);
|
|
67
|
+
await server.start();
|
|
113
68
|
|
|
114
69
|
return server;
|
|
115
70
|
};
|
package/src/errors.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GraphQLError } from 'graphql';
|
|
2
2
|
|
|
3
3
|
export const createError = (code: string, message: string): any =>
|
|
4
|
-
class extends
|
|
4
|
+
class extends GraphQLError {
|
|
5
5
|
constructor({ message: explicitMessage, ...data }) {
|
|
6
|
-
super(explicitMessage || message,
|
|
6
|
+
super(explicitMessage || message, {
|
|
7
|
+
extensions: {
|
|
8
|
+
code,
|
|
9
|
+
...data,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
7
12
|
}
|
|
8
13
|
};
|
|
9
14
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import cors from 'cors';
|
|
2
|
+
import { expressMiddleware } from '@apollo/server/express4';
|
|
3
|
+
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
|
|
4
|
+
import e from 'express';
|
|
5
|
+
|
|
6
|
+
export default function createApolloMiddleware(
|
|
7
|
+
contextResolver,
|
|
8
|
+
{ apolloGraphQLServer, corsOrigins = undefined },
|
|
9
|
+
) {
|
|
10
|
+
const originFn =
|
|
11
|
+
corsOrigins && Array.isArray(corsOrigins)
|
|
12
|
+
? (origin, callback) => {
|
|
13
|
+
if (corsOrigins.length === 0 || !origin) {
|
|
14
|
+
callback(null, true);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (corsOrigins.indexOf(origin) !== -1) {
|
|
18
|
+
callback(null, true);
|
|
19
|
+
} else {
|
|
20
|
+
callback(new Error('Not allowed by CORS'));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
: corsOrigins;
|
|
24
|
+
|
|
25
|
+
return [
|
|
26
|
+
cors(
|
|
27
|
+
!originFn
|
|
28
|
+
? undefined
|
|
29
|
+
: {
|
|
30
|
+
origin: originFn,
|
|
31
|
+
credentials: true,
|
|
32
|
+
},
|
|
33
|
+
),
|
|
34
|
+
e.json(),
|
|
35
|
+
graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }),
|
|
36
|
+
expressMiddleware(apolloGraphQLServer, {
|
|
37
|
+
context: contextResolver,
|
|
38
|
+
}),
|
|
39
|
+
];
|
|
40
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
+
import { UnchainedContextResolver } from '@unchainedshop/types/api';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { checkAction } from '../acl';
|
|
5
|
+
import { actions } from '../roles';
|
|
6
|
+
|
|
7
|
+
const logger = createLogger('unchained:bulk-import');
|
|
8
|
+
|
|
9
|
+
const { BULK_IMPORT_PAYLOAD_CACHE_DIRECTORY } = process.env;
|
|
10
|
+
|
|
11
|
+
const errorHandler = (res) => (e) => {
|
|
12
|
+
logger.error(e.message);
|
|
13
|
+
res.writeHead(503);
|
|
14
|
+
res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const methodWrongHandler = (res) => () => {
|
|
18
|
+
logger.error('Method not supported, return 404');
|
|
19
|
+
res.writeHead(404);
|
|
20
|
+
res.end();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const createWriteStreamToFilesystem = (cacheDirectory) => {
|
|
24
|
+
const date = new Date().toISOString();
|
|
25
|
+
const payloadFilePath = `${cacheDirectory}/${date}.json`;
|
|
26
|
+
const stream = fs.createWriteStream(payloadFilePath, { flags: 'a' });
|
|
27
|
+
return stream;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const createWriteStreamToMongoDB = (BulkImportPayloads) => {
|
|
31
|
+
const date = new Date().toISOString();
|
|
32
|
+
const stream = BulkImportPayloads.openUploadStreamWithId(date, `${date}.json`, {
|
|
33
|
+
contentType: 'application/json',
|
|
34
|
+
});
|
|
35
|
+
return stream;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default function bulkImportMiddleware(contextResolver: UnchainedContextResolver) {
|
|
39
|
+
return async (req, res) => {
|
|
40
|
+
try {
|
|
41
|
+
if (req.method !== 'POST') {
|
|
42
|
+
methodWrongHandler(res)();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const context = await contextResolver({ req, res });
|
|
47
|
+
await checkAction(context, (actions as any).bulkImport);
|
|
48
|
+
|
|
49
|
+
const input: any = {
|
|
50
|
+
createShouldUpsertIfIDExists: !!req.query?.createShouldUpsertIfIDExists,
|
|
51
|
+
skipCacheInvalidation: !!req.query?.skipCacheInvalidation,
|
|
52
|
+
fsPayloadCacheDirectory: BULK_IMPORT_PAYLOAD_CACHE_DIRECTORY,
|
|
53
|
+
remoteAddress: context.remoteAddress,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const stream = input.fsPayloadCacheDirectory
|
|
57
|
+
? createWriteStreamToFilesystem(input.fsPayloadCacheDirectory)
|
|
58
|
+
: createWriteStreamToMongoDB(context.bulkImporter.BulkImportPayloads);
|
|
59
|
+
|
|
60
|
+
req
|
|
61
|
+
.pipe(stream)
|
|
62
|
+
.on('error', errorHandler(res))
|
|
63
|
+
.on('finish', async (file) => {
|
|
64
|
+
try {
|
|
65
|
+
if (input.fsPayloadCacheDirectory) {
|
|
66
|
+
input.payloadFilePath = stream.path;
|
|
67
|
+
} else {
|
|
68
|
+
input.payloadId = file._id;
|
|
69
|
+
input.payloadSize = file.length;
|
|
70
|
+
}
|
|
71
|
+
const work = await context.modules.worker.addWork(
|
|
72
|
+
{
|
|
73
|
+
type: 'BULK_IMPORT',
|
|
74
|
+
input: Object.fromEntries(Object.entries(input).filter(([, value]) => Boolean(value))),
|
|
75
|
+
retries: 0,
|
|
76
|
+
priority: 10,
|
|
77
|
+
},
|
|
78
|
+
context.userId,
|
|
79
|
+
);
|
|
80
|
+
res.writeHead(200);
|
|
81
|
+
res.end(JSON.stringify(work));
|
|
82
|
+
} catch (e) {
|
|
83
|
+
errorHandler(res)(e);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
} catch (e) {
|
|
87
|
+
errorHandler(res)(e);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
+
import { UnchainedContextResolver } from '@unchainedshop/types/api';
|
|
3
|
+
import { systemLocale } from '@unchainedshop/utils';
|
|
4
|
+
import { IncomingMessage } from 'http';
|
|
5
|
+
import localePkg from 'locale';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
const { Locale } = localePkg;
|
|
9
|
+
|
|
10
|
+
const logger = createLogger('unchained:erc-metadata');
|
|
11
|
+
|
|
12
|
+
const errorHandler = (res) => (e) => {
|
|
13
|
+
logger.error(e.message);
|
|
14
|
+
res.writeHead(503);
|
|
15
|
+
res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const methodWrongHandler = (res) => () => {
|
|
19
|
+
logger.error('Method not supported, return 404');
|
|
20
|
+
res.writeHead(404);
|
|
21
|
+
res.end();
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default function ercMetadataMiddleware(contextResolver: UnchainedContextResolver) {
|
|
25
|
+
return async (req: IncomingMessage, res) => {
|
|
26
|
+
try {
|
|
27
|
+
if (req.method !== 'GET') {
|
|
28
|
+
methodWrongHandler(res)();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const context = await contextResolver({ req, res });
|
|
33
|
+
const url = new URL(req.url, process.env.ROOT_URL);
|
|
34
|
+
const parsedPath = path.parse(url.pathname);
|
|
35
|
+
|
|
36
|
+
if (parsedPath.ext !== '.json') throw new Error('Invalid ERC Metadata URI');
|
|
37
|
+
|
|
38
|
+
const [, productId, localeOrTokenFilename, tokenFileName] = url.pathname.split('/');
|
|
39
|
+
|
|
40
|
+
const locale = tokenFileName ? localeOrTokenFilename : systemLocale.language;
|
|
41
|
+
const chainTokenId = parsedPath.name;
|
|
42
|
+
|
|
43
|
+
const product = await context.modules.products.findProduct({
|
|
44
|
+
productId,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const [token] = await context.modules.warehousing.findTokens({
|
|
48
|
+
chainTokenId,
|
|
49
|
+
contractAddress: product?.tokenization?.contractAddress,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const ercMetadata = await context.modules.warehousing.tokenMetadata(
|
|
53
|
+
chainTokenId,
|
|
54
|
+
{
|
|
55
|
+
token,
|
|
56
|
+
product,
|
|
57
|
+
referenceDate: new Date(),
|
|
58
|
+
},
|
|
59
|
+
{ ...context, localeContext: new Locale(locale) },
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const body = JSON.stringify(ercMetadata);
|
|
63
|
+
res.writeHead(200, {
|
|
64
|
+
'Content-Length': Buffer.byteLength(body),
|
|
65
|
+
'Content-Type': 'text/plain',
|
|
66
|
+
});
|
|
67
|
+
res.end(body);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
errorHandler(res)(e);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
3
|
+
import { Context, UnchainedContextResolver } from '@unchainedshop/types/api';
|
|
4
|
+
import { IncomingMessage } from 'http';
|
|
5
|
+
import cookie from 'cookie';
|
|
6
|
+
|
|
7
|
+
const { ROOT_URL, NODE_ENV, UNCHAINED_CLOUD_ENDPOINT } = process.env;
|
|
8
|
+
|
|
9
|
+
const logger = createLogger('unchained:unchained-cloud-sso');
|
|
10
|
+
|
|
11
|
+
const loginWithSingleSignOn = async (remoteToken, context: Context) => {
|
|
12
|
+
const domain = process.env.UNCHAINED_COOKIE_DOMAIN || new URL(ROOT_URL).hostname || 'localhost';
|
|
13
|
+
const result = await fetch(UNCHAINED_CLOUD_ENDPOINT, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'content-type': 'application/json',
|
|
17
|
+
},
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
operationName: 'consume',
|
|
20
|
+
variables: {
|
|
21
|
+
token: remoteToken,
|
|
22
|
+
},
|
|
23
|
+
query:
|
|
24
|
+
'mutation consume($token: ID!) { controlConsumeSingleSignOnToken(token: $token) { domain } }',
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
const json: any = await result.json();
|
|
28
|
+
if (json?.errors?.length > 0) {
|
|
29
|
+
throw new Error(json.errors[0].message);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (domain === 'localhost' || domain === json?.data?.controlConsumeSingleSignOnToken?.domain) {
|
|
33
|
+
// create sso user if not exist and login
|
|
34
|
+
const ssoUserId =
|
|
35
|
+
(await context.modules.users.findUser({ username: 'sso' }))?._id ||
|
|
36
|
+
(await context.modules.accounts.createUser(
|
|
37
|
+
{
|
|
38
|
+
username: 'sso',
|
|
39
|
+
roles: ['admin'],
|
|
40
|
+
email: 'sso@unchained.local',
|
|
41
|
+
password: null,
|
|
42
|
+
guest: false,
|
|
43
|
+
},
|
|
44
|
+
{ skipMessaging: true },
|
|
45
|
+
));
|
|
46
|
+
const { tokenExpires, token } = await context.modules.accounts.createLoginToken(ssoUserId, context);
|
|
47
|
+
const expires = new Date(tokenExpires || new Date().getTime() + 100000);
|
|
48
|
+
const authCookie = cookie.serialize(process.env.UNCHAINED_COOKIE_NAME, token, {
|
|
49
|
+
domain,
|
|
50
|
+
httpOnly: true,
|
|
51
|
+
expires,
|
|
52
|
+
path: '/',
|
|
53
|
+
sameSite: 'strict',
|
|
54
|
+
secure: NODE_ENV === 'production',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return authCookie;
|
|
58
|
+
}
|
|
59
|
+
throw new Error('Invalid token/domain pair');
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default function singleSignOnMiddleware(contextResolver: UnchainedContextResolver) {
|
|
63
|
+
return async (req: IncomingMessage & { query?: any }, res, next) => {
|
|
64
|
+
try {
|
|
65
|
+
if (req.query?.token) {
|
|
66
|
+
const context = await contextResolver({ req, res });
|
|
67
|
+
const authCookie = await loginWithSingleSignOn(req.query.token, context);
|
|
68
|
+
|
|
69
|
+
if (authCookie) {
|
|
70
|
+
res.writeHead(303, {
|
|
71
|
+
'Set-Cookie': authCookie,
|
|
72
|
+
Location: '/',
|
|
73
|
+
});
|
|
74
|
+
res.end();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
logger.error(e.message);
|
|
80
|
+
}
|
|
81
|
+
next();
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { UnchainedCore } from '@unchainedshop/types/core';
|
|
2
|
+
import { IncomingMessage, OutgoingMessage } from 'http';
|
|
3
|
+
import { ApolloServer } from '@apollo/server';
|
|
4
|
+
import type e from 'express';
|
|
5
|
+
import { getCurrentContextResolver } from '../context';
|
|
6
|
+
import createBulkImportMiddleware from './createBulkImportMiddleware';
|
|
7
|
+
import createERCMetadataMiddleware from './createERCMetadataMiddleware';
|
|
8
|
+
import createApolloMiddleware from './createApolloMiddleware';
|
|
9
|
+
import createSingleSignOnMiddleware from './createSingleSignOnMiddleware';
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
BULK_IMPORT_API_PATH = '/bulk-import',
|
|
13
|
+
ERC_METADATA_API_PATH = '/erc-metadata',
|
|
14
|
+
GRAPHQL_API_PATH = '/graphql',
|
|
15
|
+
} = process.env;
|
|
16
|
+
|
|
17
|
+
export const useMiddlewareWithCurrentContext = (expressApp, path, ...middleware) => {
|
|
18
|
+
const context = getCurrentContextResolver();
|
|
19
|
+
const addContext = async function middlewareWithContext(
|
|
20
|
+
req: IncomingMessage & { unchainedContext: UnchainedCore },
|
|
21
|
+
res: OutgoingMessage,
|
|
22
|
+
next,
|
|
23
|
+
) {
|
|
24
|
+
try {
|
|
25
|
+
req.unchainedContext = await context({ req, res });
|
|
26
|
+
next();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
next(error);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
expressApp.use(path, addContext, ...middleware);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const connect = (
|
|
36
|
+
expressApp: e.Express,
|
|
37
|
+
{ apolloGraphQLServer }: { apolloGraphQLServer: ApolloServer },
|
|
38
|
+
) => {
|
|
39
|
+
const contextResolver = getCurrentContextResolver();
|
|
40
|
+
|
|
41
|
+
expressApp.use(GRAPHQL_API_PATH, createApolloMiddleware(contextResolver, { apolloGraphQLServer }));
|
|
42
|
+
expressApp.use(ERC_METADATA_API_PATH, createERCMetadataMiddleware(contextResolver));
|
|
43
|
+
expressApp.use(BULK_IMPORT_API_PATH, createBulkImportMiddleware(contextResolver));
|
|
44
|
+
expressApp.use(
|
|
45
|
+
['/', '/.well-known/unchained/cloud-sso'],
|
|
46
|
+
createSingleSignOnMiddleware(contextResolver),
|
|
47
|
+
);
|
|
48
|
+
};
|
package/src/loaders/index.ts
CHANGED
|
@@ -3,10 +3,11 @@ import DataLoader from 'dataloader';
|
|
|
3
3
|
import { IncomingMessage, OutgoingMessage } from 'http';
|
|
4
4
|
import { systemLocale } from '@unchainedshop/utils';
|
|
5
5
|
import localePkg from 'locale';
|
|
6
|
-
import { AssortmentText } from '@unchainedshop/types/assortments';
|
|
7
|
-
import { FilterText } from '@unchainedshop/types/filters';
|
|
8
|
-
import { ProductText } from '@unchainedshop/types/products';
|
|
6
|
+
import { Assortment, AssortmentText } from '@unchainedshop/types/assortments';
|
|
7
|
+
import { Filter, FilterText } from '@unchainedshop/types/filters';
|
|
8
|
+
import { Product, ProductText } from '@unchainedshop/types/products';
|
|
9
9
|
import { UnchainedCore } from '@unchainedshop/types/core';
|
|
10
|
+
import { ProductStatus } from '@unchainedshop/core-products';
|
|
10
11
|
|
|
11
12
|
const { Locale } = localePkg;
|
|
12
13
|
|
|
@@ -16,6 +17,28 @@ export default async (
|
|
|
16
17
|
unchainedAPI: UnchainedCore,
|
|
17
18
|
): Promise<UnchainedLoaders['loaders']> => {
|
|
18
19
|
return {
|
|
20
|
+
assortmentLoader: new DataLoader<{ assortmentId: string; includeInactive: boolean }, Assortment>(
|
|
21
|
+
async (queries) => {
|
|
22
|
+
const assortmentIds = [...new Set(queries.map((q) => q.assortmentId).filter(Boolean))];
|
|
23
|
+
|
|
24
|
+
const assortments = await unchainedAPI.modules.assortments.findAssortments({
|
|
25
|
+
assortmentIds,
|
|
26
|
+
includeInactive: true,
|
|
27
|
+
includeLeaves: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return queries.map(({ assortmentId, includeInactive }) => {
|
|
31
|
+
return assortments.find((assortment) => {
|
|
32
|
+
if (assortment._id !== assortmentId) return false;
|
|
33
|
+
if (!includeInactive) {
|
|
34
|
+
return assortment.isActive === true;
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
),
|
|
41
|
+
|
|
19
42
|
assortmentTextLoader: new DataLoader<{ assortmentId: string; locale: string }, AssortmentText>(
|
|
20
43
|
async (queries) => {
|
|
21
44
|
const assortmentIds = [...new Set(queries.map((q) => q.assortmentId).filter(Boolean))];
|
|
@@ -46,6 +69,22 @@ export default async (
|
|
|
46
69
|
},
|
|
47
70
|
),
|
|
48
71
|
|
|
72
|
+
filterLoader: new DataLoader<{ filterId: string }, Filter>(async (queries) => {
|
|
73
|
+
const filterIds = [...new Set(queries.map((q) => q.filterId).filter(Boolean))];
|
|
74
|
+
|
|
75
|
+
const filters = await unchainedAPI.modules.filters.findFilters({
|
|
76
|
+
filterIds,
|
|
77
|
+
includeInactive: true,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return queries.map(({ filterId }) => {
|
|
81
|
+
return filters.find((product) => {
|
|
82
|
+
if (product._id !== filterId) return false;
|
|
83
|
+
return true;
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}),
|
|
87
|
+
|
|
49
88
|
filterTextLoader: new DataLoader<
|
|
50
89
|
{ filterId: string; filterOptionValue?: string; locale: string },
|
|
51
90
|
FilterText
|
|
@@ -79,6 +118,27 @@ export default async (
|
|
|
79
118
|
});
|
|
80
119
|
}),
|
|
81
120
|
|
|
121
|
+
productLoader: new DataLoader<{ productId: string; includeDrafts: boolean }, Product>(
|
|
122
|
+
async (queries) => {
|
|
123
|
+
const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))];
|
|
124
|
+
|
|
125
|
+
const products = await unchainedAPI.modules.products.findProducts({
|
|
126
|
+
productIds,
|
|
127
|
+
includeDrafts: true,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return queries.map(({ productId, includeDrafts }) => {
|
|
131
|
+
return products.find((product) => {
|
|
132
|
+
if (product._id !== productId) return false;
|
|
133
|
+
if (!includeDrafts) {
|
|
134
|
+
return product.status === ProductStatus.ACTIVE;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
),
|
|
141
|
+
|
|
82
142
|
productTextLoader: new DataLoader<{ productId: string; locale: string }, ProductText>(
|
|
83
143
|
async (queries) => {
|
|
84
144
|
const productIds = [...new Set(queries.map((q) => q.productId).filter(Boolean))];
|
package/src/resolvers/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
|
|
2
2
|
import { JSONResolver, TimestampResolver, DateTimeResolver, DateResolver } from 'graphql-scalars';
|
|
3
3
|
import Query from './queries';
|
|
4
4
|
import Mutation from './mutations';
|