@reactionary/core 0.0.37 → 0.0.39
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/index.js +3 -8
- package/package.json +2 -3
- package/providers/analytics.provider.js +3 -0
- package/providers/base.provider.js +20 -1
- package/providers/cart.provider.js +3 -0
- package/providers/category.provider.js +9 -0
- package/providers/identity.provider.js +3 -0
- package/providers/inventory.provider.js +3 -0
- package/providers/price.provider.js +26 -0
- package/providers/product.provider.js +3 -0
- package/providers/search.provider.js +3 -0
- package/schemas/capabilities.schema.js +2 -1
- package/schemas/models/base.model.js +24 -1
- package/schemas/models/cart.model.js +24 -3
- package/schemas/models/category.model.js +16 -0
- package/schemas/models/identifiers.model.js +18 -1
- package/schemas/models/inventory.model.js +5 -1
- package/schemas/models/price.model.js +9 -3
- package/schemas/queries/category.query.js +27 -0
- package/schemas/queries/index.js +9 -0
- package/schemas/queries/inventory.query.js +7 -2
- package/schemas/session.schema.js +11 -1
- package/src/client/client.d.ts +2 -0
- package/src/index.d.ts +3 -8
- package/src/providers/analytics.provider.d.ts +1 -0
- package/src/providers/base.provider.d.ts +11 -2
- package/src/providers/cart.provider.d.ts +1 -0
- package/src/providers/category.provider.d.ts +67 -0
- package/src/providers/identity.provider.d.ts +1 -0
- package/src/providers/inventory.provider.d.ts +1 -0
- package/src/providers/price.provider.d.ts +29 -0
- package/src/providers/product.provider.d.ts +1 -0
- package/src/providers/search.provider.d.ts +1 -0
- package/src/schemas/capabilities.schema.d.ts +1 -0
- package/src/schemas/models/base.model.d.ts +51 -0
- package/src/schemas/models/cart.model.d.ts +4584 -0
- package/src/schemas/models/category.model.d.ts +130 -0
- package/src/schemas/models/identifiers.model.d.ts +49 -0
- package/src/schemas/models/inventory.model.d.ts +28 -0
- package/src/schemas/models/price.model.d.ts +394 -3
- package/src/schemas/mutations/analytics.mutation.d.ts +4 -4
- package/src/schemas/queries/category.query.d.ts +94 -0
- package/src/schemas/queries/index.d.ts +9 -0
- package/src/schemas/queries/inventory.query.d.ts +39 -3
- package/src/schemas/queries/search.query.d.ts +1 -1
- package/src/schemas/session.schema.d.ts +386 -0
- package/decorators/trpc.decorators.js +0 -66
- package/src/decorators/trpc.decorators.d.ts +0 -88
package/index.js
CHANGED
|
@@ -4,7 +4,6 @@ export * from "./cache/redis-cache";
|
|
|
4
4
|
export * from "./cache/noop-cache";
|
|
5
5
|
export * from "./client/client";
|
|
6
6
|
export * from "./client/client-builder";
|
|
7
|
-
export * from "./decorators/trpc.decorators";
|
|
8
7
|
export * from "./providers/analytics.provider";
|
|
9
8
|
export * from "./providers/base.provider";
|
|
10
9
|
export * from "./providers/cart.provider";
|
|
@@ -13,6 +12,7 @@ export * from "./providers/inventory.provider";
|
|
|
13
12
|
export * from "./providers/price.provider";
|
|
14
13
|
export * from "./providers/product.provider";
|
|
15
14
|
export * from "./providers/search.provider";
|
|
15
|
+
export * from "./providers/category.provider";
|
|
16
16
|
export * from "./schemas/capabilities.schema";
|
|
17
17
|
export * from "./schemas/session.schema";
|
|
18
18
|
export * from "./schemas/models/base.model";
|
|
@@ -24,6 +24,7 @@ export * from "./schemas/models/inventory.model";
|
|
|
24
24
|
export * from "./schemas/models/price.model";
|
|
25
25
|
export * from "./schemas/models/product.model";
|
|
26
26
|
export * from "./schemas/models/search.model";
|
|
27
|
+
export * from "./schemas/models/category.model";
|
|
27
28
|
export * from "./schemas/mutations/base.mutation";
|
|
28
29
|
export * from "./schemas/mutations/cart.mutation";
|
|
29
30
|
export * from "./schemas/mutations/identity.mutation";
|
|
@@ -31,10 +32,4 @@ export * from "./schemas/mutations/inventory.mutation";
|
|
|
31
32
|
export * from "./schemas/mutations/price.mutation";
|
|
32
33
|
export * from "./schemas/mutations/product.mutation";
|
|
33
34
|
export * from "./schemas/mutations/search.mutation";
|
|
34
|
-
export * from "./schemas/queries
|
|
35
|
-
export * from "./schemas/queries/cart.query";
|
|
36
|
-
export * from "./schemas/queries/identity.query";
|
|
37
|
-
export * from "./schemas/queries/inventory.query";
|
|
38
|
-
export * from "./schemas/queries/price.query";
|
|
39
|
-
export * from "./schemas/queries/product.query";
|
|
40
|
-
export * from "./schemas/queries/search.query";
|
|
35
|
+
export * from "./schemas/queries";
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactionary/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "src/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"zod": "4.0.0-beta.20250430T185432",
|
|
8
|
-
"@upstash/redis": "^1.34.9"
|
|
9
|
-
"reflect-metadata": "0.2.2"
|
|
8
|
+
"@upstash/redis": "^1.34.9"
|
|
10
9
|
}
|
|
11
10
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createPaginatedResponseSchema } from "../schemas/models/base.model";
|
|
1
2
|
class BaseProvider {
|
|
2
3
|
constructor(schema, cache) {
|
|
3
4
|
this.schema = schema;
|
|
@@ -20,10 +21,28 @@ class BaseProvider {
|
|
|
20
21
|
* Handler for parsing a response from a remote provider and converting it
|
|
21
22
|
* into the typed domain model.
|
|
22
23
|
*/
|
|
23
|
-
parseSingle(_body) {
|
|
24
|
+
parseSingle(_body, session) {
|
|
24
25
|
const model = this.newModel();
|
|
25
26
|
return this.assert(model);
|
|
26
27
|
}
|
|
28
|
+
parsePaginatedResult(_body, session) {
|
|
29
|
+
return createPaginatedResponseSchema(this.schema).parse({});
|
|
30
|
+
}
|
|
31
|
+
generateCacheKeyPaginatedResult(resultSetName, res, session) {
|
|
32
|
+
const type = this.getResourceName();
|
|
33
|
+
const langPart = session.languageContext.locale;
|
|
34
|
+
const currencyPart = session.languageContext.currencyCode || "default";
|
|
35
|
+
const storePart = session.storeIdentifier?.key || "default";
|
|
36
|
+
return `${type}-${resultSetName}-paginated|pageNumber:${res.pageNumber}|pageSize:${res.pageSize}|store:${storePart}|lang:${langPart}|currency:${currencyPart}`;
|
|
37
|
+
}
|
|
38
|
+
generateCacheKeySingle(identifier, session) {
|
|
39
|
+
const type = this.getResourceName();
|
|
40
|
+
const idPart = Object.entries(identifier).map(([k, v]) => `${k}:${v.key}`).join("#");
|
|
41
|
+
const langPart = session.languageContext.locale;
|
|
42
|
+
const currencyPart = session.languageContext.currencyCode || "default";
|
|
43
|
+
const storePart = session.storeIdentifier?.key || "default";
|
|
44
|
+
return `${type}-${idPart}|store:${storePart}|lang:${langPart}|currency:${currencyPart}`;
|
|
45
|
+
}
|
|
27
46
|
}
|
|
28
47
|
export {
|
|
29
48
|
BaseProvider
|
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
import { BaseProvider } from "./base.provider";
|
|
2
2
|
class PriceProvider extends BaseProvider {
|
|
3
|
+
/**
|
|
4
|
+
* Utility function to create an empty price result, with a value of -1.
|
|
5
|
+
* This is used when no price is found for a given SKU + currency combination.
|
|
6
|
+
* You should check for meta.placeholder to see if this is a real price or a placeholder.
|
|
7
|
+
* @param sku
|
|
8
|
+
* @param currency
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
getEmptyPriceResult(sku, currency) {
|
|
12
|
+
const base = this.newModel();
|
|
13
|
+
base.identifier = {
|
|
14
|
+
sku: { key: sku }
|
|
15
|
+
};
|
|
16
|
+
base.unitPrice = {
|
|
17
|
+
value: -1,
|
|
18
|
+
currency
|
|
19
|
+
};
|
|
20
|
+
base.meta = {
|
|
21
|
+
cache: { hit: false, key: `price-${sku}-${currency}` },
|
|
22
|
+
placeholder: true
|
|
23
|
+
};
|
|
24
|
+
return this.assert(base);
|
|
25
|
+
}
|
|
26
|
+
getResourceName() {
|
|
27
|
+
return "price";
|
|
28
|
+
}
|
|
3
29
|
}
|
|
4
30
|
export {
|
|
5
31
|
PriceProvider
|
|
@@ -10,8 +10,31 @@ const MetaSchema = z.looseInterface({
|
|
|
10
10
|
const BaseModelSchema = z.looseInterface({
|
|
11
11
|
meta: MetaSchema.default(() => MetaSchema.parse({}))
|
|
12
12
|
});
|
|
13
|
+
const PaginationOptionsSchema = z.looseInterface({
|
|
14
|
+
pageNumber: z.number().default(1).describe("Current page number, starting from 1"),
|
|
15
|
+
pageSize: z.number().default(20).describe("Number of items per page")
|
|
16
|
+
});
|
|
17
|
+
function createPaginatedResponseSchema(itemSchema) {
|
|
18
|
+
return z.object({
|
|
19
|
+
meta: MetaSchema.default(() => MetaSchema.parse({})),
|
|
20
|
+
pageNumber: z.number().min(1).describe("Current page number, starting from 1"),
|
|
21
|
+
pageSize: z.number().min(1).max(50).describe("Number of items per page"),
|
|
22
|
+
totalCount: z.number().min(0).describe("Total number of items available"),
|
|
23
|
+
totalPages: z.number().min(0).describe("Total number of pages available"),
|
|
24
|
+
items: z.array(itemSchema)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const ImageSchema = z.looseInterface({
|
|
28
|
+
sourceUrl: z.string().default("").describe("The original source URL of the image. Pass this through your image resizing and transcoding service to get the desired size, and generate thumbnails as needed"),
|
|
29
|
+
altText: z.string().default("").describe("Alternative text for the image, for accessibility purposes. Must always be set, and non-empty"),
|
|
30
|
+
width: z.number().optional().describe("Width of the original image, in pixels, if known"),
|
|
31
|
+
height: z.number().optional().describe("Height of the original image, in pixels, if known")
|
|
32
|
+
});
|
|
13
33
|
export {
|
|
14
34
|
BaseModelSchema,
|
|
15
35
|
CacheInformationSchema,
|
|
16
|
-
|
|
36
|
+
ImageSchema,
|
|
37
|
+
MetaSchema,
|
|
38
|
+
PaginationOptionsSchema,
|
|
39
|
+
createPaginatedResponseSchema
|
|
17
40
|
};
|
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { CartIdentifierSchema, CartItemIdentifierSchema, ProductIdentifierSchema } from "../models/identifiers.model";
|
|
3
3
|
import { BaseModelSchema } from "./base.model";
|
|
4
|
+
import { MonetaryAmountSchema } from "./price.model";
|
|
5
|
+
const CostBreakDownSchema = z.looseObject({
|
|
6
|
+
totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc."),
|
|
7
|
+
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of discount applied to the cart."),
|
|
8
|
+
totalSurcharge: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of surcharge applied to the cart."),
|
|
9
|
+
totalShipping: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of shipping fees for the cart."),
|
|
10
|
+
totalProductPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price of products in the cart."),
|
|
11
|
+
grandTotal: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for the cart including all taxes, discounts, and shipping.")
|
|
12
|
+
});
|
|
13
|
+
const ItemCostBreakdownSchema = z.looseObject({
|
|
14
|
+
unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The price per single unit of the item."),
|
|
15
|
+
unitDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The discount applied per single unit of the item."),
|
|
16
|
+
totalPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for all units of the item."),
|
|
17
|
+
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total discount applied to all units of the item.")
|
|
18
|
+
});
|
|
4
19
|
const CartItemSchema = z.looseInterface({
|
|
5
20
|
identifier: CartItemIdentifierSchema.default(() => CartItemIdentifierSchema.parse({})),
|
|
6
21
|
product: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({})),
|
|
7
|
-
quantity: z.number().default(0)
|
|
22
|
+
quantity: z.number().default(0),
|
|
23
|
+
price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({}))
|
|
8
24
|
});
|
|
9
25
|
const CartSchema = BaseModelSchema.extend({
|
|
10
26
|
identifier: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({})),
|
|
11
|
-
items: z.array(CartItemSchema).default(() => [])
|
|
27
|
+
items: z.array(CartItemSchema).default(() => []),
|
|
28
|
+
price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
|
|
29
|
+
name: z.string().default(""),
|
|
30
|
+
description: z.string().default("")
|
|
12
31
|
});
|
|
13
32
|
export {
|
|
14
33
|
CartItemSchema,
|
|
15
|
-
CartSchema
|
|
34
|
+
CartSchema,
|
|
35
|
+
CostBreakDownSchema,
|
|
36
|
+
ItemCostBreakdownSchema
|
|
16
37
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BaseModelSchema, createPaginatedResponseSchema, ImageSchema } from "./base.model";
|
|
3
|
+
import { CategoryIdentifierSchema } from "./identifiers.model";
|
|
4
|
+
const CategorySchema = BaseModelSchema.extend({
|
|
5
|
+
identifier: CategoryIdentifierSchema.default(() => CategoryIdentifierSchema.parse({})),
|
|
6
|
+
name: z.string().default(""),
|
|
7
|
+
slug: z.string().default(""),
|
|
8
|
+
text: z.string().default(""),
|
|
9
|
+
images: z.array(ImageSchema.required()).default(() => []),
|
|
10
|
+
parentCategory: CategoryIdentifierSchema.optional()
|
|
11
|
+
});
|
|
12
|
+
const CategoryPaginatedResultSchema = createPaginatedResponseSchema(CategorySchema);
|
|
13
|
+
export {
|
|
14
|
+
CategoryPaginatedResultSchema,
|
|
15
|
+
CategorySchema
|
|
16
|
+
};
|
|
@@ -27,13 +27,30 @@ const CartItemIdentifierSchema = z.looseInterface({
|
|
|
27
27
|
const PriceIdentifierSchema = z.looseInterface({
|
|
28
28
|
sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({}))
|
|
29
29
|
});
|
|
30
|
+
const CategoryIdentifierSchema = z.looseInterface({
|
|
31
|
+
key: z.string().default("").nonoptional()
|
|
32
|
+
});
|
|
33
|
+
const WebStoreIdentifierSchema = z.looseInterface({
|
|
34
|
+
key: z.string().default("").nonoptional()
|
|
35
|
+
});
|
|
36
|
+
const InventoryChannelIdentifierSchema = z.looseInterface({
|
|
37
|
+
key: z.string().default("online").nonoptional()
|
|
38
|
+
});
|
|
39
|
+
const InventoryIdentifierSchema = z.looseInterface({
|
|
40
|
+
sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({})),
|
|
41
|
+
channelId: InventoryChannelIdentifierSchema.default(() => InventoryChannelIdentifierSchema.parse({}))
|
|
42
|
+
});
|
|
30
43
|
export {
|
|
31
44
|
CartIdentifierSchema,
|
|
32
45
|
CartItemIdentifierSchema,
|
|
46
|
+
CategoryIdentifierSchema,
|
|
33
47
|
FacetIdentifierSchema,
|
|
34
48
|
FacetValueIdentifierSchema,
|
|
49
|
+
InventoryChannelIdentifierSchema,
|
|
50
|
+
InventoryIdentifierSchema,
|
|
35
51
|
PriceIdentifierSchema,
|
|
36
52
|
ProductIdentifierSchema,
|
|
37
53
|
SKUIdentifierSchema,
|
|
38
|
-
SearchIdentifierSchema
|
|
54
|
+
SearchIdentifierSchema,
|
|
55
|
+
WebStoreIdentifierSchema
|
|
39
56
|
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BaseModelSchema } from "./base.model";
|
|
3
|
+
import { InventoryIdentifierSchema } from "./identifiers.model";
|
|
3
4
|
const InventorySchema = BaseModelSchema.extend({
|
|
4
|
-
|
|
5
|
+
identifier: InventoryIdentifierSchema.default(() => InventoryIdentifierSchema.parse({})),
|
|
6
|
+
sku: z.string().default(""),
|
|
7
|
+
quantity: z.number().default(0),
|
|
8
|
+
status: z.enum(["inStock", "outOfStock", "onBackOrder", "preOrder", "discontinued"]).default("inStock")
|
|
5
9
|
});
|
|
6
10
|
export {
|
|
7
11
|
InventorySchema
|
|
@@ -3,14 +3,20 @@ import { BaseModelSchema } from "./base.model";
|
|
|
3
3
|
import { PriceIdentifierSchema } from "./identifiers.model";
|
|
4
4
|
import { CurrencySchema } from "./currency.model";
|
|
5
5
|
const MonetaryAmountSchema = z.looseInterface({
|
|
6
|
-
|
|
6
|
+
value: z.number().default(0).describe("The monetary amount in decimal-precision."),
|
|
7
7
|
currency: CurrencySchema.default("XXX").describe("The currency associated with the amount, as a ISO 4217 standardized code.")
|
|
8
8
|
});
|
|
9
|
+
const TieredPriceSchema = z.looseObject({
|
|
10
|
+
minimumQuantity: z.number().default(0).describe("The minimum quantity required to be eligible for the tiered price."),
|
|
11
|
+
price: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The monetary amount for the tiered price.")
|
|
12
|
+
});
|
|
9
13
|
const PriceSchema = BaseModelSchema.extend({
|
|
10
14
|
identifier: PriceIdentifierSchema.default(() => PriceIdentifierSchema.parse({})),
|
|
11
|
-
|
|
15
|
+
unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})),
|
|
16
|
+
tieredPrices: z.array(TieredPriceSchema).default(() => [])
|
|
12
17
|
});
|
|
13
18
|
export {
|
|
14
19
|
MonetaryAmountSchema,
|
|
15
|
-
PriceSchema
|
|
20
|
+
PriceSchema,
|
|
21
|
+
TieredPriceSchema
|
|
16
22
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { CategoryIdentifierSchema } from "../models/identifiers.model";
|
|
3
|
+
import { BaseQuerySchema } from "./base.query";
|
|
4
|
+
import { PaginationOptionsSchema } from "../models/base.model";
|
|
5
|
+
const CategoryQueryById = BaseQuerySchema.extend({
|
|
6
|
+
id: CategoryIdentifierSchema.default(() => CategoryIdentifierSchema.parse({}))
|
|
7
|
+
});
|
|
8
|
+
const CategoryQueryBySlug = BaseQuerySchema.extend({
|
|
9
|
+
slug: z.string().default("")
|
|
10
|
+
});
|
|
11
|
+
const CategoryQueryForBreadcrumb = BaseQuerySchema.extend({
|
|
12
|
+
id: CategoryIdentifierSchema.default(() => CategoryIdentifierSchema.parse({}))
|
|
13
|
+
});
|
|
14
|
+
const CategoryQueryForChildCategories = BaseQuerySchema.extend({
|
|
15
|
+
parentId: CategoryIdentifierSchema.default(() => CategoryIdentifierSchema.parse({})),
|
|
16
|
+
paginationOptions: PaginationOptionsSchema.default(() => PaginationOptionsSchema.parse({}))
|
|
17
|
+
});
|
|
18
|
+
const CategoryQueryForTopCategories = BaseQuerySchema.extend({
|
|
19
|
+
paginationOptions: PaginationOptionsSchema.default(() => PaginationOptionsSchema.parse({}))
|
|
20
|
+
});
|
|
21
|
+
export {
|
|
22
|
+
CategoryQueryById,
|
|
23
|
+
CategoryQueryBySlug,
|
|
24
|
+
CategoryQueryForBreadcrumb,
|
|
25
|
+
CategoryQueryForChildCategories,
|
|
26
|
+
CategoryQueryForTopCategories
|
|
27
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./analytics.query";
|
|
2
|
+
export * from "./base.query";
|
|
3
|
+
export * from "./cart.query";
|
|
4
|
+
export * from "./category.query";
|
|
5
|
+
export * from "./identity.query";
|
|
6
|
+
export * from "./inventory.query";
|
|
7
|
+
export * from "./price.query";
|
|
8
|
+
export * from "./product.query";
|
|
9
|
+
export * from "./search.query";
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BaseQuerySchema } from "./base.query";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { ProductIdentifierSchema } from "../models/identifiers.model";
|
|
4
|
+
const InventoryQueryBySKUSchema = BaseQuerySchema.extend({
|
|
5
|
+
query: z.literal("sku"),
|
|
6
|
+
sku: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({}))
|
|
5
7
|
});
|
|
8
|
+
const InventoryQuerySchema = z.union([InventoryQueryBySKUSchema]);
|
|
9
|
+
;
|
|
6
10
|
export {
|
|
11
|
+
InventoryQueryBySKUSchema,
|
|
7
12
|
InventoryQuerySchema
|
|
8
13
|
};
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { IdentitySchema } from "./models/identity.model";
|
|
3
|
+
import { WebStoreIdentifierSchema } from "./models/identifiers.model";
|
|
4
|
+
import { CurrencySchema } from "./models/currency.model";
|
|
5
|
+
const LanguageContextSchema = z.looseObject({
|
|
6
|
+
locale: z.string().default("en-US"),
|
|
7
|
+
currencyCode: CurrencySchema.default(() => CurrencySchema.parse({})),
|
|
8
|
+
countryCode: z.string().default("US")
|
|
9
|
+
});
|
|
3
10
|
const SessionSchema = z.looseObject({
|
|
4
11
|
id: z.string(),
|
|
5
|
-
identity: IdentitySchema.default(() => IdentitySchema.parse({}))
|
|
12
|
+
identity: IdentitySchema.default(() => IdentitySchema.parse({})),
|
|
13
|
+
languageContext: LanguageContextSchema.default(() => LanguageContextSchema.parse({})),
|
|
14
|
+
storeIdentifier: WebStoreIdentifierSchema.default(() => WebStoreIdentifierSchema.parse({}))
|
|
6
15
|
});
|
|
7
16
|
export {
|
|
17
|
+
LanguageContextSchema,
|
|
8
18
|
SessionSchema
|
|
9
19
|
};
|
package/src/client/client.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { CartProvider } from "../providers/cart.provider";
|
|
|
6
6
|
import { PriceProvider } from "../providers/price.provider";
|
|
7
7
|
import { InventoryProvider } from "../providers/inventory.provider";
|
|
8
8
|
import { Cache } from "../cache/cache.interface";
|
|
9
|
+
import { CategoryProvider } from "../providers/category.provider";
|
|
9
10
|
export interface Client {
|
|
10
11
|
product: ProductProvider;
|
|
11
12
|
search: SearchProvider;
|
|
@@ -15,6 +16,7 @@ export interface Client {
|
|
|
15
16
|
analytics: Array<AnalyticsProvider>;
|
|
16
17
|
price: PriceProvider;
|
|
17
18
|
inventory: InventoryProvider;
|
|
19
|
+
category: CategoryProvider;
|
|
18
20
|
}
|
|
19
21
|
export interface BuildClientOptions {
|
|
20
22
|
cache?: Cache;
|
package/src/index.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ export * from './cache/redis-cache';
|
|
|
4
4
|
export * from './cache/noop-cache';
|
|
5
5
|
export * from './client/client';
|
|
6
6
|
export * from './client/client-builder';
|
|
7
|
-
export * from './decorators/trpc.decorators';
|
|
8
7
|
export * from './providers/analytics.provider';
|
|
9
8
|
export * from './providers/base.provider';
|
|
10
9
|
export * from './providers/cart.provider';
|
|
@@ -13,6 +12,7 @@ export * from './providers/inventory.provider';
|
|
|
13
12
|
export * from './providers/price.provider';
|
|
14
13
|
export * from './providers/product.provider';
|
|
15
14
|
export * from './providers/search.provider';
|
|
15
|
+
export * from './providers/category.provider';
|
|
16
16
|
export * from './schemas/capabilities.schema';
|
|
17
17
|
export * from './schemas/session.schema';
|
|
18
18
|
export * from './schemas/models/base.model';
|
|
@@ -24,6 +24,7 @@ export * from './schemas/models/inventory.model';
|
|
|
24
24
|
export * from './schemas/models/price.model';
|
|
25
25
|
export * from './schemas/models/product.model';
|
|
26
26
|
export * from './schemas/models/search.model';
|
|
27
|
+
export * from './schemas/models/category.model';
|
|
27
28
|
export * from './schemas/mutations/base.mutation';
|
|
28
29
|
export * from './schemas/mutations/cart.mutation';
|
|
29
30
|
export * from './schemas/mutations/identity.mutation';
|
|
@@ -31,10 +32,4 @@ export * from './schemas/mutations/inventory.mutation';
|
|
|
31
32
|
export * from './schemas/mutations/price.mutation';
|
|
32
33
|
export * from './schemas/mutations/product.mutation';
|
|
33
34
|
export * from './schemas/mutations/search.mutation';
|
|
34
|
-
export * from './schemas/queries
|
|
35
|
-
export * from './schemas/queries/cart.query';
|
|
36
|
-
export * from './schemas/queries/identity.query';
|
|
37
|
-
export * from './schemas/queries/inventory.query';
|
|
38
|
-
export * from './schemas/queries/price.query';
|
|
39
|
-
export * from './schemas/queries/product.query';
|
|
40
|
-
export * from './schemas/queries/search.query';
|
|
35
|
+
export * from './schemas/queries';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AnalyticsEvent } from '../schemas/models/analytics.model';
|
|
2
2
|
import { BaseProvider } from './base.provider';
|
|
3
3
|
export declare abstract class AnalyticsProvider<T extends AnalyticsEvent = AnalyticsEvent> extends BaseProvider<T> {
|
|
4
|
+
protected getResourceName(): string;
|
|
4
5
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { BaseModel } from '../schemas/models/base.model';
|
|
2
|
+
import { BaseModel, createPaginatedResponseSchema } from '../schemas/models/base.model';
|
|
3
3
|
import { Cache } from '../cache/cache.interface';
|
|
4
|
+
import { Session } from '../schemas/session.schema';
|
|
5
|
+
import { IdentifierType } from '../schemas/models/identifiers.model';
|
|
4
6
|
/**
|
|
5
7
|
* Base capability provider, responsible for mutations (changes) and queries (fetches)
|
|
6
8
|
* for a given business object domain.
|
|
@@ -22,5 +24,12 @@ export declare abstract class BaseProvider<T extends BaseModel = BaseModel> {
|
|
|
22
24
|
* Handler for parsing a response from a remote provider and converting it
|
|
23
25
|
* into the typed domain model.
|
|
24
26
|
*/
|
|
25
|
-
protected parseSingle(_body: unknown): T;
|
|
27
|
+
protected parseSingle(_body: unknown, session: Session): T;
|
|
28
|
+
protected parsePaginatedResult(_body: unknown, session: Session): z.infer<ReturnType<typeof createPaginatedResponseSchema<typeof this.schema>>>;
|
|
29
|
+
protected generateCacheKeyPaginatedResult(resultSetName: string, res: ReturnType<typeof this.parsePaginatedResult>, session: Session): string;
|
|
30
|
+
protected generateCacheKeySingle(identifier: IdentifierType, session: Session): string;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the abstract resource name provided by the remote system.
|
|
33
|
+
*/
|
|
34
|
+
protected abstract getResourceName(): string;
|
|
26
35
|
}
|
|
@@ -8,4 +8,5 @@ export declare abstract class CartProvider<T extends Cart = Cart> extends BasePr
|
|
|
8
8
|
abstract add(payload: CartMutationItemAdd, session: Session): Promise<T>;
|
|
9
9
|
abstract remove(payload: CartMutationItemRemove, session: Session): Promise<T>;
|
|
10
10
|
abstract changeQuantity(payload: CartMutationItemQuantityChange, session: Session): Promise<T>;
|
|
11
|
+
protected getResourceName(): string;
|
|
11
12
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Category } from "../schemas/models/category.model";
|
|
2
|
+
import { CategoryQueryById, CategoryQueryBySlug, CategoryQueryForBreadcrumb, CategoryQueryForChildCategories, CategoryQueryForTopCategories } from "../schemas/queries/category.query";
|
|
3
|
+
import { Session } from "../schemas/session.schema";
|
|
4
|
+
import { BaseProvider } from "./base.provider";
|
|
5
|
+
/**
|
|
6
|
+
* CategoryProvider
|
|
7
|
+
*
|
|
8
|
+
* This provider allows fetching of single or sets of categories.
|
|
9
|
+
*
|
|
10
|
+
* We only allow fetching one hierachy level at a time, for now. This is to avoid development patterns of "fetch 5000 categories in one go.."
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export declare abstract class CategoryProvider<T extends Category = Category> extends BaseProvider<T> {
|
|
14
|
+
/**
|
|
15
|
+
* Get a single category by its ID. Cannot return null, because HOW did you come across a categories ID that does not exist?
|
|
16
|
+
*
|
|
17
|
+
* DISCUSSION: What do you persist in, say, a CMS or Recommendation engine? The seo slug or the ID?
|
|
18
|
+
* We have previous discussed, that the ID is not necessarily the DATABASE id, but rather an externally unique identifier for the category.
|
|
19
|
+
*
|
|
20
|
+
* So, if you persist that externally, you could actually end up with an ID that does not exist in the current system.
|
|
21
|
+
*
|
|
22
|
+
* For now, the result will be en empty category, but we should probably throw an error instead.
|
|
23
|
+
*
|
|
24
|
+
* Use case: You have received a list of category ids from a recommendation engine, and you need to show a tile of this.
|
|
25
|
+
* Future optimization: getByIds(ids: CategoryIdentifier[], session: Session): Promise<T[]>
|
|
26
|
+
* @param id
|
|
27
|
+
* @param session
|
|
28
|
+
*/
|
|
29
|
+
abstract getById(payload: CategoryQueryById, session: Session): Promise<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Gets a single category by its seo slug
|
|
32
|
+
*
|
|
33
|
+
* Usecase: You are rendering a category page, and you have the slug from the URL.
|
|
34
|
+
* @param slug the slug
|
|
35
|
+
* @param session
|
|
36
|
+
*/
|
|
37
|
+
abstract getBySlug(payload: CategoryQueryBySlug, session: Session): Promise<T | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Gets the breadcrumb path to the category, i.e. all parents up to the root.
|
|
40
|
+
* The returned order is from root to leaf.
|
|
41
|
+
*
|
|
42
|
+
* Usecase: You are rendering a category or product page, and you need to show the breadcrumb path.
|
|
43
|
+
* @param id
|
|
44
|
+
* @param session
|
|
45
|
+
*/
|
|
46
|
+
abstract getBreadcrumbPathToCategory(payload: CategoryQueryForBreadcrumb, session: Session): Promise<T[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Finds all child categories of a given category.
|
|
49
|
+
*
|
|
50
|
+
* Usecase: You are rendering a top menu, or mega menu, and you need the show the child categories of a given category.
|
|
51
|
+
*
|
|
52
|
+
* NOTE: it is recommended to create a navigational service, that allows combining CMS and Static pages into this, rather than fetching categories directly.
|
|
53
|
+
*
|
|
54
|
+
* @param id The ID of the parent category.
|
|
55
|
+
* @param session The session information.
|
|
56
|
+
*/
|
|
57
|
+
abstract findChildCategories(payload: CategoryQueryForChildCategories, session: Session): Promise<ReturnType<typeof this.parsePaginatedResult>>;
|
|
58
|
+
/**
|
|
59
|
+
* Returns all top categories, i.e. categories without a parent.
|
|
60
|
+
*
|
|
61
|
+
* Usecase: You are rendering a top menu, or mega menu, and you need the show the top level categories.
|
|
62
|
+
* @param paginationOptions
|
|
63
|
+
* @param session
|
|
64
|
+
*/
|
|
65
|
+
abstract findTopCategories(payload: CategoryQueryForTopCategories, session: Session): Promise<ReturnType<typeof this.parsePaginatedResult>>;
|
|
66
|
+
protected getResourceName(): string;
|
|
67
|
+
}
|
|
@@ -7,4 +7,5 @@ export declare abstract class IdentityProvider<T extends Identity = Identity> ex
|
|
|
7
7
|
abstract getSelf(payload: IdentityQuerySelf, session: Session): Promise<T>;
|
|
8
8
|
abstract login(payload: IdentityMutationLogin, session: Session): Promise<T>;
|
|
9
9
|
abstract logout(payload: IdentityMutationLogout, session: Session): Promise<T>;
|
|
10
|
+
protected getResourceName(): string;
|
|
10
11
|
}
|
|
@@ -4,4 +4,5 @@ import { Session } from '../schemas/session.schema';
|
|
|
4
4
|
import { BaseProvider } from './base.provider';
|
|
5
5
|
export declare abstract class InventoryProvider<T extends Inventory = Inventory> extends BaseProvider<T> {
|
|
6
6
|
abstract getBySKU(payload: InventoryQuery, session: Session): Promise<T>;
|
|
7
|
+
protected getResourceName(): string;
|
|
7
8
|
}
|