@reskin/core 0.0.22 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/bundles/reskin-core-directives.umd.js +303 -163
  2. package/bundles/reskin-core-directives.umd.js.map +1 -1
  3. package/bundles/reskin-core-guards.umd.js +119 -32
  4. package/bundles/reskin-core-guards.umd.js.map +1 -1
  5. package/bundles/reskin-core-interceptors.umd.js +286 -104
  6. package/bundles/reskin-core-interceptors.umd.js.map +1 -1
  7. package/bundles/reskin-core-utils.umd.js +220 -77
  8. package/bundles/reskin-core-utils.umd.js.map +1 -1
  9. package/directives/auth.directive.d.ts +56 -9
  10. package/directives/load.styles.directive.d.ts +45 -5
  11. package/directives/string.template.outlet.directive.d.ts +68 -11
  12. package/esm2015/directives/auth.directive.js +71 -30
  13. package/esm2015/directives/load.styles.directive.js +84 -15
  14. package/esm2015/directives/string.template.outlet.directive.js +118 -60
  15. package/esm2015/guards/auth.guard.js +117 -30
  16. package/esm2015/interceptors/blob.interceptor.js +67 -28
  17. package/esm2015/interceptors/cache.interceptor.js +46 -14
  18. package/esm2015/interceptors/error.interceptor.js +104 -12
  19. package/esm2015/interceptors/public-api.js +2 -1
  20. package/esm2015/interceptors/token.interceptor.js +66 -53
  21. package/esm2015/interceptors/types.js +5 -0
  22. package/esm2015/utils/array.js +42 -22
  23. package/esm2015/utils/dom.js +29 -11
  24. package/esm2015/utils/form.js +44 -13
  25. package/esm2015/utils/store.js +101 -26
  26. package/fesm2015/reskin-core-directives.js +269 -103
  27. package/fesm2015/reskin-core-directives.js.map +1 -1
  28. package/fesm2015/reskin-core-guards.js +116 -29
  29. package/fesm2015/reskin-core-guards.js.map +1 -1
  30. package/fesm2015/reskin-core-interceptors.js +282 -102
  31. package/fesm2015/reskin-core-interceptors.js.map +1 -1
  32. package/fesm2015/reskin-core-utils.js +212 -68
  33. package/fesm2015/reskin-core-utils.js.map +1 -1
  34. package/guards/auth.guard.d.ts +85 -5
  35. package/interceptors/blob.interceptor.d.ts +30 -3
  36. package/interceptors/cache.interceptor.d.ts +28 -4
  37. package/interceptors/error.interceptor.d.ts +43 -2
  38. package/interceptors/public-api.d.ts +1 -0
  39. package/interceptors/token.interceptor.d.ts +35 -18
  40. package/interceptors/types.d.ts +68 -0
  41. package/package.json +1 -1
  42. package/utils/array.d.ts +8 -1
  43. package/utils/dom.d.ts +32 -5
  44. package/utils/form.d.ts +37 -2
  45. package/utils/store.d.ts +56 -15
@@ -2,43 +2,63 @@ import * as i0 from '@angular/core';
2
2
  import { Injectable } from '@angular/core';
3
3
  import { HTTP_INTERCEPTORS, HttpHeaders, HttpEventType, HttpResponse } from '@angular/common/http';
4
4
  import * as i1 from '@reskin/core/services';
5
- import { of, Observable } from 'rxjs';
5
+ import { throwError, Observable } from 'rxjs';
6
6
  import { catchError, shareReplay, switchMap } from 'rxjs/operators';
7
7
  import * as i1$1 from '@angular/router';
8
+ import { Router } from '@angular/router';
8
9
 
9
- // 定义默认的 token header 名称
10
+ /**
11
+ * HTTP 拦截器相关类型定义
12
+ */
13
+
14
+ /**
15
+ * Token 拦截器常量
16
+ */
10
17
  const DEFAULT_TOKEN_HEADER_NAME = 'Authorization';
11
18
  const TOKEN_CONTROL_HEADER = 'Token-Control';
12
19
  const CUSTOM_TOKEN_HEADER = 'Custom-Token';
13
20
  const CUSTOM_TOKEN_HEADER_NAME = 'Custom-Token-Header';
14
21
  const AUTH_ID_HEADER = 'X-Auth-Id';
22
+ /**
23
+ * Token 拦截器
24
+ * 自动为 HTTP 请求添加认证 Token
25
+ */
15
26
  class TokenInterceptor {
16
- constructor(service) {
17
- this.service = service;
27
+ constructor(authService) {
28
+ this.authService = authService;
18
29
  }
30
+ /**
31
+ * 拦截 HTTP 请求,添加 Token 认证信息
32
+ * @param request HTTP 请求对象
33
+ * @param next 下一个拦截器处理器
34
+ * @returns Observable<HttpEvent<unknown>>
35
+ */
19
36
  intercept(request, next) {
20
- const tc = request.headers.get(TOKEN_CONTROL_HEADER);
21
- // 检查是否提供了自定义token
37
+ const tokenControl = request.headers.get(TOKEN_CONTROL_HEADER);
38
+ // 如果明确指定不需要 Token,直接放行
39
+ if (tokenControl === 'no-token') {
40
+ return next.handle(request);
41
+ }
22
42
  const customToken = request.headers.get(CUSTOM_TOKEN_HEADER);
23
- // 检查是否提供了自定义token header名称
24
43
  const customTokenHeaderName = request.headers.get(CUSTOM_TOKEN_HEADER_NAME) || DEFAULT_TOKEN_HEADER_NAME;
25
- if (tc !== 'no-token') {
26
- let headers = {};
27
- if (customToken) {
28
- // 使用自定义token
29
- headers[customTokenHeaderName] = customToken;
30
- }
31
- else {
32
- // 使用默认认证信息
33
- const auth = this.service.token;
34
- if (auth.token) {
35
- headers[DEFAULT_TOKEN_HEADER_NAME] = auth.token;
44
+ const headers = {};
45
+ if (customToken) {
46
+ // 使用自定义 Token
47
+ headers[customTokenHeaderName] = customToken;
48
+ }
49
+ else {
50
+ // 使用默认认证信息
51
+ const auth = this.authService.token;
52
+ if (auth === null || auth === void 0 ? void 0 : auth.token) {
53
+ headers[DEFAULT_TOKEN_HEADER_NAME] = auth.token;
54
+ if (auth.id) {
36
55
  headers[AUTH_ID_HEADER] = auth.id;
37
56
  }
38
57
  }
39
- if (Object.keys(headers).length > 0) {
40
- request = request.clone({ setHeaders: headers });
41
- }
58
+ }
59
+ // 如果有需要添加的 Header,克隆请求并添加
60
+ if (Object.keys(headers).length > 0) {
61
+ request = request.clone({ setHeaders: headers });
42
62
  }
43
63
  return next.handle(request);
44
64
  }
@@ -49,78 +69,141 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
49
69
  type: Injectable
50
70
  }], ctorParameters: function () { return [{ type: i1.RkAuthService }]; } });
51
71
  /**
52
- * 请求头增加token验证拦截器
72
+ * 提供 Token 拦截器
73
+ * @returns Provider 配置对象
53
74
  */
54
75
  function providerAuthToken() {
55
76
  return { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true };
56
77
  }
57
78
  /**
58
- * 不带token验证信息请求
59
- * @param urls 地址
60
- * @param params 参数
61
- * @constructor
79
+ * 创建不带 Token 的请求配置
80
+ * @param urls 模板字符串数组
81
+ * @param params 模板参数
82
+ * @returns [url, options] 元组
83
+ * @example
84
+ * this.http.get(...NoAuthTokenTemplate`/api/public/data`).subscribe();
62
85
  */
63
86
  function NoAuthTokenTemplate(urls, ...params) {
64
- let [url] = urls;
65
- if (params.length > 0) {
66
- url = String.raw(urls, ...params);
67
- }
68
- return [url, { headers: new HttpHeaders({ 'Token-Control': 'no-token' }) }];
87
+ const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];
88
+ return [url, { headers: new HttpHeaders({ [TOKEN_CONTROL_HEADER]: 'no-token' }) }];
69
89
  }
70
90
  /**
71
- * 使用自定义token的请求
72
- * @param token 自定义token
73
- * @param urls 地址
74
- * @param params 参数
75
- * @constructor
91
+ * 创建使用自定义 Token 的请求配置
92
+ * @param token 自定义 Token
93
+ * @param urls 模板字符串数组
94
+ * @param params 模板参数
95
+ * @returns [url, options] 元组
96
+ * @example
97
+ * this.http.get(...CustomTokenTemplate('my-token', `/api/data`)).subscribe();
76
98
  */
77
99
  function CustomTokenTemplate(token, urls, ...params) {
78
- let [url] = urls;
79
- if (params.length > 0) {
80
- url = String.raw(urls, ...params);
81
- }
82
- return [url, { headers: new HttpHeaders({ 'Custom-Token': token }) }];
100
+ const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];
101
+ return [url, { headers: new HttpHeaders({ [CUSTOM_TOKEN_HEADER]: token }) }];
83
102
  }
84
103
  /**
85
- * 使用自定义token和自定义header名称的请求
86
- * @param token 自定义token
87
- * @param headerName 自定义header名称
88
- * @param urls 地址
89
- * @param params 参数
90
- * @constructor
104
+ * 创建使用自定义 Token 和自定义 Header 名称的请求配置
105
+ * @param token 自定义 Token
106
+ * @param headerName 自定义 Header 名称
107
+ * @param urls 模板字符串数组
108
+ * @param params 模板参数
109
+ * @returns [url, options] 元组
110
+ * @example
111
+ * this.http.get(...CustomTokenWithHeaderTemplate('my-token', 'X-API-Key', `/api/data`)).subscribe();
91
112
  */
92
113
  function CustomTokenWithHeaderTemplate(token, headerName, urls, ...params) {
93
- let [url] = urls;
94
- if (params.length > 0) {
95
- url = String.raw(urls, ...params);
96
- }
114
+ const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];
97
115
  return [
98
116
  url,
99
117
  {
100
118
  headers: new HttpHeaders({
101
- 'Custom-Token': token,
102
- 'Custom-Token-Header': headerName,
119
+ [CUSTOM_TOKEN_HEADER]: token,
120
+ [CUSTOM_TOKEN_HEADER_NAME]: headerName,
103
121
  }),
104
122
  },
105
123
  ];
106
124
  }
107
125
 
126
+ /**
127
+ * 默认配置
128
+ */
129
+ const DEFAULT_CONFIG = {
130
+ unauthorizedPath: '/errors/401',
131
+ enableLogging: false,
132
+ };
133
+ /**
134
+ * HTTP 错误拦截器
135
+ * 统一处理 HTTP 请求错误,包括 401 未授权错误的自动跳转
136
+ */
108
137
  class ErrorInterceptor {
109
138
  constructor(router) {
110
139
  this.router = router;
140
+ this.config = DEFAULT_CONFIG;
141
+ }
142
+ /**
143
+ * 设置拦截器配置
144
+ * @param config 配置对象
145
+ */
146
+ setConfig(config) {
147
+ this.config = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
111
148
  }
149
+ /**
150
+ * 拦截 HTTP 请求,处理错误响应
151
+ * @param request HTTP 请求对象
152
+ * @param next 下一个拦截器处理器
153
+ * @returns Observable<HttpEvent<unknown>>
154
+ */
112
155
  intercept(request, next) {
113
- return next.handle(request).pipe(catchError((result) => {
114
- var _a;
115
- if (result.status === 401) {
116
- this.router.navigate(['/errors/401']).then();
156
+ return next.handle(request).pipe(catchError((error) => {
157
+ // 处理 401 未授权错误
158
+ if (error.status === 401) {
159
+ this.handleUnauthorizedError();
160
+ return throwError(error);
117
161
  }
118
- if (result.error.code) {
119
- return of(result.error);
162
+ // 记录错误日志
163
+ if (this.config.enableLogging) {
164
+ console.error('[HTTP Error]', {
165
+ url: request.url,
166
+ method: request.method,
167
+ status: error.status,
168
+ message: error.message,
169
+ error: error.error,
170
+ });
120
171
  }
121
- throw (_a = result.error.msg) !== null && _a !== void 0 ? _a : result.message;
172
+ // 提取错误信息
173
+ const errorMessage = this.extractErrorMessage(error);
174
+ return throwError(new Error(errorMessage));
122
175
  }));
123
176
  }
177
+ /**
178
+ * 处理 401 未授权错误
179
+ */
180
+ handleUnauthorizedError() {
181
+ const path = this.config.unauthorizedPath || DEFAULT_CONFIG.unauthorizedPath;
182
+ this.router.navigate([path]).catch((err) => {
183
+ console.error('导航到错误页面失败:', err);
184
+ });
185
+ }
186
+ /**
187
+ * 提取错误信息
188
+ * @param error HTTP 错误响应
189
+ * @returns 错误信息字符串
190
+ */
191
+ extractErrorMessage(error) {
192
+ if (error.error) {
193
+ // 尝试从 error.error 中提取信息
194
+ if (typeof error.error === 'string') {
195
+ return error.error;
196
+ }
197
+ if (error.error.msg) {
198
+ return error.error.msg;
199
+ }
200
+ if (error.error.message) {
201
+ return error.error.message;
202
+ }
203
+ }
204
+ // 使用默认错误信息
205
+ return error.message || `HTTP Error ${error.status}`;
206
+ }
124
207
  }
125
208
  ErrorInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ErrorInterceptor, deps: [{ token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
126
209
  ErrorInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ErrorInterceptor });
@@ -128,28 +211,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
128
211
  type: Injectable
129
212
  }], ctorParameters: function () { return [{ type: i1$1.Router }]; } });
130
213
  /**
131
- * 请求错误拦截器
214
+ * 提供 HTTP 错误拦截器
215
+ * @param config 可选的配置对象
216
+ * @returns Provider 配置对象
217
+ * @example
218
+ * providers: [
219
+ * providerHttpError({ unauthorizedPath: '/login', enableLogging: true })
220
+ * ]
132
221
  */
133
- function providerHttpError() {
134
- return { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true };
222
+ function providerHttpError(config) {
223
+ if (config) {
224
+ // 如果有配置,使用 useFactory
225
+ return {
226
+ provide: HTTP_INTERCEPTORS,
227
+ useFactory: (router) => {
228
+ const interceptor = new ErrorInterceptor(router);
229
+ interceptor.setConfig(config);
230
+ return interceptor;
231
+ },
232
+ deps: [Router],
233
+ multi: true,
234
+ };
235
+ }
236
+ else {
237
+ // 没有配置,直接使用 useClass
238
+ return {
239
+ provide: HTTP_INTERCEPTORS,
240
+ useClass: ErrorInterceptor,
241
+ multi: true,
242
+ };
243
+ }
135
244
  }
136
245
 
246
+ /**
247
+ * 缓存策略标识
248
+ */
249
+ const CACHE_HEADER = 'Cache-Map';
250
+ const CACHE_STRATEGY = 'Storage';
251
+ /**
252
+ * HTTP 缓存拦截器
253
+ * 为 GET 请求提供缓存功能,减少重复请求
254
+ */
137
255
  class CacheInterceptor {
138
- constructor(cacheHttp) {
139
- this.cacheHttp = cacheHttp;
256
+ constructor(cacheHttpService) {
257
+ this.cacheHttpService = cacheHttpService;
140
258
  }
259
+ /**
260
+ * 拦截 HTTP 请求,实现缓存逻辑
261
+ * @param request HTTP 请求对象
262
+ * @param next 下一个拦截器处理器
263
+ * @returns Observable<HttpEvent<unknown>>
264
+ */
141
265
  intercept(request, next) {
142
- // 1.判断是GET
143
- // 2.header中添加 Cache-Map: Storage
144
- const cacheMap = request.headers.get('Cache-Map');
145
- if (request.method === 'GET' && cacheMap === 'Storage') {
146
- let response = this.cacheHttp.get(request.url);
147
- if (!response) {
148
- response = next.handle(request).pipe(shareReplay(1));
149
- this.cacheHttp.set(request.url, response);
266
+ // 只缓存 GET 请求且明确标记了缓存策略的请求
267
+ const cacheStrategy = request.headers.get(CACHE_HEADER);
268
+ if (request.method === 'GET' && cacheStrategy === CACHE_STRATEGY) {
269
+ // 尝试从缓存中获取响应
270
+ let cachedResponse = this.cacheHttpService.get(request.url);
271
+ if (!cachedResponse) {
272
+ // 缓存未命中,发起请求并缓存结果
273
+ cachedResponse = next.handle(request).pipe(shareReplay(1));
274
+ this.cacheHttpService.set(request.url, cachedResponse);
150
275
  }
151
- return response;
276
+ return cachedResponse;
152
277
  }
278
+ // 非缓存请求,直接放行
153
279
  return next.handle(request);
154
280
  }
155
281
  }
@@ -159,58 +285,110 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
159
285
  type: Injectable
160
286
  }], ctorParameters: function () { return [{ type: i1.RkCacheHttpService }]; } });
161
287
  /**
162
- * GET请求缓存拦截器
288
+ * 提供 HTTP 缓存拦截器
289
+ * @returns Provider 配置对象
290
+ * @example
291
+ * providers: [providerHttpCache()]
163
292
  */
164
293
  function providerHttpCache() {
165
294
  return { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true };
295
+ }
296
+ /**
297
+ * 创建带缓存标记的 GET 请求配置
298
+ * @param urls 模板字符串数组
299
+ * @param params 模板参数
300
+ * @returns [url, options] 元组
301
+ * @example
302
+ * this.http.get(...CacheHttpTemplate`/api/data`).subscribe();
303
+ */
304
+ function CacheHttpTemplate(urls, ...params) {
305
+ const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];
306
+ return [url, { headers: new HttpHeaders({ [CACHE_HEADER]: CACHE_STRATEGY }) }];
166
307
  }
167
308
 
309
+ /**
310
+ * Blob 响应拦截器
311
+ * 处理文件下载请求中的 JSON 错误响应
312
+ */
168
313
  class BlobInterceptor {
314
+ /**
315
+ * 拦截 HTTP 请求,处理 Blob 类型响应
316
+ * @param request HTTP 请求对象
317
+ * @param next 下一个拦截器处理器
318
+ * @returns Observable<HttpEvent<T>>
319
+ */
169
320
  intercept(request, next) {
321
+ // 只处理 responseType 为 blob 的请求
170
322
  if (request.responseType !== 'blob') {
171
323
  return next.handle(request);
172
324
  }
173
- return next.handle(request).pipe(switchMap((response) => this.handleBlobResponse(response)), catchError((response) => this.handleBlobError(response)));
325
+ return next.handle(request).pipe(switchMap((event) => this.handleBlobResponse(event)), catchError((error) => this.handleBlobError(error)));
174
326
  }
175
- handleBlobResponse(response) {
176
- if (response.type !== HttpEventType.Response) {
327
+ /**
328
+ * 处理 Blob 响应事件
329
+ * @param event HTTP 事件
330
+ * @returns Observable<HttpEvent<any>>
331
+ */
332
+ handleBlobResponse(event) {
333
+ var _a;
334
+ // 只处理完整的响应事件
335
+ if (event.type !== HttpEventType.Response) {
177
336
  return new Observable((subscriber) => {
178
- subscriber.next(response);
337
+ subscriber.next(event);
179
338
  subscriber.complete();
180
339
  });
181
340
  }
182
- if (response instanceof HttpResponse && response.body && response.body.type === 'application/json') {
183
- return new Observable((subscriber) => this.blobToJson(response.body, subscriber));
341
+ // 检查响应体是否为 JSON 类型(通常表示错误)
342
+ if (event instanceof HttpResponse && ((_a = event.body) === null || _a === void 0 ? void 0 : _a.type) === 'application/json') {
343
+ return this.convertBlobToJson(event.body);
184
344
  }
185
345
  return new Observable((subscriber) => {
186
- subscriber.next(response);
346
+ subscriber.next(event);
187
347
  subscriber.complete();
188
348
  });
189
349
  }
190
- handleBlobError(response) {
191
- if (response.error && response.error.type === 'application/json') {
192
- return new Observable((subscriber) => this.blobToJson(response.error, subscriber));
350
+ /**
351
+ * 处理 Blob 错误响应
352
+ * @param error HTTP 错误响应
353
+ * @returns Observable<HttpEvent<any>>
354
+ */
355
+ handleBlobError(error) {
356
+ var _a;
357
+ // 如果错误响应体是 JSON 类型的 Blob,转换为 JSON 对象
358
+ if (((_a = error.error) === null || _a === void 0 ? void 0 : _a.type) === 'application/json') {
359
+ return this.convertBlobToJson(error.error);
193
360
  }
194
361
  return new Observable((subscriber) => {
195
- subscriber.error(response);
362
+ subscriber.error(error);
196
363
  subscriber.complete();
197
364
  });
198
365
  }
199
- blobToJson(blob, subscriber) {
200
- const reader = new FileReader();
201
- reader.addEventListener('loadend', () => {
202
- try {
203
- const json = JSON.parse(reader.result);
204
- subscriber.error(json);
205
- }
206
- catch (error) {
207
- subscriber.error(error);
208
- }
209
- finally {
366
+ /**
367
+ * Blob 转换为 JSON 对象并抛出错误
368
+ * @param blob Blob 对象
369
+ * @returns Observable<HttpEvent<T>>
370
+ */
371
+ convertBlobToJson(blob) {
372
+ return new Observable((subscriber) => {
373
+ const reader = new FileReader();
374
+ reader.addEventListener('loadend', () => {
375
+ try {
376
+ const json = JSON.parse(reader.result);
377
+ subscriber.error(json);
378
+ }
379
+ catch (parseError) {
380
+ subscriber.error(parseError);
381
+ }
382
+ finally {
383
+ subscriber.complete();
384
+ }
385
+ });
386
+ reader.addEventListener('error', () => {
387
+ subscriber.error(new Error('读取 Blob 数据失败'));
210
388
  subscriber.complete();
211
- }
389
+ });
390
+ reader.readAsText(blob, 'utf-8');
212
391
  });
213
- reader.readAsText(blob, 'utf-8');
214
392
  }
215
393
  }
216
394
  BlobInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: BlobInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -219,8 +397,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImpo
219
397
  type: Injectable
220
398
  }] });
221
399
  /**
222
- * 下载文件拦截器
223
- * blob类型的请求会被处理
400
+ * 提供 Blob 响应拦截器
401
+ * @returns Provider 配置对象
402
+ * @example
403
+ * providers: [providerDownBlob()]
224
404
  */
225
405
  function providerDownBlob() {
226
406
  return { provide: HTTP_INTERCEPTORS, useClass: BlobInterceptor, multi: true };
@@ -230,5 +410,5 @@ function providerDownBlob() {
230
410
  * Generated bundle index. Do not edit.
231
411
  */
232
412
 
233
- export { BlobInterceptor, CacheInterceptor, CustomTokenTemplate, CustomTokenWithHeaderTemplate, ErrorInterceptor, NoAuthTokenTemplate, TokenInterceptor, providerAuthToken, providerDownBlob, providerHttpCache, providerHttpError };
413
+ export { BlobInterceptor, CacheHttpTemplate, CacheInterceptor, CustomTokenTemplate, CustomTokenWithHeaderTemplate, ErrorInterceptor, NoAuthTokenTemplate, TokenInterceptor, providerAuthToken, providerDownBlob, providerHttpCache, providerHttpError };
234
414
  //# sourceMappingURL=reskin-core-interceptors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reskin-core-interceptors.js","sources":["../../../library/core/interceptors/token.interceptor.ts","../../../library/core/interceptors/error.interceptor.ts","../../../library/core/interceptors/cache.interceptor.ts","../../../library/core/interceptors/blob.interceptor.ts","../../../library/core/interceptors/reskin-core-interceptors.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport { RkAuthService } from '@reskin/core/services';\r\nimport { IAuth } from '@reskin/core/entity/user';\r\n\r\n// 定义默认的 token header 名称\r\nconst DEFAULT_TOKEN_HEADER_NAME = 'Authorization';\r\nconst TOKEN_CONTROL_HEADER = 'Token-Control';\r\nconst CUSTOM_TOKEN_HEADER = 'Custom-Token';\r\nconst CUSTOM_TOKEN_HEADER_NAME = 'Custom-Token-Header';\r\nconst AUTH_ID_HEADER = 'X-Auth-Id';\r\n\r\n@Injectable()\r\nexport class TokenInterceptor implements HttpInterceptor {\r\n constructor(private service: RkAuthService) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n const tc = request.headers.get(TOKEN_CONTROL_HEADER);\r\n // 检查是否提供了自定义token\r\n const customToken = request.headers.get(CUSTOM_TOKEN_HEADER);\r\n // 检查是否提供了自定义token header名称\r\n const customTokenHeaderName = request.headers.get(CUSTOM_TOKEN_HEADER_NAME) || DEFAULT_TOKEN_HEADER_NAME;\r\n\r\n if (tc !== 'no-token') {\r\n let headers: { [name: string]: string | string[] } = {};\r\n\r\n if (customToken) {\r\n // 使用自定义token\r\n headers[customTokenHeaderName] = customToken;\r\n } else {\r\n // 使用默认认证信息\r\n const auth: IAuth = this.service.token;\r\n if (auth.token) {\r\n headers[DEFAULT_TOKEN_HEADER_NAME] = auth.token;\r\n headers[AUTH_ID_HEADER] = auth.id;\r\n }\r\n }\r\n\r\n if (Object.keys(headers).length > 0) {\r\n request = request.clone({ setHeaders: headers });\r\n }\r\n }\r\n return next.handle(request);\r\n }\r\n}\r\n\r\n/**\r\n * 请求头增加token验证拦截器\r\n */\r\nexport function providerAuthToken() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true };\r\n}\r\n\r\n/**\r\n * 不带token验证信息请求\r\n * @param urls 地址\r\n * @param params 参数\r\n * @constructor\r\n */\r\nexport function NoAuthTokenTemplate(urls: TemplateStringsArray, ...params: any[]): [string, { headers: HttpHeaders }] {\r\n let [url] = urls;\r\n if (params.length > 0) {\r\n url = String.raw(urls, ...params);\r\n }\r\n return [url, { headers: new HttpHeaders({ 'Token-Control': 'no-token' }) }];\r\n}\r\n\r\n/**\r\n * 使用自定义token的请求\r\n * @param token 自定义token值\r\n * @param urls 地址\r\n * @param params 参数\r\n * @constructor\r\n */\r\nexport function CustomTokenTemplate(token: string, urls: TemplateStringsArray, ...params: any[]): [string, { headers: HttpHeaders }] {\r\n let [url] = urls;\r\n if (params.length > 0) {\r\n url = String.raw(urls, ...params);\r\n }\r\n return [url, { headers: new HttpHeaders({ 'Custom-Token': token }) }];\r\n}\r\n\r\n/**\r\n * 使用自定义token和自定义header名称的请求\r\n * @param token 自定义token值\r\n * @param headerName 自定义header名称\r\n * @param urls 地址\r\n * @param params 参数\r\n * @constructor\r\n */\r\nexport function CustomTokenWithHeaderTemplate(\r\n token: string,\r\n headerName: string,\r\n urls: TemplateStringsArray,\r\n ...params: any[]\r\n): [string, { headers: HttpHeaders }] {\r\n let [url] = urls;\r\n if (params.length > 0) {\r\n url = String.raw(urls, ...params);\r\n }\r\n return [\r\n url,\r\n {\r\n headers: new HttpHeaders({\r\n 'Custom-Token': token,\r\n 'Custom-Token-Header': headerName,\r\n }),\r\n },\r\n ];\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport { Observable, of } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\nimport { Router } from '@angular/router';\r\n\r\n@Injectable()\r\nexport class ErrorInterceptor implements HttpInterceptor {\r\n constructor(private router: Router) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n return next.handle(request).pipe(\r\n catchError((result) => {\r\n if (result.status === 401) {\r\n this.router.navigate(['/errors/401']).then();\r\n }\r\n if (result.error.code) {\r\n return of(result.error);\r\n }\r\n throw result.error.msg ?? result.message;\r\n }),\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * 请求错误拦截器\r\n */\r\nexport function providerHttpError() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true };\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport { shareReplay } from 'rxjs/operators';\r\nimport { RkCacheHttpService } from '@reskin/core/services';\r\n\r\n@Injectable()\r\nexport class CacheInterceptor implements HttpInterceptor {\r\n constructor(private cacheHttp: RkCacheHttpService) {}\r\n\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n // 1.判断是GET\r\n // 2.header中添加 Cache-Map: Storage\r\n const cacheMap = request.headers.get('Cache-Map');\r\n if (request.method === 'GET' && cacheMap === 'Storage') {\r\n let response = this.cacheHttp.get(request.url);\r\n if (!response) {\r\n response = next.handle(request).pipe(shareReplay(1));\r\n this.cacheHttp.set(request.url, response);\r\n }\r\n return response;\r\n }\r\n return next.handle(request);\r\n }\r\n}\r\n\r\n/**\r\n * GET请求缓存拦截器\r\n */\r\nexport function providerHttpCache() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true };\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport {\r\n HttpRequest,\r\n HttpHandler,\r\n HttpEvent,\r\n HttpInterceptor,\r\n HttpEventType,\r\n HttpResponse,\r\n HttpErrorResponse,\r\n HTTP_INTERCEPTORS,\r\n} from '@angular/common/http';\r\nimport { Observable, Subscriber } from 'rxjs';\r\nimport { catchError, switchMap } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class BlobInterceptor implements HttpInterceptor {\r\n intercept<T>(request: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {\r\n if (request.responseType !== 'blob') {\r\n return next.handle(request);\r\n }\r\n return next.handle(request).pipe(\r\n switchMap((response: HttpEvent<any>) => this.handleBlobResponse(response)),\r\n catchError((response: HttpErrorResponse) => this.handleBlobError(response)),\r\n );\r\n }\r\n\r\n private handleBlobResponse<T>(response: HttpEvent<any>): Observable<HttpEvent<any>> {\r\n if (response.type !== HttpEventType.Response) {\r\n return new Observable((subscriber) => {\r\n subscriber.next(response);\r\n subscriber.complete();\r\n });\r\n }\r\n\r\n if (response instanceof HttpResponse && response.body && response.body.type === 'application/json') {\r\n return new Observable((subscriber) => this.blobToJson<T>(response.body, subscriber));\r\n }\r\n\r\n return new Observable((subscriber) => {\r\n subscriber.next(response);\r\n subscriber.complete();\r\n });\r\n }\r\n\r\n private handleBlobError<T>(response: HttpErrorResponse): Observable<HttpEvent<any>> {\r\n if (response.error && response.error.type === 'application/json') {\r\n return new Observable((subscriber) => this.blobToJson<T>(response.error, subscriber));\r\n }\r\n\r\n return new Observable((subscriber) => {\r\n subscriber.error(response);\r\n subscriber.complete();\r\n });\r\n }\r\n\r\n private blobToJson<T>(blob: Blob, subscriber: Subscriber<HttpEvent<T>>) {\r\n const reader = new FileReader();\r\n reader.addEventListener('loadend', () => {\r\n try {\r\n const json: T = JSON.parse(reader.result as string);\r\n subscriber.error(json);\r\n } catch (error) {\r\n subscriber.error(error);\r\n } finally {\r\n subscriber.complete();\r\n }\r\n });\r\n reader.readAsText(blob, 'utf-8');\r\n }\r\n}\r\n\r\n/**\r\n * 下载文件拦截器\r\n * blob类型的请求会被处理\r\n */\r\nexport function providerDownBlob() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: BlobInterceptor, multi: true };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"reskin-core-interceptors.js","sources":["../../../library/core/interceptors/types.ts","../../../library/core/interceptors/token.interceptor.ts","../../../library/core/interceptors/error.interceptor.ts","../../../library/core/interceptors/cache.interceptor.ts","../../../library/core/interceptors/blob.interceptor.ts","../../../library/core/interceptors/reskin-core-interceptors.ts"],"sourcesContent":["/**\r\n * HTTP 拦截器相关类型定义\r\n */\r\n\r\n/**\r\n * Token 拦截器配置\r\n */\r\nexport interface TokenInterceptorConfig {\r\n /**\r\n * 默认的 Token Header 名称\r\n * @default 'Authorization'\r\n */\r\n tokenHeaderName?: string;\r\n /**\r\n * 认证 ID Header 名称\r\n * @default 'X-Auth-Id'\r\n */\r\n authIdHeaderName?: string;\r\n}\r\n\r\n/**\r\n * 错误拦截器配置\r\n */\r\nexport interface ErrorInterceptorConfig {\r\n /**\r\n * 401 错误跳转路径\r\n * @default '/errors/401'\r\n */\r\n unauthorizedPath?: string;\r\n /**\r\n * 是否启用错误日志\r\n * @default false\r\n */\r\n enableLogging?: boolean;\r\n /**\r\n * 自定义错误处理函数\r\n */\r\n customErrorHandler?: (error: any) => void;\r\n}\r\n\r\n/**\r\n * 缓存拦截器配置\r\n */\r\nexport interface CacheInterceptorConfig {\r\n /**\r\n * 缓存最大数量\r\n * @default 100\r\n */\r\n maxCacheSize?: number;\r\n /**\r\n * 缓存过期时间(毫秒)\r\n * @default undefined (永不过期)\r\n */\r\n cacheExpiration?: number;\r\n}\r\n\r\n/**\r\n * HTTP 请求选项扩展\r\n */\r\nexport interface HttpRequestOptions {\r\n headers?: { [name: string]: string | string[] };\r\n}\r\n\r\n/**\r\n * Token 控制类型\r\n */\r\nexport type TokenControl = 'no-token' | 'custom-token';\r\n\r\n/**\r\n * 缓存策略类型\r\n */\r\nexport type CacheStrategy = 'Storage' | 'Memory';\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport { RkAuthService } from '@reskin/core/services';\r\nimport { IAuth } from '@reskin/core/entity/user';\r\n\r\n/**\r\n * Token 拦截器常量\r\n */\r\nconst DEFAULT_TOKEN_HEADER_NAME = 'Authorization';\r\nconst TOKEN_CONTROL_HEADER = 'Token-Control';\r\nconst CUSTOM_TOKEN_HEADER = 'Custom-Token';\r\nconst CUSTOM_TOKEN_HEADER_NAME = 'Custom-Token-Header';\r\nconst AUTH_ID_HEADER = 'X-Auth-Id';\r\n\r\n/**\r\n * Token 拦截器\r\n * 自动为 HTTP 请求添加认证 Token\r\n */\r\n@Injectable()\r\nexport class TokenInterceptor implements HttpInterceptor {\r\n constructor(private authService: RkAuthService) {}\r\n\r\n /**\r\n * 拦截 HTTP 请求,添加 Token 认证信息\r\n * @param request HTTP 请求对象\r\n * @param next 下一个拦截器处理器\r\n * @returns Observable<HttpEvent<unknown>>\r\n */\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n const tokenControl = request.headers.get(TOKEN_CONTROL_HEADER);\r\n \r\n // 如果明确指定不需要 Token,直接放行\r\n if (tokenControl === 'no-token') {\r\n return next.handle(request);\r\n }\r\n\r\n const customToken = request.headers.get(CUSTOM_TOKEN_HEADER);\r\n const customTokenHeaderName = request.headers.get(CUSTOM_TOKEN_HEADER_NAME) || DEFAULT_TOKEN_HEADER_NAME;\r\n\r\n const headers: { [name: string]: string | string[] } = {};\r\n\r\n if (customToken) {\r\n // 使用自定义 Token\r\n headers[customTokenHeaderName] = customToken;\r\n } else {\r\n // 使用默认认证信息\r\n const auth: IAuth = this.authService.token;\r\n if (auth?.token) {\r\n headers[DEFAULT_TOKEN_HEADER_NAME] = auth.token;\r\n if (auth.id) {\r\n headers[AUTH_ID_HEADER] = auth.id;\r\n }\r\n }\r\n }\r\n\r\n // 如果有需要添加的 Header,克隆请求并添加\r\n if (Object.keys(headers).length > 0) {\r\n request = request.clone({ setHeaders: headers });\r\n }\r\n\r\n return next.handle(request);\r\n }\r\n}\r\n\r\n/**\r\n * 提供 Token 拦截器\r\n * @returns Provider 配置对象\r\n */\r\nexport function providerAuthToken() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true };\r\n}\r\n\r\n/**\r\n * 创建不带 Token 的请求配置\r\n * @param urls 模板字符串数组\r\n * @param params 模板参数\r\n * @returns [url, options] 元组\r\n * @example\r\n * this.http.get(...NoAuthTokenTemplate`/api/public/data`).subscribe();\r\n */\r\nexport function NoAuthTokenTemplate(urls: TemplateStringsArray, ...params: any[]): [string, { headers: HttpHeaders }] {\r\n const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];\r\n return [url, { headers: new HttpHeaders({ [TOKEN_CONTROL_HEADER]: 'no-token' }) }];\r\n}\r\n\r\n/**\r\n * 创建使用自定义 Token 的请求配置\r\n * @param token 自定义 Token 值\r\n * @param urls 模板字符串数组\r\n * @param params 模板参数\r\n * @returns [url, options] 元组\r\n * @example\r\n * this.http.get(...CustomTokenTemplate('my-token', `/api/data`)).subscribe();\r\n */\r\nexport function CustomTokenTemplate(token: string, urls: TemplateStringsArray, ...params: any[]): [string, { headers: HttpHeaders }] {\r\n const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];\r\n return [url, { headers: new HttpHeaders({ [CUSTOM_TOKEN_HEADER]: token }) }];\r\n}\r\n\r\n/**\r\n * 创建使用自定义 Token 和自定义 Header 名称的请求配置\r\n * @param token 自定义 Token 值\r\n * @param headerName 自定义 Header 名称\r\n * @param urls 模板字符串数组\r\n * @param params 模板参数\r\n * @returns [url, options] 元组\r\n * @example\r\n * this.http.get(...CustomTokenWithHeaderTemplate('my-token', 'X-API-Key', `/api/data`)).subscribe();\r\n */\r\nexport function CustomTokenWithHeaderTemplate(\r\n token: string,\r\n headerName: string,\r\n urls: TemplateStringsArray,\r\n ...params: any[]\r\n): [string, { headers: HttpHeaders }] {\r\n const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];\r\n return [\r\n url,\r\n {\r\n headers: new HttpHeaders({\r\n [CUSTOM_TOKEN_HEADER]: token,\r\n [CUSTOM_TOKEN_HEADER_NAME]: headerName,\r\n }),\r\n },\r\n ];\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS, HttpErrorResponse } from '@angular/common/http';\r\nimport { Observable, throwError } from 'rxjs';\r\nimport { catchError } from 'rxjs/operators';\r\nimport { Router } from '@angular/router';\r\nimport { ErrorInterceptorConfig } from './types';\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst DEFAULT_CONFIG: ErrorInterceptorConfig = {\r\n unauthorizedPath: '/errors/401',\r\n enableLogging: false,\r\n};\r\n\r\n/**\r\n * HTTP 错误拦截器\r\n * 统一处理 HTTP 请求错误,包括 401 未授权错误的自动跳转\r\n */\r\n@Injectable()\r\nexport class ErrorInterceptor implements HttpInterceptor {\r\n private config: ErrorInterceptorConfig = DEFAULT_CONFIG;\r\n\r\n constructor(private router: Router) {}\r\n\r\n /**\r\n * 设置拦截器配置\r\n * @param config 配置对象\r\n */\r\n setConfig(config: ErrorInterceptorConfig): void {\r\n this.config = { ...DEFAULT_CONFIG, ...config };\r\n }\r\n\r\n /**\r\n * 拦截 HTTP 请求,处理错误响应\r\n * @param request HTTP 请求对象\r\n * @param next 下一个拦截器处理器\r\n * @returns Observable<HttpEvent<unknown>>\r\n */\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n return next.handle(request).pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n // 处理 401 未授权错误\r\n if (error.status === 401) {\r\n this.handleUnauthorizedError();\r\n return throwError(error);\r\n }\r\n\r\n // 记录错误日志\r\n if (this.config.enableLogging) {\r\n console.error('[HTTP Error]', {\r\n url: request.url,\r\n method: request.method,\r\n status: error.status,\r\n message: error.message,\r\n error: error.error,\r\n });\r\n }\r\n\r\n // 提取错误信息\r\n const errorMessage = this.extractErrorMessage(error);\r\n return throwError(new Error(errorMessage));\r\n }),\r\n );\r\n }\r\n\r\n /**\r\n * 处理 401 未授权错误\r\n */\r\n private handleUnauthorizedError(): void {\r\n const path = this.config.unauthorizedPath || DEFAULT_CONFIG.unauthorizedPath;\r\n this.router.navigate([path]).catch((err) => {\r\n console.error('导航到错误页面失败:', err);\r\n });\r\n }\r\n\r\n /**\r\n * 提取错误信息\r\n * @param error HTTP 错误响应\r\n * @returns 错误信息字符串\r\n */\r\n private extractErrorMessage(error: HttpErrorResponse): string {\r\n if (error.error) {\r\n // 尝试从 error.error 中提取信息\r\n if (typeof error.error === 'string') {\r\n return error.error;\r\n }\r\n if (error.error.msg) {\r\n return error.error.msg;\r\n }\r\n if (error.error.message) {\r\n return error.error.message;\r\n }\r\n }\r\n // 使用默认错误信息\r\n return error.message || `HTTP Error ${error.status}`;\r\n }\r\n}\r\n\r\n/**\r\n * 提供 HTTP 错误拦截器\r\n * @param config 可选的配置对象\r\n * @returns Provider 配置对象\r\n * @example\r\n * providers: [\r\n * providerHttpError({ unauthorizedPath: '/login', enableLogging: true })\r\n * ]\r\n */\r\nexport function providerHttpError(config?: ErrorInterceptorConfig) {\r\n if (config) {\r\n // 如果有配置,使用 useFactory\r\n return {\r\n provide: HTTP_INTERCEPTORS,\r\n useFactory: (router: Router) => {\r\n const interceptor = new ErrorInterceptor(router);\r\n interceptor.setConfig(config);\r\n return interceptor;\r\n },\r\n deps: [Router],\r\n multi: true,\r\n };\r\n } else {\r\n // 没有配置,直接使用 useClass\r\n return {\r\n provide: HTTP_INTERCEPTORS,\r\n useClass: ErrorInterceptor,\r\n multi: true,\r\n };\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HTTP_INTERCEPTORS, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport { shareReplay } from 'rxjs/operators';\r\nimport { RkCacheHttpService } from '@reskin/core/services';\r\n\r\n/**\r\n * 缓存策略标识\r\n */\r\nconst CACHE_HEADER = 'Cache-Map';\r\nconst CACHE_STRATEGY = 'Storage';\r\n\r\n/**\r\n * HTTP 缓存拦截器\r\n * 为 GET 请求提供缓存功能,减少重复请求\r\n */\r\n@Injectable()\r\nexport class CacheInterceptor implements HttpInterceptor {\r\n constructor(private cacheHttpService: RkCacheHttpService) {}\r\n\r\n /**\r\n * 拦截 HTTP 请求,实现缓存逻辑\r\n * @param request HTTP 请求对象\r\n * @param next 下一个拦截器处理器\r\n * @returns Observable<HttpEvent<unknown>>\r\n */\r\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\r\n // 只缓存 GET 请求且明确标记了缓存策略的请求\r\n const cacheStrategy = request.headers.get(CACHE_HEADER);\r\n \r\n if (request.method === 'GET' && cacheStrategy === CACHE_STRATEGY) {\r\n // 尝试从缓存中获取响应\r\n let cachedResponse = this.cacheHttpService.get(request.url);\r\n \r\n if (!cachedResponse) {\r\n // 缓存未命中,发起请求并缓存结果\r\n cachedResponse = next.handle(request).pipe(shareReplay(1));\r\n this.cacheHttpService.set(request.url, cachedResponse);\r\n }\r\n \r\n return cachedResponse;\r\n }\r\n\r\n // 非缓存请求,直接放行\r\n return next.handle(request);\r\n }\r\n}\r\n\r\n/**\r\n * 提供 HTTP 缓存拦截器\r\n * @returns Provider 配置对象\r\n * @example\r\n * providers: [providerHttpCache()]\r\n */\r\nexport function providerHttpCache() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true };\r\n}\r\n\r\n/**\r\n * 创建带缓存标记的 GET 请求配置\r\n * @param urls 模板字符串数组\r\n * @param params 模板参数\r\n * @returns [url, options] 元组\r\n * @example\r\n * this.http.get(...CacheHttpTemplate`/api/data`).subscribe();\r\n */\r\nexport function CacheHttpTemplate(urls: TemplateStringsArray, ...params: any[]): [string, { headers: HttpHeaders }] {\r\n const url = params.length > 0 ? String.raw(urls, ...params) : urls[0];\r\n return [url, { headers: new HttpHeaders({ [CACHE_HEADER]: CACHE_STRATEGY }) }];\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport {\r\n HttpRequest,\r\n HttpHandler,\r\n HttpEvent,\r\n HttpInterceptor,\r\n HttpEventType,\r\n HttpResponse,\r\n HttpErrorResponse,\r\n HTTP_INTERCEPTORS,\r\n} from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport { switchMap, catchError } from 'rxjs/operators';\r\n\r\n/**\r\n * Blob 响应拦截器\r\n * 处理文件下载请求中的 JSON 错误响应\r\n */\r\n@Injectable()\r\nexport class BlobInterceptor implements HttpInterceptor {\r\n /**\r\n * 拦截 HTTP 请求,处理 Blob 类型响应\r\n * @param request HTTP 请求对象\r\n * @param next 下一个拦截器处理器\r\n * @returns Observable<HttpEvent<T>>\r\n */\r\n intercept<T>(request: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {\r\n // 只处理 responseType 为 blob 的请求\r\n if (request.responseType !== 'blob') {\r\n return next.handle(request);\r\n }\r\n\r\n return next.handle(request).pipe(\r\n switchMap((event: HttpEvent<any>) => this.handleBlobResponse(event)),\r\n catchError((error: HttpErrorResponse) => this.handleBlobError(error)),\r\n );\r\n }\r\n\r\n /**\r\n * 处理 Blob 响应事件\r\n * @param event HTTP 事件\r\n * @returns Observable<HttpEvent<any>>\r\n */\r\n private handleBlobResponse(event: HttpEvent<any>): Observable<HttpEvent<any>> {\r\n // 只处理完整的响应事件\r\n if (event.type !== HttpEventType.Response) {\r\n return new Observable((subscriber) => {\r\n subscriber.next(event);\r\n subscriber.complete();\r\n });\r\n }\r\n\r\n // 检查响应体是否为 JSON 类型(通常表示错误)\r\n if (event instanceof HttpResponse && event.body?.type === 'application/json') {\r\n return this.convertBlobToJson(event.body);\r\n }\r\n\r\n return new Observable((subscriber) => {\r\n subscriber.next(event);\r\n subscriber.complete();\r\n });\r\n }\r\n\r\n /**\r\n * 处理 Blob 错误响应\r\n * @param error HTTP 错误响应\r\n * @returns Observable<HttpEvent<any>>\r\n */\r\n private handleBlobError(error: HttpErrorResponse): Observable<HttpEvent<any>> {\r\n // 如果错误响应体是 JSON 类型的 Blob,转换为 JSON 对象\r\n if (error.error?.type === 'application/json') {\r\n return this.convertBlobToJson(error.error);\r\n }\r\n\r\n return new Observable((subscriber) => {\r\n subscriber.error(error);\r\n subscriber.complete();\r\n });\r\n }\r\n\r\n /**\r\n * 将 Blob 转换为 JSON 对象并抛出错误\r\n * @param blob Blob 对象\r\n * @returns Observable<HttpEvent<T>>\r\n */\r\n private convertBlobToJson<T>(blob: Blob): Observable<HttpEvent<T>> {\r\n return new Observable((subscriber) => {\r\n const reader = new FileReader();\r\n \r\n reader.addEventListener('loadend', () => {\r\n try {\r\n const json: T = JSON.parse(reader.result as string);\r\n subscriber.error(json);\r\n } catch (parseError) {\r\n subscriber.error(parseError);\r\n } finally {\r\n subscriber.complete();\r\n }\r\n });\r\n\r\n reader.addEventListener('error', () => {\r\n subscriber.error(new Error('读取 Blob 数据失败'));\r\n subscriber.complete();\r\n });\r\n\r\n reader.readAsText(blob, 'utf-8');\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * 提供 Blob 响应拦截器\r\n * @returns Provider 配置对象\r\n * @example\r\n * providers: [providerDownBlob()]\r\n */\r\nexport function providerDownBlob() {\r\n return { provide: HTTP_INTERCEPTORS, useClass: BlobInterceptor, multi: true };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1"],"mappings":"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"}