@reactionary/core 0.0.42 → 0.0.51
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/cache/memory-cache.js +39 -0
- package/cache/noop-cache.js +3 -13
- package/cache/redis-cache.js +16 -32
- package/decorators/reactionary.decorator.js +57 -4
- package/index.js +2 -1
- package/initialization.js +43 -0
- package/package.json +4 -2
- package/providers/base.provider.js +29 -12
- package/providers/checkout.provider.js +6 -0
- package/providers/index.js +4 -1
- package/providers/order.provider.js +15 -0
- package/providers/profile.provider.js +9 -0
- package/providers/store.provider.js +9 -0
- package/schemas/capabilities.schema.js +4 -2
- package/schemas/models/cart.model.js +3 -24
- package/schemas/models/checkout.model.js +44 -0
- package/schemas/models/cost.model.js +20 -0
- package/schemas/models/identifiers.model.js +24 -6
- package/schemas/models/identity.model.js +18 -16
- package/schemas/models/index.js +5 -0
- package/schemas/models/order.model.js +37 -0
- package/schemas/models/payment.model.js +1 -10
- package/schemas/models/product.model.js +5 -2
- package/schemas/models/profile.model.js +3 -2
- package/schemas/models/shipping-method.model.js +26 -4
- package/schemas/models/store.model.js +11 -0
- package/schemas/mutations/cart.mutation.js +2 -2
- package/schemas/mutations/checkout.mutation.js +36 -0
- package/schemas/mutations/identity.mutation.js +6 -1
- package/schemas/mutations/index.js +2 -1
- package/schemas/mutations/profile.mutation.js +9 -0
- package/schemas/queries/checkout.query.js +16 -0
- package/schemas/queries/index.js +4 -1
- package/schemas/queries/inventory.query.js +3 -5
- package/schemas/queries/order.query.js +8 -0
- package/schemas/queries/product.query.js +5 -0
- package/schemas/queries/profile.query.js +5 -0
- package/schemas/queries/store.query.js +11 -0
- package/schemas/session.schema.js +22 -8
- package/src/cache/cache.interface.d.ts +13 -20
- package/src/cache/memory-cache.d.ts +18 -0
- package/src/cache/noop-cache.d.ts +5 -11
- package/src/cache/redis-cache.d.ts +5 -11
- package/src/client/client-builder.d.ts +2 -2
- package/src/client/client.d.ts +11 -11
- package/src/decorators/reactionary.decorator.d.ts +34 -1
- package/src/index.d.ts +2 -1
- package/src/initialization.d.ts +2 -0
- package/src/providers/analytics.provider.d.ts +1 -1
- package/src/providers/base.provider.d.ts +12 -9
- package/src/providers/cart.provider.d.ts +17 -17
- package/src/providers/category.provider.d.ts +9 -9
- package/src/providers/checkout.provider.d.ts +135 -0
- package/src/providers/identity.provider.d.ts +8 -7
- package/src/providers/index.d.ts +4 -1
- package/src/providers/inventory.provider.d.ts +4 -4
- package/src/providers/order.provider.d.ts +16 -0
- package/src/providers/price.provider.d.ts +6 -6
- package/src/providers/product.provider.d.ts +6 -5
- package/src/providers/profile.provider.d.ts +10 -0
- package/src/providers/search.provider.d.ts +4 -4
- package/src/providers/store.provider.d.ts +8 -0
- package/src/schemas/capabilities.schema.d.ts +3 -1
- package/src/schemas/models/analytics.model.d.ts +1 -1
- package/src/schemas/models/cart.model.d.ts +0 -2092
- package/src/schemas/models/checkout.model.d.ts +2930 -0
- package/src/schemas/models/cost.model.d.ts +1867 -0
- package/src/schemas/models/identifiers.model.d.ts +22 -6
- package/src/schemas/models/identity.model.d.ts +78 -27
- package/src/schemas/models/index.d.ts +5 -0
- package/src/schemas/models/inventory.model.d.ts +1 -1
- package/src/schemas/models/order.model.d.ts +3144 -0
- package/src/schemas/models/payment.model.d.ts +1 -438
- package/src/schemas/models/product.model.d.ts +2 -2
- package/src/schemas/models/profile.model.d.ts +35 -0
- package/src/schemas/models/shipping-method.model.d.ts +50 -0
- package/src/schemas/models/store.model.d.ts +18 -0
- package/src/schemas/mutations/cart.mutation.d.ts +14 -0
- package/src/schemas/mutations/{cart-payment.mutation.d.ts → checkout.mutation.d.ts} +74 -6
- package/src/schemas/mutations/identity.mutation.d.ts +5 -0
- package/src/schemas/mutations/index.d.ts +2 -1
- package/src/schemas/mutations/profile.mutation.d.ts +6 -0
- package/src/schemas/queries/cart.query.d.ts +1 -1
- package/src/schemas/queries/checkout.query.d.ts +19 -0
- package/src/schemas/queries/identity.query.d.ts +1 -1
- package/src/schemas/queries/index.d.ts +4 -1
- package/src/schemas/queries/inventory.query.d.ts +6 -15
- package/src/schemas/queries/order.query.d.ts +7 -0
- package/src/schemas/queries/price.query.d.ts +1 -1
- package/src/schemas/queries/product.query.d.ts +6 -0
- package/src/schemas/queries/profile.query.d.ts +3 -0
- package/src/schemas/queries/search.query.d.ts +1 -1
- package/src/schemas/queries/store.query.d.ts +8 -0
- package/src/schemas/session.schema.d.ts +56 -21
- package/cache/cache-evaluation.interface.js +0 -0
- package/providers/cart-payment.provider.js +0 -9
- package/schemas/mutations/cart-payment.mutation.js +0 -15
- package/schemas/queries/cart-payment.query.js +0 -11
- package/src/cache/cache-evaluation.interface.d.ts +0 -17
- package/src/providers/cart-payment.provider.d.ts +0 -42
- package/src/schemas/queries/cart-payment.query.d.ts +0 -16
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class MemoryCache {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.entries = new Array();
|
|
4
|
+
}
|
|
5
|
+
async get(key, schema) {
|
|
6
|
+
const c = this.entries.find((x) => x.key === key);
|
|
7
|
+
if (!c) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const parsed = schema.parse(c.value);
|
|
11
|
+
parsed.meta.cache.hit = true;
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
async put(key, value, options) {
|
|
15
|
+
this.entries.push({
|
|
16
|
+
key,
|
|
17
|
+
value,
|
|
18
|
+
options
|
|
19
|
+
});
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
async invalidate(dependencyIds) {
|
|
23
|
+
let index = 0;
|
|
24
|
+
for (const entry of this.entries) {
|
|
25
|
+
for (const entryDependency of entry.options.dependencyIds) {
|
|
26
|
+
if (dependencyIds.indexOf(entryDependency) > -1) {
|
|
27
|
+
this.entries.splice(index, 1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
index++;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async clear() {
|
|
34
|
+
this.entries = [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
MemoryCache
|
|
39
|
+
};
|
package/cache/noop-cache.js
CHANGED
|
@@ -2,25 +2,15 @@ class NoOpCache {
|
|
|
2
2
|
async get(_key, _schema) {
|
|
3
3
|
return null;
|
|
4
4
|
}
|
|
5
|
-
async put(_key, _value,
|
|
5
|
+
async put(_key, _value, options) {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
|
-
async
|
|
8
|
+
async invalidate(dependencyIds) {
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
async
|
|
12
|
-
return [];
|
|
13
|
-
}
|
|
14
|
-
async clear(_pattern) {
|
|
11
|
+
async clear() {
|
|
15
12
|
return;
|
|
16
13
|
}
|
|
17
|
-
async getStats() {
|
|
18
|
-
return {
|
|
19
|
-
hits: 0,
|
|
20
|
-
misses: 0,
|
|
21
|
-
size: 0
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
14
|
}
|
|
25
15
|
export {
|
|
26
16
|
NoOpCache
|
package/cache/redis-cache.js
CHANGED
|
@@ -14,45 +14,29 @@ class RedisCache {
|
|
|
14
14
|
}
|
|
15
15
|
return null;
|
|
16
16
|
}
|
|
17
|
-
async put(key, value,
|
|
17
|
+
async put(key, value, options) {
|
|
18
18
|
if (!key) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
for (const key of keyArray) {
|
|
27
|
-
if (key.includes("*")) {
|
|
28
|
-
const matchingKeys = await this.redis.keys(key);
|
|
29
|
-
if (matchingKeys.length > 0) {
|
|
30
|
-
await this.redis.del(...matchingKeys);
|
|
31
|
-
}
|
|
32
|
-
} else {
|
|
33
|
-
await this.redis.del(key);
|
|
34
|
-
}
|
|
21
|
+
const serialized = JSON.stringify(value);
|
|
22
|
+
const multi = this.redis.multi();
|
|
23
|
+
multi.set(key, serialized, { ex: options.ttlSeconds });
|
|
24
|
+
for (const depId of options.dependencyIds) {
|
|
25
|
+
multi.sadd(`dep:${depId}`, key);
|
|
35
26
|
}
|
|
27
|
+
await multi.exec();
|
|
36
28
|
}
|
|
37
|
-
async
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
await this.redis.del(
|
|
29
|
+
async invalidate(dependencyIds) {
|
|
30
|
+
for (const id of dependencyIds) {
|
|
31
|
+
const depKey = `dep:${id}`;
|
|
32
|
+
const keys = await this.redis.smembers(depKey);
|
|
33
|
+
if (keys.length > 0) {
|
|
34
|
+
await this.redis.del(...keys);
|
|
35
|
+
}
|
|
36
|
+
await this.redis.del(depKey);
|
|
45
37
|
}
|
|
46
38
|
}
|
|
47
|
-
async
|
|
48
|
-
const keys = await this.redis.keys("*");
|
|
49
|
-
return {
|
|
50
|
-
hits: 0,
|
|
51
|
-
// Would need to track this separately
|
|
52
|
-
misses: 0,
|
|
53
|
-
// Would need to track this separately
|
|
54
|
-
size: keys.length
|
|
55
|
-
};
|
|
39
|
+
async clear() {
|
|
56
40
|
}
|
|
57
41
|
}
|
|
58
42
|
export {
|
|
@@ -1,13 +1,66 @@
|
|
|
1
|
+
import { getTracer, SpanKind } from "@reactionary/otel";
|
|
2
|
+
class ReactionaryDecoratorOptions {
|
|
3
|
+
constructor() {
|
|
4
|
+
/**
|
|
5
|
+
* Whether or not the query is eligible for caching. Queries that depend
|
|
6
|
+
* heavily on personalization, for example, are likely to be a poor fit
|
|
7
|
+
* for caching.
|
|
8
|
+
*/
|
|
9
|
+
this.cache = false;
|
|
10
|
+
/**
|
|
11
|
+
* Whether or not the cache entry should be variable based on the locale
|
|
12
|
+
* of the context in which it is querried.
|
|
13
|
+
*/
|
|
14
|
+
this.localeDependentCaching = false;
|
|
15
|
+
/**
|
|
16
|
+
* Whether or not the cache entry should be variable based on the currency
|
|
17
|
+
* of the context in which it is querried.
|
|
18
|
+
*/
|
|
19
|
+
this.currencyDependentCaching = false;
|
|
20
|
+
/**
|
|
21
|
+
* The number of seconds which a cache entry should be considered valid for the
|
|
22
|
+
* given query.
|
|
23
|
+
*/
|
|
24
|
+
this.cacheTimeToLiveInSeconds = 60;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
;
|
|
1
28
|
function Reactionary(options) {
|
|
2
29
|
return function(target, propertyKey, descriptor) {
|
|
3
30
|
const original = descriptor.value;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
31
|
+
const scope = `${target.constructor.name}.${propertyKey.toString()}`;
|
|
32
|
+
const configuration = { ...new ReactionaryDecoratorOptions(), ...options };
|
|
33
|
+
if (!original) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
"@Reactionary decorator may only be applied to methods on classes extending BaseProvider."
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
descriptor.value = async function(...args) {
|
|
39
|
+
const tracer = getTracer();
|
|
40
|
+
return tracer.startActiveSpan(
|
|
41
|
+
propertyKey.toString(),
|
|
42
|
+
{ kind: SpanKind.SERVER },
|
|
43
|
+
async (span) => {
|
|
44
|
+
const cacheKey = this.generateCacheKeyForQuery(scope, args[0]);
|
|
45
|
+
const fromCache = await this.cache.get(cacheKey, this.schema);
|
|
46
|
+
let result = fromCache;
|
|
47
|
+
if (!result) {
|
|
48
|
+
result = await original.apply(this, args);
|
|
49
|
+
const dependencyIds = this.generateDependencyIdsForModel(result);
|
|
50
|
+
this.cache.put(cacheKey, result, {
|
|
51
|
+
ttlSeconds: configuration.cacheTimeToLiveInSeconds,
|
|
52
|
+
dependencyIds
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
span.end();
|
|
56
|
+
return this.assert(result);
|
|
57
|
+
}
|
|
58
|
+
);
|
|
7
59
|
};
|
|
8
60
|
return descriptor;
|
|
9
61
|
};
|
|
10
62
|
}
|
|
11
63
|
export {
|
|
12
|
-
Reactionary
|
|
64
|
+
Reactionary,
|
|
65
|
+
ReactionaryDecoratorOptions
|
|
13
66
|
};
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./cache/cache.interface";
|
|
2
|
-
export * from "./cache/cache-evaluation.interface";
|
|
3
2
|
export * from "./cache/redis-cache";
|
|
3
|
+
export * from "./cache/memory-cache";
|
|
4
4
|
export * from "./cache/noop-cache";
|
|
5
5
|
export * from "./client/client";
|
|
6
6
|
export * from "./client/client-builder";
|
|
@@ -11,3 +11,4 @@ export * from "./schemas/session.schema";
|
|
|
11
11
|
export * from "./schemas/models/";
|
|
12
12
|
export * from "./schemas/mutations/";
|
|
13
13
|
export * from "./schemas/queries";
|
|
14
|
+
export * from "./initialization";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function createInitialRequestContext() {
|
|
2
|
+
return {
|
|
3
|
+
id: "",
|
|
4
|
+
identity: {
|
|
5
|
+
type: "Anonymous",
|
|
6
|
+
meta: {
|
|
7
|
+
cache: { hit: false, key: "" },
|
|
8
|
+
placeholder: false
|
|
9
|
+
},
|
|
10
|
+
id: { userId: "anonymous" },
|
|
11
|
+
token: void 0,
|
|
12
|
+
issued: /* @__PURE__ */ new Date(),
|
|
13
|
+
expiry: new Date((/* @__PURE__ */ new Date()).getTime() + 3600 * 1e3),
|
|
14
|
+
logonId: "",
|
|
15
|
+
createdAt: "",
|
|
16
|
+
updatedAt: "",
|
|
17
|
+
keyring: [],
|
|
18
|
+
currentService: void 0
|
|
19
|
+
},
|
|
20
|
+
languageContext: {
|
|
21
|
+
locale: "en-US",
|
|
22
|
+
currencyCode: "USD"
|
|
23
|
+
},
|
|
24
|
+
storeIdentifier: {
|
|
25
|
+
key: "the-good-store"
|
|
26
|
+
},
|
|
27
|
+
taxJurisdiction: {
|
|
28
|
+
countryCode: "US",
|
|
29
|
+
stateCode: "",
|
|
30
|
+
countyCode: "",
|
|
31
|
+
cityCode: ""
|
|
32
|
+
},
|
|
33
|
+
session: {},
|
|
34
|
+
correlationId: "",
|
|
35
|
+
isBot: false,
|
|
36
|
+
clientIp: "",
|
|
37
|
+
userAgent: "",
|
|
38
|
+
referrer: ""
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
createInitialRequestContext
|
|
43
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactionary/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.51",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "src/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"zod": "4.1.9",
|
|
8
|
-
"@upstash/redis": "^1.34.9"
|
|
8
|
+
"@upstash/redis": "^1.34.9",
|
|
9
|
+
"@reactionary/otel": "0.0.51",
|
|
10
|
+
"node-object-hash": "^3.1.1"
|
|
9
11
|
}
|
|
10
12
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createPaginatedResponseSchema
|
|
3
|
+
} from "../schemas/models/base.model";
|
|
4
|
+
import { hasher } from "node-object-hash";
|
|
2
5
|
class BaseProvider {
|
|
3
6
|
constructor(schema, cache) {
|
|
4
7
|
this.schema = schema;
|
|
@@ -21,26 +24,40 @@ class BaseProvider {
|
|
|
21
24
|
* Handler for parsing a response from a remote provider and converting it
|
|
22
25
|
* into the typed domain model.
|
|
23
26
|
*/
|
|
24
|
-
parseSingle(_body,
|
|
27
|
+
parseSingle(_body, reqCtx) {
|
|
25
28
|
const model = this.newModel();
|
|
26
29
|
return this.assert(model);
|
|
27
30
|
}
|
|
28
|
-
parsePaginatedResult(_body,
|
|
31
|
+
parsePaginatedResult(_body, reqCtx) {
|
|
29
32
|
return createPaginatedResponseSchema(this.schema).parse({});
|
|
30
33
|
}
|
|
31
|
-
|
|
34
|
+
generateDependencyIdsForModel(model) {
|
|
35
|
+
const identifier = model?.identifier;
|
|
36
|
+
if (!identifier) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const h = hasher({ sort: true, coerce: false });
|
|
40
|
+
const hash = h.hash(identifier);
|
|
41
|
+
return [hash];
|
|
42
|
+
}
|
|
43
|
+
generateCacheKeyForQuery(scope, query) {
|
|
44
|
+
const h = hasher({ sort: true, coerce: false });
|
|
45
|
+
const queryHash = h.hash(query);
|
|
46
|
+
return `${scope}:${queryHash}`;
|
|
47
|
+
}
|
|
48
|
+
generateCacheKeyPaginatedResult(resultSetName, res, reqCtx) {
|
|
32
49
|
const type = this.getResourceName();
|
|
33
|
-
const langPart =
|
|
34
|
-
const currencyPart =
|
|
35
|
-
const storePart =
|
|
50
|
+
const langPart = reqCtx.languageContext.locale;
|
|
51
|
+
const currencyPart = reqCtx.languageContext.currencyCode || "default";
|
|
52
|
+
const storePart = reqCtx.storeIdentifier?.key || "default";
|
|
36
53
|
return `${type}-${resultSetName}-paginated|pageNumber:${res.pageNumber}|pageSize:${res.pageSize}|store:${storePart}|lang:${langPart}|currency:${currencyPart}`;
|
|
37
54
|
}
|
|
38
|
-
generateCacheKeySingle(identifier,
|
|
55
|
+
generateCacheKeySingle(identifier, reqCtx) {
|
|
39
56
|
const type = this.getResourceName();
|
|
40
|
-
const idPart = Object.entries(identifier).map(([k, v]) => `${k}:${v
|
|
41
|
-
const langPart =
|
|
42
|
-
const currencyPart =
|
|
43
|
-
const storePart =
|
|
57
|
+
const idPart = Object.entries(identifier).map(([k, v]) => `${k}:${v}`).join("#");
|
|
58
|
+
const langPart = reqCtx.languageContext.locale;
|
|
59
|
+
const currencyPart = reqCtx.languageContext.currencyCode || "default";
|
|
60
|
+
const storePart = reqCtx.storeIdentifier?.key || "default";
|
|
44
61
|
return `${type}-${idPart}|store:${storePart}|lang:${langPart}|currency:${currencyPart}`;
|
|
45
62
|
}
|
|
46
63
|
}
|
package/providers/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export * from "./analytics.provider";
|
|
2
2
|
export * from "./base.provider";
|
|
3
|
-
export * from "./cart-payment.provider";
|
|
4
3
|
export * from "./cart.provider";
|
|
5
4
|
export * from "./category.provider";
|
|
5
|
+
export * from "./checkout.provider";
|
|
6
6
|
export * from "./identity.provider";
|
|
7
7
|
export * from "./inventory.provider";
|
|
8
8
|
export * from "./price.provider";
|
|
9
9
|
export * from "./product.provider";
|
|
10
|
+
export * from "./profile.provider";
|
|
10
11
|
export * from "./search.provider";
|
|
12
|
+
export * from "./store.provider";
|
|
13
|
+
export * from "./order.provider";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseProvider } from "./base.provider";
|
|
2
|
+
class OrderProvider extends BaseProvider {
|
|
3
|
+
createEmptyOrder() {
|
|
4
|
+
const order = this.newModel();
|
|
5
|
+
order.meta = { placeholder: true, cache: { hit: true, key: "empty-order" } };
|
|
6
|
+
order.identifier = { key: "" };
|
|
7
|
+
return order;
|
|
8
|
+
}
|
|
9
|
+
getResourceName() {
|
|
10
|
+
return "order";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
OrderProvider
|
|
15
|
+
};
|
|
@@ -5,10 +5,12 @@ const CapabilitiesSchema = z.looseObject({
|
|
|
5
5
|
analytics: z.boolean(),
|
|
6
6
|
identity: z.boolean(),
|
|
7
7
|
cart: z.boolean(),
|
|
8
|
-
|
|
8
|
+
checkout: z.boolean(),
|
|
9
|
+
order: z.boolean(),
|
|
9
10
|
inventory: z.boolean(),
|
|
10
11
|
price: z.boolean(),
|
|
11
|
-
category: z.boolean()
|
|
12
|
+
category: z.boolean(),
|
|
13
|
+
store: z.boolean()
|
|
12
14
|
});
|
|
13
15
|
export {
|
|
14
16
|
CapabilitiesSchema
|
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { CartIdentifierSchema, CartItemIdentifierSchema, IdentityIdentifierSchema, ProductIdentifierSchema, SKUIdentifierSchema } from "../models/identifiers.model";
|
|
3
3
|
import { BaseModelSchema } from "./base.model";
|
|
4
|
-
import {
|
|
5
|
-
import { AddressSchema } from "./profile.model";
|
|
6
|
-
import { ShippingMethodSchema } from "./shipping-method.model";
|
|
7
|
-
const CostBreakDownSchema = z.looseObject({
|
|
8
|
-
totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc."),
|
|
9
|
-
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of discount applied to the cart."),
|
|
10
|
-
totalSurcharge: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of surcharge applied to the cart."),
|
|
11
|
-
totalShipping: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of shipping fees for the cart."),
|
|
12
|
-
totalProductPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price of products in the cart."),
|
|
13
|
-
grandTotal: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for the cart including all taxes, discounts, and shipping.")
|
|
14
|
-
});
|
|
15
|
-
const ItemCostBreakdownSchema = z.looseObject({
|
|
16
|
-
unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The price per single unit of the item."),
|
|
17
|
-
unitDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The discount applied per single unit of the item."),
|
|
18
|
-
totalPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for all units of the item."),
|
|
19
|
-
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total discount applied to all units of the item.")
|
|
20
|
-
});
|
|
4
|
+
import { CostBreakDownSchema, ItemCostBreakdownSchema } from "./cost.model";
|
|
21
5
|
const CartItemSchema = z.looseObject({
|
|
22
6
|
identifier: CartItemIdentifierSchema.default(() => CartItemIdentifierSchema.parse({})),
|
|
23
7
|
product: ProductIdentifierSchema.default(() => ProductIdentifierSchema.parse({})),
|
|
@@ -31,14 +15,9 @@ const CartSchema = BaseModelSchema.extend({
|
|
|
31
15
|
items: z.array(CartItemSchema).default(() => []),
|
|
32
16
|
price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
|
|
33
17
|
name: z.string().default(""),
|
|
34
|
-
description: z.string().default("")
|
|
35
|
-
shippingAddress: AddressSchema.optional(),
|
|
36
|
-
billingAddress: AddressSchema.optional(),
|
|
37
|
-
shippingMethod: ShippingMethodSchema.optional()
|
|
18
|
+
description: z.string().default("")
|
|
38
19
|
});
|
|
39
20
|
export {
|
|
40
21
|
CartItemSchema,
|
|
41
|
-
CartSchema
|
|
42
|
-
CostBreakDownSchema,
|
|
43
|
-
ItemCostBreakdownSchema
|
|
22
|
+
CartSchema
|
|
44
23
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BaseModelSchema } from "./base.model";
|
|
3
|
+
import { CartIdentifierSchema, CheckoutIdentifierSchema, CheckoutItemIdentifierSchema, OrderIdentifierSchema, SKUIdentifierSchema } from "./identifiers.model";
|
|
4
|
+
import { CostBreakDownSchema, ItemCostBreakdownSchema } from "./cost.model";
|
|
5
|
+
import { AddressSchema } from "./profile.model";
|
|
6
|
+
import { ShippingInstructionSchema } from "./shipping-method.model";
|
|
7
|
+
import { PaymentInstructionSchema } from "./payment.model";
|
|
8
|
+
const CheckoutItemSchema = z.looseObject({
|
|
9
|
+
identifier: CheckoutItemIdentifierSchema.default(() => CheckoutItemIdentifierSchema.parse({})),
|
|
10
|
+
sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({})),
|
|
11
|
+
quantity: z.number().default(0),
|
|
12
|
+
price: ItemCostBreakdownSchema.default(() => ItemCostBreakdownSchema.parse({}))
|
|
13
|
+
});
|
|
14
|
+
const CheckoutSchema = BaseModelSchema.extend({
|
|
15
|
+
identifier: CheckoutIdentifierSchema.default(() => CheckoutIdentifierSchema.parse({})),
|
|
16
|
+
/**
|
|
17
|
+
* Do we need this?
|
|
18
|
+
*/
|
|
19
|
+
originalCartReference: CartIdentifierSchema.default(() => CartIdentifierSchema.parse({})),
|
|
20
|
+
/**
|
|
21
|
+
* If the checkout has been completed, this will point to the resulting order.
|
|
22
|
+
*/
|
|
23
|
+
resultingOrder: OrderIdentifierSchema.optional(),
|
|
24
|
+
items: z.array(CheckoutItemSchema).default(() => []),
|
|
25
|
+
price: CostBreakDownSchema.default(() => CostBreakDownSchema.parse({})),
|
|
26
|
+
name: z.string().default(""),
|
|
27
|
+
description: z.string().default(""),
|
|
28
|
+
billingAddress: AddressSchema.optional(),
|
|
29
|
+
/**
|
|
30
|
+
* Shipping and billing details can be changed on the checkout, but not items or quantities.
|
|
31
|
+
*/
|
|
32
|
+
shippingAddress: AddressSchema.optional(),
|
|
33
|
+
shippingInstruction: ShippingInstructionSchema.optional(),
|
|
34
|
+
paymentInstructions: z.array(PaymentInstructionSchema).default(() => []),
|
|
35
|
+
/**
|
|
36
|
+
* Indicates if the checkout has all the required information to be finalized into an order.
|
|
37
|
+
* This does not mean it will succeed, as there may be issues with payment or shipping, but all required information is present.
|
|
38
|
+
*/
|
|
39
|
+
readyForFinalization: z.boolean().default(false).describe("Indicates if the checkout has all the required information to be finalized into an order. This does not mean it will succeed, as there may be issues with payment or shipping, but all required information is present.")
|
|
40
|
+
});
|
|
41
|
+
export {
|
|
42
|
+
CheckoutItemSchema,
|
|
43
|
+
CheckoutSchema
|
|
44
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { MonetaryAmountSchema } from "./price.model";
|
|
3
|
+
const CostBreakDownSchema = z.looseObject({
|
|
4
|
+
totalTax: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of tax paid on the cart. This may include VAT, GST, sales tax, etc."),
|
|
5
|
+
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of discount applied to the cart."),
|
|
6
|
+
totalSurcharge: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of surcharge applied to the cart."),
|
|
7
|
+
totalShipping: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The amount of shipping fees for the cart."),
|
|
8
|
+
totalProductPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price of products in the cart."),
|
|
9
|
+
grandTotal: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for the cart including all taxes, discounts, and shipping.")
|
|
10
|
+
});
|
|
11
|
+
const ItemCostBreakdownSchema = z.looseObject({
|
|
12
|
+
unitPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The price per single unit of the item."),
|
|
13
|
+
unitDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The discount applied per single unit of the item."),
|
|
14
|
+
totalPrice: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total price for all units of the item."),
|
|
15
|
+
totalDiscount: MonetaryAmountSchema.default(() => MonetaryAmountSchema.parse({})).describe("The total discount applied to all units of the item.")
|
|
16
|
+
});
|
|
17
|
+
export {
|
|
18
|
+
CostBreakDownSchema,
|
|
19
|
+
ItemCostBreakdownSchema
|
|
20
|
+
};
|
|
@@ -30,26 +30,37 @@ const PriceIdentifierSchema = z.looseObject({
|
|
|
30
30
|
const CategoryIdentifierSchema = z.looseObject({
|
|
31
31
|
key: z.string().default("").nonoptional()
|
|
32
32
|
});
|
|
33
|
+
const StoreIdentifierSchema = z.looseObject({
|
|
34
|
+
key: z.string().default("").optional()
|
|
35
|
+
});
|
|
33
36
|
const OrderIdentifierSchema = z.looseObject({
|
|
34
37
|
key: z.string().default("").nonoptional()
|
|
35
38
|
});
|
|
36
39
|
const OrderItemIdentifierSchema = z.looseObject({
|
|
37
40
|
key: z.string().default("").nonoptional()
|
|
38
41
|
});
|
|
42
|
+
const CheckoutIdentifierSchema = z.looseObject({
|
|
43
|
+
key: z.string().default("").nonoptional()
|
|
44
|
+
});
|
|
45
|
+
const CheckoutItemIdentifierSchema = z.looseObject({
|
|
46
|
+
key: z.string().default("").nonoptional()
|
|
47
|
+
});
|
|
39
48
|
const WebStoreIdentifierSchema = z.looseObject({
|
|
40
49
|
key: z.string().default("").nonoptional()
|
|
41
50
|
});
|
|
42
|
-
const
|
|
43
|
-
key: z.string().default("
|
|
51
|
+
const FulfillmentCenterIdentifierSchema = z.looseObject({
|
|
52
|
+
key: z.string().default("").nonoptional()
|
|
44
53
|
});
|
|
45
54
|
const InventoryIdentifierSchema = z.looseObject({
|
|
46
55
|
sku: SKUIdentifierSchema.default(() => SKUIdentifierSchema.parse({})),
|
|
47
|
-
|
|
56
|
+
fulfillmentCenter: FulfillmentCenterIdentifierSchema.default(
|
|
57
|
+
() => FulfillmentCenterIdentifierSchema.parse({})
|
|
58
|
+
)
|
|
48
59
|
});
|
|
49
60
|
const IdentityIdentifierSchema = z.looseObject({
|
|
50
61
|
userId: z.string().default("").nonoptional()
|
|
51
62
|
});
|
|
52
|
-
const
|
|
63
|
+
const ShippingMethodIdentifierSchema = z.looseObject({
|
|
53
64
|
key: z.string().default("").nonoptional()
|
|
54
65
|
});
|
|
55
66
|
const PaymentMethodIdentifierSchema = z.looseObject({
|
|
@@ -63,24 +74,31 @@ const AddressIdentifierSchema = z.looseObject({
|
|
|
63
74
|
const PaymentInstructionIdentifierSchema = z.looseObject({
|
|
64
75
|
key: z.string().default("").nonoptional()
|
|
65
76
|
});
|
|
77
|
+
const PickupPointIdentifierSchema = z.looseObject({
|
|
78
|
+
key: z.string().default("").nonoptional()
|
|
79
|
+
});
|
|
66
80
|
export {
|
|
67
81
|
AddressIdentifierSchema,
|
|
68
82
|
CartIdentifierSchema,
|
|
69
83
|
CartItemIdentifierSchema,
|
|
70
84
|
CategoryIdentifierSchema,
|
|
85
|
+
CheckoutIdentifierSchema,
|
|
86
|
+
CheckoutItemIdentifierSchema,
|
|
71
87
|
FacetIdentifierSchema,
|
|
72
88
|
FacetValueIdentifierSchema,
|
|
89
|
+
FulfillmentCenterIdentifierSchema,
|
|
73
90
|
IdentityIdentifierSchema,
|
|
74
|
-
InventoryChannelIdentifierSchema,
|
|
75
91
|
InventoryIdentifierSchema,
|
|
76
92
|
OrderIdentifierSchema,
|
|
77
93
|
OrderItemIdentifierSchema,
|
|
78
94
|
PaymentInstructionIdentifierSchema,
|
|
79
95
|
PaymentMethodIdentifierSchema,
|
|
96
|
+
PickupPointIdentifierSchema,
|
|
80
97
|
PriceIdentifierSchema,
|
|
81
98
|
ProductIdentifierSchema,
|
|
82
99
|
SKUIdentifierSchema,
|
|
83
100
|
SearchIdentifierSchema,
|
|
84
|
-
|
|
101
|
+
ShippingMethodIdentifierSchema,
|
|
102
|
+
StoreIdentifierSchema,
|
|
85
103
|
WebStoreIdentifierSchema
|
|
86
104
|
};
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { BaseModelSchema } from "./base.model";
|
|
3
3
|
import { IdentityIdentifierSchema } from "./identifiers.model";
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const AnonymousIdentitySchema = BaseModelSchema.extend({
|
|
5
|
+
type: z.literal("Anonymous").default("Anonymous"),
|
|
6
|
+
token: z.string().optional(),
|
|
7
|
+
refresh_token: z.string().optional(),
|
|
8
|
+
expiry: z.coerce.date().default(/* @__PURE__ */ new Date())
|
|
9
|
+
});
|
|
10
|
+
const GuestIdentitySchema = BaseModelSchema.extend({
|
|
11
|
+
id: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
|
|
12
|
+
type: z.literal("Guest").default("Guest"),
|
|
13
|
+
token: z.string().optional(),
|
|
14
|
+
refresh_token: z.string().optional(),
|
|
9
15
|
expiry: z.coerce.date().default(/* @__PURE__ */ new Date())
|
|
10
16
|
});
|
|
11
|
-
const
|
|
17
|
+
const RegisteredIdentitySchema = BaseModelSchema.extend({
|
|
12
18
|
id: IdentityIdentifierSchema.default(() => IdentityIdentifierSchema.parse({})),
|
|
13
|
-
type:
|
|
19
|
+
type: z.literal("Registered").default("Registered"),
|
|
14
20
|
logonId: z.string().default(""),
|
|
15
|
-
createdAt: z.string().default(() => (/* @__PURE__ */ new Date()).toISOString()),
|
|
16
|
-
updatedAt: z.string().default(() => (/* @__PURE__ */ new Date()).toISOString()),
|
|
17
|
-
// Tokens for various services
|
|
18
|
-
keyring: z.array(ServiceTokenSchema).default(() => []),
|
|
19
|
-
// Deprecated - use serviceTokens map instead
|
|
20
|
-
currentService: z.string().optional(),
|
|
21
21
|
token: z.string().optional(),
|
|
22
|
-
|
|
22
|
+
refresh_token: z.string().optional(),
|
|
23
23
|
expiry: z.coerce.date().default(/* @__PURE__ */ new Date())
|
|
24
24
|
});
|
|
25
|
+
const IdentitySchema = z.discriminatedUnion("type", [AnonymousIdentitySchema, GuestIdentitySchema, RegisteredIdentitySchema]);
|
|
25
26
|
export {
|
|
27
|
+
AnonymousIdentitySchema,
|
|
28
|
+
GuestIdentitySchema,
|
|
26
29
|
IdentitySchema,
|
|
27
|
-
|
|
28
|
-
ServiceTokenSchema
|
|
30
|
+
RegisteredIdentitySchema
|
|
29
31
|
};
|
package/schemas/models/index.js
CHANGED
|
@@ -12,3 +12,8 @@ export * from "./product.model";
|
|
|
12
12
|
export * from "./profile.model";
|
|
13
13
|
export * from "./search.model";
|
|
14
14
|
export * from "./shipping-method.model";
|
|
15
|
+
export * from "./store.model";
|
|
16
|
+
export * from "./order.model";
|
|
17
|
+
export * from "./cost.model";
|
|
18
|
+
export * from "./checkout.model";
|
|
19
|
+
export * from "./payment.model";
|