class-resolver 2.1.1 → 2.2.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.
package/README.md CHANGED
@@ -10,6 +10,8 @@ A lightweight TypeScript/JavaScript library for implementing the Chain of Respon
10
10
  - Support for multiple resolvers with different handling logic
11
11
  - Clear error handling for unsupported types
12
12
  - Generic type support for better type safety
13
+ - **Fallback handler support for graceful handling of unsupported types**
14
+ - **Method chaining support for fluent API usage**
13
15
 
14
16
  ## Installation
15
17
 
@@ -55,6 +57,27 @@ try {
55
57
  }
56
58
  ```
57
59
 
60
+ ## Fallback Handler Usage
61
+
62
+ The fallback handler allows you to gracefully handle unsupported types without throwing errors:
63
+
64
+ ```typescript
65
+ const resolver = new Resolver(new ExampleClass(), new ExampleClass2())
66
+
67
+ // Set a fallback handler for unsupported types
68
+ resolver.setFallbackHandler((type) => {
69
+ return `Fallback: ${type}`
70
+ })
71
+
72
+ // Now unsupported types will use the fallback handler instead of throwing errors
73
+ const result = resolver.resolve('xxx')
74
+ console.log(result.handle('xxx')) // Output: Fallback: xxx
75
+
76
+ // Supported types still work normally
77
+ const c = resolver.resolve('hoge')
78
+ console.log(c.handle()) // Output: hoge
79
+ ```
80
+
58
81
  ## Advanced Usage
59
82
 
60
83
  ### With TypeScript and Parameters
@@ -113,6 +136,33 @@ resolver.addUpdater(new MessageFormatter())
113
136
  resolver.addUpdater(new ErrorFormatter())
114
137
  ```
115
138
 
139
+ ### Fallback Handler with TypeScript
140
+
141
+ The fallback handler maintains full type safety and automatically infers types from your resolver configuration:
142
+
143
+ ```typescript
144
+ // Create a resolver with specific types
145
+ const resolver = new Resolver<ResolveTarget<[string, number], string>>(
146
+ new MessageFormatter()
147
+ )
148
+
149
+ // Set a fallback handler with the same type signature
150
+ resolver.setFallbackHandler((name: string, count: number): string => {
151
+ return `Default greeting for ${name} (message #${count})`
152
+ })
153
+
154
+ // The fallback handler will be used for unsupported types
155
+ const result = resolver.resolve('unknown').handle('John', 5)
156
+ console.log(result) // Output: Default greeting for John (message #5)
157
+
158
+ // Method chaining is also supported
159
+ resolver
160
+ .setFallbackHandler((name: string, count: number): string => {
161
+ return `Custom fallback: ${name} - ${count}`
162
+ })
163
+ .addUpdater(new ErrorFormatter())
164
+ ```
165
+
116
166
  ## Generic Type Support
117
167
 
118
168
  From version 2.0.0, class-resolver supports generic types for better type safety:
@@ -209,6 +259,9 @@ This advanced type support allows you to:
209
259
  3. **Request Processing**: Process different types of requests with dedicated handlers
210
260
  4. **Plugin System**: Implement a plugin system where different plugins handle specific types of operations
211
261
  5. **Message Formatting**: Format different types of messages with specific formatters
262
+ 6. **Graceful Degradation**: Use fallback handlers to provide default behavior for unknown types
263
+ 7. **API Versioning**: Handle different API versions with fallback to backward-compatible behavior
264
+ 8. **Feature Flags**: Implement feature flags with fallback to basic functionality
212
265
 
213
266
  ## Error Handling
214
267
 
@@ -216,6 +269,26 @@ The resolver will throw errors in the following cases:
216
269
  - When no resolvers are registered: `"Unasigned resolve target."`
217
270
  - When trying to resolve an unsupported type: `"Unsupported type: xxx"`
218
271
 
272
+ ### Fallback Handler for Error Prevention
273
+
274
+ With the fallback handler, you can prevent errors for unsupported types:
275
+
276
+ ```typescript
277
+ const resolver = new Resolver(new ExampleClass())
278
+
279
+ // Without fallback handler - throws error
280
+ try {
281
+ resolver.resolve('unknown')
282
+ } catch (e) {
283
+ console.log(e) // Error: Unsupported type: unknown
284
+ }
285
+
286
+ // With fallback handler - no error thrown
287
+ resolver.setFallbackHandler((type) => `Default: ${type}`)
288
+ const result = resolver.resolve('unknown') // No error, uses fallback
289
+ console.log(result.handle('unknown')) // Output: Default: unknown
290
+ ```
291
+
219
292
  ## Upgrade Guide
220
293
 
221
294
  ### Upgrading from 1.x to 2.0.0
@@ -9,6 +9,11 @@ declare class Resolver<TBase extends ResolveTarget<any[], any, any> = ResolveTar
9
9
  * @private
10
10
  */
11
11
  private updaters;
12
+ /**
13
+ * Fallback handler function
14
+ * @private
15
+ */
16
+ private fallbackHandler?;
12
17
  /**
13
18
  * Initializes the resolver
14
19
  * @param args Initial resolver targets
@@ -35,13 +40,19 @@ declare class Resolver<TBase extends ResolveTarget<any[], any, any> = ResolveTar
35
40
  * Adds a resolver target
36
41
  * @param updater Resolver target to add
37
42
  */
38
- addUpdater(updater: TBase): void;
43
+ addUpdater(updater: TBase): this;
44
+ /**
45
+ * Sets a fallback handler for unsupported types
46
+ * @param handler Fallback handler function
47
+ * @returns This resolver instance for method chaining
48
+ */
49
+ setFallbackHandler(handler: (...args: Parameters<TBase['handle']>) => ReturnType<TBase['handle']>): this;
39
50
  /**
40
51
  * Resolves a resolver target for the specified type
41
52
  * @param type Type to resolve
42
53
  * @returns Resolved resolver target
43
54
  * @throws {Error} When no resolver targets are registered
44
- * @throws {Error} When no resolver target supporting the specified type is found
55
+ * @throws {Error} When no resolver target supporting the specified type is found and no fallback is set
45
56
  */
46
57
  resolve(type: TType): TBase;
47
58
  }
package/dist/resolver.js CHANGED
@@ -48,13 +48,23 @@ class Resolver {
48
48
  */
49
49
  addUpdater(updater) {
50
50
  this.updaters.push(updater);
51
+ return this;
52
+ }
53
+ /**
54
+ * Sets a fallback handler for unsupported types
55
+ * @param handler Fallback handler function
56
+ * @returns This resolver instance for method chaining
57
+ */
58
+ setFallbackHandler(handler) {
59
+ this.fallbackHandler = handler;
60
+ return this;
51
61
  }
52
62
  /**
53
63
  * Resolves a resolver target for the specified type
54
64
  * @param type Type to resolve
55
65
  * @returns Resolved resolver target
56
66
  * @throws {Error} When no resolver targets are registered
57
- * @throws {Error} When no resolver target supporting the specified type is found
67
+ * @throws {Error} When no resolver target supporting the specified type is found and no fallback is set
58
68
  */
59
69
  resolve(type) {
60
70
  if (this.updaters.length < 1) {
@@ -62,6 +72,13 @@ class Resolver {
62
72
  }
63
73
  const target = this.updaters.find(updater => updater.supports(type));
64
74
  if (!target) {
75
+ // If fallback handler is set, create a temporary target that uses it
76
+ if (this.fallbackHandler) {
77
+ return {
78
+ supports: () => true,
79
+ handle: this.fallbackHandler
80
+ };
81
+ }
65
82
  // Determine the string representation of the unsupported type
66
83
  // If it's a non-null object, use JSON.stringify for detailed output
67
84
  // Otherwise, use String() for basic conversion
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../libs/resolver.ts"],"names":[],"mappings":";;AAEA;;;GAGG;AACH,MAAM,QAAQ;IAOZ;;;OAGG;IACH,YAAY,GAAG,IAAa;QAV5B;;;WAGG;QACK,aAAQ,GAAY,EAAE,CAAC;QAO7B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,OAAO,CAAC,IAAa;QAC3B,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACnB,CAAC;IAED;;;OAGG;IACI,GAAG,CAAC,QAAiB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACI,WAAW,CAAC,GAAG,IAAa;QACjC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,OAAc;QAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;;OAMG;IACI,OAAO,CAAC,IAAW;QACxB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAErE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,8DAA8D;YAC9D,oEAAoE;YACpE,+CAA+C;YAC/C,MAAM,UAAU,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnG,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,kBAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../libs/resolver.ts"],"names":[],"mappings":";;AAEA;;;GAGG;AACH,MAAM,QAAQ;IAaZ;;;OAGG;IACH,YAAY,GAAG,IAAa;QAhB5B;;;WAGG;QACK,aAAQ,GAAY,EAAE,CAAC;QAa7B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,OAAO,CAAC,IAAa;QAC3B,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACnB,CAAC;IAED;;;OAGG;IACI,GAAG,CAAC,QAAiB;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACI,WAAW,CAAC,GAAG,IAAa;QACjC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,OAAc;QAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACI,kBAAkB,CACvB,OAA8E;QAE9E,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACI,OAAO,CAAC,IAAW;QACxB,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAErE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,qEAAqE;YACrE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,OAAO;oBACL,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI;oBACpB,MAAM,EAAE,IAAI,CAAC,eAAe;iBACT,CAAC;YACxB,CAAC;YAED,8DAA8D;YAC9D,oEAAoE;YACpE,+CAA+C;YAC/C,MAAM,UAAU,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnG,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED,kBAAe,QAAQ,CAAC"}
package/libs/resolver.ts CHANGED
@@ -11,6 +11,12 @@ class Resolver<TBase extends ResolveTarget<any[], any, any> = ResolveTarget<any[
11
11
  */
12
12
  private updaters: TBase[] = [];
13
13
 
14
+ /**
15
+ * Fallback handler function
16
+ * @private
17
+ */
18
+ private fallbackHandler?: (...args: Parameters<TBase['handle']>) => ReturnType<TBase['handle']>;
19
+
14
20
  /**
15
21
  * Initializes the resolver
16
22
  * @param args Initial resolver targets
@@ -51,8 +57,21 @@ class Resolver<TBase extends ResolveTarget<any[], any, any> = ResolveTarget<any[
51
57
  * Adds a resolver target
52
58
  * @param updater Resolver target to add
53
59
  */
54
- public addUpdater(updater: TBase): void {
60
+ public addUpdater(updater: TBase): this {
55
61
  this.updaters.push(updater);
62
+ return this;
63
+ }
64
+
65
+ /**
66
+ * Sets a fallback handler for unsupported types
67
+ * @param handler Fallback handler function
68
+ * @returns This resolver instance for method chaining
69
+ */
70
+ public setFallbackHandler(
71
+ handler: (...args: Parameters<TBase['handle']>) => ReturnType<TBase['handle']>
72
+ ): this {
73
+ this.fallbackHandler = handler;
74
+ return this;
56
75
  }
57
76
 
58
77
  /**
@@ -60,7 +79,7 @@ class Resolver<TBase extends ResolveTarget<any[], any, any> = ResolveTarget<any[
60
79
  * @param type Type to resolve
61
80
  * @returns Resolved resolver target
62
81
  * @throws {Error} When no resolver targets are registered
63
- * @throws {Error} When no resolver target supporting the specified type is found
82
+ * @throws {Error} When no resolver target supporting the specified type is found and no fallback is set
64
83
  */
65
84
  public resolve(type: TType): TBase {
66
85
  if (this.updaters.length < 1) {
@@ -70,6 +89,14 @@ class Resolver<TBase extends ResolveTarget<any[], any, any> = ResolveTarget<any[
70
89
  const target = this.updaters.find(updater => updater.supports(type));
71
90
 
72
91
  if (!target) {
92
+ // If fallback handler is set, create a temporary target that uses it
93
+ if (this.fallbackHandler) {
94
+ return {
95
+ supports: () => true,
96
+ handle: this.fallbackHandler
97
+ } as unknown as TBase;
98
+ }
99
+
73
100
  // Determine the string representation of the unsupported type
74
101
  // If it's a non-null object, use JSON.stringify for detailed output
75
102
  // Otherwise, use String() for basic conversion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "class-resolver",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "Simple class resolver.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme-ja.md CHANGED
@@ -10,6 +10,8 @@
10
10
  - 異なる処理ロジックを持つ複数のリゾルバーのサポート
11
11
  - サポートされていないタイプに対する明確なエラー処理
12
12
  - より良い型安全性のためのジェネリック型サポート
13
+ - **サポートされていないタイプのためのフォールバックハンドラーサポート**
14
+ - **メソッドチェーンサポートによる流れるようなAPI**
13
15
 
14
16
  ## インストール
15
17
 
@@ -55,6 +57,27 @@ try {
55
57
  }
56
58
  ```
57
59
 
60
+ ## フォールバックハンドラーの使い方
61
+
62
+ フォールバックハンドラーを使用すると、サポートされていないタイプをエラーをスローすることなく適切に処理できます:
63
+
64
+ ```typescript
65
+ const resolver = new Resolver(new ExampleClass(), new ExampleClass2())
66
+
67
+ // サポートされていないタイプのためのフォールバックハンドラーを設定
68
+ resolver.setFallbackHandler((type) => {
69
+ return `フォールバック: ${type}`
70
+ })
71
+
72
+ // これでサポートされていないタイプはエラーをスローせずにフォールバックハンドラーが使用されます
73
+ const result = resolver.resolve('xxx')
74
+ console.log(result.handle('xxx')) // 出力: フォールバック: xxx
75
+
76
+ // サポートされているタイプは通常通り動作します
77
+ const c = resolver.resolve('hoge')
78
+ console.log(c.handle()) // 出力: hoge
79
+ ```
80
+
58
81
  ## 高度な使い方
59
82
 
60
83
  ### TypeScriptとパラメータの使用
@@ -113,6 +136,33 @@ resolver.addUpdater(new MessageFormatter())
113
136
  resolver.addUpdater(new ErrorFormatter())
114
137
  ```
115
138
 
139
+ ### TypeScriptでのフォールバックハンドラー
140
+
141
+ フォールバックハンドラーは完全な型安全性を維持し、リゾルバーの設定から自動的に型を推論します:
142
+
143
+ ```typescript
144
+ // 特定の型でリゾルバーを作成
145
+ const resolver = new Resolver<ResolveTarget<[string, number], string>>(
146
+ new MessageFormatter()
147
+ )
148
+
149
+ // 同じ型シグネチャでフォールバックハンドラーを設定
150
+ resolver.setFallbackHandler((name: string, count: number): string => {
151
+ return `${name}のデフォルトの挨拶(メッセージ #${count})`
152
+ })
153
+
154
+ // フォールバックハンドラーはサポートされていないタイプに使用されます
155
+ const result = resolver.resolve('unknown').handle('田中', 5)
156
+ console.log(result) // 出力: 田中 のデフォルトの挨拶(メッセージ #5)
157
+
158
+ // メソッドチェーンもサポートされています
159
+ resolver
160
+ .setFallbackHandler((name: string, count: number): string => {
161
+ return `カスタムフォールバック: ${name} - ${count}`
162
+ })
163
+ .addUpdater(new ErrorFormatter())
164
+ ```
165
+
116
166
  ## ジェネリック型サポート
117
167
 
118
168
  バージョン2.0.0から、class-resolverはより良い型安全性のためにジェネリック型をサポートしています:
@@ -148,6 +198,9 @@ const result = formatter.handle('hello'); // resultはstring型として型付
148
198
  3. **リクエスト処理**: 専用のハンドラーで異なるタイプのリクエストを処理
149
199
  4. **プラグインシステム**: 異なるプラグインが特定のタイプの操作を処理するプラグインシステムを実装
150
200
  5. **メッセージフォーマット**: 特定のフォーマッターで異なるタイプのメッセージをフォーマット
201
+ 6. **適切な機能低下**: フォールバックハンドラーを使用して未知のタイプのデフォルト動作を提供
202
+ 7. **APIバージョニング**: フォールバックを使用して後方互換性のある動作で異なるAPIバージョンを処理
203
+ 8. **フィーチャーフラグ**: フォールバックを使用して基本的な機能にフィーチャーフラグを実装
151
204
 
152
205
  ## エラー処理
153
206
 
@@ -155,6 +208,26 @@ const result = formatter.handle('hello'); // resultはstring型として型付
155
208
  - リゾルバーが登録されていない場合: `"Unasigned resolve target."`
156
209
  - サポートされていないタイプを解決しようとした場合: `"Unsupported type: xxx"`
157
210
 
211
+ ### フォールバックハンドラーによるエラー防止
212
+
213
+ フォールバックハンドラーを使用すると、サポートされていないタイプのエラーを防ぐことができます:
214
+
215
+ ```typescript
216
+ const resolver = new Resolver(new ExampleClass())
217
+
218
+ // フォールバックハンドラーなし - エラーがスローされる
219
+ try {
220
+ resolver.resolve('unknown')
221
+ } catch (e) {
222
+ console.log(e) // Error: Unsupported type: unknown
223
+ }
224
+
225
+ // フォールバックハンドラーあり - エラーはスローされない
226
+ resolver.setFallbackHandler((type) => `デフォルト: ${type}`)
227
+ const result = resolver.resolve('unknown') // エラーなし、フォールバックが使用される
228
+ console.log(result.handle('unknown')) // 出力: デフォルト: unknown
229
+ ```
230
+
158
231
  ## アップグレードガイド
159
232
 
160
233
  ### 1.xから2.0.0へのアップグレード