@reactionary/source 0.3.18 → 0.6.2
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/README.md +28 -14
- package/core/src/client/client-builder.ts +54 -6
- package/core/src/factories/cart.factory.ts +40 -0
- package/core/src/factories/category.factory.ts +40 -0
- package/core/src/factories/checkout.factory.ts +59 -0
- package/core/src/factories/identity.factory.ts +26 -0
- package/core/src/factories/index.ts +15 -0
- package/core/src/factories/inventory.factory.ts +26 -0
- package/core/src/factories/order-search.factory.ts +33 -0
- package/core/src/factories/order.factory.ts +21 -0
- package/core/src/factories/price.factory.ts +29 -0
- package/core/src/factories/product-associations.factory.ts +30 -0
- package/core/src/factories/product-list.factory.ts +82 -0
- package/core/src/factories/product-reviews.factory.ts +58 -0
- package/core/src/factories/product-search.factory.ts +31 -0
- package/core/src/factories/product.factory.ts +21 -0
- package/core/src/factories/profile.factory.ts +23 -0
- package/core/src/factories/store.factory.ts +21 -0
- package/core/src/index.ts +3 -1
- package/core/src/providers/cart.provider.ts +12 -10
- package/core/src/providers/category.provider.ts +9 -7
- package/core/src/providers/checkout.provider.ts +14 -10
- package/core/src/providers/identity.provider.ts +7 -7
- package/core/src/providers/inventory.provider.ts +4 -4
- package/core/src/providers/order-search.provider.ts +4 -2
- package/core/src/providers/order.provider.ts +4 -4
- package/core/src/providers/price.provider.ts +5 -5
- package/core/src/providers/product-associations.provider.ts +6 -4
- package/core/src/providers/product-list.provider.ts +13 -8
- package/core/src/providers/product-reviews.provider.ts +8 -4
- package/core/src/providers/product-search.provider.ts +15 -28
- package/core/src/providers/product.provider.ts +6 -6
- package/core/src/providers/profile.provider.ts +8 -8
- package/core/src/providers/store.provider.ts +2 -2
- package/core/src/test/client-builder.spec.ts +81 -0
- package/examples/node/package.json +7 -7
- package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +10 -4
- package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +8 -2
- package/examples/node/src/basic/basic-node-setup.spec.ts +5 -1
- package/examples/node/src/basic/client-creation.spec.ts +3 -3
- package/examples/node/src/utils.ts +41 -41
- package/examples/node/tsconfig.lib.json +2 -1
- package/package.json +1 -1
- package/providers/algolia/src/core/initialize.ts +76 -21
- package/providers/algolia/src/core/initialize.types.ts +107 -0
- package/providers/algolia/src/factories/index.ts +1 -0
- package/providers/algolia/src/factories/product-search/product-search.factory.ts +182 -0
- package/providers/algolia/src/index.ts +2 -2
- package/providers/algolia/src/providers/analytics.provider.ts +4 -4
- package/providers/algolia/src/providers/product-search.provider.ts +67 -184
- package/providers/algolia/src/schema/capabilities.schema.ts +81 -7
- package/providers/algolia/src/test/analytics.spec.ts +9 -1
- package/providers/algolia/src/test/client-builder-product-search-extension.example.ts +85 -0
- package/providers/commercetools/src/core/capability-descriptors.ts +324 -0
- package/providers/commercetools/src/core/initialize.ts +35 -151
- package/providers/commercetools/src/core/initialize.types.ts +174 -0
- package/providers/commercetools/src/factories/cart/cart.factory.ts +142 -0
- package/providers/commercetools/src/factories/category/category.factory.ts +77 -0
- package/providers/commercetools/src/factories/checkout/checkout-initializer-overrides.example.ts +94 -0
- package/providers/commercetools/src/factories/checkout/checkout.factory.ts +338 -0
- package/providers/commercetools/src/factories/identity/identity.factory.ts +26 -0
- package/providers/commercetools/src/factories/inventory/inventory.factory.ts +49 -0
- package/providers/commercetools/src/factories/order/order.factory.ts +149 -0
- package/providers/commercetools/src/factories/order-search/order-search.factory.ts +108 -0
- package/providers/commercetools/src/factories/price/price.factory.ts +76 -0
- package/providers/commercetools/src/factories/product/product-factory-baseline.example.ts +14 -0
- package/providers/commercetools/src/factories/product/product-factory-schema-and-parse-extension.example.ts +35 -0
- package/providers/commercetools/src/factories/product/product-factory-schema-extension.example.ts +23 -0
- package/providers/commercetools/src/factories/product/product-initializer-factory-extension.example.ts +41 -0
- package/providers/commercetools/src/factories/product/product-provider-custom-method-only.example.ts +47 -0
- package/providers/commercetools/src/factories/product/product-provider-schema-signature-extension.example.ts +61 -0
- package/providers/commercetools/src/factories/product/product.factory.ts +220 -0
- package/providers/commercetools/src/factories/product/utils.example.ts +9 -0
- package/providers/commercetools/src/factories/product-associations/product-associations.factory.ts +103 -0
- package/providers/commercetools/src/factories/product-list/product-list.factory.ts +122 -0
- package/providers/commercetools/src/factories/product-reviews/product-reviews.factory.ts +81 -0
- package/providers/commercetools/src/factories/product-search/product-search.factory.ts +182 -0
- package/providers/commercetools/src/factories/profile/profile.factory.ts +94 -0
- package/providers/commercetools/src/factories/store/store.factory.ts +49 -0
- package/providers/commercetools/src/index.ts +15 -0
- package/providers/commercetools/src/providers/cart.provider.ts +67 -193
- package/providers/commercetools/src/providers/category.provider.ts +24 -64
- package/providers/commercetools/src/providers/checkout.provider.ts +50 -322
- package/providers/commercetools/src/providers/identity.provider.ts +35 -15
- package/providers/commercetools/src/providers/inventory.provider.ts +13 -31
- package/providers/commercetools/src/providers/order-search.provider.ts +16 -110
- package/providers/commercetools/src/providers/order.provider.ts +13 -144
- package/providers/commercetools/src/providers/price.provider.ts +37 -51
- package/providers/commercetools/src/providers/product-associations.provider.ts +39 -104
- package/providers/commercetools/src/providers/product-list.provider.ts +38 -23
- package/providers/commercetools/src/providers/product-reviews.provider.ts +34 -14
- package/providers/commercetools/src/providers/product-search.provider.ts +17 -170
- package/providers/commercetools/src/providers/product.provider.ts +20 -199
- package/providers/commercetools/src/providers/profile.provider.ts +27 -73
- package/providers/commercetools/src/providers/store.provider.ts +13 -31
- package/providers/commercetools/src/schema/capabilities.schema.ts +258 -20
- package/providers/commercetools/src/test/caching.spec.ts +18 -2
- package/providers/commercetools/src/test/client-builder-merge-extensions.example.ts +125 -0
- package/providers/fake/src/core/initialize.ts +213 -44
- package/providers/fake/src/core/initialize.types.ts +164 -0
- package/providers/fake/src/factories/cart/cart.factory.ts +34 -0
- package/providers/fake/src/factories/category/category.factory.ts +40 -0
- package/providers/fake/src/factories/checkout/checkout.factory.ts +53 -0
- package/providers/fake/src/factories/identity/identity.factory.ts +25 -0
- package/providers/fake/src/factories/index.ts +14 -0
- package/providers/fake/src/factories/inventory/inventory.factory.ts +25 -0
- package/providers/fake/src/factories/order/order.factory.ts +22 -0
- package/providers/fake/src/factories/order-search/order-search.factory.ts +27 -0
- package/providers/fake/src/factories/price/price.factory.ts +26 -0
- package/providers/fake/src/factories/product/product.factory.ts +22 -0
- package/providers/fake/src/factories/product-associations/product-associations.factory.ts +25 -0
- package/providers/fake/src/factories/product-reviews/product-reviews.factory.ts +53 -0
- package/providers/fake/src/factories/product-search/product-search.factory.ts +27 -0
- package/providers/fake/src/factories/profile/profile.factory.ts +22 -0
- package/providers/fake/src/factories/store/store.factory.ts +22 -0
- package/providers/fake/src/index.ts +2 -0
- package/providers/fake/src/providers/cart.provider.ts +23 -14
- package/providers/fake/src/providers/category.provider.ts +120 -105
- package/providers/fake/src/providers/checkout.provider.ts +39 -20
- package/providers/fake/src/providers/identity.provider.ts +40 -34
- package/providers/fake/src/providers/inventory.provider.ts +26 -24
- package/providers/fake/src/providers/order-search.provider.ts +38 -30
- package/providers/fake/src/providers/order.provider.ts +21 -37
- package/providers/fake/src/providers/price.provider.ts +42 -34
- package/providers/fake/src/providers/product-associations.provider.ts +23 -10
- package/providers/fake/src/providers/product-reviews.provider.ts +71 -69
- package/providers/fake/src/providers/product-search.provider.ts +43 -70
- package/providers/fake/src/providers/product.provider.ts +34 -32
- package/providers/fake/src/providers/profile.provider.ts +62 -55
- package/providers/fake/src/providers/store.provider.ts +38 -22
- package/providers/fake/src/schema/capabilities.schema.ts +175 -18
- package/providers/fake/src/test/cart.provider.spec.ts +20 -3
- package/providers/fake/src/test/category.provider.spec.ts +4 -1
- package/providers/fake/src/test/checkout.provider.spec.ts +12 -2
- package/providers/fake/src/test/client-builder-product-extension.example.ts +75 -0
- package/providers/fake/src/test/order-search.provider.spec.ts +4 -7
- package/providers/fake/src/test/order.provider.spec.ts +4 -6
- package/providers/fake/src/test/price.provider.spec.ts +3 -1
- package/providers/fake/src/test/product.provider.spec.ts +8 -2
- package/providers/fake/src/test/profile.provider.spec.ts +4 -2
- package/providers/google-analytics/src/core/initialize.ts +37 -12
- package/providers/google-analytics/src/core/initialize.types.ts +47 -0
- package/providers/google-analytics/src/index.ts +1 -0
- package/providers/google-analytics/src/schema/capabilities.schema.ts +31 -5
- package/providers/medusa/src/core/initialize.ts +324 -81
- package/providers/medusa/src/core/initialize.types.ts +184 -0
- package/providers/medusa/src/factories/cart/cart.factory.ts +34 -0
- package/providers/medusa/src/factories/category/category.factory.ts +37 -0
- package/providers/medusa/src/factories/checkout/checkout.factory.ts +50 -0
- package/providers/medusa/src/factories/identity/identity.factory.ts +22 -0
- package/providers/medusa/src/factories/index.ts +12 -0
- package/providers/medusa/src/factories/inventory/inventory.factory.ts +25 -0
- package/providers/medusa/src/factories/order/order.factory.ts +22 -0
- package/providers/medusa/src/factories/order-search/order-search.factory.ts +27 -0
- package/providers/medusa/src/factories/price/price.factory.ts +26 -0
- package/providers/medusa/src/factories/product/product.factory.ts +22 -0
- package/providers/medusa/src/factories/product-associations/product-associations.factory.ts +25 -0
- package/providers/medusa/src/factories/product-search/product-search.factory.ts +27 -0
- package/providers/medusa/src/factories/profile/profile.factory.ts +22 -0
- package/providers/medusa/src/index.ts +2 -0
- package/providers/medusa/src/providers/cart.provider.ts +33 -20
- package/providers/medusa/src/providers/category.provider.ts +30 -12
- package/providers/medusa/src/providers/checkout.provider.ts +42 -17
- package/providers/medusa/src/providers/identity.provider.ts +1 -1
- package/providers/medusa/src/providers/inventory.provider.ts +21 -7
- package/providers/medusa/src/providers/order-search.provider.ts +16 -5
- package/providers/medusa/src/providers/order.provider.ts +17 -5
- package/providers/medusa/src/providers/price.provider.ts +26 -7
- package/providers/medusa/src/providers/product-associations.provider.ts +19 -8
- package/providers/medusa/src/providers/product-search.provider.ts +19 -31
- package/providers/medusa/src/providers/product.provider.ts +47 -11
- package/providers/medusa/src/providers/profile.provider.ts +35 -11
- package/providers/medusa/src/schema/capabilities.schema.ts +229 -18
- package/providers/medusa/src/test/cart.provider.spec.ts +18 -2
- package/providers/medusa/src/test/category.provider.spec.ts +4 -1
- package/providers/medusa/src/test/checkout.spec.ts +9 -9
- package/providers/medusa/src/test/inventory.provider.spec.ts +3 -1
- package/providers/medusa/src/test/large-cart.provider.spec.ts +8 -2
- package/providers/medusa/src/test/price.provider.spec.ts +8 -1
- package/providers/medusa/src/test/product.provider.spec.ts +3 -1
- package/providers/medusa/src/test/search.provider.spec.ts +16 -3
- package/providers/meilisearch/src/core/initialize.ts +88 -21
- package/providers/meilisearch/src/core/initialize.types.ts +119 -0
- package/providers/meilisearch/src/factories/index.ts +2 -0
- package/providers/meilisearch/src/factories/order-search/order-search.factory.ts +27 -0
- package/providers/meilisearch/src/factories/product-search/product-search.factory.ts +27 -0
- package/providers/meilisearch/src/index.ts +2 -0
- package/providers/meilisearch/src/providers/index.ts +1 -0
- package/providers/meilisearch/src/providers/order-search.provider.ts +21 -6
- package/providers/meilisearch/src/providers/product-search.provider.ts +24 -8
- package/providers/meilisearch/src/schema/capabilities.schema.ts +95 -8
|
@@ -1,27 +1,82 @@
|
|
|
1
|
-
import type { Cache,
|
|
2
|
-
import { AlgoliaProductSearchProvider } from
|
|
3
|
-
import type { AlgoliaCapabilities } from
|
|
4
|
-
import type { AlgoliaConfiguration } from
|
|
5
|
-
import { AlgoliaAnalyticsProvider } from
|
|
6
|
-
import { AlgoliaProductRecommendationsProvider } from
|
|
1
|
+
import type { Cache, RequestContext } from '@reactionary/core';
|
|
2
|
+
import { AlgoliaProductSearchProvider } from '../providers/product-search.provider.js';
|
|
3
|
+
import type { AlgoliaCapabilities } from '../schema/capabilities.schema.js';
|
|
4
|
+
import type { AlgoliaConfiguration } from '../schema/configuration.schema.js';
|
|
5
|
+
import { AlgoliaAnalyticsProvider } from '../providers/analytics.provider.js';
|
|
6
|
+
import { AlgoliaProductRecommendationsProvider } from '../providers/product-recommendations.provider.js';
|
|
7
|
+
import { AlgoliaProductSearchFactory } from '../factories/product-search/product-search.factory.js';
|
|
8
|
+
import { AlgoliaProductSearchResultSchema } from '../schema/search.schema.js';
|
|
9
|
+
import {
|
|
10
|
+
type AlgoliaClientFromCapabilities,
|
|
11
|
+
resolveCapabilityProvider,
|
|
12
|
+
resolveProviderOnlyCapability,
|
|
13
|
+
} from './initialize.types.js';
|
|
7
14
|
|
|
8
|
-
export function withAlgoliaCapabilities<T extends AlgoliaCapabilities>(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
export function withAlgoliaCapabilities<T extends AlgoliaCapabilities>(
|
|
16
|
+
configuration: AlgoliaConfiguration,
|
|
17
|
+
capabilities: T,
|
|
18
|
+
) {
|
|
19
|
+
return (
|
|
20
|
+
cache: Cache,
|
|
21
|
+
context: RequestContext,
|
|
22
|
+
): AlgoliaClientFromCapabilities<T> => {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
const client: any = {};
|
|
12
25
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
if (capabilities.productSearch?.enabled) {
|
|
27
|
+
const defaultFactory = new AlgoliaProductSearchFactory(
|
|
28
|
+
AlgoliaProductSearchResultSchema,
|
|
29
|
+
);
|
|
30
|
+
client.productSearch = resolveCapabilityProvider(
|
|
31
|
+
capabilities.productSearch,
|
|
32
|
+
{
|
|
33
|
+
factory: defaultFactory,
|
|
34
|
+
provider: (args) =>
|
|
35
|
+
new AlgoliaProductSearchProvider(
|
|
36
|
+
args.cache,
|
|
37
|
+
args.context,
|
|
38
|
+
args.config,
|
|
39
|
+
args.factory,
|
|
40
|
+
),
|
|
41
|
+
},
|
|
42
|
+
(factory) => ({
|
|
43
|
+
cache,
|
|
44
|
+
context,
|
|
45
|
+
config: configuration,
|
|
46
|
+
factory,
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
16
50
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
51
|
+
if (capabilities.analytics?.enabled) {
|
|
52
|
+
client.analytics = resolveProviderOnlyCapability(
|
|
53
|
+
capabilities.analytics,
|
|
54
|
+
(args) => new AlgoliaAnalyticsProvider(args.cache, args.context, args.config),
|
|
55
|
+
{
|
|
56
|
+
cache,
|
|
57
|
+
context,
|
|
58
|
+
config: configuration,
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
}
|
|
20
62
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
63
|
+
if (capabilities.productRecommendations?.enabled) {
|
|
64
|
+
client.productRecommendations = resolveProviderOnlyCapability(
|
|
65
|
+
capabilities.productRecommendations,
|
|
66
|
+
(args) =>
|
|
67
|
+
new AlgoliaProductRecommendationsProvider(
|
|
68
|
+
args.config,
|
|
69
|
+
args.cache,
|
|
70
|
+
args.context,
|
|
71
|
+
),
|
|
72
|
+
{
|
|
73
|
+
cache,
|
|
74
|
+
context,
|
|
75
|
+
config: configuration,
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
}
|
|
24
79
|
|
|
25
|
-
|
|
26
|
-
|
|
80
|
+
return client;
|
|
81
|
+
};
|
|
27
82
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ClientFromCapabilities,
|
|
3
|
+
ProductSearchFactory,
|
|
4
|
+
} from '@reactionary/core';
|
|
5
|
+
import type { AlgoliaCapabilities } from '../schema/capabilities.schema.js';
|
|
6
|
+
import type { AlgoliaProductSearchFactory } from '../factories/product-search/product-search.factory.js';
|
|
7
|
+
import type { AlgoliaAnalyticsProvider } from '../providers/analytics.provider.js';
|
|
8
|
+
import type { AlgoliaProductRecommendationsProvider } from '../providers/product-recommendations.provider.js';
|
|
9
|
+
import type { AlgoliaProductSearchProvider } from '../providers/product-search.provider.js';
|
|
10
|
+
|
|
11
|
+
type EnabledCapability<TCapability> =
|
|
12
|
+
TCapability extends { enabled: true } ? true : false;
|
|
13
|
+
|
|
14
|
+
type NormalizeConfiguredCapabilities<T extends AlgoliaCapabilities> =
|
|
15
|
+
Omit<T, 'productSearch' | 'analytics' | 'productRecommendations'> & {
|
|
16
|
+
productSearch?: EnabledCapability<T['productSearch']>;
|
|
17
|
+
analytics?: EnabledCapability<T['analytics']>;
|
|
18
|
+
productRecommendations?: EnabledCapability<T['productRecommendations']>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type ExtractCapabilityFactory<TCapability, TContract, TDefaultFactory> =
|
|
22
|
+
TCapability extends { enabled: true; factory?: infer TFactory }
|
|
23
|
+
? TFactory extends TContract
|
|
24
|
+
? TFactory
|
|
25
|
+
: TDefaultFactory
|
|
26
|
+
: TDefaultFactory;
|
|
27
|
+
|
|
28
|
+
type ExtractCapabilityProvider<TCapability, TDefaultProvider> =
|
|
29
|
+
TCapability extends { enabled: true; provider?: infer TProviderFactory }
|
|
30
|
+
? TProviderFactory extends (...args: unknown[]) => infer TProvider
|
|
31
|
+
? TProvider
|
|
32
|
+
: TDefaultProvider
|
|
33
|
+
: TDefaultProvider;
|
|
34
|
+
|
|
35
|
+
type CapabilityOverride<
|
|
36
|
+
TCapability,
|
|
37
|
+
TKey extends string,
|
|
38
|
+
TProvider,
|
|
39
|
+
> = TCapability extends { enabled: true }
|
|
40
|
+
? { [K in TKey]: TProvider }
|
|
41
|
+
: Record<never, never>;
|
|
42
|
+
|
|
43
|
+
type ProductSearchFactoryFor<T extends AlgoliaCapabilities> =
|
|
44
|
+
ExtractCapabilityFactory<
|
|
45
|
+
T['productSearch'],
|
|
46
|
+
ProductSearchFactory,
|
|
47
|
+
AlgoliaProductSearchFactory
|
|
48
|
+
>;
|
|
49
|
+
|
|
50
|
+
type ProductSearchProviderFor<T extends AlgoliaCapabilities> =
|
|
51
|
+
ExtractCapabilityProvider<
|
|
52
|
+
T['productSearch'],
|
|
53
|
+
AlgoliaProductSearchProvider<ProductSearchFactoryFor<T>>
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
type AnalyticsProviderFor<T extends AlgoliaCapabilities> =
|
|
57
|
+
ExtractCapabilityProvider<T['analytics'], AlgoliaAnalyticsProvider>;
|
|
58
|
+
|
|
59
|
+
type ProductRecommendationsProviderFor<T extends AlgoliaCapabilities> =
|
|
60
|
+
ExtractCapabilityProvider<
|
|
61
|
+
T['productRecommendations'],
|
|
62
|
+
AlgoliaProductRecommendationsProvider
|
|
63
|
+
>;
|
|
64
|
+
|
|
65
|
+
export type AlgoliaClientFromCapabilities<T extends AlgoliaCapabilities> = Omit<
|
|
66
|
+
ClientFromCapabilities<NormalizeConfiguredCapabilities<T>>,
|
|
67
|
+
'productSearch' | 'analytics' | 'productRecommendations'
|
|
68
|
+
> &
|
|
69
|
+
CapabilityOverride<T['productSearch'], 'productSearch', ProductSearchProviderFor<T>> &
|
|
70
|
+
CapabilityOverride<T['analytics'], 'analytics', AnalyticsProviderFor<T>> &
|
|
71
|
+
CapabilityOverride<
|
|
72
|
+
T['productRecommendations'],
|
|
73
|
+
'productRecommendations',
|
|
74
|
+
ProductRecommendationsProviderFor<T>
|
|
75
|
+
>;
|
|
76
|
+
|
|
77
|
+
export function resolveCapabilityProvider<TFactory, TProvider, TProviderArgs>(
|
|
78
|
+
capability:
|
|
79
|
+
| {
|
|
80
|
+
factory?: TFactory;
|
|
81
|
+
provider?: (args: TProviderArgs) => TProvider;
|
|
82
|
+
}
|
|
83
|
+
| undefined,
|
|
84
|
+
defaults: {
|
|
85
|
+
factory: TFactory;
|
|
86
|
+
provider: (args: TProviderArgs) => TProvider;
|
|
87
|
+
},
|
|
88
|
+
buildProviderArgs: (factory: TFactory) => TProviderArgs,
|
|
89
|
+
): TProvider {
|
|
90
|
+
const factory = capability?.factory ?? defaults.factory;
|
|
91
|
+
const provider = capability?.provider ?? defaults.provider;
|
|
92
|
+
|
|
93
|
+
return provider(buildProviderArgs(factory));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function resolveProviderOnlyCapability<TProvider, TProviderArgs>(
|
|
97
|
+
capability:
|
|
98
|
+
| {
|
|
99
|
+
provider?: (args: TProviderArgs) => TProvider;
|
|
100
|
+
}
|
|
101
|
+
| undefined,
|
|
102
|
+
defaultProvider: (args: TProviderArgs) => TProvider,
|
|
103
|
+
args: TProviderArgs,
|
|
104
|
+
): TProvider {
|
|
105
|
+
const provider = capability?.provider ?? defaultProvider;
|
|
106
|
+
return provider(args);
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './product-search/product-search.factory.js';
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnyProductSearchResultSchema,
|
|
3
|
+
FacetIdentifier,
|
|
4
|
+
FacetValueIdentifier,
|
|
5
|
+
ProductSearchFactory,
|
|
6
|
+
ProductSearchQueryByTerm,
|
|
7
|
+
ProductSearchResultFacet,
|
|
8
|
+
ProductSearchResultFacetValue,
|
|
9
|
+
ProductSearchResultItem,
|
|
10
|
+
ProductSearchResultItemVariant,
|
|
11
|
+
RequestContext,
|
|
12
|
+
} from '@reactionary/core';
|
|
13
|
+
import {
|
|
14
|
+
FacetIdentifierSchema,
|
|
15
|
+
FacetValueIdentifierSchema,
|
|
16
|
+
ImageSchema,
|
|
17
|
+
ProductSearchResultFacetSchema,
|
|
18
|
+
ProductSearchResultFacetValueSchema,
|
|
19
|
+
ProductSearchResultItemVariantSchema,
|
|
20
|
+
} from '@reactionary/core';
|
|
21
|
+
import type * as z from 'zod';
|
|
22
|
+
import type { SearchResponse } from 'algoliasearch';
|
|
23
|
+
import type {
|
|
24
|
+
AlgoliaNativeRecord,
|
|
25
|
+
AlgoliaNativeVariant,
|
|
26
|
+
AlgoliaProductSearchResult,
|
|
27
|
+
} from '../../schema/search.schema.js';
|
|
28
|
+
import type { AlgoliaProductSearchResultSchema } from '../../schema/search.schema.js';
|
|
29
|
+
|
|
30
|
+
export class AlgoliaProductSearchFactory<
|
|
31
|
+
TProductSearchResultSchema extends AnyProductSearchResultSchema = typeof AlgoliaProductSearchResultSchema,
|
|
32
|
+
> implements ProductSearchFactory<TProductSearchResultSchema>
|
|
33
|
+
{
|
|
34
|
+
public readonly productSearchResultSchema: TProductSearchResultSchema;
|
|
35
|
+
|
|
36
|
+
constructor(productSearchResultSchema: TProductSearchResultSchema) {
|
|
37
|
+
this.productSearchResultSchema = productSearchResultSchema;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public parseSearchResult(
|
|
41
|
+
_context: RequestContext,
|
|
42
|
+
data: unknown,
|
|
43
|
+
query: ProductSearchQueryByTerm,
|
|
44
|
+
): z.output<TProductSearchResultSchema> {
|
|
45
|
+
const body = this.parseInput(data);
|
|
46
|
+
const items = body.hits.map((hit) => this.parseSingle(hit));
|
|
47
|
+
|
|
48
|
+
let facets: ProductSearchResultFacet[] = [];
|
|
49
|
+
for (const id in body.facets) {
|
|
50
|
+
const values = body.facets[id];
|
|
51
|
+
const facetId = FacetIdentifierSchema.parse({ key: id });
|
|
52
|
+
facets.push(this.parseFacet(facetId, values));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const selectedCategoryFacet =
|
|
56
|
+
query.search.facets.find((x) => x.facet.key === 'categories') ||
|
|
57
|
+
query.search.categoryFilter;
|
|
58
|
+
|
|
59
|
+
let subCategoryFacet;
|
|
60
|
+
if (selectedCategoryFacet) {
|
|
61
|
+
const valueDepth = selectedCategoryFacet.key.split(' > ').length;
|
|
62
|
+
subCategoryFacet = facets.find(
|
|
63
|
+
(f) => f.identifier.key === `hierarchy.lvl${valueDepth}`,
|
|
64
|
+
);
|
|
65
|
+
} else {
|
|
66
|
+
subCategoryFacet = facets.find((f) => f.identifier.key === 'hierarchy.lvl0');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (subCategoryFacet) {
|
|
70
|
+
subCategoryFacet.identifier = FacetIdentifierSchema.parse({ key: 'categories' });
|
|
71
|
+
subCategoryFacet.name = 'Categories';
|
|
72
|
+
for (const value of subCategoryFacet.values) {
|
|
73
|
+
const pathParts = value.identifier.key.split(' > ');
|
|
74
|
+
value.identifier.facet = subCategoryFacet.identifier;
|
|
75
|
+
value.name = pathParts[pathParts.length - 1];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
facets = facets.filter((f) => !f.identifier.key.startsWith('hierarchy.lvl'));
|
|
80
|
+
|
|
81
|
+
const result = {
|
|
82
|
+
identifier: {
|
|
83
|
+
term: query.search.term,
|
|
84
|
+
facets: query.search.facets,
|
|
85
|
+
filters: query.search.filters,
|
|
86
|
+
paginationOptions: query.search.paginationOptions,
|
|
87
|
+
index: body.index || '',
|
|
88
|
+
key: body.queryID || '',
|
|
89
|
+
},
|
|
90
|
+
pageNumber: (body.page || 0) + 1,
|
|
91
|
+
pageSize: body.hitsPerPage || 0,
|
|
92
|
+
totalCount: body.nbHits || 0,
|
|
93
|
+
totalPages: body.nbPages || 0,
|
|
94
|
+
items,
|
|
95
|
+
facets,
|
|
96
|
+
} satisfies AlgoliaProductSearchResult;
|
|
97
|
+
|
|
98
|
+
return this.productSearchResultSchema.parse(result);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected parseSingle(body: AlgoliaNativeRecord): ProductSearchResultItem {
|
|
102
|
+
return {
|
|
103
|
+
identifier: { key: body.objectID },
|
|
104
|
+
name: body.name || body.objectID,
|
|
105
|
+
slug: body.slug || body.objectID,
|
|
106
|
+
variants: [...(body.variants || [])].map((variant) =>
|
|
107
|
+
this.parseVariant(variant, body),
|
|
108
|
+
),
|
|
109
|
+
} satisfies ProductSearchResultItem;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
protected parseVariant(
|
|
113
|
+
variant: AlgoliaNativeVariant,
|
|
114
|
+
product: AlgoliaNativeRecord,
|
|
115
|
+
): ProductSearchResultItemVariant {
|
|
116
|
+
return ProductSearchResultItemVariantSchema.parse({
|
|
117
|
+
variant: {
|
|
118
|
+
sku: variant.sku,
|
|
119
|
+
},
|
|
120
|
+
image: ImageSchema.parse({
|
|
121
|
+
sourceUrl: variant.image,
|
|
122
|
+
altText: product.name || '',
|
|
123
|
+
}),
|
|
124
|
+
} satisfies Partial<ProductSearchResultItemVariant>);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
protected parseFacet(
|
|
128
|
+
facetIdentifier: FacetIdentifier,
|
|
129
|
+
facetValues: Record<string, number>,
|
|
130
|
+
): ProductSearchResultFacet {
|
|
131
|
+
const result = ProductSearchResultFacetSchema.parse({
|
|
132
|
+
identifier: facetIdentifier,
|
|
133
|
+
name: facetIdentifier.key,
|
|
134
|
+
values: [],
|
|
135
|
+
} satisfies Partial<ProductSearchResultFacet>);
|
|
136
|
+
|
|
137
|
+
for (const valueId in facetValues) {
|
|
138
|
+
const count = facetValues[valueId];
|
|
139
|
+
const facetValueIdentifier = FacetValueIdentifierSchema.parse({
|
|
140
|
+
facet: facetIdentifier,
|
|
141
|
+
key: valueId,
|
|
142
|
+
} satisfies Partial<FacetValueIdentifier>);
|
|
143
|
+
|
|
144
|
+
result.values.push(this.parseFacetValue(facetValueIdentifier, valueId, count));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
protected parseFacetValue(
|
|
151
|
+
facetValueIdentifier: FacetValueIdentifier,
|
|
152
|
+
label: string,
|
|
153
|
+
count: number,
|
|
154
|
+
): ProductSearchResultFacetValue {
|
|
155
|
+
return ProductSearchResultFacetValueSchema.parse({
|
|
156
|
+
identifier: facetValueIdentifier,
|
|
157
|
+
name: label,
|
|
158
|
+
count,
|
|
159
|
+
active: false,
|
|
160
|
+
} satisfies Partial<ProductSearchResultFacetValue>);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
protected parseInput(data: unknown): SearchResponse<AlgoliaNativeRecord> {
|
|
164
|
+
if (!this.isSearchResponse(data)) {
|
|
165
|
+
throw new Error('Invalid Algolia search response');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return data;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
protected isSearchResponse(data: unknown): data is SearchResponse<AlgoliaNativeRecord> {
|
|
172
|
+
if (!data || typeof data !== 'object') {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!('hits' in data) || !Array.isArray(data.hits)) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './core/initialize.js';
|
|
2
|
-
export * from './providers/
|
|
3
|
-
export * from './
|
|
2
|
+
export * from './providers/index.js';
|
|
3
|
+
export * from './factories/index.js';
|
|
4
4
|
|
|
5
5
|
export * from './schema/configuration.schema.js';
|
|
6
6
|
export * from './schema/capabilities.schema.js';
|
|
@@ -48,7 +48,7 @@ export class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
48
48
|
.key,
|
|
49
49
|
} satisfies AddedToCartObjectIDsAfterSearch;
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
await this.client.pushEvents({
|
|
52
52
|
events: [algoliaEvent],
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -69,7 +69,7 @@ export class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
69
69
|
.key,
|
|
70
70
|
} satisfies ClickedObjectIDsAfterSearch;
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
await this.client.pushEvents({
|
|
73
73
|
events: [algoliaEvent],
|
|
74
74
|
});
|
|
75
75
|
}
|
|
@@ -87,7 +87,7 @@ export class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
87
87
|
userToken: this.context.session.identityContext.personalizationKey,
|
|
88
88
|
} satisfies ViewedObjectIDs;
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
await this.client.pushEvents({
|
|
91
91
|
events: [algoliaEvent],
|
|
92
92
|
});
|
|
93
93
|
}
|
|
@@ -107,7 +107,7 @@ export class AlgoliaAnalyticsProvider extends AnalyticsProvider {
|
|
|
107
107
|
userToken: this.context.session.identityContext.personalizationKey,
|
|
108
108
|
} satisfies PurchasedObjectIDs;
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
await this.client.pushEvents({
|
|
111
111
|
events: [algoliaEvent],
|
|
112
112
|
});
|
|
113
113
|
}
|