@smess/networking 1.0.2 → 1.0.4

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 (36) hide show
  1. package/README.md +4 -25
  2. package/dist/index.d.ts +4 -4
  3. package/dist/index.js +4 -4
  4. package/dist/scripts/real-test.js +188 -15
  5. package/dist/src/core/base.service.wrapper.js +1 -1
  6. package/dist/src/core/base.service.wrapper.test.js +1 -1
  7. package/dist/src/services/auth.service.d.ts +57 -0
  8. package/dist/src/services/auth.service.js +96 -0
  9. package/dist/src/services/auth.service.test.d.ts +1 -0
  10. package/dist/src/services/auth.service.test.js +131 -0
  11. package/dist/src/services/customer.service.d.ts +43 -0
  12. package/dist/src/services/customer.service.js +75 -0
  13. package/dist/src/services/customer.service.test.d.ts +1 -0
  14. package/dist/src/services/customer.service.test.js +98 -0
  15. package/dist/src/services/order.service.d.ts +60 -0
  16. package/dist/src/services/order.service.js +94 -0
  17. package/dist/src/services/order.service.test.d.ts +1 -0
  18. package/dist/src/services/order.service.test.js +137 -0
  19. package/dist/src/services/product.service.d.ts +21 -0
  20. package/dist/src/services/product.service.js +47 -0
  21. package/dist/src/services/product.service.test.d.ts +1 -0
  22. package/dist/src/services/product.service.test.js +54 -0
  23. package/dist/src/services/smess.service.d.ts +36 -0
  24. package/dist/src/services/smess.service.js +136 -0
  25. package/dist/src/services/smess.service.test.d.ts +1 -0
  26. package/dist/src/services/smess.service.test.js +102 -0
  27. package/dist/src/services/store.service.d.ts +39 -0
  28. package/dist/src/services/store.service.js +78 -0
  29. package/dist/src/services/store.service.test.d.ts +1 -0
  30. package/dist/src/services/store.service.test.js +106 -0
  31. package/dist/src/services/user.service.d.ts +16 -0
  32. package/dist/src/services/user.service.js +39 -0
  33. package/dist/src/services/user.service.test.d.ts +1 -0
  34. package/dist/src/services/user.service.test.js +47 -0
  35. package/dist/src/types/types.d.ts +1 -3
  36. package/package.json +1 -1
@@ -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,136 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SmessService = exports.Accept = exports.ContentType = exports.SMESSHeader = void 0;
7
+ const types_1 = require("../types/types");
8
+ const rxjs_import_1 = require("../utils/rxjs-import");
9
+ const rx_http_service_1 = __importDefault(require("../core/rx.http.service"));
10
+ const logger_service_1 = require("../services/logger.service");
11
+ var SMESSHeader;
12
+ (function (SMESSHeader) {
13
+ SMESSHeader["ContentType"] = "Content-Type";
14
+ SMESSHeader["Authorization"] = "Authorization";
15
+ SMESSHeader["Accept"] = "Accept";
16
+ SMESSHeader["ApiKey"] = "X-Api-Key";
17
+ SMESSHeader["ClientId"] = "X-Client-Id";
18
+ })(SMESSHeader || (exports.SMESSHeader = SMESSHeader = {}));
19
+ var ContentType;
20
+ (function (ContentType) {
21
+ ContentType["Json"] = "application/json";
22
+ ContentType["FormURLEncoded"] = "application/x-www-form-urlencoded";
23
+ })(ContentType || (exports.ContentType = ContentType = {}));
24
+ var Accept;
25
+ (function (Accept) {
26
+ Accept["V1"] = "application/json";
27
+ Accept["V2"] = "application/vnd.smess.v2+json";
28
+ Accept["V3"] = "application/vnd.smess.v3+json";
29
+ Accept["V4"] = "application/vnd.smess.v4+json";
30
+ Accept["V5"] = "application/vnd.smess.v5+json";
31
+ Accept["V6"] = "application/vnd.smess.v6+json";
32
+ Accept["V7"] = "application/vnd.smess.v7+json";
33
+ Accept["V8"] = "application/vnd.smess.v8+json";
34
+ Accept["V9"] = "application/vnd.smess.v9+json";
35
+ Accept["V10"] = "application/vnd.smess.v10+json";
36
+ })(Accept || (exports.Accept = Accept = {}));
37
+ class SmessService {
38
+ constructor(target) {
39
+ this.target = target;
40
+ // Set default headers
41
+ logger_service_1.$logger.info('SmessService initialized', {
42
+ target: this.target,
43
+ baseURL: this.target.baseURL,
44
+ method: this.target.method,
45
+ headers: this.target.headers,
46
+ }, 'SmessService');
47
+ this.httpService = rx_http_service_1.default.create({
48
+ baseURL: this.target.baseURL,
49
+ headers: this.target.headers,
50
+ method: this.target.method,
51
+ });
52
+ this.httpService.interceptors.response.use((response) => response, async (error) => {
53
+ var _a;
54
+ const originalRequest = error.config;
55
+ if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 && !originalRequest._retry) {
56
+ originalRequest._retry = true;
57
+ logger_service_1.$logger.info('SmessService constructor - 401 retry', originalRequest, 'SmessService');
58
+ // Implement token refresh logic here
59
+ // Then retry the original request
60
+ // return httpService.request(originalRequest);
61
+ }
62
+ return Promise.reject(error);
63
+ });
64
+ }
65
+ static getHeaders(version, authorization = null, options) {
66
+ const headers = this.commonHeaders(version, options);
67
+ if (authorization) {
68
+ headers['Authorization'] = authorization;
69
+ }
70
+ return headers;
71
+ }
72
+ static filterHeaders(headers) {
73
+ const filteredHeaders = Object.fromEntries(Object.entries(headers).filter(([_, value]) => value !== undefined && value !== null && value !== ''));
74
+ return filteredHeaders;
75
+ }
76
+ static commonHeaders(version, options) {
77
+ const { shouldAddClientIdHeader = true, } = options !== null && options !== void 0 ? options : {};
78
+ const headers = {
79
+ Accept: version,
80
+ Authorization: '',
81
+ 'Content-Type': ContentType.Json,
82
+ 'X-Api-Key': ''
83
+ };
84
+ return headers;
85
+ }
86
+ // MARK: - Public
87
+ request(request, mockResponse, ...queryParams) {
88
+ const url = queryParams.length
89
+ ? this.target.getPath(...queryParams)
90
+ : this.target.path;
91
+ const config = { url };
92
+ let observable;
93
+ if (this.target.method === 'GET') {
94
+ if (request) {
95
+ config.data = request;
96
+ config.params = request;
97
+ }
98
+ observable = this.httpService.get(url, config);
99
+ }
100
+ else if (this.target.method === 'POST') {
101
+ observable = this.httpService.post(url, request, config);
102
+ }
103
+ else if (this.target.method === 'PATCH') {
104
+ observable = this.httpService.patch(url, request, config);
105
+ }
106
+ else if (this.target.method === 'PUT') {
107
+ observable = this.httpService.put(url, request, config);
108
+ }
109
+ else {
110
+ observable = this.httpService.request(config);
111
+ }
112
+ return observable.pipe((0, rxjs_import_1.catchError)((error) => this.transformAxiosError(error, mockResponse)), (0, rxjs_import_1.mergeMap)((data) => this.transformAxiosResponse(data)), (0, rxjs_import_1.startWith)(types_1.NetworkingUIEventWrapped.waiting()));
113
+ }
114
+ // MARK: - Private
115
+ transformAxiosError(error, mockResponse) {
116
+ logger_service_1.$logger.error('transformAxiosError', error, 'SmessService');
117
+ const message = error instanceof Error ? error.message : String(error);
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Required for axios compatibility
119
+ const response = error.response;
120
+ const httpErrorCode = response ? response.status : 0;
121
+ const title = response === null || response === void 0 ? void 0 : response.statusText;
122
+ const alertModel = new types_1.AlertModel(message, httpErrorCode, true, title, response === null || response === void 0 ? void 0 : response.data, [types_1.AlertButtonModel.buttonYes()]);
123
+ if (mockResponse) {
124
+ return (0, rxjs_import_1.of)(types_1.NetworkingUIEventWrapped.succeeded(mockResponse));
125
+ }
126
+ return (0, rxjs_import_1.of)(types_1.NetworkingUIEventWrapped.failed(alertModel));
127
+ }
128
+ transformAxiosResponse(response) {
129
+ logger_service_1.$logger.info('transformAxiosResponse', response, 'SmessService');
130
+ if (response instanceof types_1.NetworkingUIEventWrapped) {
131
+ return (0, rxjs_import_1.of)(response);
132
+ }
133
+ return (0, rxjs_import_1.of)(types_1.NetworkingUIEventWrapped.succeeded(response.data));
134
+ }
135
+ }
136
+ exports.SmessService = SmessService;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable @typescript-eslint/no-explicit-any -- Required for test mocks */
4
+ const smess_service_1 = require("./smess.service");
5
+ const types_1 = require("../types/types");
6
+ const rxjs_1 = require("rxjs");
7
+ describe('SmessService', () => {
8
+ const config = {
9
+ baseUrl: 'https://api.example.com',
10
+ isProd: false,
11
+ clientId: 'test-client',
12
+ apiKey: 'test-key',
13
+ };
14
+ const provider = {
15
+ baseURL: config.baseUrl,
16
+ path: '/resource',
17
+ method: 'GET',
18
+ headers: {},
19
+ getPath: () => '/resource',
20
+ };
21
+ it('should return succeeded for GET', done => {
22
+ const service = new smess_service_1.SmessService(provider);
23
+ service['httpService'] = {
24
+ get: jest.fn(() => (0, rxjs_1.of)({ data: { foo: 'bar' } })),
25
+ post: jest.fn(),
26
+ patch: jest.fn(),
27
+ put: jest.fn(),
28
+ request: jest.fn(),
29
+ interceptors: { response: { use: jest.fn() } },
30
+ };
31
+ service.request().subscribe(result => {
32
+ if (result.hasSuccess) {
33
+ expect(result.response).toEqual({ foo: 'bar' });
34
+ done();
35
+ }
36
+ });
37
+ });
38
+ it('should return succeeded for POST', done => {
39
+ const postProvider = Object.assign(Object.assign({}, provider), { method: 'POST' });
40
+ const service = new smess_service_1.SmessService(postProvider);
41
+ service['httpService'] = {
42
+ get: jest.fn(),
43
+ post: jest.fn(() => (0, rxjs_1.of)({ data: { foo: 'baz' } })),
44
+ patch: jest.fn(),
45
+ put: jest.fn(),
46
+ request: jest.fn(),
47
+ interceptors: { response: { use: jest.fn() } },
48
+ };
49
+ service.request({ some: 'data' }).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 smess_service_1.SmessService(provider);
58
+ service['httpService'] = {
59
+ get: jest.fn(() => (0, rxjs_1.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
+ var _a;
68
+ if (result.hasFailed) {
69
+ expect(result).toBeInstanceOf(types_1.NetworkingUIEventWrapped);
70
+ expect(result.hasFailed).toBe(true);
71
+ expect(result.alertModel).toBeTruthy();
72
+ expect((_a = result.alertModel) === null || _a === void 0 ? void 0 : _a.message).toBe('Test error');
73
+ done();
74
+ }
75
+ });
76
+ });
77
+ it('should return mock response if provided', done => {
78
+ const service = new smess_service_1.SmessService(provider);
79
+ service['httpService'] = {
80
+ get: jest.fn(() => (0, rxjs_1.throwError)(() => new Error('Test error'))),
81
+ post: jest.fn(),
82
+ patch: jest.fn(),
83
+ put: jest.fn(),
84
+ request: jest.fn((payload, mockResponse) => {
85
+ if (payload === 'error') {
86
+ return (0, rxjs_1.throwError)(() => new Error('Test error'));
87
+ }
88
+ if (mockResponse !== undefined) {
89
+ return (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(mockResponse));
90
+ }
91
+ return (0, rxjs_1.of)({ data: { foo: 'mock' } });
92
+ }),
93
+ interceptors: { response: { use: jest.fn() } },
94
+ };
95
+ service.request(undefined, { foo: 'mock' }).subscribe(result => {
96
+ if (result.hasSuccess) {
97
+ expect(result.response).toEqual({ foo: 'mock' });
98
+ done();
99
+ }
100
+ });
101
+ });
102
+ });
@@ -0,0 +1,39 @@
1
+ import { ProviderType, NetworkingConfig, NetworkingUIEventWrapped, HttpResponse } from '../types/types';
2
+ import { SmessService } from './smess.service';
3
+ import { BehaviorSubject, Observable } from 'rxjs';
4
+ export type StoreTarget = 'store-get' | 'store-list' | 'store-product-category-list' | 'store-product-collection' | 'store-featured-product-list';
5
+ export interface ProductCollectionRequest {
6
+ page?: number;
7
+ per_page?: number;
8
+ search?: string;
9
+ sort_by?: string;
10
+ category?: string;
11
+ min_price?: number;
12
+ max_price?: number;
13
+ only_discounted?: boolean;
14
+ unit?: string;
15
+ supplier?: string;
16
+ has_offer?: boolean;
17
+ }
18
+ export declare class StoreProvider implements ProviderType {
19
+ private readonly config;
20
+ private readonly target;
21
+ private readonly $authToken;
22
+ constructor(config: NetworkingConfig, target: StoreTarget, $authToken: BehaviorSubject<string | null>);
23
+ get baseURL(): string;
24
+ get path(): string;
25
+ get method(): string;
26
+ get headers(): Record<string, string>;
27
+ getPath(...queryParams: unknown[]): string;
28
+ }
29
+ export declare class StoreService {
30
+ private readonly config;
31
+ private readonly $authToken;
32
+ constructor(config: NetworkingConfig, $authToken: BehaviorSubject<string | null>);
33
+ provider(target: StoreTarget): SmessService<StoreProvider>;
34
+ get(id: string): Observable<NetworkingUIEventWrapped<HttpResponse>>;
35
+ list(): Observable<NetworkingUIEventWrapped<HttpResponse>>;
36
+ productCategoryList(): Observable<NetworkingUIEventWrapped<HttpResponse>>;
37
+ productCollection(id: string, payload: ProductCollectionRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
38
+ featuredProductList(id: string): Observable<NetworkingUIEventWrapped<HttpResponse>>;
39
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StoreService = exports.StoreProvider = void 0;
4
+ const smess_service_1 = require("./smess.service");
5
+ class StoreProvider {
6
+ constructor(config, target, $authToken) {
7
+ this.config = config;
8
+ this.target = target;
9
+ this.$authToken = $authToken;
10
+ }
11
+ get baseURL() {
12
+ return this.config.version ? `${this.config.baseUrl}/${this.config.version}` : this.config.baseUrl;
13
+ }
14
+ get path() {
15
+ switch (this.target) {
16
+ case 'store-get':
17
+ return '/store/${id}/information';
18
+ case 'store-list':
19
+ return '/store/list';
20
+ case 'store-product-category-list':
21
+ return '/store/product-category-list';
22
+ case 'store-product-collection':
23
+ return '/store/${id}/product-collection';
24
+ case 'store-featured-product-list':
25
+ return '/store/${id}/featured-product-list';
26
+ default:
27
+ return '/store/${id}';
28
+ }
29
+ }
30
+ get method() {
31
+ return 'GET';
32
+ }
33
+ get headers() {
34
+ let headers = smess_service_1.SmessService.getHeaders(smess_service_1.Accept.V1, this.$authToken.value);
35
+ if (this.config.clientId) {
36
+ headers[smess_service_1.SMESSHeader.ClientId] = this.config.clientId;
37
+ }
38
+ if (this.config.apiKey) {
39
+ headers[smess_service_1.SMESSHeader.ApiKey] = this.config.apiKey;
40
+ }
41
+ return smess_service_1.SmessService.filterHeaders(headers);
42
+ }
43
+ getPath(...queryParams) {
44
+ let definedPath = this.path;
45
+ const params = definedPath.match(/\$\{(.+?)\}/g);
46
+ params === null || params === void 0 ? void 0 : params.forEach((value, index) => {
47
+ definedPath = definedPath.replace(value, String(queryParams[index]));
48
+ });
49
+ return definedPath;
50
+ }
51
+ }
52
+ exports.StoreProvider = StoreProvider;
53
+ class StoreService {
54
+ constructor(config, $authToken) {
55
+ this.config = config;
56
+ this.$authToken = $authToken;
57
+ }
58
+ provider(target) {
59
+ const targetWrapper = new StoreProvider(this.config, target, this.$authToken);
60
+ return new smess_service_1.SmessService(targetWrapper);
61
+ }
62
+ get(id) {
63
+ return this.provider('store-get').request(null, undefined, id);
64
+ }
65
+ list() {
66
+ return this.provider('store-list').request();
67
+ }
68
+ productCategoryList() {
69
+ return this.provider('store-product-category-list').request();
70
+ }
71
+ productCollection(id, payload) {
72
+ return this.provider('store-product-collection').request(payload, undefined, id);
73
+ }
74
+ featuredProductList(id) {
75
+ return this.provider('store-featured-product-list').request(null, undefined, id);
76
+ }
77
+ }
78
+ exports.StoreService = StoreService;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const store_service_1 = require("./store.service");
4
+ const types_1 = require("../types/types");
5
+ const rxjs_1 = require("rxjs");
6
+ describe('StoreService', () => {
7
+ const config = {
8
+ baseUrl: 'https://api.example.com',
9
+ isProd: false,
10
+ clientId: 'test-client-id',
11
+ apiKey: 'test-api-key',
12
+ };
13
+ let service;
14
+ let $authToken;
15
+ beforeEach(() => {
16
+ $authToken = new rxjs_1.BehaviorSubject(null);
17
+ service = new store_service_1.StoreService(config, $authToken);
18
+ });
19
+ it('get success', async () => {
20
+ const response = { data: { id: '1', name: 'Store' } };
21
+ jest.spyOn(service, 'provider').mockReturnValue({
22
+ request: (_payload, _mockResponse, id) => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(response)),
23
+ });
24
+ const result = await service.get('1').toPromise();
25
+ expect(result === null || result === void 0 ? void 0 : result.hasSuccess).toBe(true);
26
+ expect(result === null || result === void 0 ? void 0 : result.response).toEqual(response);
27
+ });
28
+ it('get error', async () => {
29
+ jest.spyOn(service, 'provider').mockReturnValue({
30
+ request: (_payload, _mockResponse, id) => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.failed(types_1.AlertModel.default())),
31
+ });
32
+ const result = await service.get('1').toPromise();
33
+ expect(result === null || result === void 0 ? void 0 : result.hasFailed).toBe(true);
34
+ expect(result === null || result === void 0 ? void 0 : result.alertModel).toBeInstanceOf(types_1.AlertModel);
35
+ });
36
+ it('list success', async () => {
37
+ const response = { data: [{ id: '1', name: 'Store' }] };
38
+ jest.spyOn(service, 'provider').mockReturnValue({
39
+ request: () => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(response)),
40
+ });
41
+ const result = await service.list().toPromise();
42
+ expect(result === null || result === void 0 ? void 0 : result.hasSuccess).toBe(true);
43
+ expect(result === null || result === void 0 ? void 0 : result.response).toEqual(response);
44
+ });
45
+ it('list error', async () => {
46
+ jest.spyOn(service, 'provider').mockReturnValue({
47
+ request: () => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.failed(types_1.AlertModel.default())),
48
+ });
49
+ const result = await service.list().toPromise();
50
+ expect(result === null || result === void 0 ? void 0 : result.hasFailed).toBe(true);
51
+ expect(result === null || result === void 0 ? void 0 : result.alertModel).toBeInstanceOf(types_1.AlertModel);
52
+ });
53
+ it('productCategoryList success', async () => {
54
+ const response = { data: [{ id: 'cat1', name: 'Category' }] };
55
+ jest.spyOn(service, 'provider').mockReturnValue({
56
+ request: () => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(response)),
57
+ });
58
+ const result = await service.productCategoryList().toPromise();
59
+ expect(result === null || result === void 0 ? void 0 : result.hasSuccess).toBe(true);
60
+ expect(result === null || result === void 0 ? void 0 : result.response).toEqual(response);
61
+ });
62
+ it('productCategoryList error', async () => {
63
+ jest.spyOn(service, 'provider').mockReturnValue({
64
+ request: () => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.failed(types_1.AlertModel.default())),
65
+ });
66
+ const result = await service.productCategoryList().toPromise();
67
+ expect(result === null || result === void 0 ? void 0 : result.hasFailed).toBe(true);
68
+ expect(result === null || result === void 0 ? void 0 : result.alertModel).toBeInstanceOf(types_1.AlertModel);
69
+ });
70
+ it('productCollection success', async () => {
71
+ const response = { data: [{ id: 'prod1', name: 'Product' }] };
72
+ const payload = { page: 1, per_page: 10 };
73
+ jest.spyOn(service, 'provider').mockReturnValue({
74
+ request: (payload, _mockResponse, id) => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(response)),
75
+ });
76
+ const result = await service.productCollection('1', payload).toPromise();
77
+ expect(result === null || result === void 0 ? void 0 : result.hasSuccess).toBe(true);
78
+ expect(result === null || result === void 0 ? void 0 : result.response).toEqual(response);
79
+ });
80
+ it('productCollection error', async () => {
81
+ const payload = { page: 1, per_page: 10 };
82
+ jest.spyOn(service, 'provider').mockReturnValue({
83
+ request: (payload, _mockResponse, id) => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.failed(types_1.AlertModel.default())),
84
+ });
85
+ const result = await service.productCollection('1', payload).toPromise();
86
+ expect(result === null || result === void 0 ? void 0 : result.hasFailed).toBe(true);
87
+ expect(result === null || result === void 0 ? void 0 : result.alertModel).toBeInstanceOf(types_1.AlertModel);
88
+ });
89
+ it('featuredProductList success', async () => {
90
+ const response = { data: [{ id: 'feat1', name: 'Featured' }] };
91
+ jest.spyOn(service, 'provider').mockReturnValue({
92
+ request: (_payload, _mockResponse, storeId) => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(response)),
93
+ });
94
+ const result = await service.featuredProductList('1').toPromise();
95
+ expect(result === null || result === void 0 ? void 0 : result.hasSuccess).toBe(true);
96
+ expect(result === null || result === void 0 ? void 0 : result.response).toEqual(response);
97
+ });
98
+ it('featuredProductList error', async () => {
99
+ jest.spyOn(service, 'provider').mockReturnValue({
100
+ request: (_payload, _mockResponse, storeId) => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.failed(types_1.AlertModel.default())),
101
+ });
102
+ const result = await service.featuredProductList('1').toPromise();
103
+ expect(result === null || result === void 0 ? void 0 : result.hasFailed).toBe(true);
104
+ expect(result === null || result === void 0 ? void 0 : result.alertModel).toBeInstanceOf(types_1.AlertModel);
105
+ });
106
+ });
@@ -0,0 +1,16 @@
1
+ import { BaseProvider } from '../core/base.provider';
2
+ import { BaseServiceWrapper } from '../core/base.service.wrapper';
3
+ import { NetworkingConfig } from '../types/types';
4
+ export interface User {
5
+ id: number;
6
+ name: string;
7
+ email: string;
8
+ }
9
+ export declare class UserProvider extends BaseProvider {
10
+ constructor(config: NetworkingConfig, userId?: number);
11
+ }
12
+ export declare class UserService extends BaseServiceWrapper<UserProvider> {
13
+ constructor(config: NetworkingConfig, userId?: number);
14
+ fetchUserById(id: number): import("rxjs").Observable<import("../types/types").NetworkingUIEventWrapped<User>>;
15
+ fetchAllUsers(): import("rxjs").Observable<import("../types/types").NetworkingUIEventWrapped<User[]>>;
16
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserService = exports.UserProvider = void 0;
4
+ const base_provider_1 = require("../core/base.provider");
5
+ const base_service_wrapper_1 = require("../core/base.service.wrapper");
6
+ // UserProvider implements ProviderType for user endpoints
7
+ class UserProvider extends base_provider_1.BaseProvider {
8
+ constructor(config, userId) {
9
+ super({
10
+ config,
11
+ path: userId ? `/users/${userId}` : '/users',
12
+ method: 'GET',
13
+ headers: {},
14
+ getPath: () => (userId ? `/users/${userId}` : '/users'),
15
+ });
16
+ }
17
+ }
18
+ exports.UserProvider = UserProvider;
19
+ // UserService provides high-level methods for user API
20
+ class UserService extends base_service_wrapper_1.BaseServiceWrapper {
21
+ constructor(config, userId) {
22
+ super(new UserProvider(config, userId));
23
+ }
24
+ // Fetch a user by ID
25
+ fetchUserById(id) {
26
+ this.provider = new UserProvider({ baseUrl: 'https://jsonplaceholder.typicode.com', isProd: false }, id);
27
+ return this.request();
28
+ }
29
+ // Fetch all users
30
+ fetchAllUsers() {
31
+ this.provider = new UserProvider({ baseUrl: 'https://jsonplaceholder.typicode.com', isProd: false });
32
+ return this.request();
33
+ }
34
+ }
35
+ exports.UserService = UserService;
36
+ // Example usage:
37
+ // setNetworkingConfig({ baseUrl: 'https://jsonplaceholder.typicode.com', isProd: false });
38
+ // const userService = new UserService();
39
+ // userService.fetchUserById(1).subscribe(result => console.log(result));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const user_service_1 = require("./user.service");
4
+ const types_1 = require("../types/types");
5
+ const rxjs_1 = require("rxjs");
6
+ const base_service_wrapper_1 = require("../core/base.service.wrapper");
7
+ describe('UserService', () => {
8
+ const config = {
9
+ baseUrl: 'https://jsonplaceholder.typicode.com',
10
+ isProd: false,
11
+ clientId: 'test-client',
12
+ apiKey: 'test-key',
13
+ };
14
+ const user = { id: 1, name: 'Test', email: 'test@example.com' };
15
+ let requestSpy;
16
+ beforeEach(() => {
17
+ requestSpy = jest.spyOn(base_service_wrapper_1.BaseServiceWrapper.prototype, 'request').mockImplementation(() => (0, rxjs_1.of)(types_1.NetworkingUIEventWrapped.succeeded(user)));
18
+ });
19
+ afterEach(() => {
20
+ requestSpy.mockRestore();
21
+ });
22
+ it('fetchUserById should return user (success)', done => {
23
+ const service = new user_service_1.UserService(config);
24
+ service.fetchUserById(1).subscribe(result => {
25
+ expect(result.response).toEqual(user);
26
+ done();
27
+ });
28
+ });
29
+ it('fetchAllUsers should return users (success)', done => {
30
+ const service = new user_service_1.UserService(config);
31
+ service.fetchAllUsers().subscribe(result => {
32
+ expect(result.response).toEqual(user);
33
+ done();
34
+ });
35
+ });
36
+ it('request should handle error', done => {
37
+ requestSpy.mockImplementationOnce(() => (0, rxjs_1.throwError)(() => new Error('Test error')));
38
+ const service = new user_service_1.UserService(config);
39
+ service.request('error').subscribe({
40
+ error: err => {
41
+ expect(err).toBeInstanceOf(Error);
42
+ expect(err.message).toBe('Test error');
43
+ done();
44
+ },
45
+ });
46
+ });
47
+ });
@@ -63,9 +63,6 @@ export interface ProviderType {
63
63
  headers: Record<string, string | undefined>;
64
64
  getPath(...queryParams: unknown[]): string;
65
65
  }
66
- export interface ProviderTypeMockable {
67
- shouldUseMockData: boolean;
68
- }
69
66
  export interface HeaderType {
70
67
  shouldAddEncryptionHeader?: boolean;
71
68
  shouldAddClientIdHeader?: boolean;
@@ -88,6 +85,7 @@ export interface ServerErrorResponse {
88
85
  }
89
86
  export interface NetworkingConfig {
90
87
  baseUrl: string;
88
+ version?: string;
91
89
  isProd: boolean;
92
90
  clientId?: string;
93
91
  apiKey?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smess/networking",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Networking utilities and services for SMESS platform.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",