@goat-bravos/shared-lib-client 1.0.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 (39) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +579 -0
  3. package/dist/enums/error-code.enum.d.ts +11 -0
  4. package/dist/enums/error-code.enum.d.ts.map +1 -0
  5. package/dist/enums/error-code.enum.js +14 -0
  6. package/dist/enums/error-code.enum.js.map +1 -0
  7. package/dist/enums/http-status.enum.d.ts +13 -0
  8. package/dist/enums/http-status.enum.d.ts.map +1 -0
  9. package/dist/enums/http-status.enum.js +16 -0
  10. package/dist/enums/http-status.enum.js.map +1 -0
  11. package/dist/enums/localstorage-key.enum.d.ts +5 -0
  12. package/dist/enums/localstorage-key.enum.d.ts.map +1 -0
  13. package/dist/enums/localstorage-key.enum.js +8 -0
  14. package/dist/enums/localstorage-key.enum.js.map +1 -0
  15. package/dist/index.d.ts +11 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +30 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/interfaces/api-response.interface.d.ts +53 -0
  20. package/dist/interfaces/api-response.interface.d.ts.map +1 -0
  21. package/dist/interfaces/api-response.interface.js +2 -0
  22. package/dist/interfaces/api-response.interface.js.map +1 -0
  23. package/dist/interfaces/http-heades.interface.d.ts +9 -0
  24. package/dist/interfaces/http-heades.interface.d.ts.map +1 -0
  25. package/dist/interfaces/http-heades.interface.js +2 -0
  26. package/dist/interfaces/http-heades.interface.js.map +1 -0
  27. package/dist/interfaces/pagination.interface.d.ts +13 -0
  28. package/dist/interfaces/pagination.interface.d.ts.map +1 -0
  29. package/dist/interfaces/pagination.interface.js +2 -0
  30. package/dist/interfaces/pagination.interface.js.map +1 -0
  31. package/dist/services/rest/rest.config.d.ts +12 -0
  32. package/dist/services/rest/rest.config.d.ts.map +1 -0
  33. package/dist/services/rest/rest.config.js +5 -0
  34. package/dist/services/rest/rest.config.js.map +1 -0
  35. package/dist/services/rest/rest.service.d.ts +64 -0
  36. package/dist/services/rest/rest.service.d.ts.map +1 -0
  37. package/dist/services/rest/rest.service.js +112 -0
  38. package/dist/services/rest/rest.service.js.map +1 -0
  39. package/package.json +40 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bravos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,579 @@
1
+ # @intern-hub/shared-lib-client
2
+
3
+ A TypeScript library for Angular applications that provides shared utilities, interfaces, and services for making HTTP requests with a standardized API response format.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **REST Service**: A powerful HTTP client wrapper with and without interceptors
8
+ - 🔐 **Built-in Authentication**: Automatic token handling with configurable storage key
9
+ - 🔄 **Auto-Retry**: Configurable retry mechanism for failed requests
10
+ - 📦 **Type-Safe Interfaces**: Standardized API response formats with TypeScript
11
+ - 🔢 **Enums**: Pre-defined HTTP status codes, error codes, and storage keys
12
+ - 🎯 **Angular Integration**: Built specifically for Angular applications with dependency injection support
13
+ - 📝 **Full TypeScript Support**: Complete type definitions included
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @intern-hub/shared-lib-client
19
+ ```
20
+
21
+ ### Peer Dependencies
22
+
23
+ This library requires the following peer dependencies:
24
+
25
+ ```json
26
+ {
27
+ "@angular/common": "21.0.1",
28
+ "@angular/core": "21.1.0-rc.0",
29
+ "@angular/router": "21.0.1"
30
+ }
31
+ ```
32
+
33
+ ## Configuration
34
+
35
+ ### Step 1: Provide REST_CONFIG in Your Application
36
+
37
+ Before using the `RestService`, you need to provide the `REST_CONFIG` injection token in your Angular application:
38
+
39
+ ```typescript
40
+ import { ApplicationConfig } from '@angular/core';
41
+ import { provideHttpClient, withInterceptors } from '@angular/common/http';
42
+ import { provideRouter } from '@angular/router';
43
+ import { REST_CONFIG, RestConfig } from '@intern-hub/shared-lib-client';
44
+
45
+ export const appConfig: ApplicationConfig = {
46
+ providers: [
47
+ provideHttpClient(
48
+ // Add your interceptors here if needed
49
+ withInterceptors([yourInterceptor])
50
+ ),
51
+ provideRouter(routes),
52
+ {
53
+ provide: REST_CONFIG,
54
+ useValue: {
55
+ apiBaseUrl: 'https://api.example.com',
56
+ enableLogging: true,
57
+ internalAutoRetry: true,
58
+ retryAttempts: 3,
59
+ retryIntervalMs: 1000,
60
+ loginPath: '/login',
61
+ tokenKey: 'accessToken'
62
+ } as RestConfig
63
+ }
64
+ ]
65
+ };
66
+ ```
67
+
68
+ Or in a traditional NgModule:
69
+
70
+ ```typescript
71
+ import { NgModule } from '@angular/core';
72
+ import { HttpClientModule } from '@angular/common/http';
73
+ import { RouterModule } from '@angular/router';
74
+ import { REST_CONFIG, RestConfig } from '@intern-hub/shared-lib-client';
75
+
76
+ @NgModule({
77
+ imports: [HttpClientModule, RouterModule],
78
+ providers: [
79
+ {
80
+ provide: REST_CONFIG,
81
+ useValue: {
82
+ apiBaseUrl: 'https://api.example.com',
83
+ enableLogging: true,
84
+ internalAutoRetry: true,
85
+ retryAttempts: 3,
86
+ retryIntervalMs: 1000,
87
+ loginPath: '/login',
88
+ tokenKey: 'accessToken'
89
+ } as RestConfig
90
+ }
91
+ ]
92
+ })
93
+ export class AppModule { }
94
+ ```
95
+
96
+ ### REST_CONFIG Interface
97
+
98
+ ```typescript
99
+ interface RestConfig {
100
+ apiBaseUrl: string; // Base URL for internal API calls
101
+ enableLogging: boolean; // Enable/disable error logging
102
+ internalAutoRetry: boolean; // Enable auto-retry for internal calls
103
+ retryAttempts: number; // Number of retry attempts
104
+ retryIntervalMs: number; // Interval between retries in milliseconds
105
+ loginPath: string; // Path to redirect when no auth token found
106
+ tokenKey: string; // LocalStorage key for the authentication token
107
+ }
108
+ ```
109
+
110
+ ## Usage
111
+
112
+ ### RestService
113
+
114
+ The `RestService` provides two sets of HTTP methods:
115
+
116
+ 1. **External Methods** (`get`, `post`, `put`, `patch`, `delete`): Make requests without Angular interceptors - useful for third-party APIs
117
+ 2. **Internal Methods** (`getInternal`, `postInternal`, `putInternal`, `patchInternal`, `deleteInternal`): Make requests with Angular interceptors, automatically prepend the `apiBaseUrl`, and support automatic authentication
118
+
119
+ #### Example: External API Calls (Without Interceptors)
120
+
121
+ ```typescript
122
+ import { Component, inject } from '@angular/core';
123
+ import { RestService, ResponseApi } from '@intern-hub/shared-lib-client';
124
+
125
+ interface User {
126
+ id: number;
127
+ name: string;
128
+ email: string;
129
+ }
130
+
131
+ @Component({
132
+ selector: 'app-user',
133
+ template: `...`
134
+ })
135
+ export class UserComponent {
136
+ private restService = inject(RestService);
137
+
138
+ loadExternalUser() {
139
+ // GET request to external API (no interceptors)
140
+ this.restService.get<User>('https://external-api.com/users/1')
141
+ .subscribe({
142
+ next: (user) => console.log('User:', user),
143
+ error: (err) => console.error('Error:', err)
144
+ });
145
+ }
146
+
147
+ createExternalUser() {
148
+ const newUser = { name: 'John Doe', email: 'john@example.com' };
149
+
150
+ this.restService.post<User>(
151
+ 'https://external-api.com/users',
152
+ newUser
153
+ ).subscribe({
154
+ next: (user) => console.log('Created:', user),
155
+ error: (err) => console.error('Error:', err)
156
+ });
157
+ }
158
+ }
159
+ ```
160
+
161
+ #### Example: Internal API Calls (With Interceptors)
162
+
163
+ ```typescript
164
+ import { Component, inject } from '@angular/core';
165
+ import { RestService, ResponseApi, SuccessResponse } from '@intern-hub/shared-lib-client';
166
+
167
+ interface Product {
168
+ id: number;
169
+ name: string;
170
+ price: number;
171
+ }
172
+
173
+ @Component({
174
+ selector: 'app-product',
175
+ template: `...`
176
+ })
177
+ export class ProductComponent {
178
+ private restService = inject(RestService);
179
+
180
+ // If apiBaseUrl is 'https://api.example.com'
181
+ // This will call: https://api.example.com/api/products
182
+ loadProducts() {
183
+ // Second parameter `credentials: false` - no auth token required
184
+ this.restService.getInternal<ResponseApi<Product[]>>('/api/products', false)
185
+ .subscribe({
186
+ next: (response) => {
187
+ if (response.data) {
188
+ console.log('Products:', response.data);
189
+ }
190
+ },
191
+ error: (err) => console.error('Error:', err)
192
+ });
193
+ }
194
+
195
+ // With authentication - automatically adds Bearer token from localStorage
196
+ loadMyProducts() {
197
+ // Second parameter `credentials: true` - auth token will be added
198
+ this.restService.getInternal<ResponseApi<Product[]>>('/api/my-products', true)
199
+ .subscribe({
200
+ next: (response) => {
201
+ if (response.data) {
202
+ console.log('My Products:', response.data);
203
+ }
204
+ },
205
+ error: (err) => console.error('Error:', err)
206
+ });
207
+ }
208
+
209
+ createProduct() {
210
+ const newProduct = { name: 'Laptop', price: 999.99 };
211
+
212
+ // POST with authentication
213
+ this.restService.postInternal<ResponseApi<Product>>(
214
+ '/api/products',
215
+ newProduct,
216
+ true // credentials: true
217
+ ).subscribe({
218
+ next: (response) => console.log('Created:', response.data),
219
+ error: (err) => console.error('Error:', err)
220
+ });
221
+ }
222
+
223
+ updateProduct(id: number) {
224
+ const updates = { price: 899.99 };
225
+
226
+ this.restService.patchInternal<ResponseApi<Product>>(
227
+ `/api/products/${id}`,
228
+ updates,
229
+ true // credentials: true
230
+ ).subscribe({
231
+ next: (response) => console.log('Updated:', response.data),
232
+ error: (err) => console.error('Error:', err)
233
+ });
234
+ }
235
+
236
+ deleteProduct(id: number) {
237
+ this.restService.deleteInternal<ResponseApi<void>>(
238
+ `/api/products/${id}`,
239
+ true // credentials: true
240
+ ).subscribe({
241
+ next: () => console.log('Deleted successfully'),
242
+ error: (err) => console.error('Error:', err)
243
+ });
244
+ }
245
+ }
246
+ ```
247
+
248
+ #### Example: With Custom Headers and Query Params
249
+
250
+ ```typescript
251
+ loadProductsWithParams() {
252
+ const params = { category: 'electronics', sort: 'price' };
253
+ const headers = { 'X-Custom-Header': 'custom-value' };
254
+
255
+ // getInternal(path, credentials, params, headers)
256
+ this.restService.getInternal<ResponseApi<Product[]>>(
257
+ '/api/products',
258
+ true, // credentials
259
+ params, // query params
260
+ headers // custom headers
261
+ ).subscribe({
262
+ next: (response) => console.log('Products:', response.data),
263
+ error: (err) => console.error('Error:', err)
264
+ });
265
+ }
266
+ ```
267
+
268
+ ### Interfaces
269
+
270
+ #### API Response Interfaces
271
+
272
+ ```typescript
273
+ import {
274
+ ResponseApi,
275
+ SuccessResponse,
276
+ ErrorResponse,
277
+ ApiStatus,
278
+ ApiMetadata,
279
+ PaginatedResponse,
280
+ PaginatedData
281
+ } from '@intern-hub/shared-lib-client';
282
+
283
+ // Generic response structure
284
+ const response: ResponseApi<User> = {
285
+ status: null,
286
+ data: { id: 1, name: 'John' },
287
+ metaData: null
288
+ };
289
+
290
+ // Success response
291
+ const success: SuccessResponse<User> = {
292
+ status: null,
293
+ data: { id: 1, name: 'John' },
294
+ metaData: null
295
+ };
296
+
297
+ // Error response
298
+ const error: ErrorResponse = {
299
+ status: {
300
+ code: 'validation.error',
301
+ message: 'Validation failed',
302
+ errors: {
303
+ email: ['Email is required'],
304
+ name: ['Name must be at least 3 characters']
305
+ }
306
+ },
307
+ data: null,
308
+ metaData: {
309
+ requestId: 'abc-123',
310
+ traceId: 'xyz-789',
311
+ timestamp: 1234567890
312
+ }
313
+ };
314
+
315
+ // Paginated response
316
+ const paginated: PaginatedResponse<User> = {
317
+ status: null,
318
+ data: {
319
+ items: [
320
+ { id: 1, name: 'John' },
321
+ { id: 2, name: 'Jane' }
322
+ ],
323
+ totalItems: 100,
324
+ totalPages: 10
325
+ },
326
+ metaData: null
327
+ };
328
+ ```
329
+
330
+ #### HTTP Client Headers
331
+
332
+ ```typescript
333
+ import { HttpClientHeaders } from '@intern-hub/shared-lib-client';
334
+
335
+ const headers: HttpClientHeaders = {
336
+ 'Content-Type': 'application/json',
337
+ 'Authorization': 'Bearer token123',
338
+ 'X-Custom-Header': 'custom-value'
339
+ };
340
+ ```
341
+
342
+ ### Enums
343
+
344
+ #### HTTP Status Codes
345
+
346
+ ```typescript
347
+ import { HttpStatus } from '@intern-hub/shared-lib-client';
348
+
349
+ if (response.status === HttpStatus.OK) {
350
+ console.log('Success!');
351
+ }
352
+
353
+ // Available statuses:
354
+ // HttpStatus.OK = 200
355
+ // HttpStatus.CREATED = 201
356
+ // HttpStatus.NO_CONTENT = 204
357
+ // HttpStatus.BAD_REQUEST = 400
358
+ // HttpStatus.UNAUTHORIZED = 401
359
+ // HttpStatus.FORBIDDEN = 403
360
+ // HttpStatus.NOT_FOUND = 404
361
+ // HttpStatus.CONFLICT = 409
362
+ // HttpStatus.INTERNAL_SERVER_ERROR = 500
363
+ // HttpStatus.SERVICE_UNAVAILABLE = 503
364
+ ```
365
+
366
+ #### Error Codes
367
+
368
+ ```typescript
369
+ import { ErrorCode } from '@intern-hub/shared-lib-client';
370
+
371
+ if (error.status?.code === ErrorCode.UNAUTHORIZED) {
372
+ // Handle unauthorized
373
+ }
374
+
375
+ // Available error codes:
376
+ // ErrorCode.RESOURCE_NOT_FOUND = 'resource.not.found'
377
+ // ErrorCode.UNAUTHORIZED = 'unauthorized'
378
+ // ErrorCode.FORBIDDEN = 'forbidden'
379
+ // ErrorCode.BAD_REQUEST = 'bad.request'
380
+ // ErrorCode.INTERNAL_SERVER_ERROR = 'internal.server.error'
381
+ // ErrorCode.VALIDATION_ERROR = 'validation.error'
382
+ // ErrorCode.CONFLICT = 'conflict'
383
+ // ErrorCode.SERVICE_UNAVAILABLE = 'service.unavailable'
384
+ ```
385
+
386
+ #### Storage Keys
387
+
388
+ ```typescript
389
+ import { StorageKey } from '@intern-hub/shared-lib-client';
390
+
391
+ localStorage.setItem(StorageKey.ACCESS_TOKEN, 'token123');
392
+ const token = localStorage.getItem(StorageKey.ACCESS_TOKEN);
393
+
394
+ // Available keys:
395
+ // StorageKey.ACCESS_TOKEN = 'accessToken'
396
+ // StorageKey.CONTENT_TYPE = 'application/json'
397
+ ```
398
+
399
+ ## Complete Example: User Service
400
+
401
+ ```typescript
402
+ import { Injectable, inject } from '@angular/core';
403
+ import { Observable, map, catchError, throwError } from 'rxjs';
404
+ import {
405
+ RestService,
406
+ ResponseApi,
407
+ ErrorCode
408
+ } from '@intern-hub/shared-lib-client';
409
+
410
+ interface User {
411
+ id: number;
412
+ name: string;
413
+ email: string;
414
+ role: string;
415
+ }
416
+
417
+ @Injectable({ providedIn: 'root' })
418
+ export class UserService {
419
+ private restService = inject(RestService);
420
+
421
+ // Public endpoint - no authentication needed
422
+ getUsers(): Observable<User[]> {
423
+ return this.restService.getInternal<ResponseApi<User[]>>('/api/users', false)
424
+ .pipe(
425
+ map(response => response.data || []),
426
+ catchError(this.handleError)
427
+ );
428
+ }
429
+
430
+ // Protected endpoint - requires authentication
431
+ getCurrentUser(): Observable<User> {
432
+ return this.restService.getInternal<ResponseApi<User>>('/api/users/me', true)
433
+ .pipe(
434
+ map(response => {
435
+ if (!response.data) {
436
+ throw new Error('User not found');
437
+ }
438
+ return response.data;
439
+ }),
440
+ catchError(this.handleError)
441
+ );
442
+ }
443
+
444
+ createUser(user: Omit<User, 'id'>): Observable<User> {
445
+ return this.restService.postInternal<ResponseApi<User>>(
446
+ '/api/users',
447
+ user,
448
+ true // requires auth
449
+ ).pipe(
450
+ map(response => {
451
+ if (!response.data) {
452
+ throw new Error('Failed to create user');
453
+ }
454
+ return response.data;
455
+ }),
456
+ catchError(this.handleError)
457
+ );
458
+ }
459
+
460
+ updateUser(id: number, updates: Partial<User>): Observable<User> {
461
+ return this.restService.patchInternal<ResponseApi<User>>(
462
+ `/api/users/${id}`,
463
+ updates,
464
+ true // requires auth
465
+ ).pipe(
466
+ map(response => {
467
+ if (!response.data) {
468
+ throw new Error('Failed to update user');
469
+ }
470
+ return response.data;
471
+ }),
472
+ catchError(this.handleError)
473
+ );
474
+ }
475
+
476
+ deleteUser(id: number): Observable<void> {
477
+ return this.restService.deleteInternal<ResponseApi<void>>(
478
+ `/api/users/${id}`,
479
+ true // requires auth
480
+ ).pipe(
481
+ map(() => undefined),
482
+ catchError(this.handleError)
483
+ );
484
+ }
485
+
486
+ private handleError(error: any): Observable<never> {
487
+ console.error('API Error:', error);
488
+
489
+ if (error.status?.code === ErrorCode.UNAUTHORIZED) {
490
+ // User will be automatically redirected to loginPath
491
+ }
492
+
493
+ return throwError(() => error);
494
+ }
495
+ }
496
+ ```
497
+
498
+ ## API Reference
499
+
500
+ ### RestService Methods
501
+
502
+ #### External Methods (Without Interceptors)
503
+
504
+ | Method | Signature |
505
+ |--------|-----------|
506
+ | `get` | `get<T>(path: string, params?: object, headers?: object): Observable<T>` |
507
+ | `post` | `post<T>(path: string, body: unknown, params?: object, headers?: object): Observable<T>` |
508
+ | `put` | `put<T>(path: string, body: unknown, params?: object, headers?: object): Observable<T>` |
509
+ | `patch` | `patch<T>(path: string, body: unknown, params?: object, headers?: object): Observable<T>` |
510
+ | `delete` | `delete<T>(path: string, params?: object, headers?: object): Observable<T>` |
511
+
512
+ #### Internal Methods (With Interceptors)
513
+
514
+ | Method | Signature |
515
+ |--------|-----------|
516
+ | `getInternal` | `getInternal<T>(path: string, credentials?: boolean, params?: object, headers?: object): Observable<T>` |
517
+ | `postInternal` | `postInternal<T>(path: string, body: unknown, credentials?: boolean, params?: object, headers?: object): Observable<T>` |
518
+ | `putInternal` | `putInternal<T>(path: string, body: unknown, credentials?: boolean, params?: object, headers?: object): Observable<T>` |
519
+ | `patchInternal` | `patchInternal<T>(path: string, body: unknown, credentials?: boolean, params?: object, headers?: object): Observable<T>` |
520
+ | `deleteInternal` | `deleteInternal<T>(path: string, credentials?: boolean, params?: object, headers?: object): Observable<T>` |
521
+
522
+ **Note:** When `credentials` is `true`, the service automatically:
523
+ 1. Retrieves the token from `localStorage` using the configured `tokenKey`
524
+ 2. Adds an `Authorization: Bearer <token>` header to the request
525
+ 3. Redirects to `loginPath` if no token is found
526
+
527
+ ## Development
528
+
529
+ ### Build the Library
530
+
531
+ ```bash
532
+ npm run build
533
+ ```
534
+
535
+ This will compile the TypeScript files and generate the distributable files in the `dist` folder.
536
+
537
+ ### Project Structure
538
+
539
+ ```
540
+ intern-fe-library/
541
+ ├── src/
542
+ │ ├── enums/
543
+ │ │ ├── error-code.enum.ts
544
+ │ │ ├── http-status.enum.ts
545
+ │ │ └── localstorage-key.enum.ts
546
+ │ ├── interfaces/
547
+ │ │ ├── api-response.interface.ts
548
+ │ │ ├── http-heades.interface.ts
549
+ │ │ └── pagination.interface.ts
550
+ │ ├── services/
551
+ │ │ └── rest/
552
+ │ │ ├── rest.config.ts
553
+ │ │ └── rest.service.ts
554
+ │ └── index.ts
555
+ ├── package.json
556
+ ├── tsconfig.json
557
+ └── README.md
558
+ ```
559
+
560
+ ## TypeScript Configuration
561
+
562
+ This library is built with the following TypeScript features:
563
+
564
+ - **Decorators**: Full support for Angular decorators (`experimentalDecorators`, `emitDecoratorMetadata`)
565
+ - **Strict Mode**: Enabled for better type safety
566
+ - **Module System**: Uses `NodeNext` for modern ES modules
567
+ - **Declaration Files**: Generates `.d.ts` files for TypeScript consumers
568
+
569
+ ## License
570
+
571
+ ISC
572
+
573
+ ## Author
574
+
575
+ intern-hub
576
+
577
+ ## Contributing
578
+
579
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,11 @@
1
+ export declare enum ErrorCode {
2
+ RESOURCE_NOT_FOUND = "resource.not.found",
3
+ UNAUTHORIZED = "unauthorized",
4
+ FORBIDDEN = "forbidden",
5
+ BAD_REQUEST = "bad.request",
6
+ INTERNAL_SERVER_ERROR = "internal.server.error",
7
+ VALIDATION_ERROR = "validation.error",
8
+ CONFLICT = "conflict",
9
+ SERVICE_UNAVAILABLE = "service.unavailable"
10
+ }
11
+ //# sourceMappingURL=error-code.enum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-code.enum.d.ts","sourceRoot":"","sources":["../../src/enums/error-code.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACjB,kBAAkB,uBAAuB;IACzC,YAAY,iBAAiB;IAC7B,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,qBAAqB,0BAA0B;IAC/C,gBAAgB,qBAAqB;IACrC,QAAQ,aAAa;IACrB,mBAAmB,wBAAwB;CAC9C"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ErrorCode = void 0;
4
+ var ErrorCode;
5
+ (function (ErrorCode) {
6
+ ErrorCode["RESOURCE_NOT_FOUND"] = "resource.not.found";
7
+ ErrorCode["UNAUTHORIZED"] = "unauthorized";
8
+ ErrorCode["FORBIDDEN"] = "forbidden";
9
+ ErrorCode["BAD_REQUEST"] = "bad.request";
10
+ ErrorCode["INTERNAL_SERVER_ERROR"] = "internal.server.error";
11
+ ErrorCode["VALIDATION_ERROR"] = "validation.error";
12
+ ErrorCode["CONFLICT"] = "conflict";
13
+ ErrorCode["SERVICE_UNAVAILABLE"] = "service.unavailable";
14
+ })(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-code.enum.js","sourceRoot":"","sources":["../../src/enums/error-code.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,SASX;AATD,WAAY,SAAS;IACjB,sDAAyC,CAAA;IACzC,0CAA6B,CAAA;IAC7B,oCAAuB,CAAA;IACvB,wCAA2B,CAAA;IAC3B,4DAA+C,CAAA;IAC/C,kDAAqC,CAAA;IACrC,kCAAqB,CAAA;IACrB,wDAA2C,CAAA;AAC/C,CAAC,EATW,SAAS,yBAAT,SAAS,QASpB"}
@@ -0,0 +1,13 @@
1
+ export declare enum HttpStatus {
2
+ OK = 200,
3
+ CREATED = 201,
4
+ NO_CONTENT = 204,
5
+ BAD_REQUEST = 400,
6
+ UNAUTHORIZED = 401,
7
+ FORBIDDEN = 403,
8
+ NOT_FOUND = 404,
9
+ CONFLICT = 409,
10
+ INTERNAL_SERVER_ERROR = 500,
11
+ SERVICE_UNAVAILABLE = 503
12
+ }
13
+ //# sourceMappingURL=http-status.enum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-status.enum.d.ts","sourceRoot":"","sources":["../../src/enums/http-status.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,EAAE,MAAM;IACR,OAAO,MAAM;IACb,UAAU,MAAM;IAChB,WAAW,MAAM;IACjB,YAAY,MAAM;IAClB,SAAS,MAAM;IACf,SAAS,MAAM;IACf,QAAQ,MAAM;IACd,qBAAqB,MAAM;IAC3B,mBAAmB,MAAM;CAC5B"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpStatus = void 0;
4
+ var HttpStatus;
5
+ (function (HttpStatus) {
6
+ HttpStatus[HttpStatus["OK"] = 200] = "OK";
7
+ HttpStatus[HttpStatus["CREATED"] = 201] = "CREATED";
8
+ HttpStatus[HttpStatus["NO_CONTENT"] = 204] = "NO_CONTENT";
9
+ HttpStatus[HttpStatus["BAD_REQUEST"] = 400] = "BAD_REQUEST";
10
+ HttpStatus[HttpStatus["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
11
+ HttpStatus[HttpStatus["FORBIDDEN"] = 403] = "FORBIDDEN";
12
+ HttpStatus[HttpStatus["NOT_FOUND"] = 404] = "NOT_FOUND";
13
+ HttpStatus[HttpStatus["CONFLICT"] = 409] = "CONFLICT";
14
+ HttpStatus[HttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
15
+ HttpStatus[HttpStatus["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
16
+ })(HttpStatus || (exports.HttpStatus = HttpStatus = {}));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-status.enum.js","sourceRoot":"","sources":["../../src/enums/http-status.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,UAWX;AAXD,WAAY,UAAU;IAClB,yCAAQ,CAAA;IACR,mDAAa,CAAA;IACb,yDAAgB,CAAA;IAChB,2DAAiB,CAAA;IACjB,6DAAkB,CAAA;IAClB,uDAAe,CAAA;IACf,uDAAe,CAAA;IACf,qDAAc,CAAA;IACd,+EAA2B,CAAA;IAC3B,2EAAyB,CAAA;AAC7B,CAAC,EAXW,UAAU,0BAAV,UAAU,QAWrB"}
@@ -0,0 +1,5 @@
1
+ export declare enum StorageKey {
2
+ ACCESS_TOKEN = "accessToken",
3
+ CONTENT_TYPE = "application/json"
4
+ }
5
+ //# sourceMappingURL=localstorage-key.enum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localstorage-key.enum.d.ts","sourceRoot":"","sources":["../../src/enums/localstorage-key.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IAClB,YAAY,gBAAgB;IAC5B,YAAY,qBAAqB;CACpC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorageKey = void 0;
4
+ var StorageKey;
5
+ (function (StorageKey) {
6
+ StorageKey["ACCESS_TOKEN"] = "accessToken";
7
+ StorageKey["CONTENT_TYPE"] = "application/json";
8
+ })(StorageKey || (exports.StorageKey = StorageKey = {}));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localstorage-key.enum.js","sourceRoot":"","sources":["../../src/enums/localstorage-key.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,UAGX;AAHD,WAAY,UAAU;IAClB,0CAA4B,CAAA;IAC5B,+CAAiC,CAAA;AACrC,CAAC,EAHW,UAAU,0BAAV,UAAU,QAGrB"}
@@ -0,0 +1,11 @@
1
+ export * from './enums/error-code.enum';
2
+ export * from './enums/http-status.enum';
3
+ export * from './interfaces/api-response.interface';
4
+ export * from './interfaces/http-heades.interface';
5
+ export * from './interfaces/pagination.interface';
6
+ export * from './services/rest/rest.config';
7
+ export * from './services/rest/rest.service';
8
+ export * from './enums/http-status.enum';
9
+ export * from './enums/error-code.enum';
10
+ export * from './enums/localstorage-key.enum';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAGlD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAG5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ // Export các enums
18
+ __exportStar(require("./enums/error-code.enum"), exports);
19
+ __exportStar(require("./enums/http-status.enum"), exports);
20
+ // Export các interface (HttpClientHeaders, ApiResponse)
21
+ __exportStar(require("./interfaces/api-response.interface"), exports);
22
+ __exportStar(require("./interfaces/http-heades.interface"), exports);
23
+ __exportStar(require("./interfaces/pagination.interface"), exports);
24
+ // Export Service
25
+ __exportStar(require("./services/rest/rest.config"), exports);
26
+ __exportStar(require("./services/rest/rest.service"), exports);
27
+ // Export ENUM
28
+ __exportStar(require("./enums/http-status.enum"), exports);
29
+ __exportStar(require("./enums/error-code.enum"), exports);
30
+ __exportStar(require("./enums/localstorage-key.enum"), exports);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mBAAmB;AACnB,0DAAwC;AACxC,2DAAyC;AAEzC,wDAAwD;AACxD,sEAAoD;AACpD,qEAAmD;AACnD,oEAAkD;AAElD,iBAAiB;AACjB,8DAA2C;AAC3C,+DAA4C;AAE5C,cAAc;AACd,2DAAyC;AACzC,0DAAwC;AACxC,gEAA8C"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * API Status Interface
3
+ */
4
+ export interface ApiStatus {
5
+ code: string;
6
+ message: string;
7
+ errors?: Record<string, string[]> | null;
8
+ }
9
+ /**
10
+ * API Metadata Interface
11
+ */
12
+ export interface ApiMetadata {
13
+ requestId?: string;
14
+ traceId?: string;
15
+ signature?: string | null;
16
+ timestamp?: number;
17
+ [key: string]: any;
18
+ }
19
+ /**
20
+ * API Metadata Interface
21
+ */
22
+ export interface ApiMetadata {
23
+ requestId?: string;
24
+ traceId?: string;
25
+ signature?: string | null;
26
+ timestamp?: number;
27
+ [key: string]: any;
28
+ }
29
+ /**
30
+ * Base Response API Interface
31
+ */
32
+ export interface ResponseApi<T = any> {
33
+ status: ApiStatus | null;
34
+ data: T | null;
35
+ metaData: ApiMetadata | null;
36
+ }
37
+ /**
38
+ * Success Response
39
+ */
40
+ export interface SuccessResponse<T = any> extends ResponseApi<T> {
41
+ status: null;
42
+ data: T;
43
+ metaData: null;
44
+ }
45
+ /**
46
+ * Error Response
47
+ */
48
+ export interface ErrorResponse extends ResponseApi<null> {
49
+ status: ApiStatus;
50
+ data: null;
51
+ metaData: ApiMetadata;
52
+ }
53
+ //# sourceMappingURL=api-response.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-response.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/api-response.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAChC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,WAAW,CAAC,CAAC,CAAC;IAC5D,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,IAAI,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,WAAW,CAAC,IAAI,CAAC;IACpD,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,WAAW,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-response.interface.js","sourceRoot":"","sources":["../../src/interfaces/api-response.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * HTTP Client Headers Interface
3
+ */
4
+ export interface HttpClientHeaders {
5
+ 'Content-Type'?: string | undefined;
6
+ 'Authorization'?: `Bearer ${string}` | undefined;
7
+ [key: string]: string | undefined;
8
+ }
9
+ //# sourceMappingURL=http-heades.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-heades.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/http-heades.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,eAAe,CAAC,EAAE,UAAU,MAAM,EAAE,GAAG,SAAS,CAAC;IACjD,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-heades.interface.js","sourceRoot":"","sources":["../../src/interfaces/http-heades.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { ResponseApi } from "./api-response.interface";
2
+ /**
3
+ * Paginated Response
4
+ */
5
+ export interface PaginatedData<T = any> {
6
+ items: T[];
7
+ totalItems: number;
8
+ totalPages: number;
9
+ }
10
+ export interface PaginatedResponse<T = any> extends ResponseApi<PaginatedData<T>> {
11
+ data: PaginatedData<T> | null;
12
+ }
13
+ //# sourceMappingURL=pagination.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/pagination.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,0BAA0B,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,GAAG;IAClC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAC7E,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CACjC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.interface.js","sourceRoot":"","sources":["../../src/interfaces/pagination.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { InjectionToken } from "@angular/core";
2
+ export interface RestConfig {
3
+ apiBaseUrl: string;
4
+ enableLogging: boolean;
5
+ internalAutoRetry: boolean;
6
+ retryAttempts: number;
7
+ retryIntervalMs: number;
8
+ loginPath: string;
9
+ tokenKey: string;
10
+ }
11
+ export declare const REST_CONFIG: InjectionToken<RestConfig>;
12
+ //# sourceMappingURL=rest.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.config.d.ts","sourceRoot":"","sources":["../../../src/services/rest/rest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,4BAAgD,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REST_CONFIG = void 0;
4
+ const core_1 = require("@angular/core");
5
+ exports.REST_CONFIG = new core_1.InjectionToken('REST_CONFIG');
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.config.js","sourceRoot":"","sources":["../../../src/services/rest/rest.config.ts"],"names":[],"mappings":";;;AAAA,wCAA6C;AAYhC,QAAA,WAAW,GAAG,IAAI,qBAAc,CAAa,aAAa,CAAC,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { HttpBackend, HttpClient } from "@angular/common/http";
2
+ import { Observable } from "rxjs";
3
+ import { Router } from "@angular/router";
4
+ import type { RestConfig } from "./rest.config";
5
+ export declare class RestService {
6
+ private config;
7
+ private router;
8
+ private readonly httpBackend;
9
+ private readonly httpClient;
10
+ constructor(config: RestConfig, router: Router, httpClient: HttpClient, httpBackend: HttpBackend);
11
+ private requestWithoutInterceptor;
12
+ get<T>(path: string, params?: {
13
+ [param: string]: string | string[];
14
+ }, headers?: {
15
+ [header: string]: string;
16
+ }): Observable<T>;
17
+ post<T>(path: string, body: unknown, params?: {
18
+ [param: string]: string | string[];
19
+ }, headers?: {
20
+ [header: string]: string;
21
+ }): Observable<T>;
22
+ put<T>(path: string, body: unknown, params?: {
23
+ [param: string]: string | string[];
24
+ }, headers?: {
25
+ [header: string]: string;
26
+ }): Observable<T>;
27
+ patch<T>(path: string, body: unknown, params?: {
28
+ [param: string]: string | string[];
29
+ }, headers?: {
30
+ [header: string]: string;
31
+ }): Observable<T>;
32
+ delete<T>(path: string, params?: {
33
+ [param: string]: string | string[];
34
+ }, headers?: {
35
+ [header: string]: string;
36
+ }): Observable<T>;
37
+ private requestWithInterceptor;
38
+ getInternal<T>(path: string, credentials?: boolean, params?: {
39
+ [param: string]: string | string[];
40
+ }, headers?: {
41
+ [header: string]: string;
42
+ }): Observable<T>;
43
+ postInternal<T>(path: string, body: unknown, credentials?: boolean, params?: {
44
+ [param: string]: string | string[];
45
+ }, headers?: {
46
+ [header: string]: string;
47
+ }): Observable<T>;
48
+ putInternal<T>(path: string, body: unknown, credentials?: boolean, params?: {
49
+ [param: string]: string | string[];
50
+ }, headers?: {
51
+ [header: string]: string;
52
+ }): Observable<T>;
53
+ patchInternal<T>(path: string, body: unknown, credentials?: boolean, params?: {
54
+ [param: string]: string | string[];
55
+ }, headers?: {
56
+ [header: string]: string;
57
+ }): Observable<T>;
58
+ deleteInternal<T>(path: string, credentials?: boolean, params?: {
59
+ [param: string]: string | string[];
60
+ }, headers?: {
61
+ [header: string]: string;
62
+ }): Observable<T>;
63
+ }
64
+ //# sourceMappingURL=rest.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.service.d.ts","sourceRoot":"","sources":["../../../src/services/rest/rest.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RestService = void 0;
16
+ const http_1 = require("@angular/common/http");
17
+ const rxjs_1 = require("rxjs");
18
+ const operators_1 = require("rxjs/operators");
19
+ const core_1 = require("@angular/core");
20
+ const router_1 = require("@angular/router");
21
+ const rest_config_1 = require("./rest.config");
22
+ let RestService = class RestService {
23
+ config;
24
+ router;
25
+ httpBackend;
26
+ httpClient;
27
+ constructor(config, router, httpClient, httpBackend) {
28
+ this.config = config;
29
+ this.router = router;
30
+ this.httpClient = httpClient;
31
+ this.httpBackend = new http_1.HttpClient(httpBackend);
32
+ }
33
+ requestWithoutInterceptor(method, path, body, params, headers = { 'Content-Type': 'application/json' }) {
34
+ const httpParams = new http_1.HttpParams({
35
+ fromObject: params || {}
36
+ });
37
+ return this.httpBackend.request(method, path, {
38
+ headers: headers,
39
+ body: body,
40
+ params: httpParams,
41
+ });
42
+ }
43
+ get(path, params, headers = { 'Content-Type': 'application/json' }) {
44
+ return this.requestWithoutInterceptor('GET', path, undefined, params, headers);
45
+ }
46
+ post(path, body, params, headers = { 'Content-Type': 'application/json' }) {
47
+ return this.requestWithoutInterceptor('POST', path, body, params, headers);
48
+ }
49
+ put(path, body, params, headers = { 'Content-Type': 'application/json' }) {
50
+ return this.requestWithoutInterceptor('PUT', path, body, params, headers);
51
+ }
52
+ patch(path, body, params, headers = { 'Content-Type': 'application/json' }) {
53
+ return this.requestWithoutInterceptor('PATCH', path, body, params, headers);
54
+ }
55
+ delete(path, params, headers = { 'Content-Type': 'application/json' }) {
56
+ return this.requestWithoutInterceptor('DELETE', path, undefined, params, headers);
57
+ }
58
+ requestWithInterceptor(method, path, credentials = false, body, params, headers = { 'Content-Type': 'application/json' }) {
59
+ const httpParams = new http_1.HttpParams({
60
+ fromObject: params || {}
61
+ });
62
+ if (credentials) {
63
+ const token = localStorage.getItem(this.config.tokenKey);
64
+ if (!token) {
65
+ this.router.navigate([this.config.loginPath]);
66
+ return (0, rxjs_1.throwError)(() => new Error('No authentication token found'));
67
+ }
68
+ headers = { ...headers, 'Authorization': `Bearer ${token}` };
69
+ }
70
+ let request$ = this.httpClient.request(method, this.config.apiBaseUrl + path, {
71
+ headers: headers,
72
+ body: body,
73
+ params: httpParams,
74
+ });
75
+ // Handle auto retry if enabled
76
+ if (this.config.internalAutoRetry && this.config.retryAttempts > 0) {
77
+ request$ = request$.pipe((0, operators_1.retry)({
78
+ count: this.config.retryAttempts,
79
+ delay: this.config.retryIntervalMs
80
+ }), (0, operators_1.catchError)((error) => {
81
+ if (this.config.enableLogging) {
82
+ console.error(`Request failed after ${this.config.retryAttempts} retries:`, error);
83
+ }
84
+ return (0, rxjs_1.throwError)(() => error);
85
+ }));
86
+ }
87
+ return request$;
88
+ }
89
+ getInternal(path, credentials = false, params, headers = { 'Content-Type': 'application/json' }) {
90
+ return this.requestWithInterceptor('GET', path, credentials, undefined, params, headers);
91
+ }
92
+ postInternal(path, body, credentials = false, params, headers = { 'Content-Type': 'application/json' }) {
93
+ return this.requestWithInterceptor('POST', path, credentials, body, params, headers);
94
+ }
95
+ putInternal(path, body, credentials = false, params, headers = { 'Content-Type': 'application/json' }) {
96
+ return this.requestWithInterceptor('PUT', path, credentials, body, params, headers);
97
+ }
98
+ patchInternal(path, body, credentials = false, params, headers = { 'Content-Type': 'application/json' }) {
99
+ return this.requestWithInterceptor('PATCH', path, credentials, body, params, headers);
100
+ }
101
+ deleteInternal(path, credentials = false, params, headers = { 'Content-Type': 'application/json' }) {
102
+ return this.requestWithInterceptor('DELETE', path, credentials, undefined, params, headers);
103
+ }
104
+ };
105
+ exports.RestService = RestService;
106
+ exports.RestService = RestService = __decorate([
107
+ (0, core_1.Injectable)({ providedIn: 'root' }),
108
+ __param(0, (0, core_1.Inject)(rest_config_1.REST_CONFIG)),
109
+ __metadata("design:paramtypes", [Object, router_1.Router,
110
+ http_1.HttpClient,
111
+ http_1.HttpBackend])
112
+ ], RestService);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.service.js","sourceRoot":"","sources":["../../../src/services/rest/rest.service.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@goat-bravos/shared-lib-client",
3
+ "version": "1.0.0",
4
+ "peerDependencies": {
5
+ "@angular/common": "21.0.1",
6
+ "@angular/core": "21.1.0-rc.0",
7
+ "@angular/router": "21.0.1"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/Bravos-World/intern-shared-lib"
12
+ },
13
+ "description": "Library containing shared HttpClientHeaders and ApiResponse formats",
14
+ "main": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "typescript",
26
+ "api",
27
+ "http",
28
+ "response",
29
+ "shared"
30
+ ],
31
+ "author": "intern-hub",
32
+ "license": "ISC",
33
+ "devDependencies": {
34
+ "@angular/common": "^21.1.1",
35
+ "@angular/core": "^21.1.1",
36
+ "@angular/router": "^21.1.1",
37
+ "rxjs": "^7.8.2",
38
+ "typescript": "^5.9.3"
39
+ }
40
+ }