@ahoo-wang/fetcher-cosec 3.0.2 → 3.0.5

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
@@ -26,6 +26,7 @@ This package provides seamless integration between the Fetcher HTTP client and t
26
26
  - **⚡ Performance Optimized**: Minimal overhead with connection pooling and caching
27
27
  - **🛠️ TypeScript First**: Complete type definitions with strict type safety
28
28
  - **🔌 Pluggable Architecture**: Modular design for easy integration and customization
29
+ - **⚙️ Simplified Configuration**: One-line setup with `CoSecConfigurer` for minimal configuration overhead
29
30
 
30
31
  ## 🚀 Quick Start
31
32
 
@@ -112,6 +113,70 @@ fetcher.interceptors.response.use(
112
113
  );
113
114
  ```
114
115
 
116
+ ## 🚀 Simplified Setup (Recommended)
117
+
118
+ For a much simpler setup experience, use the `CoSecConfigurer` class which automatically handles all the complex dependency creation and interceptor configuration:
119
+
120
+ ```typescript
121
+ import { Fetcher } from '@ahoo-wang/fetcher';
122
+ import { CoSecConfigurer } from '@ahoo-wang/fetcher-cosec';
123
+
124
+ // Create a Fetcher instance
125
+ const fetcher = new Fetcher({
126
+ baseURL: 'https://api.example.com',
127
+ });
128
+
129
+ // Create CoSec configurer with minimal required configuration
130
+ const configurer = new CoSecConfigurer({
131
+ appId: 'your-app-id',
132
+ tokenRefresher: {
133
+ refresh: async token => {
134
+ // Implement your token refresh logic
135
+ const response = await fetch('/api/auth/refresh', {
136
+ method: 'POST',
137
+ headers: { 'Content-Type': 'application/json' },
138
+ body: JSON.stringify({ refreshToken: token.refreshToken }),
139
+ });
140
+
141
+ if (!response.ok) {
142
+ throw new Error('Token refresh failed');
143
+ }
144
+
145
+ const tokens = await response.json();
146
+ return {
147
+ accessToken: tokens.accessToken,
148
+ refreshToken: tokens.refreshToken,
149
+ };
150
+ },
151
+ },
152
+ // Optional: Custom error handlers (only add interceptors if provided)
153
+ onUnauthorized: exchange => {
154
+ console.error('Unauthorized access:', exchange.request.url);
155
+ // Redirect to login or handle as needed
156
+ window.location.href = '/login';
157
+ },
158
+ onForbidden: async exchange => {
159
+ console.error('Forbidden access:', exchange.request.url);
160
+ // Show permission error
161
+ alert('You do not have permission to access this resource');
162
+ }
163
+ });
164
+
165
+ // Apply all CoSec interceptors with one call
166
+ configurer.applyTo(fetcher);
167
+
168
+ // Now you can use the fetcher with full CoSec authentication
169
+ const response = await fetcher.get('/protected-endpoint');
170
+ ```
171
+
172
+ ### Benefits of CoSecConfigurer
173
+
174
+ - ✅ **One-line setup**: `configurer.applyTo(fetcher)` configures everything
175
+ - ✅ **Minimal configuration**: Only `appId` and `tokenRefresher` are required
176
+ - ✅ **Sensible defaults**: Automatic error handling and parameter names
177
+ - ✅ **Type-safe**: Full TypeScript support with intelligent defaults
178
+ - ✅ **Backward compatible**: Original manual setup still works
179
+
115
180
  ## 🔧 Configuration
116
181
 
117
182
  ### CoSecOptions Interface
@@ -163,6 +228,45 @@ The interceptor automatically adds the following headers to requests:
163
228
 
164
229
  ### Core Classes
165
230
 
231
+ #### CoSecConfigurer
232
+
233
+ The recommended way to configure CoSec authentication. Provides a simplified API that automatically creates and configures all necessary interceptors and dependencies.
234
+
235
+ ```typescript
236
+ const configurer = new CoSecConfigurer({
237
+ appId: 'your-app-id',
238
+ tokenRefresher: {
239
+ refresh: async token => {
240
+ // Your token refresh implementation
241
+ return {
242
+ accessToken: 'new-access-token',
243
+ refreshToken: 'new-refresh-token',
244
+ };
245
+ },
246
+ },
247
+ // Optional error handlers (interceptors only added if provided)
248
+ onUnauthorized: exchange => {
249
+ /* handle 401 */
250
+ },
251
+ onForbidden: async exchange => {
252
+ /* handle 403 */
253
+ },
254
+ tenantId: 'tenantId', // default: 'tenantId'
255
+ ownerId: 'ownerId', // default: 'ownerId'
256
+ });
257
+
258
+ configurer.applyTo(fetcher);
259
+ ```
260
+
261
+ **Automatically Configured Interceptors:**
262
+
263
+ - `CoSecRequestInterceptor` - Adds CoSec headers
264
+ - `AuthorizationRequestInterceptor` - Adds Bearer token
265
+ - `ResourceAttributionRequestInterceptor` - Adds tenant/owner parameters
266
+ - `AuthorizationResponseInterceptor` - Handles token refresh
267
+ - `UnauthorizedErrorInterceptor` - Handles 401 errors
268
+ - `ForbiddenErrorInterceptor` - Handles 403 errors
269
+
166
270
  #### AuthorizationRequestInterceptor
167
271
 
168
272
  Automatically adds CoSec authentication headers to outgoing HTTP requests.
package/README.zh-CN.md CHANGED
@@ -26,6 +26,7 @@
26
26
  - **⚡ 性能优化**:最小开销,支持连接池和缓存
27
27
  - **🛠️ TypeScript 优先**:完整类型定义,严格类型安全
28
28
  - **🔌 可插拔架构**:模块化设计,易于集成和定制
29
+ - **⚙️ 简化配置**:使用 `CoSecConfigurer` 的一行设置,最小化配置开销
29
30
 
30
31
  ## 🚀 快速开始
31
32
 
@@ -112,6 +113,70 @@ fetcher.interceptors.response.use(
112
113
  );
113
114
  ```
114
115
 
116
+ ## 🚀 简化设置(推荐)
117
+
118
+ 为了获得更简单的设置体验,请使用 `CoSecConfigurer` 类,它会自动处理所有复杂的依赖创建和拦截器配置:
119
+
120
+ ```typescript
121
+ import { Fetcher } from '@ahoo-wang/fetcher';
122
+ import { CoSecConfigurer } from '@ahoo-wang/fetcher-cosec';
123
+
124
+ // 创建 Fetcher 实例
125
+ const fetcher = new Fetcher({
126
+ baseURL: 'https://api.example.com',
127
+ });
128
+
129
+ // 使用最少的必需配置创建 CoSec 配置器
130
+ const configurer = new CoSecConfigurer({
131
+ appId: 'your-app-id',
132
+ tokenRefresher: {
133
+ refresh: async token => {
134
+ // 实现您的令牌刷新逻辑
135
+ const response = await fetch('/api/auth/refresh', {
136
+ method: 'POST',
137
+ headers: { 'Content-Type': 'application/json' },
138
+ body: JSON.stringify({ refreshToken: token.refreshToken }),
139
+ });
140
+
141
+ if (!response.ok) {
142
+ throw new Error('Token refresh failed');
143
+ }
144
+
145
+ const tokens = await response.json();
146
+ return {
147
+ accessToken: tokens.accessToken,
148
+ refreshToken: tokens.refreshToken,
149
+ };
150
+ },
151
+ },
152
+ // 可选:自定义错误处理器(仅在提供时才添加拦截器)
153
+ onUnauthorized: exchange => {
154
+ console.error('未授权访问:', exchange.request.url);
155
+ // 重定向到登录或根据需要处理
156
+ window.location.href = '/login';
157
+ },
158
+ onForbidden: async exchange => {
159
+ console.error('禁止访问:', exchange.request.url);
160
+ // 显示权限错误
161
+ alert('您没有权限访问此资源');
162
+ }
163
+ });
164
+
165
+ // 使用一次调用应用所有 CoSec 拦截器
166
+ configurer.applyTo(fetcher);
167
+
168
+ // 现在您可以使用具有完整 CoSec 认证的 fetcher
169
+ const response = await fetcher.get('/protected-endpoint');
170
+ ```
171
+
172
+ ### CoSecConfigurer 的优势
173
+
174
+ - ✅ **一行设置**:`configurer.applyTo(fetcher)` 配置一切
175
+ - ✅ **最小配置**:仅需要 `appId` 和 `tokenRefresher`
176
+ - ✅ **合理的默认值**:自动错误处理和参数名称
177
+ - ✅ **类型安全**:完整的 TypeScript 支持和智能默认值
178
+ - ✅ **向后兼容**:原始手动设置仍然有效
179
+
115
180
  ## 🔧 配置
116
181
 
117
182
  ### CoSecOptions 接口
@@ -163,6 +228,45 @@ interface JwtTokenManagerCapable {
163
228
 
164
229
  ### 核心类
165
230
 
231
+ #### CoSecConfigurer
232
+
233
+ 配置 CoSec 认证的推荐方式。提供简化的 API,自动创建和配置所有必要的拦截器和依赖项。
234
+
235
+ ```typescript
236
+ const configurer = new CoSecConfigurer({
237
+ appId: 'your-app-id',
238
+ tokenRefresher: {
239
+ refresh: async token => {
240
+ // 您的令牌刷新实现
241
+ return {
242
+ accessToken: 'new-access-token',
243
+ refreshToken: 'new-refresh-token',
244
+ };
245
+ },
246
+ },
247
+ // 可选错误处理器(仅在提供时才添加拦截器)
248
+ onUnauthorized: exchange => {
249
+ /* 处理 401 */
250
+ },
251
+ onForbidden: async exchange => {
252
+ /* 处理 403 */
253
+ },
254
+ tenantId: 'tenantId', // 默认: 'tenantId'
255
+ ownerId: 'ownerId', // 默认: 'ownerId'
256
+ });
257
+
258
+ configurer.applyTo(fetcher);
259
+ ```
260
+
261
+ **自动配置的拦截器:**
262
+
263
+ - `CoSecRequestInterceptor` - 添加 CoSec 头部
264
+ - `AuthorizationRequestInterceptor` - 添加 Bearer 令牌
265
+ - `ResourceAttributionRequestInterceptor` - 添加租户/所有者参数
266
+ - `AuthorizationResponseInterceptor` - 处理令牌刷新
267
+ - `UnauthorizedErrorInterceptor` - 处理 401 错误
268
+ - `ForbiddenErrorInterceptor` - 处理 403 错误
269
+
166
270
  #### AuthorizationRequestInterceptor
167
271
 
168
272
  自动向传出 HTTP 请求添加 CoSec 认证头部。
@@ -0,0 +1,88 @@
1
+ import { Fetcher, FetcherConfigurer, FetchExchange } from '@ahoo-wang/fetcher';
2
+ import { DeviceIdStorage } from './deviceIdStorage';
3
+ import { JwtTokenManager } from './jwtTokenManager';
4
+ import { TokenRefresher } from './tokenRefresher';
5
+ import { TokenStorage } from './tokenStorage';
6
+ /**
7
+ * Simplified configuration interface for CoSec setup.
8
+ * Only requires the essential configuration, with sensible defaults for everything else.
9
+ */
10
+ export interface CoSecConfig {
11
+ /**
12
+ * Application ID to be sent in the CoSec-App-Id header.
13
+ * This is required for identifying your application in the CoSec system.
14
+ */
15
+ appId: string;
16
+ /**
17
+ * Token refresher implementation for handling expired tokens.
18
+ * This is required to enable automatic token refresh functionality.
19
+ */
20
+ tokenRefresher: TokenRefresher;
21
+ /**
22
+ * Callback function invoked when an unauthorized (401) response is detected.
23
+ * If not provided, defaults to throwing an error.
24
+ */
25
+ onUnauthorized?: (exchange: FetchExchange) => Promise<void> | void;
26
+ /**
27
+ * Callback function invoked when a forbidden (403) response is detected.
28
+ * If not provided, 403 errors will not be intercepted.
29
+ */
30
+ onForbidden?: (exchange: FetchExchange) => Promise<void>;
31
+ }
32
+ /**
33
+ * CoSecConfigurer provides a simplified way to configure all CoSec interceptors
34
+ * and dependencies with a single configuration object.
35
+ *
36
+ * This class automatically creates all necessary dependencies (TokenStorage, DeviceIdStorage,
37
+ * JwtTokenManager) and configures all CoSec interceptors with sensible defaults.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const configurer = new CoSecConfigurer({
42
+ * appId: 'my-app-001',
43
+ * tokenRefresher: {
44
+ * refresh: async (token: CompositeToken) => {
45
+ * // Your token refresh logic here
46
+ * const response = await fetch('/api/auth/refresh', {
47
+ * method: 'POST',
48
+ * body: JSON.stringify({ refreshToken: token.refreshToken }),
49
+ * });
50
+ * const newTokens = await response.json();
51
+ * return {
52
+ * accessToken: newTokens.accessToken,
53
+ * refreshToken: newTokens.refreshToken,
54
+ * };
55
+ * },
56
+ * },
57
+ * });
58
+ *
59
+ * configurer.applyTo(fetcher);
60
+ * ```
61
+ */
62
+ export declare class CoSecConfigurer implements FetcherConfigurer {
63
+ readonly config: CoSecConfig;
64
+ readonly tokenStorage: TokenStorage;
65
+ readonly deviceIdStorage: DeviceIdStorage;
66
+ readonly tokenManager: JwtTokenManager;
67
+ /**
68
+ * Creates a new CoSecConfigurer instance with the provided configuration.
69
+ *
70
+ * @param config - Simplified CoSec configuration
71
+ */
72
+ constructor(config: CoSecConfig);
73
+ /**
74
+ * Applies all CoSec interceptors to the provided Fetcher instance.
75
+ *
76
+ * This method configures the following interceptors in the correct order:
77
+ * 1. CoSecRequestInterceptor - Adds CoSec headers (appId, deviceId, requestId)
78
+ * 2. AuthorizationRequestInterceptor - Adds Authorization header with Bearer token
79
+ * 3. ResourceAttributionRequestInterceptor - Adds tenant/owner path parameters
80
+ * 4. AuthorizationResponseInterceptor - Handles 401 responses with token refresh
81
+ * 5. UnauthorizedErrorInterceptor - Handles unauthorized errors
82
+ * 6. ForbiddenErrorInterceptor - Handles forbidden errors
83
+ *
84
+ * @param fetcher - The Fetcher instance to configure
85
+ */
86
+ applyTo(fetcher: Fetcher): void;
87
+ }
88
+ //# sourceMappingURL=cosecConfigurer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cosecConfigurer.d.ts","sourceRoot":"","sources":["../src/cosecConfigurer.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAI/E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEnE;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,eAAgB,YAAW,iBAAiB;aAU3B,MAAM,EAAE,WAAW;IAT/C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IAEvC;;;;OAIG;gBACyB,MAAM,EAAE,WAAW;IAY/C;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;CA0ChC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './authorizationRequestInterceptor';
2
2
  export * from './authorizationResponseInterceptor';
3
+ export * from './cosecConfigurer';
3
4
  export * from './cosecRequestInterceptor';
4
5
  export * from './deviceIdStorage';
5
6
  export * from './idGenerator';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,yCAAyC,CAAC;AACxD,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,yCAAyC,CAAC;AACxD,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC"}