@unchainedshop/api 2.8.18 → 2.9.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/jest.config.js +2 -2
- package/lib/errors.d.ts +1 -0
- package/lib/errors.js +1 -0
- package/lib/errors.js.map +1 -1
- package/lib/resolvers/mutations/index.d.ts +1 -0
- package/lib/resolvers/mutations/index.js +2 -0
- package/lib/resolvers/mutations/index.js.map +1 -1
- package/lib/resolvers/mutations/warehousing/invalidateToken.d.ts +4 -0
- package/lib/resolvers/mutations/warehousing/invalidateToken.js +26 -0
- package/lib/resolvers/mutations/warehousing/invalidateToken.js.map +1 -0
- package/lib/resolvers/queries/index.d.ts +1 -0
- package/lib/resolvers/queries/index.js +2 -0
- package/lib/resolvers/queries/index.js.map +1 -1
- package/lib/resolvers/queries/warehousing/tokens.d.ts +5 -0
- package/lib/resolvers/queries/warehousing/tokens.js +6 -0
- package/lib/resolvers/queries/warehousing/tokens.js.map +1 -0
- package/lib/resolvers/type/index.d.ts +367 -9
- package/lib/resolvers/type/order/order-item-types.d.ts +15 -17
- package/lib/resolvers/type/order/order-item-types.js +28 -23
- package/lib/resolvers/type/order/order-item-types.js.map +1 -1
- package/lib/resolvers/type/order/order-types.d.ts +15 -19
- package/lib/resolvers/type/order/order-types.js +48 -28
- package/lib/resolvers/type/order/order-types.js.map +1 -1
- package/lib/resolvers/type/product/product-bundle-types.d.ts +34 -2
- package/lib/resolvers/type/product/product-bundle-types.js.map +1 -1
- package/lib/resolvers/type/product/product-configurable-types.d.ts +62 -2
- package/lib/resolvers/type/product/product-configurable-types.js +10 -10
- package/lib/resolvers/type/product/product-configurable-types.js.map +1 -1
- package/lib/resolvers/type/product/product-plan-types.d.ts +53 -2
- package/lib/resolvers/type/product/product-plan-types.js +9 -9
- package/lib/resolvers/type/product/product-plan-types.js.map +1 -1
- package/lib/resolvers/type/product/product-simple-types.d.ts +85 -2
- package/lib/resolvers/type/product/product-simple-types.js +7 -7
- package/lib/resolvers/type/product/product-simple-types.js.map +1 -1
- package/lib/resolvers/type/product/product-tokenized-types.d.ts +67 -2
- package/lib/resolvers/type/product/product-tokenized-types.js +19 -10
- package/lib/resolvers/type/product/product-tokenized-types.js.map +1 -1
- package/lib/resolvers/type/product/product-types.d.ts +38 -2
- package/lib/resolvers/type/product/product-types.js +15 -15
- package/lib/resolvers/type/product/product-types.js.map +1 -1
- package/lib/resolvers/type/token-types.d.ts +9 -12
- package/lib/resolvers/type/token-types.js +22 -3
- package/lib/resolvers/type/token-types.js.map +1 -1
- package/lib/roles/all.js +38 -17
- package/lib/roles/all.js.map +1 -1
- package/lib/roles/index.js +1 -0
- package/lib/roles/index.js.map +1 -1
- package/lib/roles/loggedIn.js +9 -14
- package/lib/roles/loggedIn.js.map +1 -1
- package/lib/schema/mutation.js +5 -1
- package/lib/schema/mutation.js.map +1 -1
- package/lib/schema/query.js +5 -0
- package/lib/schema/query.js.map +1 -1
- package/lib/schema/types/order/item.js +1 -0
- package/lib/schema/types/order/item.js.map +1 -1
- package/lib/schema/types/product/tokenized-product.js +2 -0
- package/lib/schema/types/product/tokenized-product.js.map +1 -1
- package/lib/schema/types/warehousing.js +9 -2
- package/lib/schema/types/warehousing.js.map +1 -1
- package/package.json +8 -8
- package/src/errors.ts +2 -0
- package/src/resolvers/mutations/index.ts +2 -0
- package/src/resolvers/mutations/warehousing/invalidateToken.ts +42 -0
- package/src/resolvers/queries/index.ts +2 -1
- package/src/resolvers/queries/warehousing/tokens.ts +18 -0
- package/src/resolvers/type/order/order-item-types.ts +59 -49
- package/src/resolvers/type/order/order-types.ts +58 -54
- package/src/resolvers/type/product/product-bundle-types.ts +3 -3
- package/src/resolvers/type/product/product-configurable-types.ts +79 -19
- package/src/resolvers/type/product/product-plan-types.ts +34 -15
- package/src/resolvers/type/product/product-simple-types.ts +41 -10
- package/src/resolvers/type/product/product-tokenized-types.ts +43 -13
- package/src/resolvers/type/product/product-types.ts +77 -18
- package/src/resolvers/type/token-types.ts +35 -20
- package/src/roles/all.ts +46 -17
- package/src/roles/index.ts +1 -0
- package/src/roles/loggedIn.ts +10 -24
- package/src/schema/mutation.ts +5 -1
- package/src/schema/query.ts +5 -0
- package/src/schema/types/order/item.ts +1 -0
- package/src/schema/types/product/tokenized-product.ts +2 -0
- package/src/schema/types/warehousing.ts +9 -2
|
@@ -1,24 +1,62 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Product as ProductType,
|
|
3
|
+
ProductAssignment,
|
|
4
|
+
ProductConfiguration,
|
|
5
|
+
ProductPriceRange,
|
|
6
|
+
} from '@unchainedshop/types/products.js';
|
|
7
|
+
import { Context } from '@unchainedshop/types/api.js';
|
|
8
|
+
import { ProductVariation } from '@unchainedshop/types/products.variations.js';
|
|
2
9
|
import { Product } from './product-types.js';
|
|
3
10
|
|
|
4
|
-
export const ConfigurableProduct
|
|
11
|
+
export const ConfigurableProduct = {
|
|
5
12
|
...Product,
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
async assignments(
|
|
15
|
+
product: ProductType,
|
|
16
|
+
params: {
|
|
17
|
+
includeInactive: boolean;
|
|
18
|
+
},
|
|
19
|
+
{ modules }: Context,
|
|
20
|
+
): Promise<
|
|
21
|
+
Array<{
|
|
22
|
+
assignment: ProductAssignment;
|
|
23
|
+
product: typeof product;
|
|
24
|
+
}>
|
|
25
|
+
> {
|
|
26
|
+
return modules.products.proxyAssignments(product, params);
|
|
9
27
|
},
|
|
10
28
|
|
|
11
|
-
|
|
12
|
-
|
|
29
|
+
async products(
|
|
30
|
+
product: ProductType,
|
|
31
|
+
{
|
|
32
|
+
vectors,
|
|
33
|
+
includeInactive,
|
|
34
|
+
}: {
|
|
35
|
+
vectors: Array<ProductConfiguration>;
|
|
36
|
+
includeInactive: boolean;
|
|
37
|
+
},
|
|
38
|
+
{ modules }: Context,
|
|
39
|
+
): Promise<Array<typeof product>> {
|
|
40
|
+
return modules.products.proxyProducts(product, vectors, {
|
|
13
41
|
includeInactive,
|
|
14
42
|
});
|
|
15
43
|
},
|
|
16
44
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
45
|
+
async catalogPriceRange(
|
|
46
|
+
product: ProductType,
|
|
47
|
+
{
|
|
48
|
+
quantity,
|
|
49
|
+
vectors,
|
|
50
|
+
currency: forcedCurrencyCode,
|
|
51
|
+
includeInactive,
|
|
52
|
+
}: {
|
|
53
|
+
currency?: string;
|
|
54
|
+
includeInactive: boolean;
|
|
55
|
+
quantity: number;
|
|
56
|
+
vectors: Array<ProductConfiguration>;
|
|
57
|
+
},
|
|
58
|
+
requestContext: Context,
|
|
59
|
+
): Promise<ProductPriceRange> {
|
|
22
60
|
const { countryContext, modules } = requestContext;
|
|
23
61
|
const currencyCode =
|
|
24
62
|
forcedCurrencyCode ||
|
|
@@ -28,7 +66,7 @@ export const ConfigurableProduct: ConfigurableProductHelperTypes = {
|
|
|
28
66
|
},
|
|
29
67
|
requestContext,
|
|
30
68
|
));
|
|
31
|
-
return modules.products.prices.catalogPriceRange(
|
|
69
|
+
return modules.products.prices.catalogPriceRange(product, {
|
|
32
70
|
quantity,
|
|
33
71
|
vectors,
|
|
34
72
|
includeInactive,
|
|
@@ -37,19 +75,41 @@ export const ConfigurableProduct: ConfigurableProductHelperTypes = {
|
|
|
37
75
|
});
|
|
38
76
|
},
|
|
39
77
|
|
|
40
|
-
|
|
78
|
+
async variations(
|
|
79
|
+
product: ProductType,
|
|
80
|
+
{
|
|
81
|
+
limit = 10,
|
|
82
|
+
offset = 0,
|
|
83
|
+
}: {
|
|
84
|
+
limit: number;
|
|
85
|
+
offset: number;
|
|
86
|
+
},
|
|
87
|
+
{ modules }: Context,
|
|
88
|
+
): Promise<Array<ProductVariation>> {
|
|
41
89
|
return modules.products.variations.findProductVariations({
|
|
42
|
-
productId:
|
|
90
|
+
productId: product._id,
|
|
43
91
|
limit,
|
|
44
92
|
offset,
|
|
45
93
|
});
|
|
46
94
|
},
|
|
47
95
|
|
|
48
96
|
async simulatedPriceRange(
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
|
|
52
|
-
|
|
97
|
+
product: ProductType,
|
|
98
|
+
{
|
|
99
|
+
currency: forcedCurrencyCode,
|
|
100
|
+
quantity,
|
|
101
|
+
useNetPrice,
|
|
102
|
+
vectors,
|
|
103
|
+
includeInactive,
|
|
104
|
+
}: {
|
|
105
|
+
currency?: string;
|
|
106
|
+
includeInactive: boolean;
|
|
107
|
+
quantity?: number;
|
|
108
|
+
vectors: Array<ProductConfiguration>;
|
|
109
|
+
useNetPrice: boolean;
|
|
110
|
+
},
|
|
111
|
+
requestContext: Context,
|
|
112
|
+
): Promise<ProductPriceRange> {
|
|
53
113
|
const { countryContext, modules } = requestContext;
|
|
54
114
|
const currency =
|
|
55
115
|
forcedCurrencyCode ||
|
|
@@ -60,7 +120,7 @@ export const ConfigurableProduct: ConfigurableProductHelperTypes = {
|
|
|
60
120
|
requestContext,
|
|
61
121
|
));
|
|
62
122
|
return modules.products.prices.simulatedPriceRange(
|
|
63
|
-
|
|
123
|
+
product,
|
|
64
124
|
{
|
|
65
125
|
quantity,
|
|
66
126
|
currency,
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProductPrice, Product as ProductType } from '@unchainedshop/types/products.js';
|
|
2
|
+
import { Context } from '@unchainedshop/types/api.js';
|
|
2
3
|
import { Product } from './product-types.js';
|
|
3
4
|
|
|
4
|
-
export const PlanProduct
|
|
5
|
+
export const PlanProduct = {
|
|
5
6
|
...Product,
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
async catalogPrice(
|
|
9
|
+
product: ProductType,
|
|
10
|
+
{ quantity, currency: forcedCurrencyCode }: { quantity?: number; currency?: string },
|
|
11
|
+
requestContext: Context,
|
|
12
|
+
): Promise<ProductPrice> {
|
|
8
13
|
const { modules, countryContext } = requestContext;
|
|
9
14
|
const currencyCode =
|
|
10
15
|
forcedCurrencyCode ||
|
|
@@ -21,11 +26,15 @@ export const PlanProduct: PlanProductHelperTypes = {
|
|
|
21
26
|
});
|
|
22
27
|
},
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
obj,
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
async simulatedPrice(
|
|
30
|
+
obj: ProductType,
|
|
31
|
+
{
|
|
32
|
+
currency: forcedCurrencyCode,
|
|
33
|
+
quantity,
|
|
34
|
+
useNetPrice,
|
|
35
|
+
}: { quantity?: number; currency?: string; useNetPrice?: boolean },
|
|
36
|
+
requestContext: Context,
|
|
37
|
+
): Promise<ProductPrice> {
|
|
29
38
|
const { countryContext, modules } = requestContext;
|
|
30
39
|
const currency =
|
|
31
40
|
forcedCurrencyCode ||
|
|
@@ -42,7 +51,17 @@ export const PlanProduct: PlanProductHelperTypes = {
|
|
|
42
51
|
);
|
|
43
52
|
},
|
|
44
53
|
|
|
45
|
-
|
|
54
|
+
async leveledCatalogPrices(
|
|
55
|
+
obj: ProductType,
|
|
56
|
+
{ currency: forcedCurrencyCode }: { currency?: string },
|
|
57
|
+
requestContext: Context,
|
|
58
|
+
): Promise<
|
|
59
|
+
Array<{
|
|
60
|
+
minQuantity: number;
|
|
61
|
+
maxQuantity: number;
|
|
62
|
+
price: ProductPrice;
|
|
63
|
+
}>
|
|
64
|
+
> {
|
|
46
65
|
const { countryContext, modules } = requestContext;
|
|
47
66
|
const currency =
|
|
48
67
|
forcedCurrencyCode ||
|
|
@@ -55,13 +74,13 @@ export const PlanProduct: PlanProductHelperTypes = {
|
|
|
55
74
|
return modules.products.prices.catalogPricesLeveled(obj, { currency, country: countryContext });
|
|
56
75
|
},
|
|
57
76
|
|
|
58
|
-
salesUnit(
|
|
59
|
-
return
|
|
77
|
+
salesUnit({ commerce }: ProductType): string {
|
|
78
|
+
return commerce?.salesUnit;
|
|
60
79
|
},
|
|
61
|
-
salesQuantityPerUnit(
|
|
62
|
-
return
|
|
80
|
+
salesQuantityPerUnit({ commerce }: ProductType): string {
|
|
81
|
+
return commerce?.salesQuantityPerUnit;
|
|
63
82
|
},
|
|
64
|
-
defaultOrderQuantity(
|
|
65
|
-
return
|
|
83
|
+
defaultOrderQuantity({ commerce }: ProductType): number {
|
|
84
|
+
return commerce?.defaultOrderQuantity;
|
|
66
85
|
},
|
|
67
86
|
};
|
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { WarehousingContext } from '@unchainedshop/types/warehousing.js';
|
|
1
|
+
import { Product, ProductSupply } from '@unchainedshop/types/products.js';
|
|
2
|
+
import { WarehousingContext, WarehousingProvider } from '@unchainedshop/types/warehousing.js';
|
|
3
|
+
import { Context } from '@unchainedshop/types/api.js';
|
|
4
|
+
import { DeliveryProviderType } from '@unchainedshop/core-delivery';
|
|
5
|
+
import { DeliveryProvider } from '@unchainedshop/types/delivery.js';
|
|
3
6
|
import { PlanProduct } from './product-plan-types.js';
|
|
4
7
|
|
|
5
|
-
export const SimpleProduct
|
|
8
|
+
export const SimpleProduct = {
|
|
6
9
|
...PlanProduct,
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
async simulatedDispatches(
|
|
12
|
+
obj: Product,
|
|
13
|
+
params: { referenceDate: Date; quantity: number; deliveryProviderType: DeliveryProviderType },
|
|
14
|
+
requestContext: Context,
|
|
15
|
+
): Promise<
|
|
16
|
+
Array<{
|
|
17
|
+
_id: string;
|
|
18
|
+
deliveryProvider?: DeliveryProvider;
|
|
19
|
+
warehousingProvider?: WarehousingProvider;
|
|
20
|
+
shipping?: Date;
|
|
21
|
+
earliestDelivery?: Date;
|
|
22
|
+
}>
|
|
23
|
+
> {
|
|
9
24
|
const { deliveryProviderType, referenceDate, quantity } = params;
|
|
10
25
|
const { modules } = requestContext;
|
|
11
26
|
|
|
@@ -51,7 +66,21 @@ export const SimpleProduct: SimpleProductHelperTypes = {
|
|
|
51
66
|
}, Promise.resolve([]));
|
|
52
67
|
},
|
|
53
68
|
|
|
54
|
-
|
|
69
|
+
async simulatedStocks(
|
|
70
|
+
obj: Product,
|
|
71
|
+
params: {
|
|
72
|
+
referenceDate: Date;
|
|
73
|
+
deliveryProviderType: DeliveryProviderType;
|
|
74
|
+
},
|
|
75
|
+
requestContext: Context,
|
|
76
|
+
): Promise<
|
|
77
|
+
Array<{
|
|
78
|
+
_id: string;
|
|
79
|
+
deliveryProvider?: DeliveryProvider;
|
|
80
|
+
warehousingProvider?: WarehousingProvider;
|
|
81
|
+
quantity?: number;
|
|
82
|
+
}>
|
|
83
|
+
> {
|
|
55
84
|
const { modules } = requestContext;
|
|
56
85
|
const { referenceDate, deliveryProviderType } = params;
|
|
57
86
|
|
|
@@ -96,13 +125,15 @@ export const SimpleProduct: SimpleProductHelperTypes = {
|
|
|
96
125
|
}, Promise.resolve([]));
|
|
97
126
|
},
|
|
98
127
|
|
|
99
|
-
baseUnit
|
|
100
|
-
return
|
|
128
|
+
baseUnit({ warehousing }): string {
|
|
129
|
+
return warehousing?.baseUnit;
|
|
101
130
|
},
|
|
102
|
-
|
|
103
|
-
|
|
131
|
+
|
|
132
|
+
sku({ warehousing }): string {
|
|
133
|
+
return warehousing?.sku;
|
|
104
134
|
},
|
|
105
|
-
|
|
135
|
+
|
|
136
|
+
dimensions({ supply }): ProductSupply {
|
|
106
137
|
if (!supply) return null;
|
|
107
138
|
const { weightInGram, heightInMillimeters, lengthInMillimeters, widthInMillimeters } = supply;
|
|
108
139
|
return {
|
|
@@ -1,28 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Product,
|
|
3
|
+
ProductContractConfiguration,
|
|
4
|
+
ProductContractStandard,
|
|
5
|
+
} from '@unchainedshop/types/products.js';
|
|
6
|
+
import { WarehousingContext, WarehousingProvider } from '@unchainedshop/types/warehousing.js';
|
|
7
|
+
import { Context } from '@unchainedshop/types/api.js';
|
|
8
|
+
import { DeliveryProvider } from '@unchainedshop/types/delivery.js';
|
|
3
9
|
import { PlanProduct } from './product-plan-types.js';
|
|
10
|
+
import { checkAction } from '../../../acl.js';
|
|
11
|
+
import { actions } from '../../../roles/index.js';
|
|
4
12
|
|
|
5
|
-
export const TokenizedProduct
|
|
13
|
+
export const TokenizedProduct = {
|
|
6
14
|
...PlanProduct,
|
|
7
15
|
|
|
8
|
-
contractAddress(
|
|
9
|
-
return
|
|
16
|
+
contractAddress({ tokenization }: Product): string {
|
|
17
|
+
return tokenization?.contractAddress;
|
|
10
18
|
},
|
|
11
19
|
|
|
12
|
-
contractConfiguration(
|
|
13
|
-
if (!
|
|
20
|
+
contractConfiguration({ tokenization }: Product): ProductContractConfiguration {
|
|
21
|
+
if (!tokenization) return null;
|
|
14
22
|
return {
|
|
15
|
-
supply:
|
|
16
|
-
tokenId:
|
|
17
|
-
ercMetadataProperties:
|
|
23
|
+
supply: tokenization.supply,
|
|
24
|
+
tokenId: tokenization.tokenId,
|
|
25
|
+
ercMetadataProperties: tokenization.ercMetadataProperties,
|
|
18
26
|
};
|
|
19
27
|
},
|
|
20
28
|
|
|
21
|
-
contractStandard(
|
|
22
|
-
return
|
|
29
|
+
contractStandard({ tokenization }: Product): ProductContractStandard {
|
|
30
|
+
return tokenization?.contractStandard;
|
|
23
31
|
},
|
|
24
32
|
|
|
25
|
-
|
|
33
|
+
async simulatedStocks(
|
|
34
|
+
obj: Product,
|
|
35
|
+
params: {
|
|
36
|
+
referenceDate: Date;
|
|
37
|
+
},
|
|
38
|
+
requestContext: Context,
|
|
39
|
+
): Promise<
|
|
40
|
+
Array<{
|
|
41
|
+
_id: string;
|
|
42
|
+
deliveryProvider?: DeliveryProvider;
|
|
43
|
+
warehousingProvider?: WarehousingProvider;
|
|
44
|
+
quantity?: number;
|
|
45
|
+
}>
|
|
46
|
+
> {
|
|
26
47
|
const { modules } = requestContext;
|
|
27
48
|
const { referenceDate } = params;
|
|
28
49
|
|
|
@@ -64,6 +85,15 @@ export const TokenizedProduct: TokenizedProductHelperTypes = {
|
|
|
64
85
|
return result.concat(result, mappedWarehousingProviders);
|
|
65
86
|
}, Promise.resolve([]));
|
|
66
87
|
},
|
|
88
|
+
|
|
89
|
+
async tokens(product: Product, params: never, requestContext: Context) {
|
|
90
|
+
await checkAction(requestContext, actions.viewTokens, [undefined, params]);
|
|
91
|
+
|
|
92
|
+
const tokens = await requestContext.modules.warehousing.findTokens({
|
|
93
|
+
productId: product._id,
|
|
94
|
+
});
|
|
95
|
+
return tokens;
|
|
96
|
+
},
|
|
67
97
|
};
|
|
68
98
|
|
|
69
99
|
delete TokenizedProduct.salesUnit;
|
|
@@ -1,40 +1,91 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ProductTypes } from '@unchainedshop/core-products';
|
|
1
|
+
import { ProductText, Product as ProductType } from '@unchainedshop/types/products.js';
|
|
2
|
+
import { ProductStatus, ProductTypes } from '@unchainedshop/core-products';
|
|
3
3
|
import { objectInvert } from '@unchainedshop/utils';
|
|
4
|
+
import { Context, SortOption } from '@unchainedshop/types/api.js';
|
|
5
|
+
import { AssortmentPathLink } from '@unchainedshop/types/assortments.js';
|
|
6
|
+
import { ProductMedia } from '@unchainedshop/types/products.media.js';
|
|
7
|
+
import { ProductReview } from '@unchainedshop/types/products.reviews.js';
|
|
4
8
|
|
|
5
|
-
export const Product
|
|
6
|
-
__resolveType: (
|
|
9
|
+
export const Product = {
|
|
10
|
+
__resolveType: (product: ProductType): string => {
|
|
7
11
|
const invertedProductTypes = objectInvert(ProductTypes);
|
|
8
|
-
return invertedProductTypes[
|
|
12
|
+
return invertedProductTypes[product.type];
|
|
9
13
|
},
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
async assortmentPaths(
|
|
16
|
+
product: ProductType,
|
|
17
|
+
params: {
|
|
18
|
+
forceLocale?: string;
|
|
19
|
+
},
|
|
20
|
+
{ modules }: Context,
|
|
21
|
+
): Promise<
|
|
22
|
+
Array<{
|
|
23
|
+
links: Array<AssortmentPathLink>;
|
|
24
|
+
}>
|
|
25
|
+
> {
|
|
12
26
|
return modules.assortments.breadcrumbs({
|
|
13
|
-
productId:
|
|
27
|
+
productId: product._id,
|
|
14
28
|
});
|
|
15
29
|
},
|
|
16
30
|
|
|
17
|
-
|
|
31
|
+
async media(
|
|
32
|
+
product: ProductType,
|
|
33
|
+
params: {
|
|
34
|
+
limit: number;
|
|
35
|
+
offset: number;
|
|
36
|
+
tags?: Array<string>;
|
|
37
|
+
},
|
|
38
|
+
{ modules }: Context,
|
|
39
|
+
): Promise<Array<ProductMedia>> {
|
|
18
40
|
return modules.products.media.findProductMedias({
|
|
19
|
-
productId:
|
|
41
|
+
productId: product._id,
|
|
20
42
|
...params,
|
|
21
43
|
});
|
|
22
44
|
},
|
|
23
45
|
|
|
24
|
-
|
|
46
|
+
async reviews(
|
|
47
|
+
product: ProductType,
|
|
48
|
+
{
|
|
49
|
+
limit = 10,
|
|
50
|
+
offset = 0,
|
|
51
|
+
sort,
|
|
52
|
+
queryString,
|
|
53
|
+
}: {
|
|
54
|
+
queryString?: string;
|
|
55
|
+
limit?: number;
|
|
56
|
+
offset?: number;
|
|
57
|
+
sort?: Array<SortOption>;
|
|
58
|
+
},
|
|
59
|
+
{ modules }: Context,
|
|
60
|
+
): Promise<Array<ProductReview>> {
|
|
25
61
|
return modules.products.reviews.findProductReviews({
|
|
26
|
-
productId:
|
|
62
|
+
productId: product._id,
|
|
27
63
|
limit,
|
|
28
64
|
offset,
|
|
29
65
|
sort,
|
|
30
66
|
queryString,
|
|
31
67
|
});
|
|
32
68
|
},
|
|
33
|
-
|
|
34
|
-
|
|
69
|
+
async reviewsCount(
|
|
70
|
+
product: ProductType,
|
|
71
|
+
params: {
|
|
72
|
+
queryString?: string;
|
|
73
|
+
},
|
|
74
|
+
{ modules }: Context,
|
|
75
|
+
): Promise<number> {
|
|
76
|
+
return modules.products.reviews.count({ ...params, productId: product._id });
|
|
35
77
|
},
|
|
36
78
|
|
|
37
|
-
|
|
79
|
+
async siblings(
|
|
80
|
+
product: ProductType,
|
|
81
|
+
params: {
|
|
82
|
+
assortmentId?: string;
|
|
83
|
+
limit: number;
|
|
84
|
+
offset: number;
|
|
85
|
+
includeInactive: boolean;
|
|
86
|
+
},
|
|
87
|
+
{ modules }: Context,
|
|
88
|
+
): Promise<Array<typeof product>> {
|
|
38
89
|
const { assortmentId, limit, offset, includeInactive = false } = params;
|
|
39
90
|
|
|
40
91
|
const productId = product._id;
|
|
@@ -57,14 +108,22 @@ export const Product: ProductHelperTypes = {
|
|
|
57
108
|
});
|
|
58
109
|
},
|
|
59
110
|
|
|
60
|
-
status(
|
|
61
|
-
return modules.products.normalizedStatus(
|
|
111
|
+
status(product: ProductType, _, { modules }: Context): ProductStatus {
|
|
112
|
+
return modules.products.normalizedStatus(product);
|
|
62
113
|
},
|
|
63
114
|
|
|
64
|
-
async texts(
|
|
115
|
+
async texts(
|
|
116
|
+
product: ProductType,
|
|
117
|
+
{
|
|
118
|
+
forceLocale,
|
|
119
|
+
}: {
|
|
120
|
+
forceLocale?: string;
|
|
121
|
+
},
|
|
122
|
+
requestContext: Context,
|
|
123
|
+
): Promise<ProductText> {
|
|
65
124
|
const { localeContext, loaders } = requestContext;
|
|
66
125
|
return loaders.productTextLoader.load({
|
|
67
|
-
productId:
|
|
126
|
+
productId: product._id,
|
|
68
127
|
locale: forceLocale || localeContext.normalized,
|
|
69
128
|
});
|
|
70
129
|
},
|
|
@@ -1,36 +1,23 @@
|
|
|
1
1
|
import { Context } from '@unchainedshop/types/api.js';
|
|
2
|
-
import { Product } from '@unchainedshop/types/products.js';
|
|
3
|
-
import { User } from '@unchainedshop/types/user.js';
|
|
4
2
|
import { TokenStatus, TokenSurrogate } from '@unchainedshop/types/warehousing.js';
|
|
5
3
|
import { WorkStatus } from '@unchainedshop/types/worker.js';
|
|
6
4
|
import localePkg from 'locale';
|
|
5
|
+
import { checkAction } from '../../acl.js';
|
|
6
|
+
import { actions } from '../../roles/index.js';
|
|
7
7
|
|
|
8
8
|
const { Locale } = localePkg;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export interface TokenHelperTypes {
|
|
13
|
-
product: HelperType<Product>;
|
|
14
|
-
status: HelperType<TokenStatus>;
|
|
15
|
-
ercMetadata: (
|
|
16
|
-
root: TokenSurrogate,
|
|
17
|
-
params: { forceLocale?: string },
|
|
18
|
-
context: Context,
|
|
19
|
-
) => Promise<any>;
|
|
20
|
-
user: HelperType<User>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const Token: TokenHelperTypes = {
|
|
24
|
-
product: async (token, _params, { modules }) => {
|
|
10
|
+
export const Token = {
|
|
11
|
+
product: async (token: TokenSurrogate, params: never, { modules }: Context) => {
|
|
25
12
|
return modules.products.findProduct({ productId: token.productId });
|
|
26
13
|
},
|
|
27
14
|
|
|
28
|
-
user: async (token,
|
|
15
|
+
user: async (token: TokenSurrogate, params: never, { modules }: Context) => {
|
|
29
16
|
if (!token.userId) return null;
|
|
30
17
|
return modules.users.findUserById(token.userId);
|
|
31
18
|
},
|
|
32
19
|
|
|
33
|
-
status: async (token,
|
|
20
|
+
status: async (token: TokenSurrogate, params: never, { modules }: Context) => {
|
|
34
21
|
if (token.walletAddress && !token.userId) {
|
|
35
22
|
return TokenStatus.DECENTRALIZED;
|
|
36
23
|
}
|
|
@@ -42,7 +29,11 @@ export const Token: TokenHelperTypes = {
|
|
|
42
29
|
return TokenStatus.CENTRALIZED;
|
|
43
30
|
},
|
|
44
31
|
|
|
45
|
-
ercMetadata: async (
|
|
32
|
+
ercMetadata: async (
|
|
33
|
+
token: TokenSurrogate,
|
|
34
|
+
{ forceLocale }: { forceLocale: string },
|
|
35
|
+
context: Context,
|
|
36
|
+
) => {
|
|
46
37
|
const { modules } = context;
|
|
47
38
|
const product = await modules.products.findProduct({ productId: token.productId });
|
|
48
39
|
const ercMetadata = await modules.warehousing.tokenMetadata(
|
|
@@ -58,4 +49,28 @@ export const Token: TokenHelperTypes = {
|
|
|
58
49
|
|
|
59
50
|
return ercMetadata;
|
|
60
51
|
},
|
|
52
|
+
|
|
53
|
+
isInvalidateable: async (token: TokenSurrogate, _params: never, context: Context) => {
|
|
54
|
+
const { modules } = context;
|
|
55
|
+
const product = await modules.products.findProduct({ productId: token.productId });
|
|
56
|
+
const isInvalidateable = await modules.warehousing.isInvalidateable(
|
|
57
|
+
token.chainTokenId,
|
|
58
|
+
{
|
|
59
|
+
token,
|
|
60
|
+
product,
|
|
61
|
+
referenceDate: new Date(),
|
|
62
|
+
},
|
|
63
|
+
context,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return isInvalidateable;
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
accessKey: async (token: TokenSurrogate, params: never, requestContext: Context) => {
|
|
70
|
+
const { modules } = requestContext;
|
|
71
|
+
await checkAction(requestContext, actions.updateToken, [undefined, { tokenId: token._id }]);
|
|
72
|
+
// This generates a hash that is stable until ownership is changed and allows accessing token
|
|
73
|
+
// data and operations
|
|
74
|
+
return modules.warehousing.buildAccessKeyForToken(token._id);
|
|
75
|
+
},
|
|
61
76
|
};
|