@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
|
@@ -1,19 +1,78 @@
|
|
|
1
1
|
import type { Product } from '../schemas/models/product.model.js';
|
|
2
2
|
import { BaseProvider } from './base.provider.js';
|
|
3
|
-
import type { RequestContext } from '../schemas/session.schema.js';
|
|
4
3
|
import type { ProductQueryById, ProductQueryBySKU, ProductQueryBySlug } from '../schemas/queries/product.query.js';
|
|
4
|
+
import type { Result } from '../schemas/result.js';
|
|
5
|
+
import type { NotFoundError } from '../schemas/index.js';
|
|
6
|
+
|
|
7
|
+
export abstract class ProductProvider extends BaseProvider {
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get a product by its ID.
|
|
12
|
+
* @param payload The query payload containing the product ID.
|
|
13
|
+
* @param reqCtx The request context.
|
|
14
|
+
*
|
|
15
|
+
* Usecase: Not clear. Maybe if you get a reference from marketing? But that would most likely be a partnumber.
|
|
16
|
+
* But what if the marketing system recommends products instead of variants? A product does not have a partnumber, or gtin.
|
|
17
|
+
* Marketing will TYPICALLY recommend products, and in some cases maybe HeroVariants of a product.
|
|
18
|
+
* In that case, you would need to resolve the product to its hero variant first, and then get the SKU from there.
|
|
19
|
+
*/
|
|
20
|
+
public abstract getById(payload: ProductQueryById): Promise<Result<Product>>;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get a product by its slug.
|
|
25
|
+
* @param payload The query payload containing the product slug.
|
|
26
|
+
* @param reqCtx The request context.
|
|
27
|
+
*
|
|
28
|
+
* Usecase: You are rendering a product detail page, and you need to fetch the product by its slug.
|
|
29
|
+
*/
|
|
30
|
+
public abstract getBySlug(payload: ProductQueryBySlug): Promise<Result<Product, NotFoundError>>;
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get a product by its SKU
|
|
35
|
+
* @param payload
|
|
36
|
+
* @param reqCtx
|
|
37
|
+
*
|
|
38
|
+
* Usecase: you want to look up product details for a cart item. Or you have a SKU from an external system (e.g. ERP, PIM, Marketing, OMS/Order History),
|
|
39
|
+
* and you need to fetch the product details for that SKU. You will get the a Product back, with the variant matching the SKU set as heroSku.
|
|
40
|
+
* It might also be used on a quick-order page, or product recommendations from external system.
|
|
41
|
+
*/
|
|
42
|
+
public abstract getBySKU(payload: ProductQueryBySKU): Promise<Result<Product>>;
|
|
43
|
+
|
|
44
|
+
protected createEmptyProduct(id: string): Product {
|
|
45
|
+
// FIXME: We can probably get rid of this once we switch to errors as values, as we shouldn't even
|
|
46
|
+
// be materializing an empty product...
|
|
47
|
+
const product = {
|
|
48
|
+
brand: '',
|
|
49
|
+
description: '',
|
|
50
|
+
identifier: {
|
|
51
|
+
key: id
|
|
52
|
+
},
|
|
53
|
+
longDescription: '',
|
|
54
|
+
mainVariant: {
|
|
55
|
+
barcode: '',
|
|
56
|
+
ean: '',
|
|
57
|
+
gtin: '',
|
|
58
|
+
identifier: {
|
|
59
|
+
sku: ''
|
|
60
|
+
},
|
|
61
|
+
images: [],
|
|
62
|
+
name: '',
|
|
63
|
+
options: [],
|
|
64
|
+
upc: ''
|
|
65
|
+
},
|
|
66
|
+
manufacturer: '',
|
|
67
|
+
name: '',
|
|
68
|
+
options: [],
|
|
69
|
+
parentCategories: [],
|
|
70
|
+
published: false,
|
|
71
|
+
sharedAttributes: [],
|
|
72
|
+
slug: '',
|
|
73
|
+
variants: [],
|
|
74
|
+
} satisfies Product;
|
|
5
75
|
|
|
6
|
-
export abstract class ProductProvider<
|
|
7
|
-
T extends Product = Product
|
|
8
|
-
> extends BaseProvider<T> {
|
|
9
|
-
public abstract getById(payload: ProductQueryById, reqCtx: RequestContext): Promise<T>;
|
|
10
|
-
public abstract getBySlug(payload: ProductQueryBySlug, reqCtx: RequestContext): Promise<T | null>;
|
|
11
|
-
public abstract getBySKU(payload: ProductQueryBySKU | ProductQueryBySKU[], reqCtx: RequestContext): Promise<T>;
|
|
12
|
-
|
|
13
|
-
protected createEmptyProduct(id: string): T {
|
|
14
|
-
const product = this.newModel();
|
|
15
|
-
product.identifier = { key: id };
|
|
16
|
-
product.meta.placeholder = true;
|
|
17
76
|
return product;
|
|
18
77
|
}
|
|
19
78
|
|
|
@@ -1,20 +1,80 @@
|
|
|
1
|
+
import type { InvalidInputError, NotFoundError } from '../schemas/index.js';
|
|
1
2
|
import type { Profile } from '../schemas/models/index.js';
|
|
2
|
-
import type { ProfileMutationUpdate } from '../schemas/mutations/index.js';
|
|
3
|
-
import type { ProfileQuerySelf } from '../schemas/queries/index.js';
|
|
4
|
-
import type {
|
|
3
|
+
import type { ProfileMutationAddShippingAddress, ProfileMutationMakeShippingAddressDefault, ProfileMutationRemoveShippingAddress, ProfileMutationSetBillingAddress, ProfileMutationUpdate, ProfileMutationUpdateShippingAddress } from '../schemas/mutations/index.js';
|
|
4
|
+
import type { ProfileQuerySelf as ProfileQueryById } from '../schemas/queries/index.js';
|
|
5
|
+
import type { Result } from '../schemas/result.js';
|
|
5
6
|
import { BaseProvider } from './base.provider.js';
|
|
6
7
|
|
|
7
|
-
export abstract class ProfileProvider
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
export abstract class ProfileProvider extends BaseProvider {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns the profile of the currently authenticated (registered) user.
|
|
12
|
+
*
|
|
13
|
+
* Usecase: Fetch the profile of the logged-in user for display in header, or account settings.
|
|
14
|
+
* @param payload
|
|
15
|
+
*/
|
|
16
|
+
public abstract getById(payload: ProfileQueryById): Promise<Result<Profile, NotFoundError>>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Updates the base profile information of the currently authenticated (registered) user.
|
|
20
|
+
*
|
|
21
|
+
* TODO: This should include first/lastname.
|
|
22
|
+
* TODO: In some systems, updating email/phone may require re-verification.
|
|
23
|
+
* TODO: Handle conflicts if email/phone is already in use by another user.
|
|
24
|
+
* TODO: In some systems the email might not be editable.
|
|
25
|
+
*
|
|
26
|
+
* Usecase: Update the user's name, email, or phone number.
|
|
27
|
+
* @param payload
|
|
28
|
+
*/
|
|
29
|
+
public abstract update(payload: ProfileMutationUpdate): Promise<Result<Profile, NotFoundError>>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new shipping address for the currently authenticated (registered) user.
|
|
33
|
+
* Does not set it as default automatically.
|
|
34
|
+
*
|
|
35
|
+
* Usecase: User adds a new shipping address in their profile or during checkout. Ideally, any address manipulation
|
|
36
|
+
* done at checkout should be considered local to that session, unless the addressbook is empty.
|
|
37
|
+
* @param payload
|
|
38
|
+
*/
|
|
39
|
+
public abstract addShippingAddress(payload: ProfileMutationAddShippingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Updates an existing shipping address for the currently authenticated (registered) user.
|
|
43
|
+
*
|
|
44
|
+
* Usecase: User edits an existing shipping address in their profile. Ideally, any address manipulation
|
|
45
|
+
* done at checkout should be considered local to that session/order, unless the addressbook is empty.
|
|
46
|
+
* @param payload
|
|
47
|
+
*/
|
|
48
|
+
public abstract updateShippingAddress(payload: ProfileMutationUpdateShippingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Removes an existing shipping address for the currently authenticated (registered) user.
|
|
52
|
+
*
|
|
53
|
+
* If the removed address was the default shipping address, the default shipping address is set to a random other address.
|
|
54
|
+
*
|
|
55
|
+
* Usecase: User deletes a shipping address from their profile.
|
|
56
|
+
* @param payload
|
|
57
|
+
*/
|
|
58
|
+
public abstract removeShippingAddress(payload: ProfileMutationRemoveShippingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Configures an existing shipping address as the default shipping address for the currently authenticated (registered) user.
|
|
62
|
+
*
|
|
63
|
+
* Usecase: User selects a default shipping address in their profile.
|
|
64
|
+
* @param payload
|
|
65
|
+
*/
|
|
66
|
+
public abstract makeShippingAddressDefault(payload: ProfileMutationMakeShippingAddressDefault): Promise<Result<Profile, NotFoundError>>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Sets the current/active billing address for the currently authenticated (registered) user.
|
|
70
|
+
*
|
|
71
|
+
* Usecase: User sets or updates their billing address in their profile or during checkout.
|
|
72
|
+
*
|
|
73
|
+
* It was a design decision not to support multiple billing addresses. The billing address represents who you are as the commercial
|
|
74
|
+
* entity being billed, and as such it makes sense to have a single authoritative billing address.
|
|
75
|
+
* @param payload
|
|
76
|
+
*/
|
|
77
|
+
public abstract setBillingAddress(payload: ProfileMutationSetBillingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
18
78
|
|
|
19
79
|
protected override getResourceName(): string {
|
|
20
80
|
return 'profile';
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import type { Store } from '../schemas/models/store.model.js';
|
|
2
2
|
import type { StoreQueryByProximity } from '../schemas/queries/index.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Result } from '../schemas/result.js';
|
|
4
4
|
import { BaseProvider } from './base.provider.js';
|
|
5
5
|
|
|
6
|
-
export abstract class StoreProvider
|
|
7
|
-
|
|
8
|
-
> extends BaseProvider<T> {
|
|
9
|
-
public abstract queryByProximity(payload: StoreQueryByProximity, reqCtx: RequestContext): Promise<Array<T>>;
|
|
6
|
+
export abstract class StoreProvider extends BaseProvider {
|
|
7
|
+
public abstract queryByProximity(payload: StoreQueryByProximity): Promise<Result<Array<Store>>>;
|
|
10
8
|
|
|
11
9
|
protected override getResourceName(): string {
|
|
12
10
|
return 'store';
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import type { InferType } from '../zod-utils.js';
|
|
3
|
+
import type { Client } from '../client/client.js';
|
|
2
4
|
|
|
3
5
|
export const CapabilitiesSchema = z.looseObject({
|
|
4
6
|
product: z.boolean(),
|
|
5
|
-
|
|
7
|
+
productSearch: z.boolean(),
|
|
6
8
|
analytics: z.boolean(),
|
|
7
9
|
identity: z.boolean(),
|
|
8
10
|
cart: z.boolean(),
|
|
9
11
|
checkout: z.boolean(),
|
|
10
12
|
order: z.boolean(),
|
|
13
|
+
orderSearch: z.boolean(),
|
|
11
14
|
inventory: z.boolean(),
|
|
12
15
|
price: z.boolean(),
|
|
13
16
|
category: z.boolean(),
|
|
14
|
-
store: z.boolean()
|
|
17
|
+
store: z.boolean(),
|
|
18
|
+
profile: z.boolean()
|
|
15
19
|
});
|
|
16
20
|
|
|
17
|
-
export type Capabilities =
|
|
21
|
+
export type Capabilities = InferType<typeof CapabilitiesSchema>;
|
|
22
|
+
export type ClientFromCapabilities<C extends Partial<Capabilities>> = {
|
|
23
|
+
[K in keyof C & keyof Client as C[K] extends true ? K : never]: Client[K];
|
|
24
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { InferType } from '../../zod-utils.js';
|
|
3
|
+
|
|
4
|
+
export const GenericErrorSchema = z.looseObject({
|
|
5
|
+
type: z.literal('Generic'),
|
|
6
|
+
message: z.string().nonempty()
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type GenericError = InferType<typeof GenericErrorSchema>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { InferType } from '../../zod-utils.js';
|
|
3
|
+
|
|
4
|
+
export const InvalidInputErrorSchema = z.looseObject({
|
|
5
|
+
type: z.literal('InvalidInput'),
|
|
6
|
+
error: z.ZodError
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type InvalidInputError = InferType<typeof InvalidInputErrorSchema>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { InferType } from '../../zod-utils.js';
|
|
3
|
+
|
|
4
|
+
export const InvalidOutputErrorSchema = z.looseObject({
|
|
5
|
+
type: z.literal('InvalidOutput'),
|
|
6
|
+
error: z.ZodError
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type InvalidOutputError = InferType<typeof InvalidOutputErrorSchema>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { InferType } from '../../zod-utils.js';
|
|
3
|
+
|
|
4
|
+
export const NotFoundErrorSchema = z.looseObject({
|
|
5
|
+
type: z.literal('NotFound'),
|
|
6
|
+
identifier: z.unknown()
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export type NotFoundError = InferType<typeof NotFoundErrorSchema>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import { BaseModelSchema } from './base.model.js';
|
|
3
|
+
import type { InferType } from '../../zod-utils.js';
|
|
3
4
|
|
|
4
5
|
export const AnalyticsEventSchema = BaseModelSchema.extend({
|
|
5
6
|
});
|
|
6
7
|
|
|
7
|
-
export type AnalyticsEvent =
|
|
8
|
+
export type AnalyticsEvent = InferType<typeof AnalyticsEventSchema>;
|
|
@@ -1,31 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
export const CacheInformationSchema = z.looseObject({
|
|
4
|
-
hit: z.boolean().default(false),
|
|
5
|
-
key: z.string().default('')
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
export const MetaSchema = z.looseObject({
|
|
9
|
-
cache: CacheInformationSchema.default(() => CacheInformationSchema.parse({})),
|
|
10
|
-
placeholder: z.boolean().default(false).describe('Whether or not the entity exists in a remote system, or is a default placeholder.')
|
|
11
|
-
});
|
|
2
|
+
import type { InferType } from '../../zod-utils.js';
|
|
12
3
|
|
|
13
4
|
export const BaseModelSchema = z.looseObject({
|
|
14
|
-
meta: MetaSchema.default(() => MetaSchema.parse({}))
|
|
15
5
|
});
|
|
16
6
|
|
|
17
|
-
export type CacheInformation = z.infer<typeof CacheInformationSchema>;
|
|
18
|
-
export type Meta = z.infer<typeof MetaSchema>;
|
|
19
|
-
export type BaseModel = z.infer<typeof BaseModelSchema>;
|
|
20
|
-
|
|
21
|
-
|
|
22
7
|
export const PaginationOptionsSchema = z.looseObject({
|
|
23
8
|
pageNumber: z.number().default(1).describe('Current page number, starting from 1'),
|
|
24
|
-
pageSize: z.number().default(20).describe('Number of items per page'),
|
|
9
|
+
pageSize: z.number().min(1).max(50).default(20).describe('Number of items per page'),
|
|
25
10
|
});
|
|
26
11
|
|
|
27
|
-
export type PaginationOptions = z.infer<typeof PaginationOptionsSchema>;
|
|
28
|
-
|
|
29
12
|
/**
|
|
30
13
|
* This seemed like the right way to do it, but we need to be able to pass in the item schema even later than this
|
|
31
14
|
*
|
|
@@ -34,9 +17,8 @@ export function createPaginatedResponseSchema<ItemType extends z.ZodTypeAny>(
|
|
|
34
17
|
itemSchema: ItemType,
|
|
35
18
|
) {
|
|
36
19
|
return z.object({
|
|
37
|
-
meta: MetaSchema.default(() => MetaSchema.parse({})),
|
|
38
20
|
pageNumber: z.number().min(1).describe('Current page number, starting from 1'),
|
|
39
|
-
pageSize: z.number().min(1).
|
|
21
|
+
pageSize: z.number().min(1).describe('Number of items per page'),
|
|
40
22
|
totalCount: z.number().min(0).describe('Total number of items available'),
|
|
41
23
|
totalPages: z.number().min(0).describe('Total number of pages available'),
|
|
42
24
|
items: z.array(itemSchema),
|
|
@@ -55,6 +37,6 @@ export const ImageSchema = z.looseObject({
|
|
|
55
37
|
height: z.number().optional().describe('Height of the original image, in pixels, if known'),
|
|
56
38
|
});
|
|
57
39
|
|
|
58
|
-
export type Image =
|
|
59
|
-
|
|
60
|
-
|
|
40
|
+
export type Image = InferType<typeof ImageSchema>;
|
|
41
|
+
export type PaginationOptions = InferType<typeof PaginationOptionsSchema>;
|
|
42
|
+
export type BaseModel = InferType<typeof BaseModelSchema>;
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { CartIdentifierSchema, CartItemIdentifierSchema, IdentityIdentifierSchema, ProductIdentifierSchema,
|
|
2
|
+
import { CartIdentifierSchema, CartItemIdentifierSchema, IdentityIdentifierSchema, ProductIdentifierSchema, ProductVariantIdentifierSchema } from '../models/identifiers.model.js';
|
|
3
3
|
import { CostBreakDownSchema, ItemCostBreakdownSchema } from './cost.model.js';
|
|
4
4
|
import { BaseModelSchema } from './base.model.js';
|
|
5
|
+
import type { InferType } from '../../zod-utils.js';
|
|
5
6
|
|
|
6
7
|
export const CartItemSchema = z.looseObject({
|
|
7
8
|
identifier: CartItemIdentifierSchema.default(() => CartItemIdentifierSchema.parse({})),
|
|
8
9
|
product: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({})),
|
|
9
|
-
|
|
10
|
+
variant: ProductVariantIdentifierSchema.default(() => ProductVariantIdentifierSchema.parse({})),
|
|
10
11
|
quantity: z.number().default(0),
|
|
11
12
|
price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({})),
|
|
12
13
|
});
|
|
13
14
|
|
|
14
15
|
export const CartSchema = BaseModelSchema.extend({
|
|
15
16
|
identifier: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({})),
|
|
16
|
-
|
|
17
17
|
userId: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
|
|
18
|
-
|
|
19
18
|
items: z.array(CartItemSchema).default(() => []),
|
|
20
19
|
price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
|
|
21
20
|
name: z.string().default(''),
|
|
22
21
|
description: z.string().default(''),
|
|
23
|
-
|
|
24
|
-
|
|
25
22
|
});
|
|
26
23
|
|
|
27
24
|
|
|
28
|
-
export type CartItem =
|
|
29
|
-
export type Cart =
|
|
25
|
+
export type CartItem = InferType<typeof CartItemSchema>;
|
|
26
|
+
export type Cart = InferType<typeof CartSchema>;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
// getBySeoSlug
|
|
2
|
-
// getBreadcrumbPathToCategory
|
|
3
|
-
// getById
|
|
4
|
-
// getByExternalId
|
|
5
|
-
// getChildCategories
|
|
6
|
-
|
|
7
|
-
|
|
8
1
|
import { z } from 'zod';
|
|
9
2
|
import { BaseModelSchema, createPaginatedResponseSchema, ImageSchema } from './base.model.js';
|
|
10
3
|
import { CategoryIdentifierSchema } from './identifiers.model.js';
|
|
4
|
+
import type { InferType } from '../../zod-utils.js';
|
|
5
|
+
|
|
11
6
|
export const CategorySchema = BaseModelSchema.extend({
|
|
12
7
|
identifier: CategoryIdentifierSchema.default(() => CategoryIdentifierSchema.parse({})),
|
|
13
8
|
name: z.string().default(''),
|
|
@@ -17,7 +12,7 @@ export const CategorySchema = BaseModelSchema.extend({
|
|
|
17
12
|
parentCategory: CategoryIdentifierSchema.optional(),
|
|
18
13
|
});
|
|
19
14
|
|
|
20
|
-
export type Category =
|
|
15
|
+
export type Category = InferType<typeof CategorySchema>;
|
|
21
16
|
|
|
22
17
|
export const CategoryPaginatedResultSchema = createPaginatedResponseSchema(CategorySchema);
|
|
23
|
-
export type CategoryPaginatedResult =
|
|
18
|
+
export type CategoryPaginatedResult = InferType<typeof CategoryPaginatedResultSchema>;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
import { z } from 'zod';
|
|
4
2
|
import { BaseModelSchema } from './base.model.js';
|
|
5
|
-
import { CartIdentifierSchema, CheckoutIdentifierSchema, CheckoutItemIdentifierSchema, OrderIdentifierSchema,
|
|
3
|
+
import { CartIdentifierSchema, CheckoutIdentifierSchema, CheckoutItemIdentifierSchema, OrderIdentifierSchema, ProductVariantIdentifierSchema } from './identifiers.model.js';
|
|
6
4
|
import { CostBreakDownSchema, ItemCostBreakdownSchema } from './cost.model.js';
|
|
7
5
|
import { AddressSchema } from './profile.model.js';
|
|
8
6
|
import { ShippingInstructionSchema } from './shipping-method.model.js';
|
|
9
7
|
import { PaymentInstructionSchema } from './payment.model.js';
|
|
8
|
+
import type { InferType } from '../../zod-utils.js';
|
|
10
9
|
|
|
11
10
|
export const CheckoutItemSchema = z.looseObject({
|
|
12
11
|
identifier: CheckoutItemIdentifierSchema.default(() => CheckoutItemIdentifierSchema.parse({})),
|
|
13
|
-
|
|
12
|
+
variant: ProductVariantIdentifierSchema.default(() => ProductVariantIdentifierSchema.parse({})),
|
|
14
13
|
quantity: z.number().default(0),
|
|
15
14
|
price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({})),
|
|
16
15
|
});
|
|
@@ -43,7 +42,7 @@ export const CheckoutSchema = BaseModelSchema.extend({
|
|
|
43
42
|
description: z.string().default(''),
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
billingAddress: AddressSchema.optional(),
|
|
45
|
+
billingAddress: AddressSchema.optional().nullable(),
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
48
|
* Shipping and billing details can be changed on the checkout, but not items or quantities.
|
|
@@ -62,5 +61,5 @@ export const CheckoutSchema = BaseModelSchema.extend({
|
|
|
62
61
|
|
|
63
62
|
|
|
64
63
|
|
|
65
|
-
export type CheckoutItem =
|
|
66
|
-
export type Checkout =
|
|
64
|
+
export type CheckoutItem = InferType<typeof CheckoutItemSchema>;
|
|
65
|
+
export type Checkout = InferType<typeof CheckoutSchema>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import z from "zod";
|
|
1
|
+
import { z } from "zod";
|
|
2
2
|
import { MonetaryAmountSchema } from "./price.model.js";
|
|
3
|
+
import type { InferType } from '../../zod-utils.js';
|
|
3
4
|
|
|
4
5
|
export const CostBreakDownSchema = z.looseObject({
|
|
5
6
|
totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc.'),
|
|
@@ -17,5 +18,5 @@ export const ItemCostBreakdownSchema = z.looseObject({
|
|
|
17
18
|
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe('The total discount applied to all units of the item.'),
|
|
18
19
|
});
|
|
19
20
|
|
|
20
|
-
export type CostBreakDown =
|
|
21
|
-
export type ItemCostBreakdown =
|
|
21
|
+
export type CostBreakDown = InferType<typeof CostBreakDownSchema>;
|
|
22
|
+
export type ItemCostBreakdown = InferType<typeof ItemCostBreakdownSchema>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import type { InferType } from '../../zod-utils.js';
|
|
2
3
|
|
|
3
4
|
export const CurrencySchema = z.enum([
|
|
4
5
|
'AED',
|
|
@@ -184,4 +185,4 @@ export const CurrencySchema = z.enum([
|
|
|
184
185
|
'ZWL',
|
|
185
186
|
]);
|
|
186
187
|
|
|
187
|
-
export type Currency =
|
|
188
|
+
export type Currency = InferType<typeof CurrencySchema>;
|