@smess/networking 1.0.29 → 1.0.30
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/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/services/storefront.cart.service.d.ts +73 -0
- package/dist/services/storefront.cart.service.js +167 -0
- package/dist/services/storefront.cart.service.test.d.ts +1 -0
- package/dist/services/storefront.cart.service.test.js +211 -0
- package/dist/services/storefront.checkout.service.d.ts +62 -0
- package/dist/services/storefront.checkout.service.js +75 -0
- package/dist/services/storefront.checkout.service.test.d.ts +1 -0
- package/dist/services/storefront.checkout.service.test.js +158 -0
- package/dist/services/storefront.customer.metadata.service.d.ts +91 -0
- package/dist/services/storefront.customer.metadata.service.js +225 -0
- package/dist/services/storefront.customer.metadata.service.test.d.ts +1 -0
- package/dist/services/storefront.customer.metadata.service.test.js +271 -0
- package/dist/services/storefront.order.service.d.ts +45 -0
- package/dist/services/storefront.order.service.js +99 -0
- package/dist/services/storefront.order.service.test.d.ts +1 -0
- package/dist/services/storefront.order.service.test.js +158 -0
- package/dist/services/storefront.product.service.d.ts +52 -0
- package/dist/services/storefront.product.service.js +75 -0
- package/dist/services/storefront.product.service.test.d.ts +1 -0
- package/dist/services/storefront.product.service.test.js +120 -0
- package/dist/services/storefront.store.service.d.ts +52 -0
- package/dist/services/storefront.store.service.js +140 -0
- package/dist/services/storefront.store.service.test.d.ts +1 -0
- package/dist/services/storefront.store.service.test.js +90 -0
- package/dist/src/core/axios.d.ts +51 -0
- package/dist/src/core/axios.js +65 -0
- package/dist/src/core/axios.observable.d.ts +11 -0
- package/dist/src/core/axios.observable.js +58 -0
- package/dist/src/core/base.provider.advanced.test.d.ts +1 -0
- package/dist/src/core/base.provider.advanced.test.js +29 -0
- package/dist/src/core/base.provider.d.ts +15 -0
- package/dist/src/core/base.provider.js +13 -0
- package/dist/src/core/base.provider.test.d.ts +1 -0
- package/dist/src/core/base.provider.test.js +36 -0
- package/dist/src/core/base.service.wrapper.advanced.test.d.ts +1 -0
- package/dist/src/core/base.service.wrapper.advanced.test.js +39 -0
- package/dist/src/core/base.service.wrapper.d.ts +7 -0
- package/dist/src/core/base.service.wrapper.js +11 -0
- package/dist/src/core/base.service.wrapper.test.d.ts +1 -0
- package/dist/src/core/base.service.wrapper.test.js +25 -0
- package/dist/src/core/rx.http.service.d.ts +51 -0
- package/dist/src/core/rx.http.service.js +65 -0
- package/dist/src/index.d.ts +25 -0
- package/dist/src/index.js +29 -0
- package/dist/src/services/auth.service.d.ts +65 -0
- package/dist/src/services/auth.service.js +197 -0
- package/dist/src/services/auth.service.test.d.ts +1 -0
- package/dist/src/services/auth.service.test.js +334 -0
- package/dist/src/services/cache.service.d.ts +31 -0
- package/dist/src/services/cache.service.js +77 -0
- package/dist/src/services/cache.service.test.d.ts +1 -0
- package/dist/src/services/cache.service.test.js +88 -0
- package/dist/src/services/customer.service.d.ts +199 -0
- package/dist/src/services/customer.service.js +114 -0
- package/dist/src/services/customer.service.test.d.ts +1 -0
- package/dist/src/services/customer.service.test.js +430 -0
- package/dist/src/services/employee.service.d.ts +73 -0
- package/dist/src/services/employee.service.js +74 -0
- package/dist/src/services/employee.service.test.d.ts +1 -0
- package/dist/src/services/employee.service.test.js +127 -0
- package/dist/src/services/logger.service.d.ts +31 -0
- package/dist/src/services/logger.service.js +93 -0
- package/dist/src/services/logger.service.test.d.ts +1 -0
- package/dist/src/services/logger.service.test.js +31 -0
- package/dist/src/services/order.service.d.ts +73 -0
- package/dist/src/services/order.service.js +97 -0
- package/dist/src/services/order.service.test.d.ts +1 -0
- package/dist/src/services/order.service.test.js +163 -0
- package/dist/src/services/product.service.d.ts +21 -0
- package/dist/src/services/product.service.js +42 -0
- package/dist/src/services/product.service.test.d.ts +1 -0
- package/dist/src/services/product.service.test.js +61 -0
- package/dist/src/services/smess.service.d.ts +36 -0
- package/dist/src/services/smess.service.js +128 -0
- package/dist/src/services/smess.service.test.d.ts +1 -0
- package/dist/src/services/smess.service.test.js +103 -0
- package/dist/src/services/store.cart.service.d.ts +158 -0
- package/dist/src/services/store.cart.service.js +177 -0
- package/dist/src/services/store.cart.service.test.d.ts +1 -0
- package/dist/src/services/store.cart.service.test.js +394 -0
- package/dist/src/services/store.product.service.d.ts +124 -0
- package/dist/src/services/store.product.service.js +102 -0
- package/dist/src/services/store.product.service.test.d.ts +1 -0
- package/dist/src/services/store.product.service.test.js +319 -0
- package/dist/src/services/store.service.d.ts +79 -0
- package/dist/src/services/store.service.js +235 -0
- package/dist/src/services/store.service.test.d.ts +1 -0
- package/dist/src/services/store.service.test.js +274 -0
- package/dist/src/services/storefront.cart.service.d.ts +73 -0
- package/dist/src/services/storefront.cart.service.js +167 -0
- package/dist/src/services/storefront.cart.service.test.d.ts +1 -0
- package/dist/src/services/storefront.cart.service.test.js +211 -0
- package/dist/src/services/storefront.checkout.service.d.ts +62 -0
- package/dist/src/services/storefront.checkout.service.js +75 -0
- package/dist/src/services/storefront.checkout.service.test.d.ts +1 -0
- package/dist/src/services/storefront.checkout.service.test.js +158 -0
- package/dist/src/services/storefront.customer.metadata.service.d.ts +91 -0
- package/dist/src/services/storefront.customer.metadata.service.js +225 -0
- package/dist/src/services/storefront.customer.metadata.service.test.d.ts +1 -0
- package/dist/src/services/storefront.customer.metadata.service.test.js +271 -0
- package/dist/src/services/storefront.order.service.d.ts +45 -0
- package/dist/src/services/storefront.order.service.js +99 -0
- package/dist/src/services/storefront.order.service.test.d.ts +1 -0
- package/dist/src/services/storefront.order.service.test.js +158 -0
- package/dist/src/services/storefront.product.service.d.ts +52 -0
- package/dist/src/services/storefront.product.service.js +75 -0
- package/dist/src/services/storefront.product.service.test.d.ts +1 -0
- package/dist/src/services/storefront.product.service.test.js +120 -0
- package/dist/src/services/storefront.store.service.d.ts +52 -0
- package/dist/src/services/storefront.store.service.js +140 -0
- package/dist/src/services/storefront.store.service.test.d.ts +1 -0
- package/dist/src/services/storefront.store.service.test.js +90 -0
- package/dist/src/services/user.service.d.ts +16 -0
- package/dist/src/services/user.service.js +37 -0
- package/dist/src/services/user.service.test.d.ts +1 -0
- package/dist/src/services/user.service.test.js +52 -0
- package/dist/src/services/utils/withAuthReset.d.ts +3 -0
- package/dist/src/services/utils/withAuthReset.js +8 -0
- package/dist/src/types/types.d.ts +93 -0
- package/dist/src/types/types.js +82 -0
- package/dist/src/types/types.test.d.ts +1 -0
- package/dist/src/types/types.test.js +25 -0
- package/dist/src/utils/cache-import.d.ts +3 -0
- package/dist/src/utils/cache-import.js +2 -0
- package/dist/src/utils/networking-import.d.ts +4 -0
- package/dist/src/utils/networking-import.js +3 -0
- package/dist/src/utils/rxjs-import.d.ts +5 -0
- package/dist/src/utils/rxjs-import.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { BaseProvider } from "../core/base.provider";
|
|
2
|
+
import { BaseServiceWrapper } from "../core/base.service.wrapper";
|
|
3
|
+
// ProductProvider implements ProviderType for product endpoints
|
|
4
|
+
export class ProductProvider extends BaseProvider {
|
|
5
|
+
constructor(config, { productId, method } = {}) {
|
|
6
|
+
super({
|
|
7
|
+
config,
|
|
8
|
+
path: productId ? `/products/${productId}` : "/products",
|
|
9
|
+
method: method || "GET",
|
|
10
|
+
headers: { "Content-Type": "application/json" },
|
|
11
|
+
getPath: () => (productId ? `/products/${productId}` : "/products"),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// ProductService provides high-level methods for product API
|
|
16
|
+
export class ProductService extends BaseServiceWrapper {
|
|
17
|
+
constructor(config, productId, method) {
|
|
18
|
+
super(new ProductProvider(config, { productId, method }));
|
|
19
|
+
this.config = config;
|
|
20
|
+
}
|
|
21
|
+
// Fetch a product by ID
|
|
22
|
+
fetchProductById(id) {
|
|
23
|
+
this.provider = new ProductProvider(this.config, { productId: id });
|
|
24
|
+
return this.request();
|
|
25
|
+
}
|
|
26
|
+
// Fetch all products
|
|
27
|
+
fetchAllProducts() {
|
|
28
|
+
this.provider = new ProductProvider(this.config);
|
|
29
|
+
return this.request();
|
|
30
|
+
}
|
|
31
|
+
// Create a new product (POST)
|
|
32
|
+
createProduct(product) {
|
|
33
|
+
this.provider = new ProductProvider(this.config, { method: "POST" });
|
|
34
|
+
return this.request(product);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Example usage:
|
|
38
|
+
// setNetworkingConfig({ baseUrl: 'https://fakestoreapi.com', isProd: false });
|
|
39
|
+
// const productService = new ProductService();
|
|
40
|
+
// productService.fetchProductById(1).subscribe(result => console.log(result));
|
|
41
|
+
// productService.fetchAllProducts().subscribe(result => console.log(result));
|
|
42
|
+
// productService.createProduct({ name: 'New Product', price: 99.99 }).subscribe(result => console.log(result));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ProductService } from "./product.service";
|
|
2
|
+
import { NetworkingUIEventWrapped } from "../types/types";
|
|
3
|
+
import { of, throwError } from "rxjs";
|
|
4
|
+
import { BaseServiceWrapper } from "../core/base.service.wrapper";
|
|
5
|
+
describe("ProductService", () => {
|
|
6
|
+
const config = {
|
|
7
|
+
baseUrl: "https://jsonplaceholder.typicode.com",
|
|
8
|
+
isProd: false,
|
|
9
|
+
clientId: "test-client",
|
|
10
|
+
apiKey: "test-key",
|
|
11
|
+
};
|
|
12
|
+
const product = { id: 1, name: "Product", price: 10 };
|
|
13
|
+
let requestSpy;
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
requestSpy = jest
|
|
16
|
+
.spyOn(BaseServiceWrapper.prototype, "request")
|
|
17
|
+
.mockImplementation(() => of(NetworkingUIEventWrapped.succeeded(product)));
|
|
18
|
+
});
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
requestSpy.mockRestore();
|
|
21
|
+
});
|
|
22
|
+
it("should fetch product by id", (done) => {
|
|
23
|
+
const service = new ProductService(config, 1);
|
|
24
|
+
service
|
|
25
|
+
.fetchProductById(1)
|
|
26
|
+
.subscribe((result) => {
|
|
27
|
+
expect(result.response).toEqual(product);
|
|
28
|
+
done();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it("should fetch all products", (done) => {
|
|
32
|
+
const service = new ProductService(config);
|
|
33
|
+
service
|
|
34
|
+
.fetchAllProducts()
|
|
35
|
+
.subscribe((result) => {
|
|
36
|
+
expect(result.response).toEqual(product);
|
|
37
|
+
done();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
it("should create a product", (done) => {
|
|
41
|
+
const service = new ProductService(config);
|
|
42
|
+
service
|
|
43
|
+
.createProduct({ name: "New Product", price: 99.99 })
|
|
44
|
+
.subscribe((result) => {
|
|
45
|
+
expect(result.response).toEqual(product);
|
|
46
|
+
done();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it("request should handle error", (done) => {
|
|
50
|
+
requestSpy.mockImplementationOnce(() => throwError(() => new Error("Test error")));
|
|
51
|
+
const service = new ProductService(config);
|
|
52
|
+
// Simulate error by calling a method that uses request
|
|
53
|
+
service.fetchProductById(1).subscribe({
|
|
54
|
+
error: (err) => {
|
|
55
|
+
expect(err).toBeInstanceOf(Error);
|
|
56
|
+
expect(err.message).toBe("Test error");
|
|
57
|
+
done();
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { HeaderType, NetworkingUIEventWrapped, ProviderType } from "../types/types";
|
|
2
|
+
import { Observable } from "../utils/rxjs-import";
|
|
3
|
+
export declare enum SMESSHeader {
|
|
4
|
+
ContentType = "Content-Type",
|
|
5
|
+
Authorization = "Authorization",
|
|
6
|
+
Accept = "Accept",
|
|
7
|
+
ApiKey = "X-Api-Key",
|
|
8
|
+
ClientId = "X-Client-Id"
|
|
9
|
+
}
|
|
10
|
+
export declare enum ContentType {
|
|
11
|
+
Json = "application/json",
|
|
12
|
+
FormURLEncoded = "application/x-www-form-urlencoded"
|
|
13
|
+
}
|
|
14
|
+
export declare enum Accept {
|
|
15
|
+
V1 = "application/json",
|
|
16
|
+
V2 = "application/vnd.smess.v2+json",
|
|
17
|
+
V3 = "application/vnd.smess.v3+json",
|
|
18
|
+
V4 = "application/vnd.smess.v4+json",
|
|
19
|
+
V5 = "application/vnd.smess.v5+json",
|
|
20
|
+
V6 = "application/vnd.smess.v6+json",
|
|
21
|
+
V7 = "application/vnd.smess.v7+json",
|
|
22
|
+
V8 = "application/vnd.smess.v8+json",
|
|
23
|
+
V9 = "application/vnd.smess.v9+json",
|
|
24
|
+
V10 = "application/vnd.smess.v10+json"
|
|
25
|
+
}
|
|
26
|
+
export declare class SmessService<T extends ProviderType> {
|
|
27
|
+
private httpService;
|
|
28
|
+
private target;
|
|
29
|
+
constructor(target: T);
|
|
30
|
+
static getHeaders(version: Accept, authorization?: string | null, options?: HeaderType): Partial<Record<SMESSHeader, string | undefined>>;
|
|
31
|
+
static filterHeaders(headers: Partial<Record<SMESSHeader, string | undefined>>): Record<string, string>;
|
|
32
|
+
private static commonHeaders;
|
|
33
|
+
request<R = unknown>(request?: unknown, mockResponse?: R, ...queryParams: unknown[]): Observable<NetworkingUIEventWrapped<R>>;
|
|
34
|
+
private transformAxiosError;
|
|
35
|
+
private transformAxiosResponse;
|
|
36
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { AlertButtonModel, AlertModel, NetworkingUIEventWrapped, } from "../types/types";
|
|
2
|
+
import { catchError, mergeMap, of, startWith, } from "../utils/rxjs-import";
|
|
3
|
+
import HttpService from "../core/rx.http.service";
|
|
4
|
+
import { $logger } from "../services/logger.service";
|
|
5
|
+
export var SMESSHeader;
|
|
6
|
+
(function (SMESSHeader) {
|
|
7
|
+
SMESSHeader["ContentType"] = "Content-Type";
|
|
8
|
+
SMESSHeader["Authorization"] = "Authorization";
|
|
9
|
+
SMESSHeader["Accept"] = "Accept";
|
|
10
|
+
SMESSHeader["ApiKey"] = "X-Api-Key";
|
|
11
|
+
SMESSHeader["ClientId"] = "X-Client-Id";
|
|
12
|
+
})(SMESSHeader || (SMESSHeader = {}));
|
|
13
|
+
export var ContentType;
|
|
14
|
+
(function (ContentType) {
|
|
15
|
+
ContentType["Json"] = "application/json";
|
|
16
|
+
ContentType["FormURLEncoded"] = "application/x-www-form-urlencoded";
|
|
17
|
+
})(ContentType || (ContentType = {}));
|
|
18
|
+
export var Accept;
|
|
19
|
+
(function (Accept) {
|
|
20
|
+
Accept["V1"] = "application/json";
|
|
21
|
+
Accept["V2"] = "application/vnd.smess.v2+json";
|
|
22
|
+
Accept["V3"] = "application/vnd.smess.v3+json";
|
|
23
|
+
Accept["V4"] = "application/vnd.smess.v4+json";
|
|
24
|
+
Accept["V5"] = "application/vnd.smess.v5+json";
|
|
25
|
+
Accept["V6"] = "application/vnd.smess.v6+json";
|
|
26
|
+
Accept["V7"] = "application/vnd.smess.v7+json";
|
|
27
|
+
Accept["V8"] = "application/vnd.smess.v8+json";
|
|
28
|
+
Accept["V9"] = "application/vnd.smess.v9+json";
|
|
29
|
+
Accept["V10"] = "application/vnd.smess.v10+json";
|
|
30
|
+
})(Accept || (Accept = {}));
|
|
31
|
+
export class SmessService {
|
|
32
|
+
constructor(target) {
|
|
33
|
+
this.target = target;
|
|
34
|
+
// Set default headers
|
|
35
|
+
$logger.info("SmessService initialized", {
|
|
36
|
+
target: this.target,
|
|
37
|
+
baseURL: this.target.baseURL,
|
|
38
|
+
method: this.target.method,
|
|
39
|
+
headers: this.target.headers,
|
|
40
|
+
}, "SmessService");
|
|
41
|
+
this.httpService = HttpService.create({
|
|
42
|
+
baseURL: this.target.baseURL,
|
|
43
|
+
headers: this.target.headers,
|
|
44
|
+
method: this.target.method,
|
|
45
|
+
});
|
|
46
|
+
this.httpService.interceptors.response.use((response) => response, async (error) => {
|
|
47
|
+
const originalRequest = error.config;
|
|
48
|
+
if (error.response?.status === 401 && !originalRequest._retry) {
|
|
49
|
+
originalRequest._retry = true;
|
|
50
|
+
$logger.info("SmessService constructor - 401 retry", originalRequest, "SmessService");
|
|
51
|
+
// Implement token refresh logic here
|
|
52
|
+
// Then retry the original request
|
|
53
|
+
// return httpService.request(originalRequest);
|
|
54
|
+
}
|
|
55
|
+
return Promise.reject(error);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
static getHeaders(version, authorization = null, options) {
|
|
59
|
+
const headers = this.commonHeaders(version, options);
|
|
60
|
+
if (authorization) {
|
|
61
|
+
headers["Authorization"] = 'Bearer ' + authorization;
|
|
62
|
+
}
|
|
63
|
+
return headers;
|
|
64
|
+
}
|
|
65
|
+
static filterHeaders(headers) {
|
|
66
|
+
const filteredHeaders = Object.fromEntries(Object.entries(headers).filter(([_, value]) => value !== undefined && value !== null && value !== ""));
|
|
67
|
+
return filteredHeaders;
|
|
68
|
+
}
|
|
69
|
+
static commonHeaders(version, options) {
|
|
70
|
+
const { shouldAddClientIdHeader = true } = options ?? {};
|
|
71
|
+
const headers = {
|
|
72
|
+
Accept: version,
|
|
73
|
+
Authorization: "",
|
|
74
|
+
"Content-Type": ContentType.Json,
|
|
75
|
+
"X-Api-Key": "",
|
|
76
|
+
};
|
|
77
|
+
return headers;
|
|
78
|
+
}
|
|
79
|
+
// MARK: - Public
|
|
80
|
+
request(request, mockResponse, ...queryParams) {
|
|
81
|
+
const url = queryParams.length
|
|
82
|
+
? this.target.getPath(...queryParams)
|
|
83
|
+
: this.target.path;
|
|
84
|
+
const config = { url };
|
|
85
|
+
let observable;
|
|
86
|
+
if (this.target.method === "GET") {
|
|
87
|
+
if (request) {
|
|
88
|
+
config.data = request;
|
|
89
|
+
config.params = request;
|
|
90
|
+
}
|
|
91
|
+
observable = this.httpService.get(url, config);
|
|
92
|
+
}
|
|
93
|
+
else if (this.target.method === "POST") {
|
|
94
|
+
observable = this.httpService.post(url, request, config);
|
|
95
|
+
}
|
|
96
|
+
else if (this.target.method === "PATCH") {
|
|
97
|
+
observable = this.httpService.patch(url, request, config);
|
|
98
|
+
}
|
|
99
|
+
else if (this.target.method === "PUT") {
|
|
100
|
+
observable = this.httpService.put(url, request, config);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
observable = this.httpService.request(config);
|
|
104
|
+
}
|
|
105
|
+
return observable.pipe(catchError((error) => this.transformAxiosError(error, mockResponse)), mergeMap((data) => this.transformAxiosResponse(data)), startWith(NetworkingUIEventWrapped.waiting()));
|
|
106
|
+
}
|
|
107
|
+
// MARK: - Private
|
|
108
|
+
transformAxiosError(error, mockResponse) {
|
|
109
|
+
$logger.error("transformAxiosError", error, "SmessService");
|
|
110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Required for axios compatibility
|
|
112
|
+
const response = error.response;
|
|
113
|
+
const httpErrorCode = response ? response.status : 0;
|
|
114
|
+
const title = response?.statusText;
|
|
115
|
+
const alertModel = new AlertModel(message, httpErrorCode, true, title, response?.data, [AlertButtonModel.buttonYes()]);
|
|
116
|
+
if (mockResponse) {
|
|
117
|
+
return of(NetworkingUIEventWrapped.succeeded(mockResponse));
|
|
118
|
+
}
|
|
119
|
+
return of(NetworkingUIEventWrapped.failed(alertModel));
|
|
120
|
+
}
|
|
121
|
+
transformAxiosResponse(response) {
|
|
122
|
+
$logger.info("transformAxiosResponse", response, "SmessService");
|
|
123
|
+
if (response instanceof NetworkingUIEventWrapped) {
|
|
124
|
+
return of(response);
|
|
125
|
+
}
|
|
126
|
+
return of(NetworkingUIEventWrapped.succeeded(response.data));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- Required for test mocks */
|
|
2
|
+
import { SmessService } from "./smess.service";
|
|
3
|
+
import { NetworkingUIEventWrapped, } from "../types/types";
|
|
4
|
+
import { of, throwError } from "rxjs";
|
|
5
|
+
describe("SmessService", () => {
|
|
6
|
+
const config = {
|
|
7
|
+
baseUrl: "https://api.example.com",
|
|
8
|
+
isProd: false,
|
|
9
|
+
clientId: "test-client",
|
|
10
|
+
apiKey: "test-key",
|
|
11
|
+
};
|
|
12
|
+
const provider = {
|
|
13
|
+
baseURL: config.baseUrl,
|
|
14
|
+
path: "/resource",
|
|
15
|
+
method: "GET",
|
|
16
|
+
headers: {},
|
|
17
|
+
getPath: () => "/resource",
|
|
18
|
+
};
|
|
19
|
+
it("should return succeeded for GET", (done) => {
|
|
20
|
+
const service = new SmessService(provider);
|
|
21
|
+
service["httpService"] = {
|
|
22
|
+
get: jest.fn(() => of({ data: { foo: "bar" } })),
|
|
23
|
+
post: jest.fn(),
|
|
24
|
+
patch: jest.fn(),
|
|
25
|
+
put: jest.fn(),
|
|
26
|
+
request: jest.fn(),
|
|
27
|
+
interceptors: { response: { use: jest.fn() } },
|
|
28
|
+
};
|
|
29
|
+
service.request().subscribe((result) => {
|
|
30
|
+
if (result.hasSuccess) {
|
|
31
|
+
expect(result.response).toEqual({ foo: "bar" });
|
|
32
|
+
done();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
it("should return succeeded for POST", (done) => {
|
|
37
|
+
const postProvider = { ...provider, method: "POST" };
|
|
38
|
+
const service = new SmessService(postProvider);
|
|
39
|
+
service["httpService"] = {
|
|
40
|
+
get: jest.fn(),
|
|
41
|
+
post: jest.fn(() => of({ data: { foo: "baz" } })),
|
|
42
|
+
patch: jest.fn(),
|
|
43
|
+
put: jest.fn(),
|
|
44
|
+
request: jest.fn(),
|
|
45
|
+
interceptors: { response: { use: jest.fn() } },
|
|
46
|
+
};
|
|
47
|
+
service
|
|
48
|
+
.request({ some: "data" })
|
|
49
|
+
.subscribe((result) => {
|
|
50
|
+
if (result.hasSuccess) {
|
|
51
|
+
expect(result.response).toEqual({ foo: "baz" });
|
|
52
|
+
done();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
it("should handle error", (done) => {
|
|
57
|
+
const service = new SmessService(provider);
|
|
58
|
+
service["httpService"] = {
|
|
59
|
+
get: jest.fn(() => throwError(() => new Error("Test error"))),
|
|
60
|
+
post: jest.fn(),
|
|
61
|
+
patch: jest.fn(),
|
|
62
|
+
put: jest.fn(),
|
|
63
|
+
request: jest.fn(),
|
|
64
|
+
interceptors: { response: { use: jest.fn() } },
|
|
65
|
+
};
|
|
66
|
+
service.request().subscribe((result) => {
|
|
67
|
+
if (result.hasFailed) {
|
|
68
|
+
expect(result).toBeInstanceOf(NetworkingUIEventWrapped);
|
|
69
|
+
expect(result.hasFailed).toBe(true);
|
|
70
|
+
expect(result.alertModel).toBeTruthy();
|
|
71
|
+
expect(result.alertModel?.message).toBe("Test error");
|
|
72
|
+
done();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it("should return mock response if provided", (done) => {
|
|
77
|
+
const service = new SmessService(provider);
|
|
78
|
+
service["httpService"] = {
|
|
79
|
+
get: jest.fn(() => throwError(() => new Error("Test error"))),
|
|
80
|
+
post: jest.fn(),
|
|
81
|
+
patch: jest.fn(),
|
|
82
|
+
put: jest.fn(),
|
|
83
|
+
request: jest.fn((payload, mockResponse) => {
|
|
84
|
+
if (payload === "error") {
|
|
85
|
+
return throwError(() => new Error("Test error"));
|
|
86
|
+
}
|
|
87
|
+
if (mockResponse !== undefined) {
|
|
88
|
+
return of(NetworkingUIEventWrapped.succeeded(mockResponse));
|
|
89
|
+
}
|
|
90
|
+
return of({ data: { foo: "mock" } });
|
|
91
|
+
}),
|
|
92
|
+
interceptors: { response: { use: jest.fn() } },
|
|
93
|
+
};
|
|
94
|
+
service
|
|
95
|
+
.request(undefined, { foo: "mock" })
|
|
96
|
+
.subscribe((result) => {
|
|
97
|
+
if (result.hasSuccess) {
|
|
98
|
+
expect(result.response).toEqual({ foo: "mock" });
|
|
99
|
+
done();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { ProviderType, NetworkingConfig, NetworkingUIEventWrapped, HttpResponse } from "../types/types";
|
|
2
|
+
import { SmessService } from "./smess.service";
|
|
3
|
+
import { BehaviorSubject, Observable } from "rxjs";
|
|
4
|
+
export type StoreCartTarget = "cart-get" | "cart-update" | "cart-add-item" | "cart-update-item" | "cart-delete-item" | "cart-delete-all-items" | "cart-batch-items";
|
|
5
|
+
export interface BillingInformation {
|
|
6
|
+
email?: string;
|
|
7
|
+
phone_number?: string;
|
|
8
|
+
street?: string;
|
|
9
|
+
city?: string;
|
|
10
|
+
postal_code?: string;
|
|
11
|
+
state?: string;
|
|
12
|
+
country?: string;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface ShippingInformation {
|
|
16
|
+
email?: string;
|
|
17
|
+
phone_number?: string;
|
|
18
|
+
street?: string;
|
|
19
|
+
city?: string;
|
|
20
|
+
postal_code?: string;
|
|
21
|
+
state?: string;
|
|
22
|
+
country?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface CartItem {
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
export interface StoreInfo {
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
export interface Cart {
|
|
32
|
+
dateCreated: string;
|
|
33
|
+
dateModified: string;
|
|
34
|
+
discountTotal: number;
|
|
35
|
+
discountTax: number;
|
|
36
|
+
shippingTotal: number;
|
|
37
|
+
shippingTax: number;
|
|
38
|
+
cartTax: number;
|
|
39
|
+
total: number;
|
|
40
|
+
totalTax: number;
|
|
41
|
+
customerId: string | null;
|
|
42
|
+
billingInformation: BillingInformation | null;
|
|
43
|
+
shippingInformation: ShippingInformation | null;
|
|
44
|
+
paymentMethod: string;
|
|
45
|
+
deliveryType: string;
|
|
46
|
+
transactionId: string | null;
|
|
47
|
+
customerIpAddress: string;
|
|
48
|
+
customerUserAgent: string;
|
|
49
|
+
customerNote: string | null;
|
|
50
|
+
cartHash: string;
|
|
51
|
+
cartItems: CartItem[];
|
|
52
|
+
paymentUrl: string | null;
|
|
53
|
+
store: StoreInfo | null;
|
|
54
|
+
[key: string]: unknown;
|
|
55
|
+
}
|
|
56
|
+
export interface CartUpdateRequest {
|
|
57
|
+
status?: string;
|
|
58
|
+
customer_note?: string;
|
|
59
|
+
customer_id?: string;
|
|
60
|
+
payment_method?: string;
|
|
61
|
+
delivery_type?: string;
|
|
62
|
+
billing_information?: BillingInformation;
|
|
63
|
+
shipping_information?: ShippingInformation;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
}
|
|
66
|
+
export interface CartAddItemRequest {
|
|
67
|
+
product_id: string;
|
|
68
|
+
quantity: number;
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
}
|
|
71
|
+
export interface CartUpdateItemQuantityRequest {
|
|
72
|
+
quantity: number;
|
|
73
|
+
}
|
|
74
|
+
export interface CartBatchItemsRequest {
|
|
75
|
+
create?: Array<{
|
|
76
|
+
product_id: string;
|
|
77
|
+
quantity: number;
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
}>;
|
|
80
|
+
update?: Array<{
|
|
81
|
+
product_id: string;
|
|
82
|
+
quantity: number;
|
|
83
|
+
[key: string]: unknown;
|
|
84
|
+
}>;
|
|
85
|
+
[key: string]: unknown;
|
|
86
|
+
}
|
|
87
|
+
export declare class StoreCartProvider implements ProviderType {
|
|
88
|
+
private readonly config;
|
|
89
|
+
private readonly target;
|
|
90
|
+
private readonly $cartHash;
|
|
91
|
+
private readonly $storeId;
|
|
92
|
+
constructor(config: NetworkingConfig, target: StoreCartTarget, $cartHash: BehaviorSubject<string | null>, $storeId: BehaviorSubject<string | null>);
|
|
93
|
+
get baseURL(): string;
|
|
94
|
+
get path(): string;
|
|
95
|
+
get method(): string;
|
|
96
|
+
get headers(): Record<string, string>;
|
|
97
|
+
getPath(...queryParams: unknown[]): string;
|
|
98
|
+
}
|
|
99
|
+
export interface StoreCartServiceType {
|
|
100
|
+
getCart(): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
101
|
+
updateCart(payload: CartUpdateRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
102
|
+
addItem(payload: CartAddItemRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
103
|
+
batchItems(payload: CartBatchItemsRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
104
|
+
updateItemQuantity(itemId: string, payload: CartUpdateItemQuantityRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
105
|
+
deleteItem(itemId: string): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
106
|
+
deleteAllItems(): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
107
|
+
}
|
|
108
|
+
export declare class StoreCartService implements StoreCartServiceType {
|
|
109
|
+
private readonly config;
|
|
110
|
+
private readonly $cartHash;
|
|
111
|
+
private readonly $storeId;
|
|
112
|
+
constructor(config: NetworkingConfig, $storeId?: BehaviorSubject<string | null>);
|
|
113
|
+
get currentCartHash(): string | null;
|
|
114
|
+
get cartHash$(): BehaviorSubject<string | null>;
|
|
115
|
+
get currentStoreId(): string | null;
|
|
116
|
+
get storeId$(): BehaviorSubject<string | null>;
|
|
117
|
+
setStoreId(storeId: string | null): void;
|
|
118
|
+
provider(target: StoreCartTarget): SmessService<StoreCartProvider>;
|
|
119
|
+
/**
|
|
120
|
+
* Update the cart hash from cart response
|
|
121
|
+
*/
|
|
122
|
+
private updateCartHash;
|
|
123
|
+
/**
|
|
124
|
+
* Get the current cart
|
|
125
|
+
* GET api/v1/store/cart
|
|
126
|
+
*/
|
|
127
|
+
getCart(): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
128
|
+
/**
|
|
129
|
+
* Update cart (e.g., add notes, apply coupon)
|
|
130
|
+
* PUT api/v1/store/cart
|
|
131
|
+
*/
|
|
132
|
+
updateCart(payload: CartUpdateRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
133
|
+
/**
|
|
134
|
+
* Add item to cart
|
|
135
|
+
* POST api/v1/store/cart/items
|
|
136
|
+
*/
|
|
137
|
+
addItem(payload: CartAddItemRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
138
|
+
/**
|
|
139
|
+
* Batch create/update items in cart
|
|
140
|
+
* POST api/v1/store/cart/items/batch
|
|
141
|
+
*/
|
|
142
|
+
batchItems(payload: CartBatchItemsRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
143
|
+
/**
|
|
144
|
+
* Update item quantity in cart
|
|
145
|
+
* PUT api/v1/store/cart/items/{id}
|
|
146
|
+
*/
|
|
147
|
+
updateItemQuantity(itemId: string, payload: CartUpdateItemQuantityRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
148
|
+
/**
|
|
149
|
+
* Delete item from cart
|
|
150
|
+
* DELETE api/v1/store/cart/items/{id}
|
|
151
|
+
*/
|
|
152
|
+
deleteItem(itemId: string): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
153
|
+
/**
|
|
154
|
+
* Delete all items from cart
|
|
155
|
+
* DELETE api/v1/store/cart/items
|
|
156
|
+
*/
|
|
157
|
+
deleteAllItems(): Observable<NetworkingUIEventWrapped<HttpResponse>>;
|
|
158
|
+
}
|