@smess/networking 1.0.29 → 1.1.0

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.
Files changed (132) hide show
  1. package/dist/index.d.ts +6 -0
  2. package/dist/index.js +6 -0
  3. package/dist/services/storefront.cart.service.d.ts +73 -0
  4. package/dist/services/storefront.cart.service.js +167 -0
  5. package/dist/services/storefront.cart.service.test.d.ts +1 -0
  6. package/dist/services/storefront.cart.service.test.js +211 -0
  7. package/dist/services/storefront.checkout.service.d.ts +62 -0
  8. package/dist/services/storefront.checkout.service.js +75 -0
  9. package/dist/services/storefront.checkout.service.test.d.ts +1 -0
  10. package/dist/services/storefront.checkout.service.test.js +158 -0
  11. package/dist/services/storefront.customer.metadata.service.d.ts +91 -0
  12. package/dist/services/storefront.customer.metadata.service.js +225 -0
  13. package/dist/services/storefront.customer.metadata.service.test.d.ts +1 -0
  14. package/dist/services/storefront.customer.metadata.service.test.js +271 -0
  15. package/dist/services/storefront.order.service.d.ts +45 -0
  16. package/dist/services/storefront.order.service.js +99 -0
  17. package/dist/services/storefront.order.service.test.d.ts +1 -0
  18. package/dist/services/storefront.order.service.test.js +158 -0
  19. package/dist/services/storefront.product.service.d.ts +52 -0
  20. package/dist/services/storefront.product.service.js +75 -0
  21. package/dist/services/storefront.product.service.test.d.ts +1 -0
  22. package/dist/services/storefront.product.service.test.js +120 -0
  23. package/dist/services/storefront.store.service.d.ts +54 -0
  24. package/dist/services/storefront.store.service.js +142 -0
  25. package/dist/services/storefront.store.service.test.d.ts +1 -0
  26. package/dist/services/storefront.store.service.test.js +90 -0
  27. package/dist/src/core/axios.d.ts +51 -0
  28. package/dist/src/core/axios.js +65 -0
  29. package/dist/src/core/axios.observable.d.ts +11 -0
  30. package/dist/src/core/axios.observable.js +58 -0
  31. package/dist/src/core/base.provider.advanced.test.d.ts +1 -0
  32. package/dist/src/core/base.provider.advanced.test.js +29 -0
  33. package/dist/src/core/base.provider.d.ts +15 -0
  34. package/dist/src/core/base.provider.js +13 -0
  35. package/dist/src/core/base.provider.test.d.ts +1 -0
  36. package/dist/src/core/base.provider.test.js +36 -0
  37. package/dist/src/core/base.service.wrapper.advanced.test.d.ts +1 -0
  38. package/dist/src/core/base.service.wrapper.advanced.test.js +39 -0
  39. package/dist/src/core/base.service.wrapper.d.ts +7 -0
  40. package/dist/src/core/base.service.wrapper.js +11 -0
  41. package/dist/src/core/base.service.wrapper.test.d.ts +1 -0
  42. package/dist/src/core/base.service.wrapper.test.js +25 -0
  43. package/dist/src/core/rx.http.service.d.ts +51 -0
  44. package/dist/src/core/rx.http.service.js +65 -0
  45. package/dist/src/index.d.ts +25 -0
  46. package/dist/src/index.js +29 -0
  47. package/dist/src/services/auth.service.d.ts +65 -0
  48. package/dist/src/services/auth.service.js +197 -0
  49. package/dist/src/services/auth.service.test.d.ts +1 -0
  50. package/dist/src/services/auth.service.test.js +334 -0
  51. package/dist/src/services/cache.service.d.ts +31 -0
  52. package/dist/src/services/cache.service.js +77 -0
  53. package/dist/src/services/cache.service.test.d.ts +1 -0
  54. package/dist/src/services/cache.service.test.js +88 -0
  55. package/dist/src/services/customer.service.d.ts +199 -0
  56. package/dist/src/services/customer.service.js +114 -0
  57. package/dist/src/services/customer.service.test.d.ts +1 -0
  58. package/dist/src/services/customer.service.test.js +430 -0
  59. package/dist/src/services/employee.service.d.ts +73 -0
  60. package/dist/src/services/employee.service.js +74 -0
  61. package/dist/src/services/employee.service.test.d.ts +1 -0
  62. package/dist/src/services/employee.service.test.js +127 -0
  63. package/dist/src/services/logger.service.d.ts +31 -0
  64. package/dist/src/services/logger.service.js +93 -0
  65. package/dist/src/services/logger.service.test.d.ts +1 -0
  66. package/dist/src/services/logger.service.test.js +31 -0
  67. package/dist/src/services/order.service.d.ts +73 -0
  68. package/dist/src/services/order.service.js +97 -0
  69. package/dist/src/services/order.service.test.d.ts +1 -0
  70. package/dist/src/services/order.service.test.js +163 -0
  71. package/dist/src/services/product.service.d.ts +21 -0
  72. package/dist/src/services/product.service.js +42 -0
  73. package/dist/src/services/product.service.test.d.ts +1 -0
  74. package/dist/src/services/product.service.test.js +61 -0
  75. package/dist/src/services/smess.service.d.ts +36 -0
  76. package/dist/src/services/smess.service.js +128 -0
  77. package/dist/src/services/smess.service.test.d.ts +1 -0
  78. package/dist/src/services/smess.service.test.js +103 -0
  79. package/dist/src/services/store.cart.service.d.ts +158 -0
  80. package/dist/src/services/store.cart.service.js +177 -0
  81. package/dist/src/services/store.cart.service.test.d.ts +1 -0
  82. package/dist/src/services/store.cart.service.test.js +394 -0
  83. package/dist/src/services/store.product.service.d.ts +124 -0
  84. package/dist/src/services/store.product.service.js +102 -0
  85. package/dist/src/services/store.product.service.test.d.ts +1 -0
  86. package/dist/src/services/store.product.service.test.js +319 -0
  87. package/dist/src/services/store.service.d.ts +79 -0
  88. package/dist/src/services/store.service.js +235 -0
  89. package/dist/src/services/store.service.test.d.ts +1 -0
  90. package/dist/src/services/store.service.test.js +274 -0
  91. package/dist/src/services/storefront.cart.service.d.ts +73 -0
  92. package/dist/src/services/storefront.cart.service.js +167 -0
  93. package/dist/src/services/storefront.cart.service.test.d.ts +1 -0
  94. package/dist/src/services/storefront.cart.service.test.js +211 -0
  95. package/dist/src/services/storefront.checkout.service.d.ts +62 -0
  96. package/dist/src/services/storefront.checkout.service.js +75 -0
  97. package/dist/src/services/storefront.checkout.service.test.d.ts +1 -0
  98. package/dist/src/services/storefront.checkout.service.test.js +158 -0
  99. package/dist/src/services/storefront.customer.metadata.service.d.ts +91 -0
  100. package/dist/src/services/storefront.customer.metadata.service.js +225 -0
  101. package/dist/src/services/storefront.customer.metadata.service.test.d.ts +1 -0
  102. package/dist/src/services/storefront.customer.metadata.service.test.js +271 -0
  103. package/dist/src/services/storefront.order.service.d.ts +45 -0
  104. package/dist/src/services/storefront.order.service.js +99 -0
  105. package/dist/src/services/storefront.order.service.test.d.ts +1 -0
  106. package/dist/src/services/storefront.order.service.test.js +158 -0
  107. package/dist/src/services/storefront.product.service.d.ts +52 -0
  108. package/dist/src/services/storefront.product.service.js +75 -0
  109. package/dist/src/services/storefront.product.service.test.d.ts +1 -0
  110. package/dist/src/services/storefront.product.service.test.js +120 -0
  111. package/dist/src/services/storefront.store.service.d.ts +52 -0
  112. package/dist/src/services/storefront.store.service.js +140 -0
  113. package/dist/src/services/storefront.store.service.test.d.ts +1 -0
  114. package/dist/src/services/storefront.store.service.test.js +90 -0
  115. package/dist/src/services/user.service.d.ts +16 -0
  116. package/dist/src/services/user.service.js +37 -0
  117. package/dist/src/services/user.service.test.d.ts +1 -0
  118. package/dist/src/services/user.service.test.js +52 -0
  119. package/dist/src/services/utils/withAuthReset.d.ts +3 -0
  120. package/dist/src/services/utils/withAuthReset.js +8 -0
  121. package/dist/src/types/types.d.ts +93 -0
  122. package/dist/src/types/types.js +82 -0
  123. package/dist/src/types/types.test.d.ts +1 -0
  124. package/dist/src/types/types.test.js +25 -0
  125. package/dist/src/utils/cache-import.d.ts +3 -0
  126. package/dist/src/utils/cache-import.js +2 -0
  127. package/dist/src/utils/networking-import.d.ts +4 -0
  128. package/dist/src/utils/networking-import.js +3 -0
  129. package/dist/src/utils/rxjs-import.d.ts +5 -0
  130. package/dist/src/utils/rxjs-import.js +5 -0
  131. package/dist/types/types.d.ts +3 -0
  132. package/package.json +1 -1
@@ -0,0 +1,271 @@
1
+ import { StorefrontCustomerMetadataService, StorefrontCustomerMetadataProvider, } from "./storefront.customer.metadata.service";
2
+ import { NetworkingUIEventWrapped, AlertModel, } from "../types/types";
3
+ import { of, BehaviorSubject } from "rxjs";
4
+ describe("StorefrontCustomerMetadataService", () => {
5
+ const config = {
6
+ baseUrl: "https://api.example.com",
7
+ version: "api/v1",
8
+ isProd: false,
9
+ clientId: "test-client-id",
10
+ apiKey: "test-api-key",
11
+ };
12
+ let service;
13
+ let $authToken;
14
+ beforeEach(() => {
15
+ $authToken = new BehaviorSubject(null);
16
+ service = new StorefrontCustomerMetadataService(config, $authToken);
17
+ });
18
+ describe("StorefrontCustomerMetadataProvider", () => {
19
+ it("should generate correct path for metadata-get", () => {
20
+ const provider = new StorefrontCustomerMetadataProvider(config, "metadata-get", $authToken);
21
+ expect(provider.path).toBe("/storefront/customer/metadata");
22
+ expect(provider.method).toBe("GET");
23
+ });
24
+ it("should generate correct path for favorites-add", () => {
25
+ const provider = new StorefrontCustomerMetadataProvider(config, "favorites-add", $authToken);
26
+ expect(provider.path).toBe("/storefront/customer/favorites");
27
+ expect(provider.method).toBe("POST");
28
+ });
29
+ it("should generate correct path for favorites-update-category", () => {
30
+ const provider = new StorefrontCustomerMetadataProvider(config, "favorites-update-category", $authToken);
31
+ expect(provider.path).toBe("/storefront/customer/favorites/${productId}/category");
32
+ expect(provider.method).toBe("PUT");
33
+ expect(provider.getPath(123)).toBe("/storefront/customer/favorites/123/category");
34
+ });
35
+ it("should include auth token in headers", () => {
36
+ $authToken.next("test-auth-token");
37
+ const provider = new StorefrontCustomerMetadataProvider(config, "metadata-get", $authToken);
38
+ const headers = provider.headers;
39
+ expect(headers["Authorization"]).toBe("Bearer test-auth-token");
40
+ });
41
+ });
42
+ describe("getMetadata", () => {
43
+ it("should return authentication error when not authenticated", async () => {
44
+ const result = await service.getMetadata(1).toPromise();
45
+ expect(result?.hasFailed).toBe(true);
46
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
47
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
48
+ });
49
+ it("should get metadata successfully when authenticated", async () => {
50
+ $authToken.next("test-auth-token");
51
+ const response = {
52
+ data: { customerId: "123", preferences: {} },
53
+ };
54
+ jest.spyOn(service, "provider").mockReturnValue({
55
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
56
+ });
57
+ const result = await service.getMetadata(1).toPromise();
58
+ expect(result?.hasSuccess).toBe(true);
59
+ expect(result?.response).toEqual(response);
60
+ });
61
+ });
62
+ describe("addFavorite", () => {
63
+ it("should return authentication error when not authenticated", async () => {
64
+ const payload = { productId: 123 };
65
+ const result = await service.addFavorite(1, payload).toPromise();
66
+ expect(result?.hasFailed).toBe(true);
67
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
68
+ });
69
+ it("should add favorite successfully when authenticated", async () => {
70
+ $authToken.next("test-auth-token");
71
+ const payload = { productId: 123 };
72
+ const response = {
73
+ data: { id: 1, productId: 123 },
74
+ };
75
+ jest.spyOn(service, "provider").mockReturnValue({
76
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
77
+ });
78
+ const result = await service.addFavorite(1, payload).toPromise();
79
+ expect(result?.hasSuccess).toBe(true);
80
+ expect(result?.response).toEqual(response);
81
+ });
82
+ });
83
+ describe("listFavorites", () => {
84
+ it("should return authentication error when not authenticated", async () => {
85
+ const result = await service.listFavorites(1).toPromise();
86
+ expect(result?.hasFailed).toBe(true);
87
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
88
+ });
89
+ it("should list favorites successfully when authenticated", async () => {
90
+ $authToken.next("test-auth-token");
91
+ const response = {
92
+ data: { favorites: [] },
93
+ };
94
+ jest.spyOn(service, "provider").mockReturnValue({
95
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
96
+ });
97
+ const result = await service.listFavorites(1).toPromise();
98
+ expect(result?.hasSuccess).toBe(true);
99
+ expect(result?.response).toEqual(response);
100
+ });
101
+ it("should list favorites with category filter", async () => {
102
+ $authToken.next("test-auth-token");
103
+ const response = {
104
+ data: { favorites: [] },
105
+ };
106
+ jest.spyOn(service, "provider").mockReturnValue({
107
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
108
+ });
109
+ const result = await service
110
+ .listFavorites(1, "Electronics")
111
+ .toPromise();
112
+ expect(result?.hasSuccess).toBe(true);
113
+ });
114
+ });
115
+ describe("updateFavoriteCategory", () => {
116
+ it("should return authentication error when not authenticated", async () => {
117
+ const payload = { category: "Books" };
118
+ const result = await service
119
+ .updateFavoriteCategory(123, 1, payload)
120
+ .toPromise();
121
+ expect(result?.hasFailed).toBe(true);
122
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
123
+ });
124
+ it("should update favorite category successfully when authenticated", async () => {
125
+ $authToken.next("test-auth-token");
126
+ const payload = { category: "Books" };
127
+ const response = {
128
+ data: { id: 1, category: "Books" },
129
+ };
130
+ jest.spyOn(service, "provider").mockReturnValue({
131
+ request: (_payload, _mockResponse, productId) => of(NetworkingUIEventWrapped.succeeded(response)),
132
+ });
133
+ const result = await service
134
+ .updateFavoriteCategory(123, 1, payload)
135
+ .toPromise();
136
+ expect(result?.hasSuccess).toBe(true);
137
+ expect(result?.response).toEqual(response);
138
+ });
139
+ });
140
+ describe("removeFavorite", () => {
141
+ it("should return authentication error when not authenticated", async () => {
142
+ const result = await service.removeFavorite(123, 1).toPromise();
143
+ expect(result?.hasFailed).toBe(true);
144
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
145
+ });
146
+ it("should remove favorite successfully when authenticated", async () => {
147
+ $authToken.next("test-auth-token");
148
+ const response = {
149
+ data: { message: "Favorite removed" },
150
+ };
151
+ jest.spyOn(service, "provider").mockReturnValue({
152
+ request: (_payload, _mockResponse, productId) => of(NetworkingUIEventWrapped.succeeded(response)),
153
+ });
154
+ const result = await service.removeFavorite(123, 1).toPromise();
155
+ expect(result?.hasSuccess).toBe(true);
156
+ expect(result?.response).toEqual(response);
157
+ });
158
+ });
159
+ describe("listFavoriteCategories", () => {
160
+ it("should return authentication error when not authenticated", async () => {
161
+ const result = await service.listFavoriteCategories(1).toPromise();
162
+ expect(result?.hasFailed).toBe(true);
163
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
164
+ });
165
+ it("should list favorite categories successfully when authenticated", async () => {
166
+ $authToken.next("test-auth-token");
167
+ const response = {
168
+ data: { categories: ["Books", "Electronics"] },
169
+ };
170
+ jest.spyOn(service, "provider").mockReturnValue({
171
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
172
+ });
173
+ const result = await service.listFavoriteCategories(1).toPromise();
174
+ expect(result?.hasSuccess).toBe(true);
175
+ expect(result?.response).toEqual(response);
176
+ });
177
+ });
178
+ describe("updatePreferences", () => {
179
+ it("should return authentication error when not authenticated", async () => {
180
+ const payload = { preferences: {} };
181
+ const result = await service.updatePreferences(1, payload).toPromise();
182
+ expect(result?.hasFailed).toBe(true);
183
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
184
+ });
185
+ it("should update preferences successfully when authenticated", async () => {
186
+ $authToken.next("test-auth-token");
187
+ const payload = {
188
+ preferences: { theme: "dark" },
189
+ };
190
+ const response = {
191
+ data: { preferences: { theme: "dark" } },
192
+ };
193
+ jest.spyOn(service, "provider").mockReturnValue({
194
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
195
+ });
196
+ const result = await service.updatePreferences(1, payload).toPromise();
197
+ expect(result?.hasSuccess).toBe(true);
198
+ expect(result?.response).toEqual(response);
199
+ });
200
+ });
201
+ describe("recordProductView", () => {
202
+ it("should return authentication error when not authenticated", async () => {
203
+ const payload = { productId: 123 };
204
+ const result = await service.recordProductView(1, payload).toPromise();
205
+ expect(result?.hasFailed).toBe(true);
206
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
207
+ });
208
+ it("should record product view successfully when authenticated", async () => {
209
+ $authToken.next("test-auth-token");
210
+ const payload = { productId: 123 };
211
+ const response = {
212
+ data: { message: "Product view recorded" },
213
+ };
214
+ jest.spyOn(service, "provider").mockReturnValue({
215
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
216
+ });
217
+ const result = await service.recordProductView(1, payload).toPromise();
218
+ expect(result?.hasSuccess).toBe(true);
219
+ expect(result?.response).toEqual(response);
220
+ });
221
+ });
222
+ describe("getRecentSearches", () => {
223
+ it("should return authentication error when not authenticated", async () => {
224
+ const result = await service.getRecentSearches(1).toPromise();
225
+ expect(result?.hasFailed).toBe(true);
226
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
227
+ });
228
+ it("should get recent searches successfully when authenticated", async () => {
229
+ $authToken.next("test-auth-token");
230
+ const response = {
231
+ data: { searches: ["laptop", "phone"] },
232
+ };
233
+ jest.spyOn(service, "provider").mockReturnValue({
234
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
235
+ });
236
+ const result = await service.getRecentSearches(1).toPromise();
237
+ expect(result?.hasSuccess).toBe(true);
238
+ expect(result?.response).toEqual(response);
239
+ });
240
+ });
241
+ describe("getRecentlyViewed", () => {
242
+ it("should return authentication error when not authenticated", async () => {
243
+ const result = await service.getRecentlyViewed(1).toPromise();
244
+ expect(result?.hasFailed).toBe(true);
245
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
246
+ });
247
+ it("should get recently viewed successfully when authenticated", async () => {
248
+ $authToken.next("test-auth-token");
249
+ const response = {
250
+ data: { products: [] },
251
+ };
252
+ jest.spyOn(service, "provider").mockReturnValue({
253
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
254
+ });
255
+ const result = await service.getRecentlyViewed(1).toPromise();
256
+ expect(result?.hasSuccess).toBe(true);
257
+ expect(result?.response).toEqual(response);
258
+ });
259
+ it("should get recently viewed with limit", async () => {
260
+ $authToken.next("test-auth-token");
261
+ const response = {
262
+ data: { products: [] },
263
+ };
264
+ jest.spyOn(service, "provider").mockReturnValue({
265
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
266
+ });
267
+ const result = await service.getRecentlyViewed(1, 10).toPromise();
268
+ expect(result?.hasSuccess).toBe(true);
269
+ });
270
+ });
271
+ });
@@ -0,0 +1,45 @@
1
+ import { ProviderType, NetworkingConfig, NetworkingUIEventWrapped, HttpResponse } from "../types/types";
2
+ import { SmessService } from "./smess.service";
3
+ import { BehaviorSubject, Observable } from "rxjs";
4
+ export type StorefrontOrderTarget = "order-list" | "order-detail" | "order-track";
5
+ export interface OrderListRequest {
6
+ page?: number;
7
+ limit?: number;
8
+ status?: string;
9
+ }
10
+ export interface TrackOrderRequest {
11
+ orderNumber: string;
12
+ email: string;
13
+ }
14
+ export declare class StorefrontOrderProvider implements ProviderType {
15
+ private readonly config;
16
+ private readonly target;
17
+ private readonly $authToken;
18
+ constructor(config: NetworkingConfig, target: StorefrontOrderTarget, $authToken: BehaviorSubject<string | null>);
19
+ get baseURL(): string;
20
+ get path(): string;
21
+ get method(): string;
22
+ get headers(): Record<string, string>;
23
+ getPath(...queryParams: unknown[]): string;
24
+ }
25
+ export declare class StorefrontOrderService {
26
+ private readonly config;
27
+ private readonly $authToken;
28
+ constructor(config: NetworkingConfig, $authToken: BehaviorSubject<string | null>);
29
+ provider(target: StorefrontOrderTarget): SmessService<StorefrontOrderProvider>;
30
+ /**
31
+ * List customer orders (requires authentication)
32
+ * GET /storefront/orders
33
+ */
34
+ listOrders(params?: OrderListRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
35
+ /**
36
+ * Get order details (requires authentication)
37
+ * GET /storefront/orders/{id}
38
+ */
39
+ getOrderDetail(id: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
40
+ /**
41
+ * Track guest order (no authentication required)
42
+ * POST /storefront/orders/track
43
+ */
44
+ trackOrder(payload: TrackOrderRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
45
+ }
@@ -0,0 +1,99 @@
1
+ import { NetworkingUIEventWrapped, AlertModel, AlertButtonModel, } from "../types/types";
2
+ import { Accept, SMESSHeader, SmessService } from "./smess.service";
3
+ import { of } from "rxjs";
4
+ export class StorefrontOrderProvider {
5
+ constructor(config, target, $authToken) {
6
+ this.config = config;
7
+ this.target = target;
8
+ this.$authToken = $authToken;
9
+ }
10
+ get baseURL() {
11
+ return this.config.version
12
+ ? `${this.config.baseUrl}/${this.config.version}`
13
+ : this.config.baseUrl;
14
+ }
15
+ get path() {
16
+ switch (this.target) {
17
+ case "order-list":
18
+ return "/storefront/orders";
19
+ case "order-detail":
20
+ return "/storefront/orders/${id}";
21
+ case "order-track":
22
+ return "/storefront/orders/track";
23
+ default:
24
+ return "/storefront/orders";
25
+ }
26
+ }
27
+ get method() {
28
+ switch (this.target) {
29
+ case "order-list":
30
+ case "order-detail":
31
+ return "GET";
32
+ case "order-track":
33
+ return "POST";
34
+ default:
35
+ return "GET";
36
+ }
37
+ }
38
+ get headers() {
39
+ // For order-track, don't include auth token (public endpoint)
40
+ const authToken = this.target === "order-track" ? null : this.$authToken.value;
41
+ let headers = SmessService.getHeaders(Accept.V1, authToken);
42
+ if (this.config.clientId) {
43
+ headers[SMESSHeader.ClientId] = this.config.clientId;
44
+ }
45
+ if (this.config.apiKey) {
46
+ headers[SMESSHeader.ApiKey] = this.config.apiKey;
47
+ }
48
+ return SmessService.filterHeaders(headers);
49
+ }
50
+ getPath(...queryParams) {
51
+ let definedPath = this.path;
52
+ const params = definedPath.match(/\$\{(.+?)\}/g);
53
+ params?.forEach((value, index) => {
54
+ definedPath = definedPath.replace(value, String(queryParams[index]));
55
+ });
56
+ return definedPath;
57
+ }
58
+ }
59
+ export class StorefrontOrderService {
60
+ constructor(config, $authToken) {
61
+ this.config = config;
62
+ this.$authToken = $authToken;
63
+ }
64
+ provider(target) {
65
+ const targetWrapper = new StorefrontOrderProvider(this.config, target, this.$authToken);
66
+ return new SmessService(targetWrapper);
67
+ }
68
+ /**
69
+ * List customer orders (requires authentication)
70
+ * GET /storefront/orders
71
+ */
72
+ listOrders(params) {
73
+ // Check authentication
74
+ if (!this.$authToken.value) {
75
+ const alertModel = new AlertModel("Authentication required to list orders", 401, true, "Authentication Required", null, [AlertButtonModel.buttonYes()]);
76
+ return of(NetworkingUIEventWrapped.failed(alertModel));
77
+ }
78
+ return this.provider("order-list").request(params);
79
+ }
80
+ /**
81
+ * Get order details (requires authentication)
82
+ * GET /storefront/orders/{id}
83
+ */
84
+ getOrderDetail(id) {
85
+ // Check authentication
86
+ if (!this.$authToken.value) {
87
+ const alertModel = new AlertModel("Authentication required to view order details", 401, true, "Authentication Required", null, [AlertButtonModel.buttonYes()]);
88
+ return of(NetworkingUIEventWrapped.failed(alertModel));
89
+ }
90
+ return this.provider("order-detail").request(null, undefined, id);
91
+ }
92
+ /**
93
+ * Track guest order (no authentication required)
94
+ * POST /storefront/orders/track
95
+ */
96
+ trackOrder(payload) {
97
+ return this.provider("order-track").request(payload);
98
+ }
99
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,158 @@
1
+ import { StorefrontOrderService, StorefrontOrderProvider, } from "./storefront.order.service";
2
+ import { NetworkingUIEventWrapped, AlertModel, } from "../types/types";
3
+ import { of, BehaviorSubject } from "rxjs";
4
+ describe("StorefrontOrderService", () => {
5
+ const config = {
6
+ baseUrl: "https://api.example.com",
7
+ version: "api/v1",
8
+ isProd: false,
9
+ clientId: "test-client-id",
10
+ apiKey: "test-api-key",
11
+ };
12
+ let service;
13
+ let $authToken;
14
+ beforeEach(() => {
15
+ $authToken = new BehaviorSubject(null);
16
+ service = new StorefrontOrderService(config, $authToken);
17
+ });
18
+ describe("StorefrontOrderProvider", () => {
19
+ it("should generate correct path for order-list", () => {
20
+ const provider = new StorefrontOrderProvider(config, "order-list", $authToken);
21
+ expect(provider.path).toBe("/storefront/orders");
22
+ expect(provider.method).toBe("GET");
23
+ });
24
+ it("should generate correct path for order-detail", () => {
25
+ const provider = new StorefrontOrderProvider(config, "order-detail", $authToken);
26
+ expect(provider.path).toBe("/storefront/orders/${id}");
27
+ expect(provider.method).toBe("GET");
28
+ expect(provider.getPath(123)).toBe("/storefront/orders/123");
29
+ });
30
+ it("should generate correct path for order-track", () => {
31
+ const provider = new StorefrontOrderProvider(config, "order-track", $authToken);
32
+ expect(provider.path).toBe("/storefront/orders/track");
33
+ expect(provider.method).toBe("POST");
34
+ });
35
+ it("should include auth token in headers for authenticated endpoints", () => {
36
+ $authToken.next("test-auth-token");
37
+ const provider = new StorefrontOrderProvider(config, "order-list", $authToken);
38
+ const headers = provider.headers;
39
+ expect(headers["Authorization"]).toBe("Bearer test-auth-token");
40
+ });
41
+ it("should not include auth token for order-track", () => {
42
+ $authToken.next("test-auth-token");
43
+ const provider = new StorefrontOrderProvider(config, "order-track", $authToken);
44
+ const headers = provider.headers;
45
+ expect(headers["Authorization"]).toBeUndefined();
46
+ });
47
+ });
48
+ describe("listOrders", () => {
49
+ it("should return authentication error when not authenticated", async () => {
50
+ const result = await service.listOrders().toPromise();
51
+ expect(result?.hasFailed).toBe(true);
52
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
53
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
54
+ expect(result?.alertModel?.message).toContain("Authentication required");
55
+ });
56
+ it("should list orders successfully when authenticated", async () => {
57
+ $authToken.next("test-auth-token");
58
+ const params = {
59
+ page: 1,
60
+ limit: 20,
61
+ status: "completed",
62
+ };
63
+ const response = {
64
+ data: { orders: [], total: 0 },
65
+ };
66
+ jest.spyOn(service, "provider").mockReturnValue({
67
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
68
+ });
69
+ const result = await service.listOrders(params).toPromise();
70
+ expect(result?.hasSuccess).toBe(true);
71
+ expect(result?.response).toEqual(response);
72
+ });
73
+ it("should handle list orders error when authenticated", async () => {
74
+ $authToken.next("test-auth-token");
75
+ jest.spyOn(service, "provider").mockReturnValue({
76
+ request: () => of(NetworkingUIEventWrapped.failed(AlertModel.default())),
77
+ });
78
+ const result = await service.listOrders().toPromise();
79
+ expect(result?.hasFailed).toBe(true);
80
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
81
+ });
82
+ });
83
+ describe("getOrderDetail", () => {
84
+ it("should return authentication error when not authenticated", async () => {
85
+ const result = await service.getOrderDetail(123).toPromise();
86
+ expect(result?.hasFailed).toBe(true);
87
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
88
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
89
+ expect(result?.alertModel?.message).toContain("Authentication required");
90
+ });
91
+ it("should get order detail successfully when authenticated", async () => {
92
+ $authToken.next("test-auth-token");
93
+ const response = {
94
+ data: { id: 123, status: "completed" },
95
+ };
96
+ jest.spyOn(service, "provider").mockReturnValue({
97
+ request: (_payload, _mockResponse, id) => of(NetworkingUIEventWrapped.succeeded(response)),
98
+ });
99
+ const result = await service.getOrderDetail(123).toPromise();
100
+ expect(result?.hasSuccess).toBe(true);
101
+ expect(result?.response).toEqual(response);
102
+ });
103
+ it("should handle get order detail error when authenticated", async () => {
104
+ $authToken.next("test-auth-token");
105
+ jest.spyOn(service, "provider").mockReturnValue({
106
+ request: (_payload, _mockResponse, id) => of(NetworkingUIEventWrapped.failed(AlertModel.default())),
107
+ });
108
+ const result = await service.getOrderDetail(123).toPromise();
109
+ expect(result?.hasFailed).toBe(true);
110
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
111
+ });
112
+ });
113
+ describe("trackOrder", () => {
114
+ it("should track order successfully without authentication", async () => {
115
+ const payload = {
116
+ orderNumber: "ORD-12345",
117
+ email: "customer@example.com",
118
+ };
119
+ const response = {
120
+ data: { id: 123, status: "shipped" },
121
+ };
122
+ jest.spyOn(service, "provider").mockReturnValue({
123
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
124
+ });
125
+ const result = await service.trackOrder(payload).toPromise();
126
+ expect(result?.hasSuccess).toBe(true);
127
+ expect(result?.response).toEqual(response);
128
+ });
129
+ it("should handle track order error", async () => {
130
+ const payload = {
131
+ orderNumber: "ORD-12345",
132
+ email: "customer@example.com",
133
+ };
134
+ jest.spyOn(service, "provider").mockReturnValue({
135
+ request: () => of(NetworkingUIEventWrapped.failed(AlertModel.default())),
136
+ });
137
+ const result = await service.trackOrder(payload).toPromise();
138
+ expect(result?.hasFailed).toBe(true);
139
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
140
+ });
141
+ it("should track order even when authenticated", async () => {
142
+ $authToken.next("test-auth-token");
143
+ const payload = {
144
+ orderNumber: "ORD-67890",
145
+ email: "user@example.com",
146
+ };
147
+ const response = {
148
+ data: { id: 456, status: "delivered" },
149
+ };
150
+ jest.spyOn(service, "provider").mockReturnValue({
151
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
152
+ });
153
+ const result = await service.trackOrder(payload).toPromise();
154
+ expect(result?.hasSuccess).toBe(true);
155
+ expect(result?.response).toEqual(response);
156
+ });
157
+ });
158
+ });
@@ -0,0 +1,52 @@
1
+ import { ProviderType, NetworkingConfig, NetworkingUIEventWrapped, HttpResponse } from "../types/types";
2
+ import { SmessService } from "./smess.service";
3
+ import { Observable } from "rxjs";
4
+ export type StorefrontProductTarget = "product-list" | "product-collection" | "product-detail";
5
+ export interface ProductListRequest {
6
+ page?: number;
7
+ limit?: number;
8
+ store_id?: number;
9
+ category?: string;
10
+ sub_category?: string;
11
+ min_price?: number;
12
+ max_price?: number;
13
+ in_stock?: boolean;
14
+ search?: string;
15
+ }
16
+ export interface StorefrontProductCollectionRequest extends ProductListRequest {
17
+ per_page?: number;
18
+ only_promoted?: boolean;
19
+ only_discounted?: boolean;
20
+ include_hidden?: boolean;
21
+ only_featured?: boolean;
22
+ }
23
+ export declare class StorefrontProductProvider implements ProviderType {
24
+ private readonly config;
25
+ private readonly target;
26
+ constructor(config: NetworkingConfig, target: StorefrontProductTarget);
27
+ get baseURL(): string;
28
+ get path(): string;
29
+ get method(): string;
30
+ get headers(): Record<string, string>;
31
+ getPath(...queryParams: unknown[]): string;
32
+ }
33
+ export declare class StorefrontProductService {
34
+ private readonly config;
35
+ constructor(config: NetworkingConfig);
36
+ provider(target: StorefrontProductTarget): SmessService<StorefrontProductProvider>;
37
+ /**
38
+ * List products with pagination and filtering
39
+ * GET /storefront/products
40
+ */
41
+ listProducts(params?: ProductListRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
42
+ /**
43
+ * Get product collection with per_page pagination style
44
+ * GET /storefront/products/collection
45
+ */
46
+ getProductCollection(params?: StorefrontProductCollectionRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
47
+ /**
48
+ * Get product details by ID
49
+ * GET /storefront/products/{id}
50
+ */
51
+ getProductDetail(id: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
52
+ }