@ichgamer999/wmctest 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -203,3 +203,145 @@ npm run build:lib
203
203
  ## License
204
204
 
205
205
  MIT
206
+
207
+ ## BackendService (NEW in v1.0.1)
208
+
209
+ Generic HTTP service for backend communication with automatic JWT authentication.
210
+
211
+ ### Basic Usage
212
+
213
+ ```typescript
214
+ import { Component, inject } from '@angular/core';
215
+ import { BackendService } from '@yourusername/angular-auth-template';
216
+
217
+ interface User {
218
+ id: number;
219
+ name: string;
220
+ email: string;
221
+ }
222
+
223
+ @Component({
224
+ selector: 'app-users',
225
+ template: `
226
+ @for (user of users(); track user.id) {
227
+ <div>{{ user.name }}</div>
228
+ }
229
+ `
230
+ })
231
+ export class UsersComponent {
232
+ backendService = inject(BackendService);
233
+ users = signal<User[]>([]);
234
+
235
+ ngOnInit() {
236
+ // GET request with automatic JWT token
237
+ this.backendService.get<User[]>('/users').subscribe(
238
+ users => this.users.set(users)
239
+ );
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### Available Methods
245
+
246
+ ```typescript
247
+ // GET request
248
+ backendService.get<T>(endpoint: string, params?: Record<string, string | number>)
249
+
250
+ // POST request
251
+ backendService.post<T>(endpoint: string, body: any)
252
+
253
+ // PUT request
254
+ backendService.put<T>(endpoint: string, body: any)
255
+
256
+ // PATCH request
257
+ backendService.patch<T>(endpoint: string, body: any)
258
+
259
+ // DELETE request
260
+ backendService.delete<T>(endpoint: string)
261
+
262
+ // GET with standardized response
263
+ backendService.getWithResponse<T>(endpoint: string, params?)
264
+
265
+ // POST with standardized response
266
+ backendService.postWithResponse<T>(endpoint: string, body: any)
267
+
268
+ // Upload file
269
+ backendService.uploadFile<T>(endpoint: string, file: File, additionalData?)
270
+
271
+ // Download file
272
+ backendService.downloadFile(endpoint: string): Observable<Blob>
273
+ ```
274
+
275
+ ### Examples
276
+
277
+ **With Query Parameters:**
278
+ ```typescript
279
+ backendService.get<User[]>('/users', { page: 1, limit: 10 }).subscribe();
280
+ ```
281
+
282
+ **Create Resource:**
283
+ ```typescript
284
+ const newUser = { name: 'John', email: 'john@example.com' };
285
+ backendService.post<User>('/users', newUser).subscribe();
286
+ ```
287
+
288
+ **Update Resource:**
289
+ ```typescript
290
+ const updates = { name: 'Jane' };
291
+ backendService.put<User>('/users/123', updates).subscribe();
292
+ ```
293
+
294
+ **Delete Resource:**
295
+ ```typescript
296
+ backendService.delete<void>('/users/123').subscribe();
297
+ ```
298
+
299
+ **File Upload:**
300
+ ```typescript
301
+ const file = event.target.files[0];
302
+ backendService.uploadFile('/upload', file, { category: 'profile' }).subscribe();
303
+ ```
304
+
305
+ **File Download:**
306
+ ```typescript
307
+ backendService.downloadFile('/export/users').subscribe(blob => {
308
+ const url = window.URL.createObjectURL(blob);
309
+ const a = document.createElement('a');
310
+ a.href = url;
311
+ a.download = 'users.csv';
312
+ a.click();
313
+ });
314
+ ```
315
+
316
+ ### ApiResponse Interface
317
+
318
+ For standardized API responses:
319
+
320
+ ```typescript
321
+ interface ApiResponse<T> {
322
+ data: T;
323
+ message?: string;
324
+ success: boolean;
325
+ }
326
+
327
+ // Usage
328
+ backendService.getWithResponse<User[]>('/users').subscribe(response => {
329
+ if (response.success) {
330
+ console.log(response.data);
331
+ console.log(response.message);
332
+ }
333
+ });
334
+ ```
335
+
336
+ ### Configuration
337
+
338
+ Set your API base URL:
339
+
340
+ ```typescript
341
+ ngOnInit() {
342
+ this.backendService.baseUrl = 'https://api.example.com';
343
+ }
344
+ ```
345
+
346
+ **Note:** All requests automatically include the JWT token via `authInterceptor`.
347
+
@@ -0,0 +1,10 @@
1
+ import { BackendService } from './backend.service';
2
+ export declare class BackendDemoComponent {
3
+ backendService: BackendService;
4
+ response: import("@angular/core").WritableSignal<any>;
5
+ getUsers(): void;
6
+ createUser(): void;
7
+ updateUser(): void;
8
+ deleteUser(): void;
9
+ }
10
+ //# sourceMappingURL=backend-demo.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-demo.component.d.ts","sourceRoot":"","sources":["../../../src/app/backend/backend-demo.component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQnD,qBAiIa,oBAAoB;IAC/B,cAAc,iBAA0B;IACxC,QAAQ,8CAAqB;IAE7B,QAAQ;IAQR,UAAU;IAaV,UAAU;IAaV,UAAU;CAOX"}
@@ -0,0 +1,172 @@
1
+ import { __decorate } from "tslib";
2
+ import { Component, inject, signal } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import { BackendService } from './backend.service';
5
+ let BackendDemoComponent = class BackendDemoComponent {
6
+ backendService = inject(BackendService);
7
+ response = signal(null);
8
+ getUsers() {
9
+ this.response.set(null);
10
+ this.backendService.get('/users').subscribe({
11
+ next: (users) => this.response.set(users)
12
+ });
13
+ }
14
+ createUser() {
15
+ this.response.set(null);
16
+ const newUser = {
17
+ name: 'John Doe',
18
+ email: 'john@example.com'
19
+ };
20
+ this.backendService.post('/users', newUser).subscribe({
21
+ next: (user) => this.response.set(user)
22
+ });
23
+ }
24
+ updateUser() {
25
+ this.response.set(null);
26
+ const updatedUser = {
27
+ name: 'Jane Doe',
28
+ email: 'jane@example.com'
29
+ };
30
+ this.backendService.put('/users/1', updatedUser).subscribe({
31
+ next: (user) => this.response.set(user)
32
+ });
33
+ }
34
+ deleteUser() {
35
+ this.response.set(null);
36
+ this.backendService.delete('/users/1').subscribe({
37
+ next: () => this.response.set({ message: 'User deleted successfully' })
38
+ });
39
+ }
40
+ };
41
+ BackendDemoComponent = __decorate([
42
+ Component({
43
+ selector: 'app-backend-demo',
44
+ standalone: true,
45
+ imports: [CommonModule],
46
+ template: `
47
+ <div class="demo-container">
48
+ <h2>Backend Service Demo</h2>
49
+ <p class="subtitle">Using Signals for reactive state management</p>
50
+
51
+ <div class="actions">
52
+ <button (click)="getUsers()">Get Users</button>
53
+ <button (click)="createUser()">Create User</button>
54
+ <button (click)="updateUser()">Update User</button>
55
+ <button (click)="deleteUser()">Delete User</button>
56
+ </div>
57
+
58
+ @if (backendService.loading()) {
59
+ <div class="loading">Loading...</div>
60
+ }
61
+
62
+ @if (backendService.error()) {
63
+ <div class="error">
64
+ {{ backendService.error() }}
65
+ <button (click)="backendService.clearError()">✕</button>
66
+ </div>
67
+ }
68
+
69
+ @if (response()) {
70
+ <div class="response">
71
+ <h3>Response:</h3>
72
+ <pre>{{ response() | json }}</pre>
73
+ </div>
74
+ }
75
+
76
+ <div class="info">
77
+ <h3>Features:</h3>
78
+ <ul>
79
+ <li>✅ Global loading state with Signal</li>
80
+ <li>✅ Global error state with Signal</li>
81
+ <li>✅ Automatic loading/error management</li>
82
+ <li>✅ Type-safe API calls</li>
83
+ </ul>
84
+ </div>
85
+ </div>
86
+ `,
87
+ styles: [`
88
+ .demo-container {
89
+ padding: 2rem;
90
+ max-width: 800px;
91
+ margin: 0 auto;
92
+ }
93
+
94
+ .subtitle {
95
+ color: #666;
96
+ margin-bottom: 2rem;
97
+ }
98
+
99
+ .actions {
100
+ display: flex;
101
+ gap: 1rem;
102
+ margin: 2rem 0;
103
+ flex-wrap: wrap;
104
+ }
105
+
106
+ button {
107
+ padding: 0.75rem 1.5rem;
108
+ background: #007bff;
109
+ color: white;
110
+ border: none;
111
+ border-radius: 4px;
112
+ cursor: pointer;
113
+ }
114
+
115
+ button:hover {
116
+ background: #0056b3;
117
+ }
118
+
119
+ .loading, .error, .response, .info {
120
+ padding: 1rem;
121
+ margin: 1rem 0;
122
+ border-radius: 4px;
123
+ }
124
+
125
+ .loading {
126
+ background: #e3f2fd;
127
+ color: #1976d2;
128
+ font-weight: 500;
129
+ }
130
+
131
+ .error {
132
+ background: #ffebee;
133
+ color: #c62828;
134
+ display: flex;
135
+ justify-content: space-between;
136
+ align-items: center;
137
+ }
138
+
139
+ .error button {
140
+ background: transparent;
141
+ color: #c62828;
142
+ padding: 0.25rem 0.5rem;
143
+ font-size: 1.2rem;
144
+ }
145
+
146
+ .response {
147
+ background: #f5f5f5;
148
+ border: 1px solid #ddd;
149
+ }
150
+
151
+ .info {
152
+ background: #e8f5e9;
153
+ border-left: 4px solid #4caf50;
154
+ }
155
+
156
+ .info ul {
157
+ margin: 0.5rem 0 0;
158
+ padding-left: 1.5rem;
159
+ }
160
+
161
+ .info li {
162
+ margin: 0.5rem 0;
163
+ }
164
+
165
+ pre {
166
+ overflow-x: auto;
167
+ margin: 0.5rem 0 0;
168
+ }
169
+ `]
170
+ })
171
+ ], BackendDemoComponent);
172
+ export { BackendDemoComponent };
@@ -0,0 +1,25 @@
1
+ import { Observable } from 'rxjs';
2
+ export interface ApiResponse<T> {
3
+ data: T;
4
+ message?: string;
5
+ success: boolean;
6
+ }
7
+ export declare class BackendService {
8
+ private readonly http;
9
+ baseUrl: string;
10
+ private _loading;
11
+ private _error;
12
+ readonly loading: import("@angular/core").Signal<boolean>;
13
+ readonly error: import("@angular/core").Signal<string>;
14
+ get<T>(endpoint: string, params?: Record<string, string | number>): Observable<T>;
15
+ post<T>(endpoint: string, body: any): Observable<T>;
16
+ put<T>(endpoint: string, body: any): Observable<T>;
17
+ patch<T>(endpoint: string, body: any): Observable<T>;
18
+ delete<T>(endpoint: string): Observable<T>;
19
+ getWithResponse<T>(endpoint: string, params?: Record<string, string | number>): Observable<ApiResponse<T>>;
20
+ postWithResponse<T>(endpoint: string, body: any): Observable<ApiResponse<T>>;
21
+ uploadFile<T>(endpoint: string, file: File, additionalData?: Record<string, any>): Observable<T>;
22
+ downloadFile(endpoint: string): Observable<Blob>;
23
+ clearError(): void;
24
+ }
25
+ //# sourceMappingURL=backend.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.service.d.ts","sourceRoot":"","sources":["../../../src/app/backend/backend.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAIlC,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAGa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAE3C,OAAO,SAA+B;IAEtC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,MAAM,CAAsB;IAEpC,SAAgB,OAAO,0CAA8B;IACrD,SAAgB,KAAK,yCAA4B;IAEjD,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAejF,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC;IAcnD,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC;IAclD,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC;IAcpD,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAc1C,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAe1G,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAc5E,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAuBhG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC;IAgBhD,UAAU,IAAI,IAAI;CAGnB"}
@@ -0,0 +1,114 @@
1
+ import { __decorate } from "tslib";
2
+ import { Injectable, inject, signal } from '@angular/core';
3
+ import { HttpClient, HttpParams } from '@angular/common/http';
4
+ import { tap, catchError } from 'rxjs/operators';
5
+ import { throwError } from 'rxjs';
6
+ let BackendService = class BackendService {
7
+ http = inject(HttpClient);
8
+ baseUrl = 'http://localhost:3000/api';
9
+ _loading = signal(false);
10
+ _error = signal('');
11
+ loading = this._loading.asReadonly();
12
+ error = this._error.asReadonly();
13
+ get(endpoint, params) {
14
+ this._loading.set(true);
15
+ this._error.set('');
16
+ const httpParams = params ? new HttpParams({ fromObject: params }) : undefined;
17
+ return this.http.get(`${this.baseUrl}${endpoint}`, { params: httpParams }).pipe(tap(() => this._loading.set(false)), catchError(err => {
18
+ this._loading.set(false);
19
+ this._error.set(err.message || 'Request failed');
20
+ return throwError(() => err);
21
+ }));
22
+ }
23
+ post(endpoint, body) {
24
+ this._loading.set(true);
25
+ this._error.set('');
26
+ return this.http.post(`${this.baseUrl}${endpoint}`, body).pipe(tap(() => this._loading.set(false)), catchError(err => {
27
+ this._loading.set(false);
28
+ this._error.set(err.message || 'Request failed');
29
+ return throwError(() => err);
30
+ }));
31
+ }
32
+ put(endpoint, body) {
33
+ this._loading.set(true);
34
+ this._error.set('');
35
+ return this.http.put(`${this.baseUrl}${endpoint}`, body).pipe(tap(() => this._loading.set(false)), catchError(err => {
36
+ this._loading.set(false);
37
+ this._error.set(err.message || 'Request failed');
38
+ return throwError(() => err);
39
+ }));
40
+ }
41
+ patch(endpoint, body) {
42
+ this._loading.set(true);
43
+ this._error.set('');
44
+ return this.http.patch(`${this.baseUrl}${endpoint}`, body).pipe(tap(() => this._loading.set(false)), catchError(err => {
45
+ this._loading.set(false);
46
+ this._error.set(err.message || 'Request failed');
47
+ return throwError(() => err);
48
+ }));
49
+ }
50
+ delete(endpoint) {
51
+ this._loading.set(true);
52
+ this._error.set('');
53
+ return this.http.delete(`${this.baseUrl}${endpoint}`).pipe(tap(() => this._loading.set(false)), catchError(err => {
54
+ this._loading.set(false);
55
+ this._error.set(err.message || 'Request failed');
56
+ return throwError(() => err);
57
+ }));
58
+ }
59
+ getWithResponse(endpoint, params) {
60
+ this._loading.set(true);
61
+ this._error.set('');
62
+ const httpParams = params ? new HttpParams({ fromObject: params }) : undefined;
63
+ return this.http.get(`${this.baseUrl}${endpoint}`, { params: httpParams }).pipe(tap(() => this._loading.set(false)), catchError(err => {
64
+ this._loading.set(false);
65
+ this._error.set(err.message || 'Request failed');
66
+ return throwError(() => err);
67
+ }));
68
+ }
69
+ postWithResponse(endpoint, body) {
70
+ this._loading.set(true);
71
+ this._error.set('');
72
+ return this.http.post(`${this.baseUrl}${endpoint}`, body).pipe(tap(() => this._loading.set(false)), catchError(err => {
73
+ this._loading.set(false);
74
+ this._error.set(err.message || 'Request failed');
75
+ return throwError(() => err);
76
+ }));
77
+ }
78
+ uploadFile(endpoint, file, additionalData) {
79
+ this._loading.set(true);
80
+ this._error.set('');
81
+ const formData = new FormData();
82
+ formData.append('file', file);
83
+ if (additionalData) {
84
+ Object.keys(additionalData).forEach(key => {
85
+ formData.append(key, additionalData[key]);
86
+ });
87
+ }
88
+ return this.http.post(`${this.baseUrl}${endpoint}`, formData).pipe(tap(() => this._loading.set(false)), catchError(err => {
89
+ this._loading.set(false);
90
+ this._error.set(err.message || 'Upload failed');
91
+ return throwError(() => err);
92
+ }));
93
+ }
94
+ downloadFile(endpoint) {
95
+ this._loading.set(true);
96
+ this._error.set('');
97
+ return this.http.get(`${this.baseUrl}${endpoint}`, {
98
+ responseType: 'blob'
99
+ }).pipe(tap(() => this._loading.set(false)), catchError(err => {
100
+ this._loading.set(false);
101
+ this._error.set(err.message || 'Download failed');
102
+ return throwError(() => err);
103
+ }));
104
+ }
105
+ clearError() {
106
+ this._error.set('');
107
+ }
108
+ };
109
+ BackendService = __decorate([
110
+ Injectable({
111
+ providedIn: 'root'
112
+ })
113
+ ], BackendService);
114
+ export { BackendService };
@@ -1 +1 @@
1
- {"version":3,"file":"home.component.d.ts","sourceRoot":"","sources":["../../../src/app/home/home.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,qBA0Da,aAAa;IACxB,WAAW,cAAuB;IAElC,MAAM;CAGP"}
1
+ {"version":3,"file":"home.component.d.ts","sourceRoot":"","sources":["../../../src/app/home/home.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,qBAgFa,aAAa;IACxB,WAAW,cAAuB;IAElC,MAAM;CAGP"}
@@ -22,7 +22,10 @@ HomeComponent = __decorate([
22
22
  <p>You are logged in as: <strong>{{ username }}</strong></p>
23
23
  }
24
24
 
25
- <button (click)="logout()">Logout</button>
25
+ <div class="actions">
26
+ <a href="/demo" class="btn btn-primary">Backend Service Demo</a>
27
+ <button (click)="logout()" class="btn btn-danger">Logout</button>
28
+ </div>
26
29
  </div>
27
30
  </div>
28
31
  `,
@@ -52,17 +55,36 @@ HomeComponent = __decorate([
52
55
  color: #666;
53
56
  }
54
57
 
55
- button {
58
+ .actions {
59
+ display: flex;
60
+ gap: 1rem;
61
+ flex-wrap: wrap;
62
+ }
63
+
64
+ .btn {
56
65
  padding: 0.75rem 2rem;
57
- background: #dc3545;
58
66
  color: white;
59
67
  border: none;
60
68
  border-radius: 4px;
61
69
  font-size: 1rem;
62
70
  cursor: pointer;
71
+ text-decoration: none;
72
+ display: inline-block;
73
+ }
74
+
75
+ .btn-primary {
76
+ background: #007bff;
77
+ }
78
+
79
+ .btn-primary:hover {
80
+ background: #0056b3;
81
+ }
82
+
83
+ .btn-danger {
84
+ background: #dc3545;
63
85
  }
64
86
 
65
- button:hover {
87
+ .btn-danger:hover {
66
88
  background: #c82333;
67
89
  }
68
90
  `]
@@ -3,4 +3,7 @@ export { authInterceptor } from './app/auth/auth.interceptor';
3
3
  export { authGuard } from './app/guards/auth.guard';
4
4
  export { LoginComponent } from './app/login/login.component';
5
5
  export { HomeComponent } from './app/home/home.component';
6
+ export { BackendService } from './app/backend/backend.service';
7
+ export { BackendDemoComponent } from './app/backend/backend-demo.component';
8
+ export type { ApiResponse } from './app/backend/backend.service';
6
9
  //# sourceMappingURL=public-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC"}
@@ -3,3 +3,5 @@ export { authInterceptor } from './app/auth/auth.interceptor';
3
3
  export { authGuard } from './app/guards/auth.guard';
4
4
  export { LoginComponent } from './app/login/login.component';
5
5
  export { HomeComponent } from './app/home/home.component';
6
+ export { BackendService } from './app/backend/backend.service';
7
+ export { BackendDemoComponent } from './app/backend/backend-demo.component';
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "@ichgamer999/wmctest",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Minimalist Angular authentication template with signals, JWT token handling, and HTTP interceptors",
5
- "keywords": ["angular", "authentication", "jwt", "signals", "template"],
6
- "author": "Your Name",
5
+ "keywords": [
6
+ "angular",
7
+ "authentication",
8
+ "jwt",
9
+ "signals",
10
+ "template"
11
+ ],
12
+ "author": "ICHGamer999",
7
13
  "license": "MIT",
8
14
  "repository": {
9
15
  "type": "git",
@@ -7,6 +7,11 @@ export const routes: Routes = [
7
7
  loadComponent: () => import('./home/home.component').then(m => m.HomeComponent),
8
8
  canActivate: [authGuard]
9
9
  },
10
+ {
11
+ path: 'demo',
12
+ loadComponent: () => import('./backend/backend-demo.component').then(m => m.BackendDemoComponent),
13
+ canActivate: [authGuard]
14
+ },
10
15
  {
11
16
  path: 'login',
12
17
  loadComponent: () => import('./login/login.component').then(m => m.LoginComponent)