@reactionary/source 0.0.52 → 0.2.16
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/.env-template +19 -0
- package/.github/workflows/pull-request.yml +3 -1
- package/.github/workflows/release.yml +9 -0
- package/.vscode/extensions.json +0 -2
- package/LICENSE +21 -0
- package/README.md +175 -23
- package/core/package.json +6 -3
- package/core/src/cache/cache.interface.ts +1 -0
- package/core/src/cache/index.ts +4 -0
- package/core/src/cache/memory-cache.ts +30 -2
- package/core/src/cache/noop-cache.ts +15 -1
- package/core/src/cache/redis-cache.ts +20 -0
- package/core/src/client/client-builder.ts +71 -54
- package/core/src/client/client.ts +9 -47
- package/core/src/client/index.ts +2 -0
- package/core/src/decorators/index.ts +1 -0
- package/core/src/decorators/reactionary.decorator.ts +203 -34
- package/core/src/index.ts +6 -19
- package/core/src/initialization.ts +1 -18
- package/core/src/metrics/metrics.ts +67 -0
- package/core/src/providers/analytics.provider.ts +1 -6
- package/core/src/providers/base.provider.ts +5 -69
- package/core/src/providers/cart.provider.ts +15 -55
- package/core/src/providers/category.provider.ts +7 -11
- package/core/src/providers/checkout.provider.ts +17 -15
- package/core/src/providers/identity.provider.ts +6 -8
- package/core/src/providers/index.ts +2 -1
- package/core/src/providers/inventory.provider.ts +15 -5
- package/core/src/providers/order-search.provider.ts +29 -0
- package/core/src/providers/order.provider.ts +47 -15
- package/core/src/providers/price.provider.ts +30 -36
- package/core/src/providers/product-search.provider.ts +61 -0
- package/core/src/providers/product.provider.ts +71 -12
- package/core/src/providers/profile.provider.ts +74 -14
- package/core/src/providers/store.provider.ts +3 -5
- package/core/src/schemas/capabilities.schema.ts +10 -3
- package/core/src/schemas/errors/generic.error.ts +9 -0
- package/core/src/schemas/errors/index.ts +4 -0
- package/core/src/schemas/errors/invalid-input.error.ts +9 -0
- package/core/src/schemas/errors/invalid-output.error.ts +9 -0
- package/core/src/schemas/errors/not-found.error.ts +9 -0
- package/core/src/schemas/index.ts +7 -0
- package/core/src/schemas/models/analytics.model.ts +2 -1
- package/core/src/schemas/models/base.model.ts +6 -24
- package/core/src/schemas/models/cart.model.ts +5 -8
- package/core/src/schemas/models/category.model.ts +4 -9
- package/core/src/schemas/models/checkout.model.ts +6 -7
- package/core/src/schemas/models/cost.model.ts +4 -3
- package/core/src/schemas/models/currency.model.ts +2 -1
- package/core/src/schemas/models/identifiers.model.ts +106 -62
- package/core/src/schemas/models/identity.model.ts +10 -19
- package/core/src/schemas/models/index.ts +2 -1
- package/core/src/schemas/models/inventory.model.ts +8 -5
- package/core/src/schemas/models/order-search.model.ts +28 -0
- package/core/src/schemas/models/order.model.ts +20 -26
- package/core/src/schemas/models/payment.model.ts +14 -17
- package/core/src/schemas/models/price.model.ts +11 -11
- package/core/src/schemas/models/product-search.model.ts +42 -0
- package/core/src/schemas/models/product.model.ts +64 -22
- package/core/src/schemas/models/profile.model.ts +19 -22
- package/core/src/schemas/models/shipping-method.model.ts +24 -29
- package/core/src/schemas/models/store.model.ts +9 -5
- package/core/src/schemas/mutations/analytics.mutation.ts +8 -7
- package/core/src/schemas/mutations/base.mutation.ts +2 -1
- package/core/src/schemas/mutations/cart.mutation.ts +33 -33
- package/core/src/schemas/mutations/checkout.mutation.ts +23 -30
- package/core/src/schemas/mutations/identity.mutation.ts +4 -3
- package/core/src/schemas/mutations/profile.mutation.ts +38 -3
- package/core/src/schemas/queries/base.query.ts +2 -1
- package/core/src/schemas/queries/cart.query.ts +3 -3
- package/core/src/schemas/queries/category.query.ts +18 -18
- package/core/src/schemas/queries/checkout.query.ts +7 -9
- package/core/src/schemas/queries/identity.query.ts +2 -1
- package/core/src/schemas/queries/index.ts +2 -1
- package/core/src/schemas/queries/inventory.query.ts +5 -5
- package/core/src/schemas/queries/order-search.query.ts +10 -0
- package/core/src/schemas/queries/order.query.ts +3 -2
- package/core/src/schemas/queries/price.query.ts +10 -4
- package/core/src/schemas/queries/product-search.query.ts +16 -0
- package/core/src/schemas/queries/product.query.ts +13 -6
- package/core/src/schemas/queries/profile.query.ts +5 -2
- package/core/src/schemas/queries/store.query.ts +6 -5
- package/core/src/schemas/result.ts +107 -0
- package/core/src/schemas/session.schema.ts +4 -4
- package/core/src/test/reactionary.decorator.spec.ts +249 -0
- package/core/src/zod-utils.ts +19 -0
- package/core/tsconfig.json +1 -1
- package/core/tsconfig.spec.json +2 -26
- package/core/vitest.config.ts +14 -0
- package/documentation/1-purpose.md +114 -0
- package/documentation/2-getting-started.md +229 -0
- package/documentation/3-querying-and-changing-data.md +74 -0
- package/documentation/4-product-data.md +107 -0
- package/documentation/5-cart-and-checkout.md +211 -0
- package/documentation/6-product-search.md +143 -0
- package/documentation/7-marketing.md +3 -0
- package/eslint.config.mjs +1 -0
- package/examples/node/eslint.config.mjs +1 -4
- package/examples/node/package.json +10 -3
- package/examples/node/project.json +4 -1
- package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +22 -23
- package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +15 -11
- package/examples/node/src/basic/basic-node-setup.spec.ts +44 -28
- package/examples/node/src/basic/client-creation.spec.ts +53 -0
- package/examples/node/src/capabilities/cart.spec.ts +255 -0
- package/examples/node/src/capabilities/category.spec.ts +193 -0
- package/examples/node/src/capabilities/checkout.spec.ts +341 -0
- package/examples/node/src/capabilities/identity.spec.ts +93 -0
- package/examples/node/src/capabilities/inventory.spec.ts +66 -0
- package/examples/node/src/capabilities/order-search.spec.ts +265 -0
- package/examples/node/src/capabilities/order.spec.ts +91 -0
- package/examples/node/src/capabilities/price.spec.ts +51 -0
- package/examples/node/src/capabilities/product-search.spec.ts +293 -0
- package/examples/node/src/capabilities/product.spec.ts +122 -0
- package/examples/node/src/capabilities/profile.spec.ts +316 -0
- package/examples/node/src/capabilities/store.spec.ts +26 -0
- package/examples/node/src/utils.ts +147 -0
- package/examples/node/tsconfig.json +9 -12
- package/examples/node/tsconfig.lib.json +1 -2
- package/examples/node/tsconfig.spec.json +2 -14
- package/examples/node/vitest.config.ts +14 -0
- package/migrations.json +22 -5
- package/nx.json +8 -47
- package/package.json +24 -96
- package/providers/algolia/README.md +39 -2
- package/providers/algolia/package.json +2 -1
- package/providers/algolia/src/core/initialize.ts +7 -14
- package/providers/algolia/src/index.ts +2 -4
- package/providers/algolia/src/providers/index.ts +1 -0
- package/providers/algolia/src/providers/product-search.provider.ts +241 -0
- package/providers/algolia/src/schema/capabilities.schema.ts +2 -3
- package/providers/algolia/src/schema/index.ts +3 -0
- package/providers/algolia/src/schema/search.schema.ts +8 -8
- package/providers/algolia/tsconfig.json +1 -1
- package/providers/algolia/tsconfig.lib.json +1 -1
- package/providers/algolia/tsconfig.spec.json +2 -14
- package/providers/algolia/vitest.config.ts +14 -0
- package/providers/commercetools/README.md +30 -3
- package/providers/commercetools/package.json +2 -1
- package/providers/commercetools/src/core/client.ts +178 -99
- package/providers/commercetools/src/core/initialize.ts +130 -74
- package/providers/commercetools/src/core/token-cache.ts +45 -0
- package/providers/commercetools/src/index.ts +3 -2
- package/providers/commercetools/src/providers/cart.provider.ts +281 -341
- package/providers/commercetools/src/providers/category.provider.ts +223 -138
- package/providers/commercetools/src/providers/checkout.provider.ts +631 -449
- package/providers/commercetools/src/providers/identity.provider.ts +50 -29
- package/providers/commercetools/src/providers/index.ts +2 -2
- package/providers/commercetools/src/providers/inventory.provider.ts +76 -74
- package/providers/commercetools/src/providers/order-search.provider.ts +220 -0
- package/providers/commercetools/src/providers/order.provider.ts +96 -61
- package/providers/commercetools/src/providers/price.provider.ts +147 -117
- package/providers/commercetools/src/providers/product-search.provider.ts +528 -0
- package/providers/commercetools/src/providers/product.provider.ts +249 -74
- package/providers/commercetools/src/providers/profile.provider.ts +445 -28
- package/providers/commercetools/src/providers/store.provider.ts +54 -40
- package/providers/commercetools/src/schema/capabilities.schema.ts +3 -1
- package/providers/commercetools/src/schema/commercetools.schema.ts +17 -3
- package/providers/commercetools/src/schema/configuration.schema.ts +1 -0
- package/providers/commercetools/src/schema/session.schema.ts +7 -0
- package/providers/commercetools/src/test/caching.spec.ts +82 -0
- package/providers/commercetools/src/test/identity.spec.ts +109 -0
- package/providers/commercetools/src/test/test-utils.ts +21 -19
- package/providers/commercetools/tsconfig.json +1 -1
- package/providers/commercetools/tsconfig.lib.json +1 -1
- package/providers/commercetools/tsconfig.spec.json +2 -14
- package/providers/commercetools/vitest.config.ts +15 -0
- package/providers/fake/README.md +20 -4
- package/providers/fake/package.json +2 -1
- package/providers/fake/src/core/initialize.ts +47 -49
- package/providers/fake/src/providers/analytics.provider.ts +5 -7
- package/providers/fake/src/providers/cart.provider.ts +163 -92
- package/providers/fake/src/providers/category.provider.ts +78 -50
- package/providers/fake/src/providers/checkout.provider.ts +254 -0
- package/providers/fake/src/providers/identity.provider.ts +57 -65
- package/providers/fake/src/providers/index.ts +6 -2
- package/providers/fake/src/providers/inventory.provider.ts +40 -36
- package/providers/fake/src/providers/order-search.provider.ts +78 -0
- package/providers/fake/src/providers/order.provider.ts +106 -0
- package/providers/fake/src/providers/price.provider.ts +93 -41
- package/providers/fake/src/providers/product-search.provider.ts +206 -0
- package/providers/fake/src/providers/product.provider.ts +56 -41
- package/providers/fake/src/providers/profile.provider.ts +147 -0
- package/providers/fake/src/providers/store.provider.ts +30 -20
- package/providers/fake/src/schema/capabilities.schema.ts +5 -1
- package/providers/fake/src/test/cart.provider.spec.ts +59 -80
- package/providers/fake/src/test/category.provider.spec.ts +145 -87
- package/providers/fake/src/test/checkout.provider.spec.ts +222 -0
- package/providers/fake/src/test/order-search.provider.spec.ts +50 -0
- package/providers/fake/src/test/order.provider.spec.ts +44 -0
- package/providers/fake/src/test/price.provider.spec.ts +50 -45
- package/providers/fake/src/test/product.provider.spec.ts +15 -7
- package/providers/fake/src/test/profile.provider.spec.ts +167 -0
- package/providers/fake/tsconfig.json +1 -1
- package/providers/fake/tsconfig.lib.json +1 -1
- package/providers/fake/tsconfig.spec.json +2 -12
- package/providers/fake/vitest.config.ts +14 -0
- package/providers/medusa/README.md +30 -0
- package/providers/medusa/TESTING.md +98 -0
- package/providers/medusa/eslint.config.mjs +19 -0
- package/providers/medusa/package.json +22 -0
- package/providers/medusa/project.json +34 -0
- package/providers/medusa/src/core/client.ts +370 -0
- package/providers/medusa/src/core/initialize.ts +78 -0
- package/providers/medusa/src/index.ts +13 -0
- package/providers/medusa/src/providers/cart.provider.ts +575 -0
- package/providers/medusa/src/providers/category.provider.ts +247 -0
- package/providers/medusa/src/providers/checkout.provider.ts +636 -0
- package/providers/medusa/src/providers/identity.provider.ts +137 -0
- package/providers/medusa/src/providers/inventory.provider.ts +173 -0
- package/providers/medusa/src/providers/order-search.provider.ts +202 -0
- package/providers/medusa/src/providers/order.provider.ts +226 -0
- package/providers/medusa/src/providers/price.provider.ts +140 -0
- package/providers/medusa/src/providers/product-search.provider.ts +243 -0
- package/providers/medusa/src/providers/product.provider.ts +261 -0
- package/providers/medusa/src/providers/profile.provider.ts +392 -0
- package/providers/medusa/src/schema/capabilities.schema.ts +18 -0
- package/providers/medusa/src/schema/configuration.schema.ts +11 -0
- package/providers/medusa/src/schema/medusa.schema.ts +31 -0
- package/providers/medusa/src/test/cart.provider.spec.ts +240 -0
- package/providers/medusa/src/test/category.provider.spec.ts +231 -0
- package/providers/medusa/src/test/checkout.spec.ts +349 -0
- package/providers/medusa/src/test/identity.provider.spec.ts +122 -0
- package/providers/medusa/src/test/inventory.provider.spec.ts +88 -0
- package/providers/medusa/src/test/large-cart.provider.spec.ts +103 -0
- package/providers/medusa/src/test/price.provider.spec.ts +104 -0
- package/providers/medusa/src/test/product.provider.spec.ts +146 -0
- package/providers/medusa/src/test/search.provider.spec.ts +203 -0
- package/providers/medusa/src/test/test-utils.ts +13 -0
- package/providers/medusa/src/utils/medusa-helpers.ts +89 -0
- package/providers/medusa/tsconfig.json +21 -0
- package/providers/medusa/tsconfig.lib.json +9 -0
- package/providers/medusa/tsconfig.spec.json +4 -0
- package/providers/medusa/vitest.config.ts +15 -0
- package/providers/meilisearch/README.md +48 -0
- package/providers/meilisearch/eslint.config.mjs +22 -0
- package/providers/meilisearch/package.json +13 -0
- package/providers/meilisearch/project.json +34 -0
- package/providers/meilisearch/src/core/initialize.ts +21 -0
- package/providers/meilisearch/src/index.ts +6 -0
- package/providers/meilisearch/src/providers/index.ts +1 -0
- package/providers/meilisearch/src/providers/order-search.provider.ts +222 -0
- package/providers/meilisearch/src/providers/product-search.provider.ts +251 -0
- package/providers/meilisearch/src/schema/capabilities.schema.ts +10 -0
- package/providers/meilisearch/src/schema/configuration.schema.ts +11 -0
- package/providers/meilisearch/src/schema/index.ts +3 -0
- package/providers/meilisearch/src/schema/search.schema.ts +14 -0
- package/providers/meilisearch/tsconfig.json +24 -0
- package/providers/meilisearch/tsconfig.lib.json +10 -0
- package/providers/meilisearch/tsconfig.spec.json +4 -0
- package/providers/meilisearch/vitest.config.ts +14 -0
- package/providers/posthog/package.json +2 -1
- package/providers/posthog/tsconfig.json +1 -1
- package/tsconfig.base.json +5 -0
- package/vitest.config.ts +10 -0
- package/core/src/providers/search.provider.ts +0 -18
- package/core/src/schemas/models/search.model.ts +0 -36
- package/core/src/schemas/queries/search.query.ts +0 -9
- package/examples/next/.swcrc +0 -30
- package/examples/next/eslint.config.mjs +0 -21
- package/examples/next/index.d.ts +0 -6
- package/examples/next/next-env.d.ts +0 -5
- package/examples/next/next.config.js +0 -31
- package/examples/next/project.json +0 -9
- package/examples/next/public/.gitkeep +0 -0
- package/examples/next/public/favicon.ico +0 -0
- package/examples/next/src/app/global.css +0 -0
- package/examples/next/src/app/layout.tsx +0 -18
- package/examples/next/src/app/page.module.scss +0 -2
- package/examples/next/src/app/page.tsx +0 -47
- package/examples/next/src/instrumentation.ts +0 -9
- package/examples/next/tsconfig.json +0 -44
- package/examples/node/jest.config.ts +0 -10
- package/jest.config.ts +0 -6
- package/jest.preset.js +0 -3
- package/providers/algolia/jest.config.ts +0 -10
- package/providers/algolia/src/providers/product.provider.ts +0 -66
- package/providers/algolia/src/providers/search.provider.ts +0 -106
- package/providers/algolia/src/test/search.provider.spec.ts +0 -91
- package/providers/commercetools/jest.config.cjs +0 -10
- package/providers/commercetools/src/providers/search.provider.ts +0 -96
- package/providers/commercetools/src/test/cart.provider.spec.ts +0 -199
- package/providers/commercetools/src/test/category.provider.spec.ts +0 -168
- package/providers/commercetools/src/test/checkout.provider.spec.ts +0 -312
- package/providers/commercetools/src/test/identity.provider.spec.ts +0 -88
- package/providers/commercetools/src/test/inventory.provider.spec.ts +0 -41
- package/providers/commercetools/src/test/price.provider.spec.ts +0 -81
- package/providers/commercetools/src/test/product.provider.spec.ts +0 -80
- package/providers/commercetools/src/test/profile.provider.spec.ts +0 -49
- package/providers/commercetools/src/test/search.provider.spec.ts +0 -61
- package/providers/commercetools/src/test/store.provider.spec.ts +0 -37
- package/providers/fake/jest.config.cjs +0 -10
- package/providers/fake/src/providers/search.provider.ts +0 -132
|
@@ -9,84 +9,93 @@ import type {
|
|
|
9
9
|
CartIdentifier,
|
|
10
10
|
CartMutationApplyCoupon,
|
|
11
11
|
CartMutationChangeCurrency,
|
|
12
|
-
CartMutationCheckout,
|
|
13
12
|
CartMutationDeleteCart,
|
|
14
13
|
CartMutationRemoveCoupon,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
Result,
|
|
15
|
+
NotFoundError
|
|
16
|
+
} from '@reactionary/core';
|
|
18
17
|
import {
|
|
19
|
-
|
|
18
|
+
CartIdentifierSchema,
|
|
19
|
+
CartMutationApplyCouponSchema,
|
|
20
|
+
CartMutationChangeCurrencySchema,
|
|
21
|
+
CartMutationDeleteCartSchema,
|
|
22
|
+
CartMutationItemAddSchema,
|
|
23
|
+
CartMutationItemQuantityChangeSchema,
|
|
24
|
+
CartMutationItemRemoveSchema,
|
|
25
|
+
CartMutationRemoveCouponSchema,
|
|
26
|
+
CartProvider,
|
|
27
|
+
CartQueryByIdSchema,
|
|
28
|
+
CartSchema,
|
|
29
|
+
Reactionary,
|
|
30
|
+
error,
|
|
31
|
+
success,
|
|
32
|
+
unwrapValue,
|
|
20
33
|
} from '@reactionary/core';
|
|
21
|
-
import type z from 'zod';
|
|
22
34
|
import type { FakeConfiguration } from '../schema/configuration.schema.js';
|
|
23
35
|
import { Faker, en, base } from '@faker-js/faker';
|
|
24
36
|
|
|
25
|
-
export class FakeCartProvider
|
|
26
|
-
T extends Cart = Cart
|
|
27
|
-
> extends CartProvider<T> {
|
|
37
|
+
export class FakeCartProvider extends CartProvider {
|
|
28
38
|
protected config: FakeConfiguration;
|
|
29
|
-
private carts: Map<string,
|
|
39
|
+
private carts: Map<string, Cart> = new Map();
|
|
30
40
|
private generator: Faker;
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
constructor(
|
|
43
|
+
config: FakeConfiguration,
|
|
44
|
+
cache: Cache,
|
|
45
|
+
context: RequestContext
|
|
46
|
+
) {
|
|
47
|
+
super(cache, context);
|
|
35
48
|
this.generator = new Faker({
|
|
36
49
|
locale: [en, base],
|
|
37
|
-
seed: config.seeds.product
|
|
50
|
+
seed: config.seeds.product,
|
|
38
51
|
});
|
|
39
52
|
this.config = config;
|
|
40
53
|
}
|
|
41
54
|
|
|
55
|
+
@Reactionary({
|
|
56
|
+
inputSchema: CartQueryByIdSchema,
|
|
57
|
+
outputSchema: CartSchema,
|
|
58
|
+
})
|
|
42
59
|
public override async getById(
|
|
43
|
-
payload: CartQueryById
|
|
44
|
-
|
|
45
|
-
): Promise<T> {
|
|
60
|
+
payload: CartQueryById
|
|
61
|
+
): Promise<Result<Cart, NotFoundError>> {
|
|
46
62
|
const cartId = payload.cart.key;
|
|
47
63
|
|
|
48
64
|
if (payload.cart.key === '') {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
return this.assert(result);
|
|
65
|
+
return error<NotFoundError>({
|
|
66
|
+
type: 'NotFound',
|
|
67
|
+
identifier: cartId,
|
|
68
|
+
});
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
if (!this.carts.has(cartId)) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
meta: {
|
|
63
|
-
cache: {
|
|
64
|
-
hit: false,
|
|
65
|
-
key: cartId,
|
|
66
|
-
},
|
|
67
|
-
placeholder: false,
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
this.carts.set(cartId, this.assert(model));
|
|
72
|
+
const cart = this.createEmptyCart();
|
|
73
|
+
cart.identifier.key = cartId;
|
|
74
|
+
|
|
75
|
+
this.carts.set(cartId, cart);
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
const cart = this.carts.get(cartId);
|
|
74
79
|
if (!cart) {
|
|
75
80
|
throw new Error(`Cart with id ${cartId} not found`);
|
|
76
81
|
}
|
|
77
|
-
return cart;
|
|
82
|
+
return success(cart);
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
const cartId = payload
|
|
86
|
-
const cart = await this.getById({ cart: { key: cartId } }
|
|
85
|
+
@Reactionary({
|
|
86
|
+
inputSchema: CartMutationItemAddSchema,
|
|
87
|
+
outputSchema: CartSchema,
|
|
88
|
+
})
|
|
89
|
+
public override async add(payload: CartMutationItemAdd): Promise<Result<Cart>> {
|
|
90
|
+
const cartId = payload?.cart?.key || `cart-${this.generator.string.uuid()}`;
|
|
91
|
+
const cart = unwrapValue(await this.getById({ cart: { key: cartId } }));
|
|
87
92
|
|
|
93
|
+
if (cart.identifier.key === '') {
|
|
94
|
+
cart.identifier.key = cartId;
|
|
95
|
+
this.carts.set(cartId, cart);
|
|
96
|
+
}
|
|
88
97
|
const existingItemIndex = cart.items.findIndex(
|
|
89
|
-
item => item.sku
|
|
98
|
+
(item) => item.variant.sku === payload.variant.sku
|
|
90
99
|
);
|
|
91
100
|
|
|
92
101
|
if (existingItemIndex >= 0) {
|
|
@@ -96,118 +105,180 @@ export class FakeCartProvider<
|
|
|
96
105
|
|
|
97
106
|
cart.items.push({
|
|
98
107
|
identifier: { key: `item-${Date.now()}` },
|
|
99
|
-
|
|
108
|
+
variant: payload.variant,
|
|
100
109
|
quantity: payload.quantity,
|
|
101
110
|
price: {
|
|
102
111
|
unitPrice: {
|
|
103
112
|
value: price,
|
|
104
|
-
currency:
|
|
113
|
+
currency: this.context.languageContext.currencyCode,
|
|
105
114
|
},
|
|
106
115
|
totalPrice: {
|
|
107
116
|
value: 0, // Will be calculated below
|
|
108
|
-
currency:
|
|
117
|
+
currency: this.context.languageContext.currencyCode,
|
|
109
118
|
},
|
|
110
119
|
totalDiscount: {
|
|
111
120
|
value: 0,
|
|
112
|
-
currency:
|
|
121
|
+
currency: this.context.languageContext.currencyCode,
|
|
113
122
|
},
|
|
114
123
|
unitDiscount: {
|
|
115
124
|
value: 0,
|
|
116
|
-
currency:
|
|
125
|
+
currency: this.context.languageContext.currencyCode,
|
|
117
126
|
},
|
|
118
127
|
},
|
|
119
128
|
product: {
|
|
120
|
-
key: `product-for-${payload.sku
|
|
129
|
+
key: `product-for-${payload.variant.sku}`,
|
|
121
130
|
},
|
|
122
|
-
|
|
123
|
-
|
|
124
131
|
});
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
this.recalculateCart(cart);
|
|
128
135
|
|
|
129
|
-
return
|
|
136
|
+
return success(cart);
|
|
130
137
|
}
|
|
131
138
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
139
|
+
@Reactionary({
|
|
140
|
+
inputSchema: CartMutationItemRemoveSchema,
|
|
141
|
+
outputSchema: CartSchema,
|
|
142
|
+
})
|
|
143
|
+
public override async remove(payload: CartMutationItemRemove): Promise<Result<Cart>> {
|
|
136
144
|
const cartId = payload.cart.key || `cart-${this.generator.string.uuid()}`;
|
|
137
|
-
const cart = await this.getById({ cart: { key: cartId } }
|
|
145
|
+
const cart = unwrapValue(await this.getById({ cart: { key: cartId } }));
|
|
138
146
|
|
|
139
147
|
cart.items = cart.items.filter(
|
|
140
|
-
item => item.identifier.key !== payload.item.key
|
|
148
|
+
(item) => item.identifier.key !== payload.item.key
|
|
141
149
|
);
|
|
142
150
|
this.recalculateCart(cart);
|
|
143
|
-
|
|
151
|
+
|
|
152
|
+
return success(cart);
|
|
144
153
|
}
|
|
145
154
|
|
|
155
|
+
@Reactionary({
|
|
156
|
+
inputSchema: CartMutationItemQuantityChangeSchema,
|
|
157
|
+
outputSchema: CartSchema,
|
|
158
|
+
})
|
|
146
159
|
public override async changeQuantity(
|
|
147
|
-
payload: CartMutationItemQuantityChange
|
|
148
|
-
|
|
149
|
-
): Promise<T> {
|
|
160
|
+
payload: CartMutationItemQuantityChange
|
|
161
|
+
): Promise<Result<Cart>> {
|
|
150
162
|
const cartId = payload.cart.key || `cart-${this.generator.string.uuid()}`;
|
|
151
|
-
const cart = await this.getById({ cart: { key: cartId } }
|
|
163
|
+
const cart = unwrapValue(await this.getById({ cart: { key: cartId } }));
|
|
152
164
|
|
|
153
165
|
const item = cart.items.find(
|
|
154
|
-
item => item.identifier.key === payload.item.key
|
|
166
|
+
(item) => item.identifier.key === payload.item.key
|
|
155
167
|
);
|
|
156
168
|
if (payload.quantity < 1) {
|
|
157
|
-
return cart;
|
|
169
|
+
return success(cart);
|
|
158
170
|
}
|
|
159
171
|
if (item) {
|
|
160
172
|
item.quantity = payload.quantity;
|
|
161
173
|
}
|
|
162
174
|
this.recalculateCart(cart);
|
|
163
|
-
return
|
|
175
|
+
return success(cart);
|
|
164
176
|
}
|
|
165
177
|
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
@Reactionary({
|
|
179
|
+
outputSchema: CartIdentifierSchema,
|
|
180
|
+
})
|
|
181
|
+
public override getActiveCartId(): Promise<Result<CartIdentifier, NotFoundError>> {
|
|
168
182
|
throw new Error('Method not implemented.');
|
|
169
183
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
public override setBillingAddress(payload: CartMutationSetBillingAddress, reqCtx: RequestContext): Promise<T> {
|
|
177
|
-
throw new Error('Method not implemented.');
|
|
178
|
-
}
|
|
179
|
-
public override applyCouponCode(payload: CartMutationApplyCoupon, reqCtx: RequestContext): Promise<T> {
|
|
184
|
+
|
|
185
|
+
@Reactionary({
|
|
186
|
+
inputSchema: CartMutationDeleteCartSchema,
|
|
187
|
+
outputSchema: CartSchema,
|
|
188
|
+
})
|
|
189
|
+
public override deleteCart(payload: CartMutationDeleteCart): Promise<Result<void>> {
|
|
180
190
|
throw new Error('Method not implemented.');
|
|
181
191
|
}
|
|
182
|
-
|
|
192
|
+
|
|
193
|
+
@Reactionary({
|
|
194
|
+
inputSchema: CartMutationApplyCouponSchema,
|
|
195
|
+
outputSchema: CartSchema,
|
|
196
|
+
})
|
|
197
|
+
public override applyCouponCode(
|
|
198
|
+
payload: CartMutationApplyCoupon
|
|
199
|
+
): Promise<Result<Cart>> {
|
|
183
200
|
throw new Error('Method not implemented.');
|
|
184
201
|
}
|
|
185
|
-
|
|
202
|
+
|
|
203
|
+
@Reactionary({
|
|
204
|
+
inputSchema: CartMutationRemoveCouponSchema,
|
|
205
|
+
outputSchema: CartSchema,
|
|
206
|
+
})
|
|
207
|
+
public override removeCouponCode(
|
|
208
|
+
payload: CartMutationRemoveCoupon
|
|
209
|
+
): Promise<Result<Cart>> {
|
|
186
210
|
throw new Error('Method not implemented.');
|
|
187
211
|
}
|
|
188
|
-
|
|
212
|
+
|
|
213
|
+
@Reactionary({
|
|
214
|
+
inputSchema: CartMutationChangeCurrencySchema,
|
|
215
|
+
outputSchema: CartSchema,
|
|
216
|
+
})
|
|
217
|
+
public override changeCurrency(
|
|
218
|
+
payload: CartMutationChangeCurrency
|
|
219
|
+
): Promise<Result<Cart>> {
|
|
189
220
|
throw new Error('Method not implemented.');
|
|
190
221
|
}
|
|
191
222
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
protected recalculateCart(cart: T) {
|
|
196
|
-
cart.items.forEach(item => {
|
|
223
|
+
protected recalculateCart(cart: Cart) {
|
|
224
|
+
cart.items.forEach((item) => {
|
|
197
225
|
item.price.totalPrice.value = item.price.unitPrice.value * item.quantity;
|
|
198
226
|
});
|
|
199
227
|
|
|
200
228
|
cart.price.totalProductPrice = {
|
|
201
|
-
value: cart.items.reduce(
|
|
229
|
+
value: cart.items.reduce(
|
|
230
|
+
(sum, item) => sum + item.price.totalPrice.value,
|
|
231
|
+
0
|
|
232
|
+
),
|
|
202
233
|
currency: cart.items[0]?.price.unitPrice.currency || 'USD',
|
|
203
|
-
}
|
|
234
|
+
};
|
|
204
235
|
|
|
205
236
|
cart.price.grandTotal = {
|
|
206
|
-
value: cart.items.reduce(
|
|
237
|
+
value: cart.items.reduce(
|
|
238
|
+
(sum, item) => sum + item.price.totalPrice.value,
|
|
239
|
+
0
|
|
240
|
+
),
|
|
207
241
|
currency: cart.items[0]?.price.unitPrice.currency || 'USD',
|
|
208
242
|
};
|
|
209
243
|
}
|
|
210
244
|
|
|
245
|
+
protected createEmptyCart(): Cart {
|
|
246
|
+
const cart = {
|
|
247
|
+
identifier: { key: '' },
|
|
248
|
+
description: '',
|
|
249
|
+
items: [],
|
|
250
|
+
name: '',
|
|
251
|
+
price: {
|
|
252
|
+
grandTotal: {
|
|
253
|
+
value: 0,
|
|
254
|
+
currency: 'XXX',
|
|
255
|
+
},
|
|
256
|
+
totalDiscount: {
|
|
257
|
+
value: 0,
|
|
258
|
+
currency: 'XXX',
|
|
259
|
+
},
|
|
260
|
+
totalProductPrice: {
|
|
261
|
+
value: 0,
|
|
262
|
+
currency: 'XXX',
|
|
263
|
+
},
|
|
264
|
+
totalShipping: {
|
|
265
|
+
value: 0,
|
|
266
|
+
currency: 'XXX',
|
|
267
|
+
},
|
|
268
|
+
totalSurcharge: {
|
|
269
|
+
value: 0,
|
|
270
|
+
currency: 'XXX',
|
|
271
|
+
},
|
|
272
|
+
totalTax: {
|
|
273
|
+
value: 0,
|
|
274
|
+
currency: 'XXX',
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
userId: {
|
|
278
|
+
userId: '',
|
|
279
|
+
},
|
|
280
|
+
} satisfies Cart;
|
|
211
281
|
|
|
212
|
-
|
|
282
|
+
return cart;
|
|
283
|
+
}
|
|
213
284
|
}
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import type { Category, CategoryQueryById, CategoryQueryBySlug, CategoryQueryForBreadcrumb, CategoryQueryForChildCategories, CategoryQueryForTopCategories, RequestContext} from "@reactionary/core";
|
|
2
|
-
import { CategoryProvider, Reactionary } from "@reactionary/core";
|
|
1
|
+
import type { Result, NotFoundError, Category, CategoryPaginatedResult, CategoryQueryById, CategoryQueryBySlug, CategoryQueryForBreadcrumb, CategoryQueryForChildCategories, CategoryQueryForTopCategories, RequestContext} from "@reactionary/core";
|
|
2
|
+
import { success, error, CategoryPaginatedResultSchema, CategoryProvider, CategoryQueryByIdSchema, CategoryQueryBySlugSchema, CategoryQueryForBreadcrumbSchema, CategoryQueryForChildCategoriesSchema, CategoryQueryForTopCategoriesSchema, CategorySchema, Reactionary } from "@reactionary/core";
|
|
3
3
|
import type { FakeConfiguration } from "../schema/configuration.schema.js";
|
|
4
4
|
import type { Cache as ReactionaryCache } from "@reactionary/core";
|
|
5
|
-
import
|
|
5
|
+
import z from "zod";
|
|
6
6
|
import { Faker, en, base } from '@faker-js/faker';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
> extends CategoryProvider<T> {
|
|
7
|
+
|
|
8
|
+
export class FakeCategoryProvider extends CategoryProvider {
|
|
10
9
|
|
|
11
10
|
protected config: FakeConfiguration;
|
|
12
11
|
|
|
13
|
-
protected topCategories = new Array<
|
|
14
|
-
protected childCategories = new Map<string, Array<
|
|
15
|
-
protected allCategories = new Map<string,
|
|
12
|
+
protected topCategories = new Array<Category>();
|
|
13
|
+
protected childCategories = new Map<string, Array<Category>>();
|
|
14
|
+
protected allCategories = new Map<string, Category>();
|
|
16
15
|
|
|
17
16
|
protected categoryGenerator: Faker;
|
|
18
17
|
|
|
19
|
-
protected generateFakeCategory(parent: Category | undefined, index: number):
|
|
20
|
-
|
|
18
|
+
protected generateFakeCategory(parent: Category | undefined, index: number): Category {
|
|
21
19
|
let name: string;
|
|
22
20
|
if (!parent) {
|
|
23
21
|
name = this.categoryGenerator.commerce.department();
|
|
@@ -25,21 +23,31 @@ export class FakeCategoryProvider<
|
|
|
25
23
|
name = `${parent.name}-${index}`;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
const identifier = { key: name.toLowerCase().replace(/\s+/g, '-') };
|
|
27
|
+
const text = this.categoryGenerator.lorem.sentences(3);
|
|
28
|
+
const slug = identifier.key + '-slug';
|
|
29
|
+
|
|
30
|
+
let parentCategory;
|
|
33
31
|
if (parent) {
|
|
34
|
-
|
|
32
|
+
parentCategory = parent.identifier;
|
|
35
33
|
}
|
|
36
|
-
|
|
34
|
+
|
|
35
|
+
const category = {
|
|
36
|
+
identifier,
|
|
37
|
+
images: [],
|
|
38
|
+
name,
|
|
39
|
+
slug,
|
|
40
|
+
text,
|
|
41
|
+
parentCategory
|
|
42
|
+
} satisfies Category;
|
|
43
|
+
|
|
44
|
+
this.allCategories.set(identifier.key, category);
|
|
37
45
|
return category;
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
|
|
41
|
-
constructor(config: FakeConfiguration,
|
|
42
|
-
super(
|
|
49
|
+
constructor(config: FakeConfiguration, cache: ReactionaryCache, context: RequestContext) {
|
|
50
|
+
super(cache, context);
|
|
43
51
|
this.config = config;
|
|
44
52
|
this.categoryGenerator = new Faker({
|
|
45
53
|
seed: this.config.seeds.category,
|
|
@@ -48,21 +56,21 @@ export class FakeCategoryProvider<
|
|
|
48
56
|
|
|
49
57
|
// Generate some top-level categories
|
|
50
58
|
for (let i = 0; i < 6; i++) {
|
|
51
|
-
const category
|
|
59
|
+
const category = this.generateFakeCategory(undefined, i);
|
|
52
60
|
this.topCategories.push(category);
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
// Generate two levels of child categories
|
|
56
64
|
this.topCategories.forEach((parentCategory) => {
|
|
57
|
-
const children = new Array<
|
|
65
|
+
const children = new Array<Category>();
|
|
58
66
|
for (let j = 0; j < 5; j++) {
|
|
59
|
-
const childCategory
|
|
67
|
+
const childCategory = this.generateFakeCategory(parentCategory, j);
|
|
60
68
|
children.push(childCategory);
|
|
61
69
|
|
|
62
70
|
|
|
63
|
-
const subCategoryChildren = new Array<
|
|
71
|
+
const subCategoryChildren = new Array<Category>();
|
|
64
72
|
for(let k = 0; k < 5; k++) {
|
|
65
|
-
const subChildCategory
|
|
73
|
+
const subChildCategory = this.generateFakeCategory(childCategory, k);
|
|
66
74
|
subCategoryChildren.push(subChildCategory);
|
|
67
75
|
}
|
|
68
76
|
this.childCategories.set(childCategory.identifier.key, subCategoryChildren);
|
|
@@ -71,48 +79,64 @@ export class FakeCategoryProvider<
|
|
|
71
79
|
});
|
|
72
80
|
}
|
|
73
81
|
|
|
74
|
-
@Reactionary({
|
|
75
|
-
|
|
82
|
+
@Reactionary({
|
|
83
|
+
inputSchema: CategoryQueryByIdSchema,
|
|
84
|
+
outputSchema: CategorySchema
|
|
85
|
+
})
|
|
86
|
+
public override async getById(payload: CategoryQueryById): Promise<Result<Category, NotFoundError>> {
|
|
76
87
|
const category = this.allCategories.get(payload.id.key);
|
|
77
88
|
|
|
78
89
|
if(!category) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
return error<NotFoundError>({
|
|
91
|
+
type: 'NotFound',
|
|
92
|
+
identifier: payload
|
|
93
|
+
});
|
|
83
94
|
}
|
|
84
|
-
|
|
95
|
+
|
|
96
|
+
return success(category);
|
|
85
97
|
}
|
|
86
98
|
|
|
87
|
-
@Reactionary({
|
|
88
|
-
|
|
99
|
+
@Reactionary({
|
|
100
|
+
inputSchema: CategoryQueryBySlugSchema,
|
|
101
|
+
outputSchema: CategorySchema
|
|
102
|
+
})
|
|
103
|
+
public override async getBySlug(payload: CategoryQueryBySlug): Promise<Result<Category, NotFoundError>> {
|
|
89
104
|
for(const p of this.allCategories.values()) {
|
|
90
105
|
if(p.slug === payload.slug) {
|
|
91
|
-
return
|
|
106
|
+
return success(p);
|
|
92
107
|
}
|
|
93
108
|
}
|
|
94
|
-
return
|
|
109
|
+
return error<NotFoundError>({
|
|
110
|
+
type: 'NotFound',
|
|
111
|
+
identifier: payload
|
|
112
|
+
});
|
|
95
113
|
}
|
|
96
114
|
|
|
97
|
-
@Reactionary({
|
|
98
|
-
|
|
99
|
-
|
|
115
|
+
@Reactionary({
|
|
116
|
+
inputSchema: CategoryQueryForBreadcrumbSchema,
|
|
117
|
+
outputSchema: z.array(CategorySchema)
|
|
118
|
+
})
|
|
119
|
+
public override async getBreadcrumbPathToCategory(payload: CategoryQueryForBreadcrumb): Promise<Result<Category[]>> {
|
|
120
|
+
const path = new Array<Category>();
|
|
100
121
|
let category = this.allCategories.get(payload.id.key);
|
|
101
|
-
path.push(category
|
|
122
|
+
path.push(category!);
|
|
102
123
|
while(category?.parentCategory) {
|
|
103
124
|
category = this.allCategories.get(category.parentCategory.key);
|
|
104
125
|
if(category) {
|
|
105
|
-
path.unshift(category
|
|
126
|
+
path.unshift(category);
|
|
106
127
|
}
|
|
107
128
|
}
|
|
108
|
-
return
|
|
129
|
+
return success(path);
|
|
109
130
|
}
|
|
110
131
|
|
|
111
|
-
|
|
132
|
+
@Reactionary({
|
|
133
|
+
inputSchema: CategoryQueryForChildCategoriesSchema,
|
|
134
|
+
outputSchema: CategoryPaginatedResultSchema
|
|
135
|
+
})
|
|
136
|
+
public override async findChildCategories(payload: CategoryQueryForChildCategories): Promise<Result<CategoryPaginatedResult>> {
|
|
112
137
|
const children = this.childCategories.get(payload.parentId.key);
|
|
113
138
|
const page = children?.slice((payload.paginationOptions.pageNumber - 1) * payload.paginationOptions.pageSize, payload.paginationOptions.pageNumber * payload.paginationOptions.pageSize);
|
|
114
139
|
|
|
115
|
-
|
|
116
140
|
const res = {
|
|
117
141
|
meta: {
|
|
118
142
|
placeholder: false,
|
|
@@ -121,20 +145,24 @@ export class FakeCategoryProvider<
|
|
|
121
145
|
key: 'child-categories-' + payload.parentId.key + '-' + payload.paginationOptions.pageNumber + '-' + payload.paginationOptions.pageSize,
|
|
122
146
|
},
|
|
123
147
|
},
|
|
124
|
-
items: page ? page
|
|
148
|
+
items: page ? page : [],
|
|
125
149
|
totalCount: children ? children.length : 0,
|
|
126
150
|
pageNumber: payload.paginationOptions.pageNumber,
|
|
127
151
|
pageSize: payload.paginationOptions.pageSize,
|
|
128
152
|
totalPages: children ? Math.ceil(children.length / payload.paginationOptions.pageSize) : 1,
|
|
129
153
|
};
|
|
130
154
|
|
|
131
|
-
return
|
|
155
|
+
return success(res);
|
|
132
156
|
}
|
|
133
|
-
|
|
157
|
+
|
|
158
|
+
@Reactionary({
|
|
159
|
+
inputSchema: CategoryQueryForTopCategoriesSchema,
|
|
160
|
+
outputSchema: CategoryPaginatedResultSchema
|
|
161
|
+
})
|
|
162
|
+
public override async findTopCategories(payload: CategoryQueryForTopCategories): Promise<Result<CategoryPaginatedResult>> {
|
|
134
163
|
const children = this.topCategories;
|
|
135
164
|
const page = children?.slice((payload.paginationOptions.pageNumber - 1) * payload.paginationOptions.pageSize, payload.paginationOptions.pageNumber * payload.paginationOptions.pageSize);
|
|
136
165
|
|
|
137
|
-
|
|
138
166
|
const res = {
|
|
139
167
|
meta: {
|
|
140
168
|
placeholder: false,
|
|
@@ -143,14 +171,14 @@ export class FakeCategoryProvider<
|
|
|
143
171
|
key: 'top' + '-' + payload.paginationOptions.pageNumber + '-' + payload.paginationOptions.pageSize,
|
|
144
172
|
},
|
|
145
173
|
},
|
|
146
|
-
items: page ? page
|
|
174
|
+
items: page ? page : [],
|
|
147
175
|
totalCount: children ? children.length : 0,
|
|
148
176
|
pageNumber: payload.paginationOptions.pageNumber,
|
|
149
177
|
pageSize: payload.paginationOptions.pageSize,
|
|
150
178
|
totalPages: children ? Math.ceil(children.length / payload.paginationOptions.pageSize) : 1,
|
|
151
179
|
};
|
|
152
180
|
|
|
153
|
-
return
|
|
181
|
+
return success(res);
|
|
154
182
|
}
|
|
155
183
|
|
|
156
184
|
}
|