@ahoo-wang/fetcher-decorator 1.3.3 → 1.5.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/dist/index.es.js CHANGED
@@ -1,88 +1,89 @@
1
- import { HttpMethod as c, fetcherRegistrar as A, Fetcher as g, fetcher as M, mergeRequest as v, combineURLs as D } from "@ahoo-wang/fetcher";
1
+ import { HttpMethod as c, JsonResultExtractor as P, TextResultExtractor as M, ResponseResultExtractor as v, ExchangeResultExtractor as D, fetcherRegistrar as O, Fetcher as g, fetcher as w, mergeRequest as H, combineURLs as S } from "@ahoo-wang/fetcher";
2
2
  import "reflect-metadata";
3
- const q = Symbol("endpoint:metadata");
4
- function d(t, e, r = {}) {
3
+ import { JsonEventStreamResultExtractor as F, EventStreamResultExtractor as _ } from "@ahoo-wang/fetcher-eventstream";
4
+ const T = Symbol("endpoint:metadata");
5
+ function u(t, e, r = {}) {
5
6
  return function(n, a) {
6
- const s = {
7
+ const o = {
7
8
  method: t,
8
9
  path: e,
9
10
  ...r
10
11
  };
11
12
  Reflect.defineMetadata(
12
- q,
13
- s,
13
+ T,
14
+ o,
14
15
  n,
15
16
  a
16
17
  );
17
18
  };
18
19
  }
19
- function tt(t = "", e = {}) {
20
- return d(c.GET, t, e);
21
- }
22
- function et(t = "", e = {}) {
23
- return d(c.POST, t, e);
24
- }
25
20
  function rt(t = "", e = {}) {
26
- return d(c.PUT, t, e);
21
+ return u(c.GET, t, e);
27
22
  }
28
23
  function nt(t = "", e = {}) {
29
- return d(c.DELETE, t, e);
24
+ return u(c.POST, t, e);
30
25
  }
31
26
  function at(t = "", e = {}) {
32
- return d(c.PATCH, t, e);
27
+ return u(c.PUT, t, e);
28
+ }
29
+ function ot(t = "", e = {}) {
30
+ return u(c.DELETE, t, e);
33
31
  }
34
32
  function st(t = "", e = {}) {
35
- return d(c.HEAD, t, e);
33
+ return u(c.PATCH, t, e);
36
34
  }
37
- function ot(t = "", e = {}) {
38
- return d(c.OPTIONS, t, e);
35
+ function it(t = "", e = {}) {
36
+ return u(c.HEAD, t, e);
37
+ }
38
+ function ct(t = "", e = {}) {
39
+ return u(c.OPTIONS, t, e);
39
40
  }
40
- const f = /* @__PURE__ */ new WeakMap();
41
- function w(t) {
41
+ const m = /* @__PURE__ */ new WeakMap();
42
+ function N(t) {
42
43
  if (typeof t != "function")
43
44
  throw new TypeError("Expected a function");
44
- if (f.has(t))
45
- return f.get(t);
45
+ if (m.has(t))
46
+ return m.get(t);
46
47
  try {
47
- const e = t.toString().trim(), r = H(e);
48
- if (!S(r)) {
48
+ const e = t.toString().trim(), r = k(e);
49
+ if (!Y(r)) {
49
50
  const a = [];
50
- return f.set(t, a), a;
51
+ return m.set(t, a), a;
51
52
  }
52
- const n = F(r);
53
- return f.set(t, n), n;
53
+ const n = C(r);
54
+ return m.set(t, n), n;
54
55
  } catch {
55
56
  const e = [];
56
- return f.set(t, e), e;
57
+ return m.set(t, e), e;
57
58
  }
58
59
  }
59
- function O(t, e, r, n) {
60
+ function U(t, e, r, n) {
60
61
  if (n)
61
62
  return n;
62
63
  try {
63
64
  const a = t[e];
64
65
  if (a && typeof a == "function") {
65
- const s = w(a);
66
- if (r < s.length)
67
- return s[r];
66
+ const o = N(a);
67
+ if (r < o.length)
68
+ return o[r];
68
69
  }
69
70
  } catch {
70
71
  }
71
72
  }
72
- function S(t) {
73
+ function Y(t) {
73
74
  return t != null && t.trim() !== "";
74
75
  }
75
- function H(t) {
76
+ function k(t) {
76
77
  if (t.startsWith("(")) {
77
- const n = P(t, 0);
78
+ const n = x(t, 0);
78
79
  return n === -1 ? "" : t.substring(1, n);
79
80
  }
80
81
  const e = t.indexOf("(");
81
82
  if (e === -1) return "";
82
- const r = P(t, e);
83
+ const r = x(t, e);
83
84
  return r === -1 ? "" : t.substring(e + 1, r);
84
85
  }
85
- function P(t, e) {
86
+ function x(t, e) {
86
87
  let r = 1;
87
88
  for (let n = e + 1; n < t.length; n++) {
88
89
  const a = t[n];
@@ -93,84 +94,84 @@ function P(t, e) {
93
94
  }
94
95
  return -1;
95
96
  }
96
- function F(t) {
97
- return t.split(",").map(_).filter(N).map(U);
97
+ function C(t) {
98
+ return t.split(",").map(G).filter(I).map(Q);
98
99
  }
99
- function _(t) {
100
+ function G(t) {
100
101
  return t.trim();
101
102
  }
102
- function N(t) {
103
+ function I(t) {
103
104
  return t.length > 0;
104
105
  }
105
- function U(t) {
106
- let e = Y(t);
107
- return e = k(e), e.trim();
106
+ function Q(t) {
107
+ let e = J(t);
108
+ return e = L(e), e.trim();
108
109
  }
109
- function Y(t) {
110
+ function J(t) {
110
111
  const e = t.indexOf("=");
111
112
  return e !== -1 ? t.substring(0, e) : t;
112
113
  }
113
- function k(t) {
114
+ function L(t) {
114
115
  const e = t.indexOf(":");
115
116
  return e !== -1 ? t.substring(0, e) : t;
116
117
  }
117
- var h = /* @__PURE__ */ ((t) => (t.PATH = "path", t.QUERY = "query", t.HEADER = "header", t.BODY = "body", t.REQUEST = "request", t))(h || {});
118
- const l = Symbol("parameter:metadata");
119
- function m(t, e = "") {
118
+ var d = /* @__PURE__ */ ((t) => (t.PATH = "path", t.QUERY = "query", t.HEADER = "header", t.BODY = "body", t.REQUEST = "request", t))(d || {});
119
+ const E = Symbol("parameter:metadata");
120
+ function l(t, e = "") {
120
121
  return function(r, n, a) {
121
- const s = O(
122
+ const o = U(
122
123
  r,
123
124
  n,
124
125
  a,
125
126
  e
126
- ), o = Reflect.getMetadata(l, r, n) || /* @__PURE__ */ new Map(), i = {
127
+ ), i = Reflect.getMetadata(E, r, n) || /* @__PURE__ */ new Map(), h = {
127
128
  type: t,
128
- name: s,
129
+ name: o,
129
130
  index: a
130
131
  };
131
- o.set(a, i), Reflect.defineMetadata(
132
- l,
133
- o,
132
+ i.set(a, h), Reflect.defineMetadata(
133
+ E,
134
+ i,
134
135
  r,
135
136
  n
136
137
  );
137
138
  };
138
139
  }
139
- function it(t = "") {
140
- return m("path", t);
141
- }
142
140
  function ut(t = "") {
143
- return m("query", t);
141
+ return l("path", t);
142
+ }
143
+ function ht(t = "") {
144
+ return l("query", t);
144
145
  }
145
- function ct(t = "") {
146
- return m("header", t);
146
+ function dt(t = "") {
147
+ return l("header", t);
147
148
  }
148
- function dt() {
149
- return m(
149
+ function ft() {
150
+ return l(
150
151
  "body"
151
152
  /* BODY */
152
153
  );
153
154
  }
154
- function ht() {
155
- return m(
155
+ function pt() {
156
+ return l(
156
157
  "request"
157
158
  /* REQUEST */
158
159
  );
159
160
  }
160
- const G = (t) => t, I = (t) => t.requiredResponse, x = (t) => t.requiredResponse.json(), Q = (t) => t.requiredResponse.text(), J = (t) => t.requiredResponse.requiredEventStream(), C = (t) => t.requiredResponse.requiredJsonEventStream(), L = {
161
- Exchange: G,
162
- Response: I,
163
- Json: x,
164
- Text: Q,
165
- EventStream: J,
166
- JsonEventStream: C,
167
- DEFAULT: x
161
+ const W = {
162
+ Exchange: D,
163
+ Response: v,
164
+ Json: P,
165
+ Text: M,
166
+ EventStream: _,
167
+ JsonEventStream: F,
168
+ DEFAULT: P
168
169
  };
169
170
  function j(t) {
170
171
  if (t)
171
- return t instanceof g ? t : A.requiredGet(t);
172
+ return t instanceof g ? t : O.requiredGet(t);
172
173
  }
173
- class W {
174
+ class B {
174
175
  /**
175
176
  * Creates a new FunctionMetadata instance.
176
177
  *
@@ -191,7 +192,7 @@ class W {
191
192
  * @returns The fetcher instance
192
193
  */
193
194
  get fetcher() {
194
- return j(this.endpoint.fetcher ?? this.api.fetcher) ?? M;
195
+ return j(this.endpoint.fetcher ?? this.api.fetcher) ?? w;
195
196
  }
196
197
  /**
197
198
  * Resolves the request configuration from the method arguments.
@@ -244,47 +245,52 @@ class W {
244
245
  ...this.api.headers,
245
246
  ...this.endpoint.headers
246
247
  };
247
- let s, o, i = {};
248
- e.forEach((u, y) => {
249
- if (u instanceof AbortSignal) {
250
- o = u;
248
+ let o, i, h, f = {};
249
+ e.forEach((s, q) => {
250
+ if (s instanceof AbortSignal) {
251
+ i = s;
251
252
  return;
252
253
  }
253
- const p = this.parameters.get(y);
254
+ if (s instanceof AbortController) {
255
+ h = s;
256
+ return;
257
+ }
258
+ const p = this.parameters.get(q);
254
259
  if (p)
255
260
  switch (p.type) {
256
- case h.PATH:
257
- this.processPathParam(p, u, r);
261
+ case d.PATH:
262
+ this.processPathParam(p, s, r);
258
263
  break;
259
- case h.QUERY:
260
- this.processQueryParam(p, u, n);
264
+ case d.QUERY:
265
+ this.processQueryParam(p, s, n);
261
266
  break;
262
- case h.HEADER:
263
- this.processHeaderParam(p, u, a);
267
+ case d.HEADER:
268
+ this.processHeaderParam(p, s, a);
264
269
  break;
265
- case h.BODY:
266
- s = u;
270
+ case d.BODY:
271
+ o = s;
267
272
  break;
268
- case h.REQUEST:
269
- i = this.processRequestParam(u);
273
+ case d.REQUEST:
274
+ f = this.processRequestParam(s);
270
275
  break;
271
276
  }
272
277
  });
273
- const E = {
278
+ const b = {
274
279
  path: r,
275
280
  query: n
276
- }, T = {
281
+ }, A = {
277
282
  method: this.endpoint.method,
278
- urlParams: E,
283
+ urlParams: b,
279
284
  headers: a,
280
- body: s,
285
+ body: o,
281
286
  timeout: this.resolveTimeout(),
282
- signal: o
283
- }, R = v(
284
- T,
285
- i
286
- ), b = i.path;
287
- return R.url = this.resolvePath(b), R;
287
+ signal: i,
288
+ abortController: h
289
+ }, R = H(
290
+ A,
291
+ f
292
+ ), y = f.path;
293
+ return R.url = this.resolvePath(y), R;
288
294
  }
289
295
  processPathParam(e, r, n) {
290
296
  const a = e.name || `param${e.index}`;
@@ -332,7 +338,7 @@ class W {
332
338
  */
333
339
  resolvePath(e) {
334
340
  const r = this.endpoint.basePath || this.api.basePath || "", n = e || this.endpoint.path || "";
335
- return D(r, n);
341
+ return S(r, n);
336
342
  }
337
343
  /**
338
344
  * Resolves the timeout for the request.
@@ -346,11 +352,11 @@ class W {
346
352
  return this.endpoint.timeout || this.api.timeout;
347
353
  }
348
354
  resolveResultExtractor() {
349
- return this.endpoint.resultExtractor || this.api.resultExtractor || L.DEFAULT;
355
+ return this.endpoint.resultExtractor || this.api.resultExtractor || W.DEFAULT;
350
356
  }
351
357
  }
352
- const B = "fetcher";
353
- class $ {
358
+ const $ = "fetcher";
359
+ class K {
354
360
  /**
355
361
  * Creates a new RequestExecutor instance.
356
362
  *
@@ -368,7 +374,7 @@ class $ {
368
374
  getTargetFetcher(e) {
369
375
  if (!e || typeof e != "object")
370
376
  return;
371
- const r = e[B];
377
+ const r = e[$];
372
378
  if (r instanceof g)
373
379
  return r;
374
380
  }
@@ -383,86 +389,80 @@ class $ {
383
389
  * @returns A Promise that resolves to the Response
384
390
  */
385
391
  async execute(e, r) {
386
- const n = this.getTargetFetcher(e) || this.metadata.fetcher, a = this.metadata.resolveRequest(r), s = await n.request(a);
387
- return this.metadata.resolveResultExtractor()(s);
392
+ const n = this.getTargetFetcher(e) || this.metadata.fetcher, a = this.metadata.resolveRequest(r), o = this.metadata.resolveResultExtractor();
393
+ return n.request(a, o);
388
394
  }
389
395
  }
390
- const K = Symbol("api:metadata");
391
- function V(t, e, r) {
396
+ const V = Symbol("api:metadata");
397
+ function z(t, e, r) {
392
398
  const n = t.prototype[e];
393
399
  if (e === "constructor" || typeof n != "function")
394
400
  return;
395
401
  const a = Reflect.getMetadata(
396
- q,
402
+ T,
397
403
  t.prototype,
398
404
  e
399
405
  );
400
406
  if (!a)
401
407
  return;
402
- const s = Reflect.getMetadata(
403
- l,
408
+ const o = Reflect.getMetadata(
409
+ E,
404
410
  t.prototype,
405
411
  e
406
- ) || /* @__PURE__ */ new Map(), o = new W(
412
+ ) || /* @__PURE__ */ new Map(), i = new B(
407
413
  e,
408
414
  r,
409
415
  a,
410
- s
411
- ), i = new $(o);
412
- t.prototype[e] = function(...E) {
413
- return i.execute(this, E);
416
+ o
417
+ ), h = new K(i);
418
+ t.prototype[e] = function(...f) {
419
+ return h.execute(this, f);
414
420
  };
415
421
  }
416
- function pt(t = "", e = {}) {
422
+ function mt(t = "", e = {}) {
417
423
  return function(r) {
418
424
  const n = {
419
425
  basePath: t,
420
426
  ...e
421
427
  };
422
- return Reflect.defineMetadata(K, n, r), Object.getOwnPropertyNames(r.prototype).forEach((a) => {
423
- V(r, a, n);
428
+ return Reflect.defineMetadata(V, n, r), Object.getOwnPropertyNames(r.prototype).forEach((a) => {
429
+ z(r, a, n);
424
430
  }), r;
425
431
  };
426
432
  }
427
- class z extends Error {
433
+ class X extends Error {
428
434
  constructor() {
429
435
  super("Implementation will be generated automatically."), this.name = "AutoGenerated";
430
436
  }
431
437
  }
432
- const ft = (...t) => new z();
438
+ const lt = (...t) => new X();
433
439
  export {
434
- K as API_METADATA_KEY,
435
- z as AutoGenerated,
436
- q as ENDPOINT_METADATA_KEY,
437
- J as EventStreamResultExtractor,
438
- G as ExchangeResultExtractor,
439
- W as FunctionMetadata,
440
- C as JsonEventStreamResultExtractor,
441
- x as JsonResultExtractor,
442
- l as PARAMETER_METADATA_KEY,
443
- h as ParameterType,
444
- $ as RequestExecutor,
445
- I as ResponseResultExtractor,
446
- L as ResultExtractors,
447
- Q as TextResultExtractor,
448
- pt as api,
449
- ft as autoGeneratedError,
450
- dt as body,
451
- nt as del,
452
- d as endpoint,
453
- tt as get,
440
+ V as API_METADATA_KEY,
441
+ X as AutoGenerated,
442
+ T as ENDPOINT_METADATA_KEY,
443
+ B as FunctionMetadata,
444
+ E as PARAMETER_METADATA_KEY,
445
+ d as ParameterType,
446
+ K as RequestExecutor,
447
+ W as ResultExtractors,
448
+ mt as api,
449
+ lt as autoGeneratedError,
450
+ ft as body,
451
+ ot as del,
452
+ u as endpoint,
453
+ rt as get,
454
454
  j as getFetcher,
455
- O as getParameterName,
456
- w as getParameterNames,
457
- st as head,
458
- ct as header,
459
- ot as options,
460
- m as parameter,
461
- at as patch,
462
- it as path,
463
- et as post,
464
- rt as put,
465
- ut as query,
466
- ht as request
455
+ U as getParameterName,
456
+ N as getParameterNames,
457
+ it as head,
458
+ dt as header,
459
+ ct as options,
460
+ l as parameter,
461
+ st as patch,
462
+ ut as path,
463
+ nt as post,
464
+ at as put,
465
+ ht as query,
466
+ pt as request
467
467
  };
468
468
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/endpointDecorator.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/resultExtractor.ts","../src/fetcherCapable.ts","../src/requestExecutor.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\n\nexport interface PathCapable {\n /**\n * Path for the endpoint (relative to class base path).\n *\n * This path will be appended to the class's base path to form the complete URL.\n * Path parameters can be specified using curly braces, e.g., '/users/{id}'\n */\n path?: string;\n}\n\n/**\n * Metadata for HTTP endpoints.\n *\n * Defines the configuration options for individual HTTP endpoints (methods).\n * These settings will override any corresponding class-level settings from ApiMetadata.\n */\nexport interface EndpointMetadata\n extends ApiMetadata,\n ResultExtractorCapable,\n PathCapable {\n /**\n * HTTP method for the endpoint.\n *\n * Specifies the HTTP verb to be used for this endpoint (GET, POST, PUT, DELETE, etc.)\n */\n method?: HttpMethod;\n}\n\nexport const ENDPOINT_METADATA_KEY = Symbol('endpoint:metadata');\n\nexport type MethodEndpointMetadata = Omit<EndpointMetadata, 'method' | 'path'>;\n\n/**\n * Decorator factory for defining HTTP endpoints.\n *\n * Creates a decorator that can be used to define HTTP endpoints\n * on class methods. It stores metadata about the endpoint that will be used\n * to generate the actual HTTP request.\n *\n * @param method - The HTTP method for this endpoint\n * @param path - The path for this endpoint (relative to class base path)\n * @param metadata - Additional endpoint metadata (headers, timeout, etc.)\n * @returns A method decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1')\n * class UserService {\n * @endpoint(HttpMethod.GET, '/users/{id}')\n * getUser(@path('id') id: string): Promise<Response> {\n * // Implementation will be generated automatically\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function endpoint(\n method?: HttpMethod,\n path?: string,\n metadata: MethodEndpointMetadata = {},\n) {\n return function(target: object, propertyKey: string | symbol): void {\n // Store metadata directly on the method\n const endpointMetadata = {\n method: method,\n path,\n ...metadata,\n };\n Reflect.defineMetadata(\n ENDPOINT_METADATA_KEY,\n endpointMetadata,\n target,\n propertyKey,\n );\n };\n}\n\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\nexport function options(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.OPTIONS, path, metadata);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Cache for storing previously extracted parameter names to improve performance\nconst parameterNameCache = new WeakMap<Function, string[]>();\n\n/**\n * Extracts parameter names from a function.\n *\n * This function parses the string representation of a function to extract\n * the names of its parameters. It handles various function formats including\n * regular functions, arrow functions, and methods.\n *\n * Note: This implementation provides basic parameter name extraction and may not\n * handle all edge cases of complex TypeScript parameter declarations.\n *\n * @param func - The function to extract parameter names from\n * @returns An array of parameter names, or an empty array if extraction fails\n * @throws {TypeError} If the input is not a function\n *\n * @example\n * ```typescript\n * function example(a, b, c) {}\n * const paramNames = getParameterNames(example);\n * // Returns: ['a', 'b', 'c']\n *\n * const arrowFunc = (x, y) => x + y;\n * const arrowParamNames = getParameterNames(arrowFunc);\n * // Returns: ['x', 'y']\n *\n * function complex(param1: string, param2: number = 10, ...rest: any[]) {}\n * const complexParamNames = getParameterNames(complex);\n * // Returns: ['param1', 'param2', '...rest']\n * ```\n */\nexport function getParameterNames(func: (...args: any[]) => any): string[] {\n // Validate that the input is a function\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n // Check cache first to improve performance\n if (parameterNameCache.has(func)) {\n return parameterNameCache.get(func)!;\n }\n\n try {\n // Convert function to string and trim whitespace\n const fnStr = func.toString().trim();\n\n // Extract parameter string from the function\n const paramsStr = extractParameterString(fnStr);\n\n // Handle empty parameters\n if (!hasParameters(paramsStr)) {\n const emptyResult: string[] = [];\n parameterNameCache.set(func, emptyResult);\n return emptyResult;\n }\n\n // Parse and clean parameter names\n const result = parseParameterNames(paramsStr);\n parameterNameCache.set(func, result);\n return result;\n } catch {\n // Return empty array on any parsing errors to avoid breaking the application\n const errorResult: string[] = [];\n parameterNameCache.set(func, errorResult);\n return errorResult;\n }\n}\n\n/**\n * Helper function to automatically extract parameter name when not provided.\n *\n * @param target - The target object (class prototype)\n * @param propertyKey - The method name\n * @param parameterIndex - The index of the parameter\n * @param providedName - The name explicitly provided by the user (if any)\n * @returns The parameter name, either provided or automatically extracted\n */\nexport function getParameterName(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n providedName?: string,\n): string | undefined {\n // If a name was explicitly provided, use it\n if (providedName) {\n return providedName;\n }\n\n // Try to automatically extract the parameter name\n try {\n const method = target[propertyKey as keyof typeof target];\n if (method && typeof method === 'function') {\n const paramNames = getParameterNames(method);\n if (parameterIndex < paramNames.length) {\n return paramNames[parameterIndex];\n }\n }\n } catch {\n // If we can't get the parameter name, return undefined\n // This will use default naming in the execution logic\n }\n\n return undefined;\n}\n\n/**\n * Checks if a parameter string contains actual parameters.\n *\n * @param paramsStr - The parameter string to check\n * @returns True if the string contains parameters, false otherwise\n */\nfunction hasParameters(paramsStr: string): boolean {\n return (\n paramsStr !== null && paramsStr !== undefined && paramsStr.trim() !== ''\n );\n}\n\n/**\n * Extracts the parameter string from a function string representation.\n *\n * @param fnStr - The string representation of the function\n * @returns The parameter string, or empty string if not found\n */\nfunction extractParameterString(fnStr: string): string {\n // Handle arrow functions that start with parentheses\n if (fnStr.startsWith('(')) {\n const endParenIndex = findClosingParenthesis(fnStr, 0);\n if (endParenIndex === -1) return '';\n return fnStr.substring(1, endParenIndex);\n }\n\n // Handle regular functions, async functions, and methods\n const startParenIndex = fnStr.indexOf('(');\n if (startParenIndex === -1) return '';\n\n const endParenIndex = findClosingParenthesis(fnStr, startParenIndex);\n if (endParenIndex === -1) return '';\n\n return fnStr.substring(startParenIndex + 1, endParenIndex);\n}\n\n/**\n * Finds the matching closing parenthesis for an opening parenthesis.\n *\n * @param str - The string to search in\n * @param openingParenIndex - The index of the opening parenthesis\n * @returns The index of the matching closing parenthesis, or -1 if not found\n */\nfunction findClosingParenthesis(\n str: string,\n openingParenIndex: number,\n): number {\n let parenDepth = 1;\n\n for (let i = openingParenIndex + 1; i < str.length; i++) {\n const char = str[i];\n\n if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n if (parenDepth === 0) {\n return i;\n }\n }\n }\n\n return -1; // No matching closing parenthesis found\n}\n\n/**\n * Parses and cleans parameter names from a parameter string.\n *\n * @param paramsStr - The parameter string to parse\n * @returns An array of cleaned parameter names\n */\nfunction parseParameterNames(paramsStr: string): string[] {\n return paramsStr\n .split(',')\n .map(trimWhitespace)\n .filter(isNotEmpty)\n .map(extractParameterName);\n}\n\n/**\n * Trims whitespace from a string.\n *\n * @param str - The string to trim\n * @returns The trimmed string\n */\nfunction trimWhitespace(str: string): string {\n return str.trim();\n}\n\n/**\n * Checks if a string is not empty.\n *\n * @param str - The string to check\n * @returns True if the string is not empty, false otherwise\n */\nfunction isNotEmpty(str: string): boolean {\n return str.length > 0;\n}\n\n/**\n * Extracts a clean parameter name by removing type annotations and default values.\n *\n * @param param - The raw parameter string\n * @returns The cleaned parameter name\n */\nfunction extractParameterName(param: string): string {\n // Remove default value assignment (everything after =)\n let cleanedParam = removeDefaultValue(param);\n\n // Remove type annotations (everything after :)\n cleanedParam = removeTypeAnnotation(cleanedParam);\n\n return cleanedParam.trim();\n}\n\n/**\n * Removes default value from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without default value\n */\nfunction removeDefaultValue(param: string): string {\n const equalsIndex = param.indexOf('=');\n if (equalsIndex !== -1) {\n return param.substring(0, equalsIndex);\n }\n return param;\n}\n\n/**\n * Removes type annotation from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without type annotation\n */\nfunction removeTypeAnnotation(param: string): string {\n const colonIndex = param.indexOf(':');\n if (colonIndex !== -1) {\n return param.substring(0, colonIndex);\n }\n return param;\n}\n","import { getParameterName } from './reflection';\nimport 'reflect-metadata';\nimport { type PathCapable } from './endpointDecorator';\nimport { type FetchRequestInit } from '@ahoo-wang/fetcher';\n\n/**\n * Parameter types for decorator parameters.\n *\n * Defines the different types of parameters that can be used\n * in API method decorators to specify how arguments should be handled\n * in the HTTP request.\n */\nexport enum ParameterType {\n /**\n * Path parameter that will be inserted into the URL path.\n *\n * Path parameters are used to specify dynamic parts of the URL path.\n * They are defined using curly braces in the endpoint path.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n * ```\n */\n PATH = 'path',\n\n /**\n * Query parameter that will be appended to the URL query string.\n *\n * Query parameters are used to pass non-hierarchical data to the server.\n * They appear after the '?' in the URL.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n * ```\n */\n QUERY = 'query',\n\n /**\n * Header parameter that will be added to the request headers.\n *\n * Header parameters are used to pass metadata about the request,\n * such as authentication tokens or content type information.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n * ```\n */\n HEADER = 'header',\n\n /**\n * Body parameter that will be sent as the request body.\n *\n * The body parameter represents the main data payload of the request.\n * It is typically used with POST, PUT, and PATCH requests.\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\n BODY = 'body',\n\n /**\n * Request parameter that will be used as the request object.\n */\n REQUEST = 'request',\n}\n\n/**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter\n * decorated with @path, @query, @header, or @body decorators.\n */\nexport interface ParameterMetadata {\n /**\n * Type of parameter (path, query, header, body).\n *\n * Specifies how this parameter should be handled in the HTTP request.\n */\n type: ParameterType;\n\n /**\n * Name of the parameter (used for path, query, and header parameters).\n *\n * For path and query parameters, this corresponds to the key in the URL.\n * For header parameters, this corresponds to the header name.\n * For body parameters, this is not used.\n */\n name?: string;\n\n /**\n * Index of the parameter in the method signature.\n *\n * This is used to map the runtime argument values to the correct parameter metadata.\n */\n index: number;\n}\n\nexport const PARAMETER_METADATA_KEY = Symbol('parameter:metadata');\n\n/**\n * Decorator factory for method parameters.\n *\n * Creates a decorator that can be used to specify how a method parameter\n * should be handled in the HTTP request. It stores metadata about the parameter\n * that will be used during request execution.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, or BODY)\n * @param name - The name of the parameter (used for path, query, and header parameters, optional - auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@parameter(ParameterType.PATH, 'id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@parameter(ParameterType.PATH) userId: string): Promise<Response>\n * ```\n */\nexport function parameter(type: ParameterType, name: string = '') {\n return function(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n ) {\n const paramName = getParameterName(\n target,\n propertyKey as string,\n parameterIndex,\n name,\n );\n\n const existingParameters: Map<number, ParameterMetadata> =\n Reflect.getMetadata(PARAMETER_METADATA_KEY, target, propertyKey) ||\n new Map();\n const parameterMetadata: ParameterMetadata = {\n type: type,\n name: paramName,\n index: parameterIndex,\n };\n existingParameters.set(parameterIndex, parameterMetadata);\n Reflect.defineMetadata(\n PARAMETER_METADATA_KEY,\n existingParameters,\n target,\n propertyKey,\n );\n };\n}\n\n/**\n * Path parameter decorator.\n *\n * Defines a path parameter that will be inserted into the URL path.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the path parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@path() userId: string): Promise<Response>\n * ```\n */\nexport function path(name: string = '') {\n return parameter(ParameterType.PATH, name);\n}\n\n/**\n * Query parameter decorator.\n *\n * Defines a query parameter that will be appended to the URL query string.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the query parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@query() limit: number): Promise<Response>\n * ```\n */\nexport function query(name: string = '') {\n return parameter(ParameterType.QUERY, name);\n}\n\n/**\n * Header parameter decorator.\n *\n * Defines a header parameter that will be added to the request headers.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the header parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@header() authorization: string): Promise<Response>\n * ```\n */\nexport function header(name: string = '') {\n return parameter(ParameterType.HEADER, name);\n}\n\n/**\n * Body parameter decorator.\n *\n * Defines a body parameter that will be sent as the request body.\n * Note that body parameters don't have names since there's only one body per request.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\nexport function body() {\n return parameter(ParameterType.BODY);\n}\n\n/**\n * Interface for request parameter objects.\n *\n * Combines FetchRequestInit and PathCapable interfaces to provide\n * a complete request configuration object that can be used with\n * the @request() decorator. This allows full customization of\n * the HTTP request including method, headers, body, and URL parameters.\n */\nexport interface ParameterRequest extends FetchRequestInit, PathCapable {\n}\n\n/**\n * Request parameter decorator.\n *\n * Defines a request parameter that will be used as the base request object.\n * This allows you to pass a complete ParameterRequest object to customize\n * the request configuration.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: ParameterRequest): Promise<Response>\n * ```\n */\nexport function request() {\n return parameter(ParameterType.REQUEST);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FetchExchange } from '@ahoo-wang/fetcher';\nimport type {\n JsonServerSentEventStream,\n ServerSentEventStream,\n} from '@ahoo-wang/fetcher-eventstream';\n\n/**\n * Result extractor interface\n * Defines a function type for extracting results from a FetchExchange\n * @param exchange - FetchExchange object containing request and response information\n * @returns Returns a value of type FetchExchange, Response, or Promise<any>\n */\nexport interface ResultExtractor {\n (\n exchange: FetchExchange,\n ):\n | FetchExchange\n | Response\n | Promise<any>\n | ServerSentEventStream\n | JsonServerSentEventStream<any>;\n}\n\n/**\n * Interface with result extractor capability\n * Defines an optional resultExtractor property\n */\nexport interface ResultExtractorCapable {\n resultExtractor?: ResultExtractor;\n}\n\n/**\n * Returns the original FetchExchange object\n * @param exchange - FetchExchange object\n * @returns The original FetchExchange object\n */\nexport const ExchangeResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange;\n};\n\n/**\n * Returns the response object from FetchExchange\n * @param exchange - FetchExchange object\n * @returns The response object from FetchExchange\n */\nexport const ResponseResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse;\n};\n\n/**\n * Parses the response content as JSON format\n * @param exchange - FetchExchange object\n * @returns Promise of parsed JSON data\n */\nexport const JsonResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.json();\n};\n\n/**\n * Parses the response content as text format\n * @param exchange - FetchExchange object\n * @returns Promise of parsed text data\n */\nexport const TextResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.text();\n};\n\n/**\n * ServerSentEventStream result extractor, used to extract server-sent event stream from FetchExchange\n *\n * @param exchange - FetchExchange object containing request and response information\n * @returns Readable stream object of server-sent event stream\n * @throws ExchangeError exception when server does not support ServerSentEventStream\n */\nexport const EventStreamResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.requiredEventStream();\n};\n\n/**\n * JsonServerSentEventStream result extractor, used to extract JSON server-sent event stream from FetchExchange\n *\n * @param exchange - FetchExchange object containing request and response information\n * @returns Readable stream object of JSON server-sent event stream\n * @throws ExchangeError exception when server does not support JsonServerSentEventStream\n */\nexport const JsonEventStreamResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.requiredJsonEventStream();\n};\n\n/**\n * ResultExtractors is an object that maps result extractor names to their corresponding\n * extractor functions. These extractors are used to process and extract data from different\n * types of responses or results in the application.\n *\n * Each property represents a specific type of result extractor:\n * - Exchange: Handles exchange-related result extraction\n * - Response: Handles general response result extraction\n * - Json: Handles JSON format result extraction\n * - Text: Handles plain text result extraction\n * - EventStream: Handles server-sent event stream result extraction\n * - JsonEventStream: Handles JSON server-sent event stream result extraction\n */\nexport const ResultExtractors = {\n Exchange: ExchangeResultExtractor,\n Response: ResponseResultExtractor,\n Json: JsonResultExtractor,\n Text: TextResultExtractor,\n EventStream: EventStreamResultExtractor,\n JsonEventStream: JsonEventStreamResultExtractor,\n DEFAULT: JsonResultExtractor,\n};\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Fetcher, fetcherRegistrar } from '@ahoo-wang/fetcher';\n\n/**\n * Interface that defines a capability for objects that can have a fetcher.\n * This interface is typically used to mark components or objects that can perform fetching operations\n * and may need access to fetcher functionality.\n */\nexport interface FetcherCapable {\n /**\n * Optional fetcher property that can be either a string identifier or a Fetcher instance.\n * When present, this property indicates the fetcher associated with the implementing object.\n */\n fetcher?: string | Fetcher;\n}\n\n/**\n * Gets a Fetcher instance based on the provided fetcher parameter.\n *\n * @param fetcher - A string identifier or Fetcher instance to resolve\n * @returns A Fetcher instance if found, undefined otherwise\n */\nexport function getFetcher(fetcher?: string | Fetcher): Fetcher | undefined {\n // Return undefined if no fetcher is provided\n if (!fetcher) {\n return undefined;\n }\n\n // Return the fetcher directly if it's already a Fetcher instance,\n // otherwise resolve it through the fetcher registrar\n return fetcher instanceof Fetcher\n ? fetcher\n : fetcherRegistrar.requiredGet(fetcher);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n combineURLs,\n fetcher,\n Fetcher,\n FetchExchange,\n type FetchRequest,\n type FetchRequestInit,\n mergeRequest,\n type NamedCapable,\n type RequestHeaders,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n type ParameterMetadata,\n type ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { ResultExtractor, ResultExtractors } from './resultExtractor';\nimport { ServerSentEventStream } from '@ahoo-wang/fetcher-eventstream';\nimport { getFetcher } from './fetcherCapable';\n\n/**\n * Metadata container for a function with HTTP endpoint decorators.\n *\n * Encapsulates all the metadata needed to execute an HTTP request\n * for a decorated method, including API-level defaults, endpoint-specific\n * configuration, and parameter metadata.\n */\nexport class FunctionMetadata implements NamedCapable {\n /**\n * Name of the function.\n */\n name: string;\n\n /**\n * API-level metadata (class-level configuration).\n */\n api: ApiMetadata;\n\n /**\n * Endpoint-level metadata (method-level configuration).\n */\n endpoint: EndpointMetadata;\n\n /**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter decorated with @path, @query,\n * @header, or @body decorators. Stored as a Map keyed by parameter index.\n *\n * @remarks\n * The metadata is stored as a Map<number, ParameterMetadata> where the key is\n * the parameter index and the value is the parameter metadata. This ensures\n * correct parameter ordering regardless of decorator application order.\n */\n parameters: Map<number, ParameterMetadata>;\n\n /**\n * Creates a new FunctionMetadata instance.\n *\n * @param name - The name of the function\n * @param api - API-level metadata\n * @param endpoint - Endpoint-level metadata\n * @param parameters - Parameter metadata array\n */\n constructor(\n name: string,\n api: ApiMetadata,\n endpoint: EndpointMetadata,\n parameters: Map<number, ParameterMetadata>,\n ) {\n this.name = name;\n this.api = api;\n this.endpoint = endpoint;\n this.parameters = parameters;\n }\n\n /**\n * Gets the fetcher instance to use for this function.\n *\n * Returns the fetcher specified in the endpoint metadata, or the API metadata,\n * or falls back to the default fetcher if none is specified.\n *\n * @returns The fetcher instance\n */\n get fetcher(): Fetcher {\n return getFetcher(this.endpoint.fetcher ?? this.api.fetcher) ?? fetcher;\n }\n\n /**\n * Resolves the request configuration from the method arguments.\n *\n * This method processes the runtime arguments according to the parameter metadata\n * and constructs a FetcherRequest object with path parameters, query parameters,\n * headers, body, and timeout. It handles various parameter types including:\n * - Path parameters (@path decorator)\n * - Query parameters (@query decorator)\n * - Header parameters (@header decorator)\n * - Body parameter (@body decorator)\n * - Complete request object (@request decorator)\n * - AbortSignal for request cancellation\n *\n * The method uses mergeRequest to combine the endpoint-specific configuration\n * with the parameter-provided request object, where the parameter request\n * takes precedence over endpoint configuration.\n *\n * @param args - The runtime arguments passed to the method\n * @returns A FetcherRequest object with all request configuration\n *\n * @example\n * ```typescript\n * // For a method decorated like:\n * @get('/users/{id}')\n * getUser(\n * @path('id') id: number,\n * @query('include') include: string,\n * @header('Authorization') auth: string\n * ): Promise<Response>\n *\n * // Calling with: getUser(123, 'profile', 'Bearer token')\n * // Would produce a request with:\n * // {\n * // method: 'GET',\n * // urlParams: {\n * // path: { id: 123 },\n * // query: { include: 'profile' }\n * // },\n * // headers: {\n * // 'Authorization': 'Bearer token',\n * // ...apiHeaders,\n * // ...endpointHeaders\n * // }\n * // }\n * ```\n */\n resolveRequest(args: any[]): FetchRequest {\n const pathParams: Record<string, any> = {};\n const queryParams: Record<string, any> = {};\n const headers: RequestHeaders = {\n ...this.api.headers,\n ...this.endpoint.headers,\n };\n let body: any = undefined;\n let signal: AbortSignal | null | undefined = undefined;\n let parameterRequest: ParameterRequest = {};\n // Process parameters based on their decorators\n args.forEach((value, index) => {\n if (value instanceof AbortSignal) {\n signal = value;\n return;\n }\n const funParameter = this.parameters.get(index);\n if (!funParameter) {\n return;\n }\n switch (funParameter.type) {\n case ParameterType.PATH:\n this.processPathParam(funParameter, value, pathParams);\n break;\n case ParameterType.QUERY:\n this.processQueryParam(funParameter, value, queryParams);\n break;\n case ParameterType.HEADER:\n this.processHeaderParam(funParameter, value, headers);\n break;\n case ParameterType.BODY:\n body = value;\n break;\n case ParameterType.REQUEST:\n parameterRequest = this.processRequestParam(value);\n break;\n }\n });\n const urlParams: UrlParams = {\n path: pathParams,\n query: queryParams,\n };\n const endpointRequest: FetchRequestInit = {\n method: this.endpoint.method,\n urlParams,\n headers,\n body,\n timeout: this.resolveTimeout(),\n signal,\n };\n const mergedRequest = mergeRequest(\n endpointRequest,\n parameterRequest,\n ) as any;\n const parameterPath = parameterRequest.path;\n mergedRequest.url = this.resolvePath(parameterPath);\n return mergedRequest;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n path[paramName] = value;\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n query[paramName] = value;\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n if (param.name && value !== undefined) {\n headers[param.name] = String(value);\n }\n }\n\n /**\n * Processes a request parameter value.\n *\n * This method handles the @request() decorator parameter by casting\n * the provided value to a FetcherRequest. The @request() decorator\n * allows users to pass a complete FetcherRequest object to customize\n * the request configuration.\n *\n * @param value - The value provided for the @request() parameter\n * @returns The value cast to FetcherRequest type\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: FetcherRequest): Promise<Response>\n *\n * // Usage:\n * const customRequest: FetcherRequest = {\n * headers: { 'X-Custom': 'value' },\n * timeout: 5000\n * };\n * await service.createUsers(customRequest);\n * ```\n */\n private processRequestParam(value: any): ParameterRequest {\n return value as ParameterRequest;\n }\n\n /**\n * Resolves the complete path by combining base path and endpoint path\n *\n * @param parameterPath - Optional path parameter to use instead of endpoint path\n * @returns The combined URL path\n */\n resolvePath(parameterPath?: string): string {\n // Get the base path from endpoint, API, or default to empty string\n const basePath = this.endpoint.basePath || this.api.basePath || '';\n\n // Use provided parameter path or fallback to endpoint path\n const endpointPath = parameterPath || this.endpoint.path || '';\n\n // Combine the base path and endpoint path into a complete URL\n return combineURLs(basePath, endpointPath);\n }\n\n /**\n * Resolves the timeout for the request.\n *\n * Returns the timeout specified in the endpoint metadata, or the API metadata,\n * or undefined if no timeout is specified.\n *\n * @returns The timeout value in milliseconds, or undefined\n */\n resolveTimeout(): number | undefined {\n return this.endpoint.timeout || this.api.timeout;\n }\n\n resolveResultExtractor(): ResultExtractor {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n ResultExtractors.DEFAULT\n );\n }\n}\n\nconst TARGET_FETCHER_PROPERTY = 'fetcher';\n\n/**\n * Executor for HTTP requests based on decorated method metadata.\n *\n * This class is responsible for executing HTTP requests based on the metadata\n * collected from decorators. It resolves the path, constructs the request,\n * and executes it using the appropriate fetcher.\n */\nexport class RequestExecutor {\n private readonly metadata: FunctionMetadata;\n\n /**\n * Creates a new RequestExecutor instance.\n *\n * @param metadata - The function metadata containing all request information\n */\n constructor(metadata: FunctionMetadata) {\n this.metadata = metadata;\n }\n\n /**\n * Retrieves the fetcher instance from the target object.\n *\n * @param target - The target object that may contain a fetcher property\n * @returns The fetcher instance if exists, otherwise undefined\n */\n private getTargetFetcher(target: any): Fetcher | undefined {\n if (!target || typeof target !== 'object') {\n return undefined;\n }\n // Extract the fetcher property from the target object\n const fetcher = target[TARGET_FETCHER_PROPERTY];\n\n // Validate that the fetcher is an instance of the Fetcher class\n if (fetcher instanceof Fetcher) {\n return fetcher;\n }\n\n // Return undefined if no valid fetcher instance is found\n return undefined;\n }\n\n /**\n * Executes the HTTP request.\n *\n * This method resolves the path and request configuration from the metadata\n * and arguments, then executes the request using the configured fetcher.\n *\n * @param target - The target object that the method is called on\n * @param args - The runtime arguments passed to the method\n * @returns A Promise that resolves to the Response\n */\n async execute(\n target: any,\n args: any[],\n ): Promise<FetchExchange | Response | any | ServerSentEventStream> {\n const fetcher = this.getTargetFetcher(target) || this.metadata.fetcher;\n const request = this.metadata.resolveRequest(args);\n const exchange = await fetcher.request(request);\n const extractor = this.metadata.resolveResultExtractor();\n return extractor(exchange);\n }\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Fetcher,\n type RequestHeaders,\n type RequestHeadersCapable,\n type TimeoutCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { FunctionMetadata, RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\nimport { type FetcherCapable } from './fetcherCapable';\n\n/**\n * Metadata for class-level API configuration.\n *\n * Defines the configuration options that can be applied to an entire API class.\n * These settings will be used as defaults for all endpoints within the class unless overridden\n * at the method level.\n */\nexport interface ApiMetadata\n extends TimeoutCapable,\n RequestHeadersCapable,\n ResultExtractorCapable,\n FetcherCapable {\n /**\n * Base path for all endpoints in the class.\n *\n * This path will be prepended to all endpoint paths defined in the class.\n * For example, if basePath is '/api/v1' and an endpoint has path '/users',\n * the full path will be '/api/v1/users'.\n */\n basePath?: string;\n\n /**\n * Default headers for all requests in the class.\n *\n * These headers will be included in every request made by methods in this class.\n * They can be overridden or extended at the method level.\n */\n headers?: RequestHeaders;\n\n /**\n * Default timeout for all requests in the class (in milliseconds).\n *\n * This timeout value will be applied to all requests made by methods in this class.\n * Individual methods can specify their own timeout values to override this default.\n */\n timeout?: number;\n\n /**\n * Name of the fetcher instance to use, default: 'default'.\n *\n * This allows you to specify which fetcher instance should be used for requests\n * from this API class. The fetcher must be registered with the FetcherRegistrar.\n */\n fetcher?: string | Fetcher;\n}\n\nexport const API_METADATA_KEY = Symbol('api:metadata');\n\n/**\n * Binds a request executor to a method, replacing the original method with\n * an implementation that makes HTTP requests based on the decorator metadata.\n *\n * @param constructor - The class constructor\n * @param functionName - The name of the method to bind\n * @param apiMetadata - The API metadata for the class\n */\nfunction bindExecutor<T extends new (...args: any[]) => any>(\n constructor: T,\n functionName: string,\n apiMetadata: ApiMetadata,\n) {\n const endpointFunction = constructor.prototype[functionName];\n if (functionName === 'constructor') {\n return;\n }\n if (typeof endpointFunction !== 'function') {\n return;\n }\n\n const endpointMetadata = Reflect.getMetadata(\n ENDPOINT_METADATA_KEY,\n constructor.prototype,\n functionName,\n );\n if (!endpointMetadata) {\n return;\n }\n // Get parameter metadata for this method\n const parameterMetadata =\n Reflect.getMetadata(\n PARAMETER_METADATA_KEY,\n constructor.prototype,\n functionName,\n ) || new Map();\n\n // Create function metadata\n const functionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n const requestExecutor = new RequestExecutor(functionMetadata);\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = function(...args: unknown[]) {\n return requestExecutor.execute(this, args);\n };\n}\n\nexport function api(\n basePath: string = '',\n metadata: Omit<ApiMetadata, 'basePath'> = {},\n) {\n return function <T extends new (...args: any[]) => any>(constructor: T): T {\n const apiMetadata: ApiMetadata = {\n basePath,\n ...metadata,\n };\n\n // Store metadata directly on the class constructor\n Reflect.defineMetadata(API_METADATA_KEY, apiMetadata, constructor);\n\n // Override prototype methods to implement actual HTTP calls\n Object.getOwnPropertyNames(constructor.prototype).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n\n return constructor;\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Custom error class that indicates a method implementation will be automatically generated.\n *\n * @example\n * ```\n * @post()\n * createUser(@body() user: User):Promise<Response> {\n * throw autoGeneratedError(user);\n * }\n * ```\n */\nexport class AutoGenerated extends Error {\n constructor() {\n super('Implementation will be generated automatically.');\n this.name = 'AutoGenerated';\n }\n}\n\n/**\n * Factory function that creates an AutoGenerated error instance.\n * This is typically used in methods that will be automatically implemented,\n * where a placeholder implementation is needed.\n *\n * @param _ignored - Arguments (such as 'user' in the example) are ignored to prevent\n * ESLint no-unused-vars errors in method signatures that will be auto-generated.\n * @returns A new AutoGenerated error instance\n */\nexport const autoGeneratedError = (..._ignored: any[]): AutoGenerated => {\n return new AutoGenerated();\n};\n"],"names":["ENDPOINT_METADATA_KEY","endpoint","method","path","metadata","target","propertyKey","endpointMetadata","get","HttpMethod","post","put","del","patch","head","options","parameterNameCache","getParameterNames","func","fnStr","paramsStr","extractParameterString","hasParameters","emptyResult","result","parseParameterNames","errorResult","getParameterName","parameterIndex","providedName","paramNames","endParenIndex","findClosingParenthesis","startParenIndex","str","openingParenIndex","parenDepth","i","char","trimWhitespace","isNotEmpty","extractParameterName","param","cleanedParam","removeDefaultValue","removeTypeAnnotation","equalsIndex","colonIndex","ParameterType","PARAMETER_METADATA_KEY","parameter","type","name","paramName","existingParameters","parameterMetadata","query","header","body","request","ExchangeResultExtractor","exchange","ResponseResultExtractor","JsonResultExtractor","TextResultExtractor","EventStreamResultExtractor","JsonEventStreamResultExtractor","ResultExtractors","getFetcher","fetcher","Fetcher","fetcherRegistrar","FunctionMetadata","api","parameters","args","pathParams","queryParams","headers","signal","parameterRequest","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","parameterPath","basePath","endpointPath","combineURLs","TARGET_FETCHER_PROPERTY","RequestExecutor","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","requestExecutor","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/endpointDecorator.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/resultExtractor.ts","../src/fetcherCapable.ts","../src/requestExecutor.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\n\nexport interface PathCapable {\n /**\n * Path for the endpoint (relative to class base path).\n *\n * This path will be appended to the class's base path to form the complete URL.\n * Path parameters can be specified using curly braces, e.g., '/users/{id}'\n */\n path?: string;\n}\n\n/**\n * Metadata for HTTP endpoints.\n *\n * Defines the configuration options for individual HTTP endpoints (methods).\n * These settings will override any corresponding class-level settings from ApiMetadata.\n */\nexport interface EndpointMetadata\n extends ApiMetadata,\n ResultExtractorCapable,\n PathCapable {\n /**\n * HTTP method for the endpoint.\n *\n * Specifies the HTTP verb to be used for this endpoint (GET, POST, PUT, DELETE, etc.)\n */\n method?: HttpMethod;\n}\n\nexport const ENDPOINT_METADATA_KEY = Symbol('endpoint:metadata');\n\nexport type MethodEndpointMetadata = Omit<EndpointMetadata, 'method' | 'path'>;\n\n/**\n * Decorator factory for defining HTTP endpoints.\n *\n * Creates a decorator that can be used to define HTTP endpoints\n * on class methods. It stores metadata about the endpoint that will be used\n * to generate the actual HTTP request.\n *\n * @param method - The HTTP method for this endpoint\n * @param path - The path for this endpoint (relative to class base path)\n * @param metadata - Additional endpoint metadata (headers, timeout, etc.)\n * @returns A method decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1')\n * class UserService {\n * @endpoint(HttpMethod.GET, '/users/{id}')\n * getUser(@path('id') id: string): Promise<Response> {\n * // Implementation will be generated automatically\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function endpoint(\n method?: HttpMethod,\n path?: string,\n metadata: MethodEndpointMetadata = {},\n) {\n return function(target: object, propertyKey: string | symbol): void {\n // Store metadata directly on the method\n const endpointMetadata = {\n method: method,\n path,\n ...metadata,\n };\n Reflect.defineMetadata(\n ENDPOINT_METADATA_KEY,\n endpointMetadata,\n target,\n propertyKey,\n );\n };\n}\n\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\nexport function options(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.OPTIONS, path, metadata);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Cache for storing previously extracted parameter names to improve performance\nconst parameterNameCache = new WeakMap<Function, string[]>();\n\n/**\n * Extracts parameter names from a function.\n *\n * This function parses the string representation of a function to extract\n * the names of its parameters. It handles various function formats including\n * regular functions, arrow functions, and methods.\n *\n * Note: This implementation provides basic parameter name extraction and may not\n * handle all edge cases of complex TypeScript parameter declarations.\n *\n * @param func - The function to extract parameter names from\n * @returns An array of parameter names, or an empty array if extraction fails\n * @throws {TypeError} If the input is not a function\n *\n * @example\n * ```typescript\n * function example(a, b, c) {}\n * const paramNames = getParameterNames(example);\n * // Returns: ['a', 'b', 'c']\n *\n * const arrowFunc = (x, y) => x + y;\n * const arrowParamNames = getParameterNames(arrowFunc);\n * // Returns: ['x', 'y']\n *\n * function complex(param1: string, param2: number = 10, ...rest: any[]) {}\n * const complexParamNames = getParameterNames(complex);\n * // Returns: ['param1', 'param2', '...rest']\n * ```\n */\nexport function getParameterNames(func: (...args: any[]) => any): string[] {\n // Validate that the input is a function\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n // Check cache first to improve performance\n if (parameterNameCache.has(func)) {\n return parameterNameCache.get(func)!;\n }\n\n try {\n // Convert function to string and trim whitespace\n const fnStr = func.toString().trim();\n\n // Extract parameter string from the function\n const paramsStr = extractParameterString(fnStr);\n\n // Handle empty parameters\n if (!hasParameters(paramsStr)) {\n const emptyResult: string[] = [];\n parameterNameCache.set(func, emptyResult);\n return emptyResult;\n }\n\n // Parse and clean parameter names\n const result = parseParameterNames(paramsStr);\n parameterNameCache.set(func, result);\n return result;\n } catch {\n // Return empty array on any parsing errors to avoid breaking the application\n const errorResult: string[] = [];\n parameterNameCache.set(func, errorResult);\n return errorResult;\n }\n}\n\n/**\n * Helper function to automatically extract parameter name when not provided.\n *\n * @param target - The target object (class prototype)\n * @param propertyKey - The method name\n * @param parameterIndex - The index of the parameter\n * @param providedName - The name explicitly provided by the user (if any)\n * @returns The parameter name, either provided or automatically extracted\n */\nexport function getParameterName(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n providedName?: string,\n): string | undefined {\n // If a name was explicitly provided, use it\n if (providedName) {\n return providedName;\n }\n\n // Try to automatically extract the parameter name\n try {\n const method = target[propertyKey as keyof typeof target];\n if (method && typeof method === 'function') {\n const paramNames = getParameterNames(method);\n if (parameterIndex < paramNames.length) {\n return paramNames[parameterIndex];\n }\n }\n } catch {\n // If we can't get the parameter name, return undefined\n // This will use default naming in the execution logic\n }\n\n return undefined;\n}\n\n/**\n * Checks if a parameter string contains actual parameters.\n *\n * @param paramsStr - The parameter string to check\n * @returns True if the string contains parameters, false otherwise\n */\nfunction hasParameters(paramsStr: string): boolean {\n return (\n paramsStr !== null && paramsStr !== undefined && paramsStr.trim() !== ''\n );\n}\n\n/**\n * Extracts the parameter string from a function string representation.\n *\n * @param fnStr - The string representation of the function\n * @returns The parameter string, or empty string if not found\n */\nfunction extractParameterString(fnStr: string): string {\n // Handle arrow functions that start with parentheses\n if (fnStr.startsWith('(')) {\n const endParenIndex = findClosingParenthesis(fnStr, 0);\n if (endParenIndex === -1) return '';\n return fnStr.substring(1, endParenIndex);\n }\n\n // Handle regular functions, async functions, and methods\n const startParenIndex = fnStr.indexOf('(');\n if (startParenIndex === -1) return '';\n\n const endParenIndex = findClosingParenthesis(fnStr, startParenIndex);\n if (endParenIndex === -1) return '';\n\n return fnStr.substring(startParenIndex + 1, endParenIndex);\n}\n\n/**\n * Finds the matching closing parenthesis for an opening parenthesis.\n *\n * @param str - The string to search in\n * @param openingParenIndex - The index of the opening parenthesis\n * @returns The index of the matching closing parenthesis, or -1 if not found\n */\nfunction findClosingParenthesis(\n str: string,\n openingParenIndex: number,\n): number {\n let parenDepth = 1;\n\n for (let i = openingParenIndex + 1; i < str.length; i++) {\n const char = str[i];\n\n if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n if (parenDepth === 0) {\n return i;\n }\n }\n }\n\n return -1; // No matching closing parenthesis found\n}\n\n/**\n * Parses and cleans parameter names from a parameter string.\n *\n * @param paramsStr - The parameter string to parse\n * @returns An array of cleaned parameter names\n */\nfunction parseParameterNames(paramsStr: string): string[] {\n return paramsStr\n .split(',')\n .map(trimWhitespace)\n .filter(isNotEmpty)\n .map(extractParameterName);\n}\n\n/**\n * Trims whitespace from a string.\n *\n * @param str - The string to trim\n * @returns The trimmed string\n */\nfunction trimWhitespace(str: string): string {\n return str.trim();\n}\n\n/**\n * Checks if a string is not empty.\n *\n * @param str - The string to check\n * @returns True if the string is not empty, false otherwise\n */\nfunction isNotEmpty(str: string): boolean {\n return str.length > 0;\n}\n\n/**\n * Extracts a clean parameter name by removing type annotations and default values.\n *\n * @param param - The raw parameter string\n * @returns The cleaned parameter name\n */\nfunction extractParameterName(param: string): string {\n // Remove default value assignment (everything after =)\n let cleanedParam = removeDefaultValue(param);\n\n // Remove type annotations (everything after :)\n cleanedParam = removeTypeAnnotation(cleanedParam);\n\n return cleanedParam.trim();\n}\n\n/**\n * Removes default value from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without default value\n */\nfunction removeDefaultValue(param: string): string {\n const equalsIndex = param.indexOf('=');\n if (equalsIndex !== -1) {\n return param.substring(0, equalsIndex);\n }\n return param;\n}\n\n/**\n * Removes type annotation from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without type annotation\n */\nfunction removeTypeAnnotation(param: string): string {\n const colonIndex = param.indexOf(':');\n if (colonIndex !== -1) {\n return param.substring(0, colonIndex);\n }\n return param;\n}\n","import { getParameterName } from './reflection';\nimport 'reflect-metadata';\nimport { type PathCapable } from './endpointDecorator';\nimport { type FetchRequestInit } from '@ahoo-wang/fetcher';\n\n/**\n * Parameter types for decorator parameters.\n *\n * Defines the different types of parameters that can be used\n * in API method decorators to specify how arguments should be handled\n * in the HTTP request.\n */\nexport enum ParameterType {\n /**\n * Path parameter that will be inserted into the URL path.\n *\n * Path parameters are used to specify dynamic parts of the URL path.\n * They are defined using curly braces in the endpoint path.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n * ```\n */\n PATH = 'path',\n\n /**\n * Query parameter that will be appended to the URL query string.\n *\n * Query parameters are used to pass non-hierarchical data to the server.\n * They appear after the '?' in the URL.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n * ```\n */\n QUERY = 'query',\n\n /**\n * Header parameter that will be added to the request headers.\n *\n * Header parameters are used to pass metadata about the request,\n * such as authentication tokens or content type information.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n * ```\n */\n HEADER = 'header',\n\n /**\n * Body parameter that will be sent as the request body.\n *\n * The body parameter represents the main data payload of the request.\n * It is typically used with POST, PUT, and PATCH requests.\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\n BODY = 'body',\n\n /**\n * Request parameter that will be used as the request object.\n */\n REQUEST = 'request',\n}\n\n/**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter\n * decorated with @path, @query, @header, or @body decorators.\n */\nexport interface ParameterMetadata {\n /**\n * Type of parameter (path, query, header, body).\n *\n * Specifies how this parameter should be handled in the HTTP request.\n */\n type: ParameterType;\n\n /**\n * Name of the parameter (used for path, query, and header parameters).\n *\n * For path and query parameters, this corresponds to the key in the URL.\n * For header parameters, this corresponds to the header name.\n * For body parameters, this is not used.\n */\n name?: string;\n\n /**\n * Index of the parameter in the method signature.\n *\n * This is used to map the runtime argument values to the correct parameter metadata.\n */\n index: number;\n}\n\nexport const PARAMETER_METADATA_KEY = Symbol('parameter:metadata');\n\n/**\n * Decorator factory for method parameters.\n *\n * Creates a decorator that can be used to specify how a method parameter\n * should be handled in the HTTP request. It stores metadata about the parameter\n * that will be used during request execution.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, or BODY)\n * @param name - The name of the parameter (used for path, query, and header parameters, optional - auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@parameter(ParameterType.PATH, 'id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@parameter(ParameterType.PATH) userId: string): Promise<Response>\n * ```\n */\nexport function parameter(type: ParameterType, name: string = '') {\n return function(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n ) {\n const paramName = getParameterName(\n target,\n propertyKey as string,\n parameterIndex,\n name,\n );\n\n const existingParameters: Map<number, ParameterMetadata> =\n Reflect.getMetadata(PARAMETER_METADATA_KEY, target, propertyKey) ||\n new Map();\n const parameterMetadata: ParameterMetadata = {\n type: type,\n name: paramName,\n index: parameterIndex,\n };\n existingParameters.set(parameterIndex, parameterMetadata);\n Reflect.defineMetadata(\n PARAMETER_METADATA_KEY,\n existingParameters,\n target,\n propertyKey,\n );\n };\n}\n\n/**\n * Path parameter decorator.\n *\n * Defines a path parameter that will be inserted into the URL path.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the path parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@path() userId: string): Promise<Response>\n * ```\n */\nexport function path(name: string = '') {\n return parameter(ParameterType.PATH, name);\n}\n\n/**\n * Query parameter decorator.\n *\n * Defines a query parameter that will be appended to the URL query string.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the query parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@query() limit: number): Promise<Response>\n * ```\n */\nexport function query(name: string = '') {\n return parameter(ParameterType.QUERY, name);\n}\n\n/**\n * Header parameter decorator.\n *\n * Defines a header parameter that will be added to the request headers.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the header parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@header() authorization: string): Promise<Response>\n * ```\n */\nexport function header(name: string = '') {\n return parameter(ParameterType.HEADER, name);\n}\n\n/**\n * Body parameter decorator.\n *\n * Defines a body parameter that will be sent as the request body.\n * Note that body parameters don't have names since there's only one body per request.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\nexport function body() {\n return parameter(ParameterType.BODY);\n}\n\n/**\n * Interface for request parameter objects.\n *\n * Combines FetchRequestInit and PathCapable interfaces to provide\n * a complete request configuration object that can be used with\n * the @request() decorator. This allows full customization of\n * the HTTP request including method, headers, body, and URL parameters.\n */\nexport interface ParameterRequest extends FetchRequestInit, PathCapable {\n}\n\n/**\n * Request parameter decorator.\n *\n * Defines a request parameter that will be used as the base request object.\n * This allows you to pass a complete ParameterRequest object to customize\n * the request configuration.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: ParameterRequest): Promise<Response>\n * ```\n */\nexport function request() {\n return parameter(ParameterType.REQUEST);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ExchangeResultExtractor,\n JsonResultExtractor,\n ResponseResultExtractor,\n ResultExtractor, TextResultExtractor,\n} from '@ahoo-wang/fetcher';\nimport {\n EventStreamResultExtractor, JsonEventStreamResultExtractor,\n} from '@ahoo-wang/fetcher-eventstream';\n\n\n/**\n * Interface with result extractor capability\n * Defines an optional resultExtractor property\n */\nexport interface ResultExtractorCapable {\n resultExtractor?: ResultExtractor<any>;\n}\n\n/**\n * ResultExtractors is an object that maps result extractor names to their corresponding\n * extractor functions. These extractors are used to process and extract data from different\n * types of responses or results in the application.\n *\n * Each property represents a specific type of result extractor:\n * - Exchange: Handles exchange-related result extraction\n * - Response: Handles general response result extraction\n * - Json: Handles JSON format result extraction\n * - Text: Handles plain text result extraction\n * - EventStream: Handles server-sent event stream result extraction\n * - JsonEventStream: Handles JSON server-sent event stream result extraction\n */\nexport const ResultExtractors = {\n Exchange: ExchangeResultExtractor,\n Response: ResponseResultExtractor,\n Json: JsonResultExtractor,\n Text: TextResultExtractor,\n EventStream: EventStreamResultExtractor,\n JsonEventStream: JsonEventStreamResultExtractor,\n DEFAULT: JsonResultExtractor,\n};\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Fetcher, fetcherRegistrar } from '@ahoo-wang/fetcher';\n\n/**\n * Interface that defines a capability for objects that can have a fetcher.\n * This interface is typically used to mark components or objects that can perform fetching operations\n * and may need access to fetcher functionality.\n */\nexport interface FetcherCapable {\n /**\n * Optional fetcher property that can be either a string identifier or a Fetcher instance.\n * When present, this property indicates the fetcher associated with the implementing object.\n */\n fetcher?: string | Fetcher;\n}\n\n/**\n * Gets a Fetcher instance based on the provided fetcher parameter.\n *\n * @param fetcher - A string identifier or Fetcher instance to resolve\n * @returns A Fetcher instance if found, undefined otherwise\n */\nexport function getFetcher(fetcher?: string | Fetcher): Fetcher | undefined {\n // Return undefined if no fetcher is provided\n if (!fetcher) {\n return undefined;\n }\n\n // Return the fetcher directly if it's already a Fetcher instance,\n // otherwise resolve it through the fetcher registrar\n return fetcher instanceof Fetcher\n ? fetcher\n : fetcherRegistrar.requiredGet(fetcher);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n combineURLs,\n fetcher,\n Fetcher,\n type FetchRequest,\n type FetchRequestInit,\n mergeRequest,\n type NamedCapable,\n type RequestHeaders, ResultExtractor,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n type ParameterMetadata,\n type ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { ResultExtractors } from './resultExtractor';\nimport { getFetcher } from './fetcherCapable';\n\n/**\n * Metadata container for a function with HTTP endpoint decorators.\n *\n * Encapsulates all the metadata needed to execute an HTTP request\n * for a decorated method, including API-level defaults, endpoint-specific\n * configuration, and parameter metadata.\n */\nexport class FunctionMetadata implements NamedCapable {\n /**\n * Name of the function.\n */\n name: string;\n\n /**\n * API-level metadata (class-level configuration).\n */\n api: ApiMetadata;\n\n /**\n * Endpoint-level metadata (method-level configuration).\n */\n endpoint: EndpointMetadata;\n\n /**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter decorated with @path, @query,\n * @header, or @body decorators. Stored as a Map keyed by parameter index.\n *\n * @remarks\n * The metadata is stored as a Map<number, ParameterMetadata> where the key is\n * the parameter index and the value is the parameter metadata. This ensures\n * correct parameter ordering regardless of decorator application order.\n */\n parameters: Map<number, ParameterMetadata>;\n\n /**\n * Creates a new FunctionMetadata instance.\n *\n * @param name - The name of the function\n * @param api - API-level metadata\n * @param endpoint - Endpoint-level metadata\n * @param parameters - Parameter metadata array\n */\n constructor(\n name: string,\n api: ApiMetadata,\n endpoint: EndpointMetadata,\n parameters: Map<number, ParameterMetadata>,\n ) {\n this.name = name;\n this.api = api;\n this.endpoint = endpoint;\n this.parameters = parameters;\n }\n\n /**\n * Gets the fetcher instance to use for this function.\n *\n * Returns the fetcher specified in the endpoint metadata, or the API metadata,\n * or falls back to the default fetcher if none is specified.\n *\n * @returns The fetcher instance\n */\n get fetcher(): Fetcher {\n return getFetcher(this.endpoint.fetcher ?? this.api.fetcher) ?? fetcher;\n }\n\n /**\n * Resolves the request configuration from the method arguments.\n *\n * This method processes the runtime arguments according to the parameter metadata\n * and constructs a FetcherRequest object with path parameters, query parameters,\n * headers, body, and timeout. It handles various parameter types including:\n * - Path parameters (@path decorator)\n * - Query parameters (@query decorator)\n * - Header parameters (@header decorator)\n * - Body parameter (@body decorator)\n * - Complete request object (@request decorator)\n * - AbortSignal for request cancellation\n *\n * The method uses mergeRequest to combine the endpoint-specific configuration\n * with the parameter-provided request object, where the parameter request\n * takes precedence over endpoint configuration.\n *\n * @param args - The runtime arguments passed to the method\n * @returns A FetcherRequest object with all request configuration\n *\n * @example\n * ```typescript\n * // For a method decorated like:\n * @get('/users/{id}')\n * getUser(\n * @path('id') id: number,\n * @query('include') include: string,\n * @header('Authorization') auth: string\n * ): Promise<Response>\n *\n * // Calling with: getUser(123, 'profile', 'Bearer token')\n * // Would produce a request with:\n * // {\n * // method: 'GET',\n * // urlParams: {\n * // path: { id: 123 },\n * // query: { include: 'profile' }\n * // },\n * // headers: {\n * // 'Authorization': 'Bearer token',\n * // ...apiHeaders,\n * // ...endpointHeaders\n * // }\n * // }\n * ```\n */\n resolveRequest(args: any[]): FetchRequest {\n const pathParams: Record<string, any> = {};\n const queryParams: Record<string, any> = {};\n const headers: RequestHeaders = {\n ...this.api.headers,\n ...this.endpoint.headers,\n };\n let body: any = undefined;\n let signal: AbortSignal | null | undefined = undefined;\n let abortController: AbortController | null | undefined = undefined;\n let parameterRequest: ParameterRequest = {};\n // Process parameters based on their decorators\n args.forEach((value, index) => {\n if (value instanceof AbortSignal) {\n signal = value;\n return;\n }\n if (value instanceof AbortController) {\n abortController = value;\n return;\n }\n const funParameter = this.parameters.get(index);\n if (!funParameter) {\n return;\n }\n switch (funParameter.type) {\n case ParameterType.PATH:\n this.processPathParam(funParameter, value, pathParams);\n break;\n case ParameterType.QUERY:\n this.processQueryParam(funParameter, value, queryParams);\n break;\n case ParameterType.HEADER:\n this.processHeaderParam(funParameter, value, headers);\n break;\n case ParameterType.BODY:\n body = value;\n break;\n case ParameterType.REQUEST:\n parameterRequest = this.processRequestParam(value);\n break;\n }\n });\n const urlParams: UrlParams = {\n path: pathParams,\n query: queryParams,\n };\n const endpointRequest: FetchRequestInit = {\n method: this.endpoint.method,\n urlParams,\n headers,\n body,\n timeout: this.resolveTimeout(),\n signal,\n abortController,\n };\n const mergedRequest = mergeRequest(\n endpointRequest,\n parameterRequest,\n ) as any;\n const parameterPath = parameterRequest.path;\n mergedRequest.url = this.resolvePath(parameterPath);\n return mergedRequest;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n path[paramName] = value;\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n query[paramName] = value;\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n if (param.name && value !== undefined) {\n headers[param.name] = String(value);\n }\n }\n\n /**\n * Processes a request parameter value.\n *\n * This method handles the @request() decorator parameter by casting\n * the provided value to a FetcherRequest. The @request() decorator\n * allows users to pass a complete FetcherRequest object to customize\n * the request configuration.\n *\n * @param value - The value provided for the @request() parameter\n * @returns The value cast to FetcherRequest type\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: FetcherRequest): Promise<Response>\n *\n * // Usage:\n * const customRequest: FetcherRequest = {\n * headers: { 'X-Custom': 'value' },\n * timeout: 5000\n * };\n * await service.createUsers(customRequest);\n * ```\n */\n private processRequestParam(value: any): ParameterRequest {\n return value as ParameterRequest;\n }\n\n /**\n * Resolves the complete path by combining base path and endpoint path\n *\n * @param parameterPath - Optional path parameter to use instead of endpoint path\n * @returns The combined URL path\n */\n resolvePath(parameterPath?: string): string {\n // Get the base path from endpoint, API, or default to empty string\n const basePath = this.endpoint.basePath || this.api.basePath || '';\n\n // Use provided parameter path or fallback to endpoint path\n const endpointPath = parameterPath || this.endpoint.path || '';\n\n // Combine the base path and endpoint path into a complete URL\n return combineURLs(basePath, endpointPath);\n }\n\n /**\n * Resolves the timeout for the request.\n *\n * Returns the timeout specified in the endpoint metadata, or the API metadata,\n * or undefined if no timeout is specified.\n *\n * @returns The timeout value in milliseconds, or undefined\n */\n resolveTimeout(): number | undefined {\n return this.endpoint.timeout || this.api.timeout;\n }\n\n resolveResultExtractor(): ResultExtractor<any> {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n ResultExtractors.DEFAULT\n );\n }\n}\n\nconst TARGET_FETCHER_PROPERTY = 'fetcher';\n\n/**\n * Executor for HTTP requests based on decorated method metadata.\n *\n * This class is responsible for executing HTTP requests based on the metadata\n * collected from decorators. It resolves the path, constructs the request,\n * and executes it using the appropriate fetcher.\n */\nexport class RequestExecutor {\n private readonly metadata: FunctionMetadata;\n\n /**\n * Creates a new RequestExecutor instance.\n *\n * @param metadata - The function metadata containing all request information\n */\n constructor(metadata: FunctionMetadata) {\n this.metadata = metadata;\n }\n\n /**\n * Retrieves the fetcher instance from the target object.\n *\n * @param target - The target object that may contain a fetcher property\n * @returns The fetcher instance if exists, otherwise undefined\n */\n private getTargetFetcher(target: any): Fetcher | undefined {\n if (!target || typeof target !== 'object') {\n return undefined;\n }\n // Extract the fetcher property from the target object\n const fetcher = target[TARGET_FETCHER_PROPERTY];\n\n // Validate that the fetcher is an instance of the Fetcher class\n if (fetcher instanceof Fetcher) {\n return fetcher;\n }\n\n // Return undefined if no valid fetcher instance is found\n return undefined;\n }\n\n /**\n * Executes the HTTP request.\n *\n * This method resolves the path and request configuration from the metadata\n * and arguments, then executes the request using the configured fetcher.\n *\n * @param target - The target object that the method is called on\n * @param args - The runtime arguments passed to the method\n * @returns A Promise that resolves to the Response\n */\n async execute(\n target: any,\n args: any[],\n ): Promise<any> {\n const fetcher = this.getTargetFetcher(target) || this.metadata.fetcher;\n const request = this.metadata.resolveRequest(args);\n const extractor = this.metadata.resolveResultExtractor();\n return fetcher.request(request, extractor);\n }\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Fetcher,\n type RequestHeaders,\n type RequestHeadersCapable,\n type TimeoutCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { FunctionMetadata, RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\nimport { type FetcherCapable } from './fetcherCapable';\n\n/**\n * Metadata for class-level API configuration.\n *\n * Defines the configuration options that can be applied to an entire API class.\n * These settings will be used as defaults for all endpoints within the class unless overridden\n * at the method level.\n */\nexport interface ApiMetadata\n extends TimeoutCapable,\n RequestHeadersCapable,\n ResultExtractorCapable,\n FetcherCapable {\n /**\n * Base path for all endpoints in the class.\n *\n * This path will be prepended to all endpoint paths defined in the class.\n * For example, if basePath is '/api/v1' and an endpoint has path '/users',\n * the full path will be '/api/v1/users'.\n */\n basePath?: string;\n\n /**\n * Default headers for all requests in the class.\n *\n * These headers will be included in every request made by methods in this class.\n * They can be overridden or extended at the method level.\n */\n headers?: RequestHeaders;\n\n /**\n * Default timeout for all requests in the class (in milliseconds).\n *\n * This timeout value will be applied to all requests made by methods in this class.\n * Individual methods can specify their own timeout values to override this default.\n */\n timeout?: number;\n\n /**\n * Name of the fetcher instance to use, default: 'default'.\n *\n * This allows you to specify which fetcher instance should be used for requests\n * from this API class. The fetcher must be registered with the FetcherRegistrar.\n */\n fetcher?: string | Fetcher;\n}\n\nexport const API_METADATA_KEY = Symbol('api:metadata');\n\n/**\n * Binds a request executor to a method, replacing the original method with\n * an implementation that makes HTTP requests based on the decorator metadata.\n *\n * @param constructor - The class constructor\n * @param functionName - The name of the method to bind\n * @param apiMetadata - The API metadata for the class\n */\nfunction bindExecutor<T extends new (...args: any[]) => any>(\n constructor: T,\n functionName: string,\n apiMetadata: ApiMetadata,\n) {\n const endpointFunction = constructor.prototype[functionName];\n if (functionName === 'constructor') {\n return;\n }\n if (typeof endpointFunction !== 'function') {\n return;\n }\n\n const endpointMetadata = Reflect.getMetadata(\n ENDPOINT_METADATA_KEY,\n constructor.prototype,\n functionName,\n );\n if (!endpointMetadata) {\n return;\n }\n // Get parameter metadata for this method\n const parameterMetadata =\n Reflect.getMetadata(\n PARAMETER_METADATA_KEY,\n constructor.prototype,\n functionName,\n ) || new Map();\n\n // Create function metadata\n const functionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n const requestExecutor = new RequestExecutor(functionMetadata);\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = function(...args: unknown[]) {\n return requestExecutor.execute(this, args);\n };\n}\n\nexport function api(\n basePath: string = '',\n metadata: Omit<ApiMetadata, 'basePath'> = {},\n) {\n return function <T extends new (...args: any[]) => any>(constructor: T): T {\n const apiMetadata: ApiMetadata = {\n basePath,\n ...metadata,\n };\n\n // Store metadata directly on the class constructor\n Reflect.defineMetadata(API_METADATA_KEY, apiMetadata, constructor);\n\n // Override prototype methods to implement actual HTTP calls\n Object.getOwnPropertyNames(constructor.prototype).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n\n return constructor;\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Custom error class that indicates a method implementation will be automatically generated.\n *\n * @example\n * ```\n * @post()\n * createUser(@body() user: User):Promise<Response> {\n * throw autoGeneratedError(user);\n * }\n * ```\n */\nexport class AutoGenerated extends Error {\n constructor() {\n super('Implementation will be generated automatically.');\n this.name = 'AutoGenerated';\n }\n}\n\n/**\n * Factory function that creates an AutoGenerated error instance.\n * This is typically used in methods that will be automatically implemented,\n * where a placeholder implementation is needed.\n *\n * @param _ignored - Arguments (such as 'user' in the example) are ignored to prevent\n * ESLint no-unused-vars errors in method signatures that will be auto-generated.\n * @returns A new AutoGenerated error instance\n */\nexport const autoGeneratedError = (..._ignored: any[]): AutoGenerated => {\n return new AutoGenerated();\n};\n"],"names":["ENDPOINT_METADATA_KEY","endpoint","method","path","metadata","target","propertyKey","endpointMetadata","get","HttpMethod","post","put","del","patch","head","options","parameterNameCache","getParameterNames","func","fnStr","paramsStr","extractParameterString","hasParameters","emptyResult","result","parseParameterNames","errorResult","getParameterName","parameterIndex","providedName","paramNames","endParenIndex","findClosingParenthesis","startParenIndex","str","openingParenIndex","parenDepth","i","char","trimWhitespace","isNotEmpty","extractParameterName","param","cleanedParam","removeDefaultValue","removeTypeAnnotation","equalsIndex","colonIndex","ParameterType","PARAMETER_METADATA_KEY","parameter","type","name","paramName","existingParameters","parameterMetadata","query","header","body","request","ResultExtractors","ExchangeResultExtractor","ResponseResultExtractor","JsonResultExtractor","TextResultExtractor","EventStreamResultExtractor","JsonEventStreamResultExtractor","getFetcher","fetcher","Fetcher","fetcherRegistrar","FunctionMetadata","api","parameters","args","pathParams","queryParams","headers","signal","abortController","parameterRequest","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","parameterPath","basePath","endpointPath","combineURLs","TARGET_FETCHER_PROPERTY","RequestExecutor","extractor","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","requestExecutor","AutoGenerated","autoGeneratedError","_ignored"],"mappings":";;;AAiCO,MAAMA,IAAwB,OAAO,mBAAmB;AA4BxD,SAASC,EACdC,GACAC,GACAC,IAAmC,CAAA,GACnC;AACA,SAAO,SAASC,GAAgBC,GAAoC;AAElE,UAAMC,IAAmB;AAAA,MACvB,QAAAL;AAAA,MACA,MAAAC;AAAA,MACA,GAAGC;AAAA,IAAA;AAEL,YAAQ;AAAA,MACNJ;AAAA,MACAO;AAAA,MACAF;AAAA,MACAC;AAAA,IAAA;AAAA,EAEJ;AACF;AAEO,SAASE,GAAIL,IAAe,IAAIC,IAAmC,CAAA,GAAI;AAC5E,SAAOH,EAASQ,EAAW,KAAKN,GAAMC,CAAQ;AAChD;AAEO,SAASM,GAAKP,IAAe,IAAIC,IAAmC,CAAA,GAAI;AAC7E,SAAOH,EAASQ,EAAW,MAAMN,GAAMC,CAAQ;AACjD;AAEO,SAASO,GAAIR,IAAe,IAAIC,IAAmC,CAAA,GAAI;AAC5E,SAAOH,EAASQ,EAAW,KAAKN,GAAMC,CAAQ;AAChD;AAEO,SAASQ,GAAIT,IAAe,IAAIC,IAAmC,CAAA,GAAI;AAC5E,SAAOH,EAASQ,EAAW,QAAQN,GAAMC,CAAQ;AACnD;AAEO,SAASS,GACdV,IAAe,IACfC,IAAmC,CAAA,GACnC;AACA,SAAOH,EAASQ,EAAW,OAAON,GAAMC,CAAQ;AAClD;AAEO,SAASU,GAAKX,IAAe,IAAIC,IAAmC,CAAA,GAAI;AAC7E,SAAOH,EAASQ,EAAW,MAAMN,GAAMC,CAAQ;AACjD;AAEO,SAASW,GACdZ,IAAe,IACfC,IAAmC,CAAA,GACnC;AACA,SAAOH,EAASQ,EAAW,SAASN,GAAMC,CAAQ;AACpD;ACpGA,MAAMY,wBAAyB,QAAA;AA+BxB,SAASC,EAAkBC,GAAyC;AAEzE,MAAI,OAAOA,KAAS;AAClB,UAAM,IAAI,UAAU,qBAAqB;AAI3C,MAAIF,EAAmB,IAAIE,CAAI;AAC7B,WAAOF,EAAmB,IAAIE,CAAI;AAGpC,MAAI;AAEF,UAAMC,IAAQD,EAAK,SAAA,EAAW,KAAA,GAGxBE,IAAYC,EAAuBF,CAAK;AAG9C,QAAI,CAACG,EAAcF,CAAS,GAAG;AAC7B,YAAMG,IAAwB,CAAA;AAC9B,aAAAP,EAAmB,IAAIE,GAAMK,CAAW,GACjCA;AAAA,IACT;AAGA,UAAMC,IAASC,EAAoBL,CAAS;AAC5C,WAAAJ,EAAmB,IAAIE,GAAMM,CAAM,GAC5BA;AAAA,EACT,QAAQ;AAEN,UAAME,IAAwB,CAAA;AAC9B,WAAAV,EAAmB,IAAIE,GAAMQ,CAAW,GACjCA;AAAA,EACT;AACF;AAWO,SAASC,EACdtB,GACAC,GACAsB,GACAC,GACoB;AAEpB,MAAIA;AACF,WAAOA;AAIT,MAAI;AACF,UAAM3B,IAASG,EAAOC,CAAkC;AACxD,QAAIJ,KAAU,OAAOA,KAAW,YAAY;AAC1C,YAAM4B,IAAab,EAAkBf,CAAM;AAC3C,UAAI0B,IAAiBE,EAAW;AAC9B,eAAOA,EAAWF,CAAc;AAAA,IAEpC;AAAA,EACF,QAAQ;AAAA,EAGR;AAGF;AAQA,SAASN,EAAcF,GAA4B;AACjD,SACEA,KAAc,QAAmCA,EAAU,WAAW;AAE1E;AAQA,SAASC,EAAuBF,GAAuB;AAErD,MAAIA,EAAM,WAAW,GAAG,GAAG;AACzB,UAAMY,IAAgBC,EAAuBb,GAAO,CAAC;AACrD,WAAIY,MAAkB,KAAW,KAC1BZ,EAAM,UAAU,GAAGY,CAAa;AAAA,EACzC;AAGA,QAAME,IAAkBd,EAAM,QAAQ,GAAG;AACzC,MAAIc,MAAoB,GAAI,QAAO;AAEnC,QAAMF,IAAgBC,EAAuBb,GAAOc,CAAe;AACnE,SAAIF,MAAkB,KAAW,KAE1BZ,EAAM,UAAUc,IAAkB,GAAGF,CAAa;AAC3D;AASA,SAASC,EACPE,GACAC,GACQ;AACR,MAAIC,IAAa;AAEjB,WAASC,IAAIF,IAAoB,GAAGE,IAAIH,EAAI,QAAQG,KAAK;AACvD,UAAMC,IAAOJ,EAAIG,CAAC;AAElB,QAAIC,MAAS;AACX,MAAAF;AAAA,aACSE,MAAS,QAClBF,KACIA,MAAe;AACjB,aAAOC;AAAA,EAGb;AAEA,SAAO;AACT;AAQA,SAASZ,EAAoBL,GAA6B;AACxD,SAAOA,EACJ,MAAM,GAAG,EACT,IAAImB,CAAc,EAClB,OAAOC,CAAU,EACjB,IAAIC,CAAoB;AAC7B;AAQA,SAASF,EAAeL,GAAqB;AAC3C,SAAOA,EAAI,KAAA;AACb;AAQA,SAASM,EAAWN,GAAsB;AACxC,SAAOA,EAAI,SAAS;AACtB;AAQA,SAASO,EAAqBC,GAAuB;AAEnD,MAAIC,IAAeC,EAAmBF,CAAK;AAG3C,SAAAC,IAAeE,EAAqBF,CAAY,GAEzCA,EAAa,KAAA;AACtB;AAQA,SAASC,EAAmBF,GAAuB;AACjD,QAAMI,IAAcJ,EAAM,QAAQ,GAAG;AACrC,SAAII,MAAgB,KACXJ,EAAM,UAAU,GAAGI,CAAW,IAEhCJ;AACT;AAQA,SAASG,EAAqBH,GAAuB;AACnD,QAAMK,IAAaL,EAAM,QAAQ,GAAG;AACpC,SAAIK,MAAe,KACVL,EAAM,UAAU,GAAGK,CAAU,IAE/BL;AACT;ACxPO,IAAKM,sBAAAA,OAaVA,EAAA,OAAO,QAcPA,EAAA,QAAQ,SAcRA,EAAA,SAAS,UAcTA,EAAA,OAAO,QAKPA,EAAA,UAAU,WA5DAA,IAAAA,KAAA,CAAA,CAAA;AA8FL,MAAMC,IAAyB,OAAO,oBAAoB;AA0B1D,SAASC,EAAUC,GAAqBC,IAAe,IAAI;AAChE,SAAO,SACL/C,GACAC,GACAsB,GACA;AACA,UAAMyB,IAAY1B;AAAA,MAChBtB;AAAA,MACAC;AAAA,MACAsB;AAAA,MACAwB;AAAA,IAAA,GAGIE,IACJ,QAAQ,YAAYL,GAAwB5C,GAAQC,CAAW,yBAC3D,IAAA,GACAiD,IAAuC;AAAA,MAC3C,MAAAJ;AAAA,MACA,MAAME;AAAA,MACN,OAAOzB;AAAA,IAAA;AAET,IAAA0B,EAAmB,IAAI1B,GAAgB2B,CAAiB,GACxD,QAAQ;AAAA,MACNN;AAAA,MACAK;AAAA,MACAjD;AAAA,MACAC;AAAA,IAAA;AAAA,EAEJ;AACF;AAuBO,SAASH,GAAKiD,IAAe,IAAI;AACtC,SAAOF,EAAU,QAAoBE,CAAI;AAC3C;AAuBO,SAASI,GAAMJ,IAAe,IAAI;AACvC,SAAOF,EAAU,SAAqBE,CAAI;AAC5C;AAuBO,SAASK,GAAOL,IAAe,IAAI;AACxC,SAAOF,EAAU,UAAsBE,CAAI;AAC7C;AAgBO,SAASM,KAAO;AACrB,SAAOR;AAAA,IAAU;AAAA;AAAA,EAAA;AACnB;AA4BO,SAASS,KAAU;AACxB,SAAOT;AAAA,IAAU;AAAA;AAAA,EAAA;AACnB;AC/OO,MAAMU,IAAmB;AAAA,EAC9B,UAAUC;AAAA,EACV,UAAUC;AAAA,EACV,MAAMC;AAAA,EACN,MAAMC;AAAA,EACN,aAAaC;AAAA,EACb,iBAAiBC;AAAA,EACjB,SAASH;AACX;ACnBO,SAASI,EAAWC,GAAiD;AAE1E,MAAKA;AAML,WAAOA,aAAmBC,IACtBD,IACAE,EAAiB,YAAYF,CAAO;AAC1C;ACLO,MAAMG,EAAyC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCpD,YACEnB,GACAoB,GACAvE,GACAwE,GACA;AACA,SAAK,OAAOrB,GACZ,KAAK,MAAMoB,GACX,KAAK,WAAWvE,GAChB,KAAK,aAAawE;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAI,UAAmB;AACrB,WAAON,EAAW,KAAK,SAAS,WAAW,KAAK,IAAI,OAAO,KAAKC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgDA,eAAeM,GAA2B;AACxC,UAAMC,IAAkC,CAAA,GAClCC,IAAmC,CAAA,GACnCC,IAA0B;AAAA,MAC9B,GAAG,KAAK,IAAI;AAAA,MACZ,GAAG,KAAK,SAAS;AAAA,IAAA;AAEnB,QAAInB,GACAoB,GACAC,GACAC,IAAqC,CAAA;AAEzC,IAAAN,EAAK,QAAQ,CAACO,GAAOC,MAAU;AAC7B,UAAID,aAAiB,aAAa;AAChC,QAAAH,IAASG;AACT;AAAA,MACF;AACA,UAAIA,aAAiB,iBAAiB;AACpC,QAAAF,IAAkBE;AAClB;AAAA,MACF;AACA,YAAME,IAAe,KAAK,WAAW,IAAID,CAAK;AAC9C,UAAKC;AAGL,gBAAQA,EAAa,MAAA;AAAA,UACnB,KAAKnC,EAAc;AACjB,iBAAK,iBAAiBmC,GAAcF,GAAON,CAAU;AACrD;AAAA,UACF,KAAK3B,EAAc;AACjB,iBAAK,kBAAkBmC,GAAcF,GAAOL,CAAW;AACvD;AAAA,UACF,KAAK5B,EAAc;AACjB,iBAAK,mBAAmBmC,GAAcF,GAAOJ,CAAO;AACpD;AAAA,UACF,KAAK7B,EAAc;AACjB,YAAAU,IAAOuB;AACP;AAAA,UACF,KAAKjC,EAAc;AACjB,YAAAgC,IAAmB,KAAK,oBAAoBC,CAAK;AACjD;AAAA,QAAA;AAAA,IAEN,CAAC;AACD,UAAMG,IAAuB;AAAA,MAC3B,MAAMT;AAAA,MACN,OAAOC;AAAA,IAAA,GAEHS,IAAoC;AAAA,MACxC,QAAQ,KAAK,SAAS;AAAA,MACtB,WAAAD;AAAA,MACA,SAAAP;AAAA,MACA,MAAAnB;AAAA,MACA,SAAS,KAAK,eAAA;AAAA,MACd,QAAAoB;AAAA,MACA,iBAAAC;AAAA,IAAA,GAEIO,IAAgBC;AAAA,MACpBF;AAAA,MACAL;AAAA,IAAA,GAEIQ,IAAgBR,EAAiB;AACvC,WAAAM,EAAc,MAAM,KAAK,YAAYE,CAAa,GAC3CF;AAAA,EACT;AAAA,EAEQ,iBACN5C,GACAuC,GACA9E,GACA;AACA,UAAMkD,IAAYX,EAAM,QAAQ,QAAQA,EAAM,KAAK;AACnD,IAAAvC,EAAKkD,CAAS,IAAI4B;AAAA,EACpB;AAAA,EAEQ,kBACNvC,GACAuC,GACAzB,GACA;AACA,UAAMH,IAAYX,EAAM,QAAQ,QAAQA,EAAM,KAAK;AACnD,IAAAc,EAAMH,CAAS,IAAI4B;AAAA,EACrB;AAAA,EAEQ,mBACNvC,GACAuC,GACAJ,GACA;AACA,IAAInC,EAAM,QAAQuC,MAAU,WAC1BJ,EAAQnC,EAAM,IAAI,IAAI,OAAOuC,CAAK;AAAA,EAEtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BQ,oBAAoBA,GAA8B;AACxD,WAAOA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAYO,GAAgC;AAE1C,UAAMC,IAAW,KAAK,SAAS,YAAY,KAAK,IAAI,YAAY,IAG1DC,IAAeF,KAAiB,KAAK,SAAS,QAAQ;AAG5D,WAAOG,EAAYF,GAAUC,CAAY;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,iBAAqC;AACnC,WAAO,KAAK,SAAS,WAAW,KAAK,IAAI;AAAA,EAC3C;AAAA,EAEA,yBAA+C;AAC7C,WACE,KAAK,SAAS,mBACd,KAAK,IAAI,mBACT9B,EAAiB;AAAA,EAErB;AACF;AAEA,MAAMgC,IAA0B;AASzB,MAAMC,EAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3B,YAAYzF,GAA4B;AACtC,SAAK,WAAWA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,iBAAiBC,GAAkC;AACzD,QAAI,CAACA,KAAU,OAAOA,KAAW;AAC/B;AAGF,UAAM+D,IAAU/D,EAAOuF,CAAuB;AAG9C,QAAIxB,aAAmBC;AACrB,aAAOD;AAAAA,EAKX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QACJ/D,GACAqE,GACc;AACd,UAAMN,IAAU,KAAK,iBAAiB/D,CAAM,KAAK,KAAK,SAAS,SACzDsD,IAAU,KAAK,SAAS,eAAee,CAAI,GAC3CoB,IAAY,KAAK,SAAS,uBAAA;AAChC,WAAO1B,EAAQ,QAAQT,GAASmC,CAAS;AAAA,EAC3C;AACF;ACxSO,MAAMC,IAAmB,OAAO,cAAc;AAUrD,SAASC,EACPC,GACAC,GACAC,GACA;AACA,QAAMC,IAAmBH,EAAY,UAAUC,CAAY;AAI3D,MAHIA,MAAiB,iBAGjB,OAAOE,KAAqB;AAC9B;AAGF,QAAM7F,IAAmB,QAAQ;AAAA,IAC/BP;AAAA,IACAiG,EAAY;AAAA,IACZC;AAAA,EAAA;AAEF,MAAI,CAAC3F;AACH;AAGF,QAAMgD,IACJ,QAAQ;AAAA,IACNN;AAAA,IACAgD,EAAY;AAAA,IACZC;AAAA,EAAA,yBACO,IAAA,GAGLG,IAAmB,IAAI9B;AAAA,IAC3B2B;AAAA,IACAC;AAAA,IACA5F;AAAA,IACAgD;AAAA,EAAA,GAII+C,IAAkB,IAAIT,EAAgBQ,CAAgB;AAG5D,EAAAJ,EAAY,UAAUC,CAAY,IAAI,YAAYxB,GAAiB;AACjE,WAAO4B,EAAgB,QAAQ,MAAM5B,CAAI;AAAA,EAC3C;AACF;AAEO,SAASF,GACdiB,IAAmB,IACnBrF,IAA0C,CAAA,GAC1C;AACA,SAAO,SAAiD6F,GAAmB;AACzE,UAAME,IAA2B;AAAA,MAC/B,UAAAV;AAAA,MACA,GAAGrF;AAAA,IAAA;AAIL,mBAAQ,eAAe2F,GAAkBI,GAAaF,CAAW,GAGjE,OAAO,oBAAoBA,EAAY,SAAS,EAAE,QAAQ,CAAAC,MAAgB;AACxE,MAAAF,EAAaC,GAAaC,GAAcC,CAAW;AAAA,IACrD,CAAC,GAEMF;AAAA,EACT;AACF;AC5HO,MAAMM,UAAsB,MAAM;AAAA,EACvC,cAAc;AACZ,UAAM,iDAAiD,GACvD,KAAK,OAAO;AAAA,EACd;AACF;AAWO,MAAMC,KAAqB,IAAIC,MAC7B,IAAIF,EAAA;"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(r,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("@ahoo-wang/fetcher"),require("reflect-metadata")):typeof define=="function"&&define.amd?define(["exports","@ahoo-wang/fetcher","reflect-metadata"],s):(r=typeof globalThis<"u"?globalThis:r||self,s(r.FetcherDecorator={},r.Fetcher))})(this,(function(r,s){"use strict";const R=Symbol("endpoint:metadata");function u(t,e,n={}){return function(a,o){const i={method:t,path:e,...n};Reflect.defineMetadata(R,i,a,o)}}function N(t="",e={}){return u(s.HttpMethod.GET,t,e)}function Y(t="",e={}){return u(s.HttpMethod.POST,t,e)}function G(t="",e={}){return u(s.HttpMethod.PUT,t,e)}function I(t="",e={}){return u(s.HttpMethod.DELETE,t,e)}function U(t="",e={}){return u(s.HttpMethod.PATCH,t,e)}function J(t="",e={}){return u(s.HttpMethod.HEAD,t,e)}function k(t="",e={}){return u(s.HttpMethod.OPTIONS,t,e)}const E=new WeakMap;function T(t){if(typeof t!="function")throw new TypeError("Expected a function");if(E.has(t))return E.get(t);try{const e=t.toString().trim(),n=j(e);if(!Q(n)){const o=[];return E.set(t,o),o}const a=C(n);return E.set(t,a),a}catch{const e=[];return E.set(t,e),e}}function A(t,e,n,a){if(a)return a;try{const o=t[e];if(o&&typeof o=="function"){const i=T(o);if(n<i.length)return i[n]}}catch{}}function Q(t){return t!=null&&t.trim()!==""}function j(t){if(t.startsWith("(")){const a=q(t,0);return a===-1?"":t.substring(1,a)}const e=t.indexOf("(");if(e===-1)return"";const n=q(t,e);return n===-1?"":t.substring(e+1,n)}function q(t,e){let n=1;for(let a=e+1;a<t.length;a++){const o=t[a];if(o==="(")n++;else if(o===")"&&(n--,n===0))return a}return-1}function C(t){return t.split(",").map(K).filter(L).map(W)}function K(t){return t.trim()}function L(t){return t.length>0}function W(t){let e=B(t);return e=V(e),e.trim()}function B(t){const e=t.indexOf("=");return e!==-1?t.substring(0,e):t}function V(t){const e=t.indexOf(":");return e!==-1?t.substring(0,e):t}var d=(t=>(t.PATH="path",t.QUERY="query",t.HEADER="header",t.BODY="body",t.REQUEST="request",t))(d||{});const p=Symbol("parameter:metadata");function f(t,e=""){return function(n,a,o){const i=A(n,a,o,e),c=Reflect.getMetadata(p,n,a)||new Map,h={type:t,name:i,index:o};c.set(o,h),Reflect.defineMetadata(p,c,n,a)}}function z(t=""){return f("path",t)}function X(t=""){return f("query",t)}function Z(t=""){return f("header",t)}function $(){return f("body")}function tt(){return f("request")}const M=t=>t,y=t=>t.requiredResponse,P=t=>t.requiredResponse.json(),b=t=>t.requiredResponse.text(),v=t=>t.requiredResponse.requiredEventStream(),D=t=>t.requiredResponse.requiredJsonEventStream(),x={Exchange:M,Response:y,Json:P,Text:b,EventStream:v,JsonEventStream:D,DEFAULT:P};function H(t){if(t)return t instanceof s.Fetcher?t:s.fetcherRegistrar.requiredGet(t)}class S{constructor(e,n,a,o){this.name=e,this.api=n,this.endpoint=a,this.parameters=o}get fetcher(){return H(this.endpoint.fetcher??this.api.fetcher)??s.fetcher}resolveRequest(e){const n={},a={},o={...this.api.headers,...this.endpoint.headers};let i,c,h={};e.forEach((m,it)=>{if(m instanceof AbortSignal){c=m;return}const l=this.parameters.get(it);if(l)switch(l.type){case d.PATH:this.processPathParam(l,m,n);break;case d.QUERY:this.processQueryParam(l,m,a);break;case d.HEADER:this.processHeaderParam(l,m,o);break;case d.BODY:i=m;break;case d.REQUEST:h=this.processRequestParam(m);break}});const g={path:n,query:a},ot={method:this.endpoint.method,urlParams:g,headers:o,body:i,timeout:this.resolveTimeout(),signal:c},O=s.mergeRequest(ot,h),st=h.path;return O.url=this.resolvePath(st),O}processPathParam(e,n,a){const o=e.name||`param${e.index}`;a[o]=n}processQueryParam(e,n,a){const o=e.name||`param${e.index}`;a[o]=n}processHeaderParam(e,n,a){e.name&&n!==void 0&&(a[e.name]=String(n))}processRequestParam(e){return e}resolvePath(e){const n=this.endpoint.basePath||this.api.basePath||"",a=e||this.endpoint.path||"";return s.combineURLs(n,a)}resolveTimeout(){return this.endpoint.timeout||this.api.timeout}resolveResultExtractor(){return this.endpoint.resultExtractor||this.api.resultExtractor||x.DEFAULT}}const et="fetcher";class _{constructor(e){this.metadata=e}getTargetFetcher(e){if(!e||typeof e!="object")return;const n=e[et];if(n instanceof s.Fetcher)return n}async execute(e,n){const a=this.getTargetFetcher(e)||this.metadata.fetcher,o=this.metadata.resolveRequest(n),i=await a.request(o);return this.metadata.resolveResultExtractor()(i)}}const w=Symbol("api:metadata");function nt(t,e,n){const a=t.prototype[e];if(e==="constructor"||typeof a!="function")return;const o=Reflect.getMetadata(R,t.prototype,e);if(!o)return;const i=Reflect.getMetadata(p,t.prototype,e)||new Map,c=new S(e,n,o,i),h=new _(c);t.prototype[e]=function(...g){return h.execute(this,g)}}function rt(t="",e={}){return function(n){const a={basePath:t,...e};return Reflect.defineMetadata(w,a,n),Object.getOwnPropertyNames(n.prototype).forEach(o=>{nt(n,o,a)}),n}}class F extends Error{constructor(){super("Implementation will be generated automatically."),this.name="AutoGenerated"}}const at=(...t)=>new F;r.API_METADATA_KEY=w,r.AutoGenerated=F,r.ENDPOINT_METADATA_KEY=R,r.EventStreamResultExtractor=v,r.ExchangeResultExtractor=M,r.FunctionMetadata=S,r.JsonEventStreamResultExtractor=D,r.JsonResultExtractor=P,r.PARAMETER_METADATA_KEY=p,r.ParameterType=d,r.RequestExecutor=_,r.ResponseResultExtractor=y,r.ResultExtractors=x,r.TextResultExtractor=b,r.api=rt,r.autoGeneratedError=at,r.body=$,r.del=I,r.endpoint=u,r.get=N,r.getFetcher=H,r.getParameterName=A,r.getParameterNames=T,r.head=J,r.header=Z,r.options=k,r.parameter=f,r.patch=U,r.path=z,r.post=Y,r.put=G,r.query=X,r.request=tt,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(a,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("@ahoo-wang/fetcher"),require("reflect-metadata"),require("@ahoo-wang/fetcher-eventstream")):typeof define=="function"&&define.amd?define(["exports","@ahoo-wang/fetcher","reflect-metadata","@ahoo-wang/fetcher-eventstream"],i):(a=typeof globalThis<"u"?globalThis:a||self,i(a.FetcherDecorator={},a.Fetcher,a["reflect-metadata"],a.FetcherEventStream))})(this,(function(a,i,at,T){"use strict";const R=Symbol("endpoint:metadata");function c(t,e,n={}){return function(r,o){const s={method:t,path:e,...n};Reflect.defineMetadata(R,s,r,o)}}function F(t="",e={}){return c(i.HttpMethod.GET,t,e)}function _(t="",e={}){return c(i.HttpMethod.POST,t,e)}function O(t="",e={}){return c(i.HttpMethod.PUT,t,e)}function x(t="",e={}){return c(i.HttpMethod.DELETE,t,e)}function S(t="",e={}){return c(i.HttpMethod.PATCH,t,e)}function N(t="",e={}){return c(i.HttpMethod.HEAD,t,e)}function Y(t="",e={}){return c(i.HttpMethod.OPTIONS,t,e)}const p=new WeakMap;function g(t){if(typeof t!="function")throw new TypeError("Expected a function");if(p.has(t))return p.get(t);try{const e=t.toString().trim(),n=I(e);if(!G(n)){const o=[];return p.set(t,o),o}const r=U(n);return p.set(t,r),r}catch{const e=[];return p.set(t,e),e}}function A(t,e,n,r){if(r)return r;try{const o=t[e];if(o&&typeof o=="function"){const s=g(o);if(n<s.length)return s[n]}}catch{}}function G(t){return t!=null&&t.trim()!==""}function I(t){if(t.startsWith("(")){const r=M(t,0);return r===-1?"":t.substring(1,r)}const e=t.indexOf("(");if(e===-1)return"";const n=M(t,e);return n===-1?"":t.substring(e+1,n)}function M(t,e){let n=1;for(let r=e+1;r<t.length;r++){const o=t[r];if(o==="(")n++;else if(o===")"&&(n--,n===0))return r}return-1}function U(t){return t.split(",").map(k).filter(C).map(Q)}function k(t){return t.trim()}function C(t){return t.length>0}function Q(t){let e=J(t);return e=j(e),e.trim()}function J(t){const e=t.indexOf("=");return e!==-1?t.substring(0,e):t}function j(t){const e=t.indexOf(":");return e!==-1?t.substring(0,e):t}var d=(t=>(t.PATH="path",t.QUERY="query",t.HEADER="header",t.BODY="body",t.REQUEST="request",t))(d||{});const P=Symbol("parameter:metadata");function m(t,e=""){return function(n,r,o){const s=A(n,r,o,e),h=Reflect.getMetadata(P,n,r)||new Map,f={type:t,name:s,index:o};h.set(o,f),Reflect.defineMetadata(P,h,n,r)}}function K(t=""){return m("path",t)}function L(t=""){return m("query",t)}function W(t=""){return m("header",t)}function B(){return m("body")}function V(){return m("request")}const y={Exchange:i.ExchangeResultExtractor,Response:i.ResponseResultExtractor,Json:i.JsonResultExtractor,Text:i.TextResultExtractor,EventStream:T.EventStreamResultExtractor,JsonEventStream:T.JsonEventStreamResultExtractor,DEFAULT:i.JsonResultExtractor};function b(t){if(t)return t instanceof i.Fetcher?t:i.fetcherRegistrar.requiredGet(t)}class q{constructor(e,n,r,o){this.name=e,this.api=n,this.endpoint=r,this.parameters=o}get fetcher(){return b(this.endpoint.fetcher??this.api.fetcher)??i.fetcher}resolveRequest(e){const n={},r={},o={...this.api.headers,...this.endpoint.headers};let s,h,f,E={};e.forEach((u,rt)=>{if(u instanceof AbortSignal){h=u;return}if(u instanceof AbortController){f=u;return}const l=this.parameters.get(rt);if(l)switch(l.type){case d.PATH:this.processPathParam(l,u,n);break;case d.QUERY:this.processQueryParam(l,u,r);break;case d.HEADER:this.processHeaderParam(l,u,o);break;case d.BODY:s=u;break;case d.REQUEST:E=this.processRequestParam(u);break}});const tt={path:n,query:r},et={method:this.endpoint.method,urlParams:tt,headers:o,body:s,timeout:this.resolveTimeout(),signal:h,abortController:f},w=i.mergeRequest(et,E),nt=E.path;return w.url=this.resolvePath(nt),w}processPathParam(e,n,r){const o=e.name||`param${e.index}`;r[o]=n}processQueryParam(e,n,r){const o=e.name||`param${e.index}`;r[o]=n}processHeaderParam(e,n,r){e.name&&n!==void 0&&(r[e.name]=String(n))}processRequestParam(e){return e}resolvePath(e){const n=this.endpoint.basePath||this.api.basePath||"",r=e||this.endpoint.path||"";return i.combineURLs(n,r)}resolveTimeout(){return this.endpoint.timeout||this.api.timeout}resolveResultExtractor(){return this.endpoint.resultExtractor||this.api.resultExtractor||y.DEFAULT}}const z="fetcher";class D{constructor(e){this.metadata=e}getTargetFetcher(e){if(!e||typeof e!="object")return;const n=e[z];if(n instanceof i.Fetcher)return n}async execute(e,n){const r=this.getTargetFetcher(e)||this.metadata.fetcher,o=this.metadata.resolveRequest(n),s=this.metadata.resolveResultExtractor();return r.request(o,s)}}const v=Symbol("api:metadata");function X(t,e,n){const r=t.prototype[e];if(e==="constructor"||typeof r!="function")return;const o=Reflect.getMetadata(R,t.prototype,e);if(!o)return;const s=Reflect.getMetadata(P,t.prototype,e)||new Map,h=new q(e,n,o,s),f=new D(h);t.prototype[e]=function(...E){return f.execute(this,E)}}function Z(t="",e={}){return function(n){const r={basePath:t,...e};return Reflect.defineMetadata(v,r,n),Object.getOwnPropertyNames(n.prototype).forEach(o=>{X(n,o,r)}),n}}class H extends Error{constructor(){super("Implementation will be generated automatically."),this.name="AutoGenerated"}}const $=(...t)=>new H;a.API_METADATA_KEY=v,a.AutoGenerated=H,a.ENDPOINT_METADATA_KEY=R,a.FunctionMetadata=q,a.PARAMETER_METADATA_KEY=P,a.ParameterType=d,a.RequestExecutor=D,a.ResultExtractors=y,a.api=Z,a.autoGeneratedError=$,a.body=B,a.del=x,a.endpoint=c,a.get=F,a.getFetcher=b,a.getParameterName=A,a.getParameterNames=g,a.head=N,a.header=W,a.options=Y,a.parameter=m,a.patch=S,a.path=K,a.post=_,a.put=O,a.query=L,a.request=V,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/endpointDecorator.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/resultExtractor.ts","../src/fetcherCapable.ts","../src/requestExecutor.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\n\nexport interface PathCapable {\n /**\n * Path for the endpoint (relative to class base path).\n *\n * This path will be appended to the class's base path to form the complete URL.\n * Path parameters can be specified using curly braces, e.g., '/users/{id}'\n */\n path?: string;\n}\n\n/**\n * Metadata for HTTP endpoints.\n *\n * Defines the configuration options for individual HTTP endpoints (methods).\n * These settings will override any corresponding class-level settings from ApiMetadata.\n */\nexport interface EndpointMetadata\n extends ApiMetadata,\n ResultExtractorCapable,\n PathCapable {\n /**\n * HTTP method for the endpoint.\n *\n * Specifies the HTTP verb to be used for this endpoint (GET, POST, PUT, DELETE, etc.)\n */\n method?: HttpMethod;\n}\n\nexport const ENDPOINT_METADATA_KEY = Symbol('endpoint:metadata');\n\nexport type MethodEndpointMetadata = Omit<EndpointMetadata, 'method' | 'path'>;\n\n/**\n * Decorator factory for defining HTTP endpoints.\n *\n * Creates a decorator that can be used to define HTTP endpoints\n * on class methods. It stores metadata about the endpoint that will be used\n * to generate the actual HTTP request.\n *\n * @param method - The HTTP method for this endpoint\n * @param path - The path for this endpoint (relative to class base path)\n * @param metadata - Additional endpoint metadata (headers, timeout, etc.)\n * @returns A method decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1')\n * class UserService {\n * @endpoint(HttpMethod.GET, '/users/{id}')\n * getUser(@path('id') id: string): Promise<Response> {\n * // Implementation will be generated automatically\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function endpoint(\n method?: HttpMethod,\n path?: string,\n metadata: MethodEndpointMetadata = {},\n) {\n return function(target: object, propertyKey: string | symbol): void {\n // Store metadata directly on the method\n const endpointMetadata = {\n method: method,\n path,\n ...metadata,\n };\n Reflect.defineMetadata(\n ENDPOINT_METADATA_KEY,\n endpointMetadata,\n target,\n propertyKey,\n );\n };\n}\n\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\nexport function options(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.OPTIONS, path, metadata);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Cache for storing previously extracted parameter names to improve performance\nconst parameterNameCache = new WeakMap<Function, string[]>();\n\n/**\n * Extracts parameter names from a function.\n *\n * This function parses the string representation of a function to extract\n * the names of its parameters. It handles various function formats including\n * regular functions, arrow functions, and methods.\n *\n * Note: This implementation provides basic parameter name extraction and may not\n * handle all edge cases of complex TypeScript parameter declarations.\n *\n * @param func - The function to extract parameter names from\n * @returns An array of parameter names, or an empty array if extraction fails\n * @throws {TypeError} If the input is not a function\n *\n * @example\n * ```typescript\n * function example(a, b, c) {}\n * const paramNames = getParameterNames(example);\n * // Returns: ['a', 'b', 'c']\n *\n * const arrowFunc = (x, y) => x + y;\n * const arrowParamNames = getParameterNames(arrowFunc);\n * // Returns: ['x', 'y']\n *\n * function complex(param1: string, param2: number = 10, ...rest: any[]) {}\n * const complexParamNames = getParameterNames(complex);\n * // Returns: ['param1', 'param2', '...rest']\n * ```\n */\nexport function getParameterNames(func: (...args: any[]) => any): string[] {\n // Validate that the input is a function\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n // Check cache first to improve performance\n if (parameterNameCache.has(func)) {\n return parameterNameCache.get(func)!;\n }\n\n try {\n // Convert function to string and trim whitespace\n const fnStr = func.toString().trim();\n\n // Extract parameter string from the function\n const paramsStr = extractParameterString(fnStr);\n\n // Handle empty parameters\n if (!hasParameters(paramsStr)) {\n const emptyResult: string[] = [];\n parameterNameCache.set(func, emptyResult);\n return emptyResult;\n }\n\n // Parse and clean parameter names\n const result = parseParameterNames(paramsStr);\n parameterNameCache.set(func, result);\n return result;\n } catch {\n // Return empty array on any parsing errors to avoid breaking the application\n const errorResult: string[] = [];\n parameterNameCache.set(func, errorResult);\n return errorResult;\n }\n}\n\n/**\n * Helper function to automatically extract parameter name when not provided.\n *\n * @param target - The target object (class prototype)\n * @param propertyKey - The method name\n * @param parameterIndex - The index of the parameter\n * @param providedName - The name explicitly provided by the user (if any)\n * @returns The parameter name, either provided or automatically extracted\n */\nexport function getParameterName(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n providedName?: string,\n): string | undefined {\n // If a name was explicitly provided, use it\n if (providedName) {\n return providedName;\n }\n\n // Try to automatically extract the parameter name\n try {\n const method = target[propertyKey as keyof typeof target];\n if (method && typeof method === 'function') {\n const paramNames = getParameterNames(method);\n if (parameterIndex < paramNames.length) {\n return paramNames[parameterIndex];\n }\n }\n } catch {\n // If we can't get the parameter name, return undefined\n // This will use default naming in the execution logic\n }\n\n return undefined;\n}\n\n/**\n * Checks if a parameter string contains actual parameters.\n *\n * @param paramsStr - The parameter string to check\n * @returns True if the string contains parameters, false otherwise\n */\nfunction hasParameters(paramsStr: string): boolean {\n return (\n paramsStr !== null && paramsStr !== undefined && paramsStr.trim() !== ''\n );\n}\n\n/**\n * Extracts the parameter string from a function string representation.\n *\n * @param fnStr - The string representation of the function\n * @returns The parameter string, or empty string if not found\n */\nfunction extractParameterString(fnStr: string): string {\n // Handle arrow functions that start with parentheses\n if (fnStr.startsWith('(')) {\n const endParenIndex = findClosingParenthesis(fnStr, 0);\n if (endParenIndex === -1) return '';\n return fnStr.substring(1, endParenIndex);\n }\n\n // Handle regular functions, async functions, and methods\n const startParenIndex = fnStr.indexOf('(');\n if (startParenIndex === -1) return '';\n\n const endParenIndex = findClosingParenthesis(fnStr, startParenIndex);\n if (endParenIndex === -1) return '';\n\n return fnStr.substring(startParenIndex + 1, endParenIndex);\n}\n\n/**\n * Finds the matching closing parenthesis for an opening parenthesis.\n *\n * @param str - The string to search in\n * @param openingParenIndex - The index of the opening parenthesis\n * @returns The index of the matching closing parenthesis, or -1 if not found\n */\nfunction findClosingParenthesis(\n str: string,\n openingParenIndex: number,\n): number {\n let parenDepth = 1;\n\n for (let i = openingParenIndex + 1; i < str.length; i++) {\n const char = str[i];\n\n if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n if (parenDepth === 0) {\n return i;\n }\n }\n }\n\n return -1; // No matching closing parenthesis found\n}\n\n/**\n * Parses and cleans parameter names from a parameter string.\n *\n * @param paramsStr - The parameter string to parse\n * @returns An array of cleaned parameter names\n */\nfunction parseParameterNames(paramsStr: string): string[] {\n return paramsStr\n .split(',')\n .map(trimWhitespace)\n .filter(isNotEmpty)\n .map(extractParameterName);\n}\n\n/**\n * Trims whitespace from a string.\n *\n * @param str - The string to trim\n * @returns The trimmed string\n */\nfunction trimWhitespace(str: string): string {\n return str.trim();\n}\n\n/**\n * Checks if a string is not empty.\n *\n * @param str - The string to check\n * @returns True if the string is not empty, false otherwise\n */\nfunction isNotEmpty(str: string): boolean {\n return str.length > 0;\n}\n\n/**\n * Extracts a clean parameter name by removing type annotations and default values.\n *\n * @param param - The raw parameter string\n * @returns The cleaned parameter name\n */\nfunction extractParameterName(param: string): string {\n // Remove default value assignment (everything after =)\n let cleanedParam = removeDefaultValue(param);\n\n // Remove type annotations (everything after :)\n cleanedParam = removeTypeAnnotation(cleanedParam);\n\n return cleanedParam.trim();\n}\n\n/**\n * Removes default value from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without default value\n */\nfunction removeDefaultValue(param: string): string {\n const equalsIndex = param.indexOf('=');\n if (equalsIndex !== -1) {\n return param.substring(0, equalsIndex);\n }\n return param;\n}\n\n/**\n * Removes type annotation from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without type annotation\n */\nfunction removeTypeAnnotation(param: string): string {\n const colonIndex = param.indexOf(':');\n if (colonIndex !== -1) {\n return param.substring(0, colonIndex);\n }\n return param;\n}\n","import { getParameterName } from './reflection';\nimport 'reflect-metadata';\nimport { type PathCapable } from './endpointDecorator';\nimport { type FetchRequestInit } from '@ahoo-wang/fetcher';\n\n/**\n * Parameter types for decorator parameters.\n *\n * Defines the different types of parameters that can be used\n * in API method decorators to specify how arguments should be handled\n * in the HTTP request.\n */\nexport enum ParameterType {\n /**\n * Path parameter that will be inserted into the URL path.\n *\n * Path parameters are used to specify dynamic parts of the URL path.\n * They are defined using curly braces in the endpoint path.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n * ```\n */\n PATH = 'path',\n\n /**\n * Query parameter that will be appended to the URL query string.\n *\n * Query parameters are used to pass non-hierarchical data to the server.\n * They appear after the '?' in the URL.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n * ```\n */\n QUERY = 'query',\n\n /**\n * Header parameter that will be added to the request headers.\n *\n * Header parameters are used to pass metadata about the request,\n * such as authentication tokens or content type information.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n * ```\n */\n HEADER = 'header',\n\n /**\n * Body parameter that will be sent as the request body.\n *\n * The body parameter represents the main data payload of the request.\n * It is typically used with POST, PUT, and PATCH requests.\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\n BODY = 'body',\n\n /**\n * Request parameter that will be used as the request object.\n */\n REQUEST = 'request',\n}\n\n/**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter\n * decorated with @path, @query, @header, or @body decorators.\n */\nexport interface ParameterMetadata {\n /**\n * Type of parameter (path, query, header, body).\n *\n * Specifies how this parameter should be handled in the HTTP request.\n */\n type: ParameterType;\n\n /**\n * Name of the parameter (used for path, query, and header parameters).\n *\n * For path and query parameters, this corresponds to the key in the URL.\n * For header parameters, this corresponds to the header name.\n * For body parameters, this is not used.\n */\n name?: string;\n\n /**\n * Index of the parameter in the method signature.\n *\n * This is used to map the runtime argument values to the correct parameter metadata.\n */\n index: number;\n}\n\nexport const PARAMETER_METADATA_KEY = Symbol('parameter:metadata');\n\n/**\n * Decorator factory for method parameters.\n *\n * Creates a decorator that can be used to specify how a method parameter\n * should be handled in the HTTP request. It stores metadata about the parameter\n * that will be used during request execution.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, or BODY)\n * @param name - The name of the parameter (used for path, query, and header parameters, optional - auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@parameter(ParameterType.PATH, 'id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@parameter(ParameterType.PATH) userId: string): Promise<Response>\n * ```\n */\nexport function parameter(type: ParameterType, name: string = '') {\n return function(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n ) {\n const paramName = getParameterName(\n target,\n propertyKey as string,\n parameterIndex,\n name,\n );\n\n const existingParameters: Map<number, ParameterMetadata> =\n Reflect.getMetadata(PARAMETER_METADATA_KEY, target, propertyKey) ||\n new Map();\n const parameterMetadata: ParameterMetadata = {\n type: type,\n name: paramName,\n index: parameterIndex,\n };\n existingParameters.set(parameterIndex, parameterMetadata);\n Reflect.defineMetadata(\n PARAMETER_METADATA_KEY,\n existingParameters,\n target,\n propertyKey,\n );\n };\n}\n\n/**\n * Path parameter decorator.\n *\n * Defines a path parameter that will be inserted into the URL path.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the path parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@path() userId: string): Promise<Response>\n * ```\n */\nexport function path(name: string = '') {\n return parameter(ParameterType.PATH, name);\n}\n\n/**\n * Query parameter decorator.\n *\n * Defines a query parameter that will be appended to the URL query string.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the query parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@query() limit: number): Promise<Response>\n * ```\n */\nexport function query(name: string = '') {\n return parameter(ParameterType.QUERY, name);\n}\n\n/**\n * Header parameter decorator.\n *\n * Defines a header parameter that will be added to the request headers.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the header parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@header() authorization: string): Promise<Response>\n * ```\n */\nexport function header(name: string = '') {\n return parameter(ParameterType.HEADER, name);\n}\n\n/**\n * Body parameter decorator.\n *\n * Defines a body parameter that will be sent as the request body.\n * Note that body parameters don't have names since there's only one body per request.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\nexport function body() {\n return parameter(ParameterType.BODY);\n}\n\n/**\n * Interface for request parameter objects.\n *\n * Combines FetchRequestInit and PathCapable interfaces to provide\n * a complete request configuration object that can be used with\n * the @request() decorator. This allows full customization of\n * the HTTP request including method, headers, body, and URL parameters.\n */\nexport interface ParameterRequest extends FetchRequestInit, PathCapable {\n}\n\n/**\n * Request parameter decorator.\n *\n * Defines a request parameter that will be used as the base request object.\n * This allows you to pass a complete ParameterRequest object to customize\n * the request configuration.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: ParameterRequest): Promise<Response>\n * ```\n */\nexport function request() {\n return parameter(ParameterType.REQUEST);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FetchExchange } from '@ahoo-wang/fetcher';\nimport type {\n JsonServerSentEventStream,\n ServerSentEventStream,\n} from '@ahoo-wang/fetcher-eventstream';\n\n/**\n * Result extractor interface\n * Defines a function type for extracting results from a FetchExchange\n * @param exchange - FetchExchange object containing request and response information\n * @returns Returns a value of type FetchExchange, Response, or Promise<any>\n */\nexport interface ResultExtractor {\n (\n exchange: FetchExchange,\n ):\n | FetchExchange\n | Response\n | Promise<any>\n | ServerSentEventStream\n | JsonServerSentEventStream<any>;\n}\n\n/**\n * Interface with result extractor capability\n * Defines an optional resultExtractor property\n */\nexport interface ResultExtractorCapable {\n resultExtractor?: ResultExtractor;\n}\n\n/**\n * Returns the original FetchExchange object\n * @param exchange - FetchExchange object\n * @returns The original FetchExchange object\n */\nexport const ExchangeResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange;\n};\n\n/**\n * Returns the response object from FetchExchange\n * @param exchange - FetchExchange object\n * @returns The response object from FetchExchange\n */\nexport const ResponseResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse;\n};\n\n/**\n * Parses the response content as JSON format\n * @param exchange - FetchExchange object\n * @returns Promise of parsed JSON data\n */\nexport const JsonResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.json();\n};\n\n/**\n * Parses the response content as text format\n * @param exchange - FetchExchange object\n * @returns Promise of parsed text data\n */\nexport const TextResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.text();\n};\n\n/**\n * ServerSentEventStream result extractor, used to extract server-sent event stream from FetchExchange\n *\n * @param exchange - FetchExchange object containing request and response information\n * @returns Readable stream object of server-sent event stream\n * @throws ExchangeError exception when server does not support ServerSentEventStream\n */\nexport const EventStreamResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.requiredEventStream();\n};\n\n/**\n * JsonServerSentEventStream result extractor, used to extract JSON server-sent event stream from FetchExchange\n *\n * @param exchange - FetchExchange object containing request and response information\n * @returns Readable stream object of JSON server-sent event stream\n * @throws ExchangeError exception when server does not support JsonServerSentEventStream\n */\nexport const JsonEventStreamResultExtractor: ResultExtractor = (\n exchange: FetchExchange,\n) => {\n return exchange.requiredResponse.requiredJsonEventStream();\n};\n\n/**\n * ResultExtractors is an object that maps result extractor names to their corresponding\n * extractor functions. These extractors are used to process and extract data from different\n * types of responses or results in the application.\n *\n * Each property represents a specific type of result extractor:\n * - Exchange: Handles exchange-related result extraction\n * - Response: Handles general response result extraction\n * - Json: Handles JSON format result extraction\n * - Text: Handles plain text result extraction\n * - EventStream: Handles server-sent event stream result extraction\n * - JsonEventStream: Handles JSON server-sent event stream result extraction\n */\nexport const ResultExtractors = {\n Exchange: ExchangeResultExtractor,\n Response: ResponseResultExtractor,\n Json: JsonResultExtractor,\n Text: TextResultExtractor,\n EventStream: EventStreamResultExtractor,\n JsonEventStream: JsonEventStreamResultExtractor,\n DEFAULT: JsonResultExtractor,\n};\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Fetcher, fetcherRegistrar } from '@ahoo-wang/fetcher';\n\n/**\n * Interface that defines a capability for objects that can have a fetcher.\n * This interface is typically used to mark components or objects that can perform fetching operations\n * and may need access to fetcher functionality.\n */\nexport interface FetcherCapable {\n /**\n * Optional fetcher property that can be either a string identifier or a Fetcher instance.\n * When present, this property indicates the fetcher associated with the implementing object.\n */\n fetcher?: string | Fetcher;\n}\n\n/**\n * Gets a Fetcher instance based on the provided fetcher parameter.\n *\n * @param fetcher - A string identifier or Fetcher instance to resolve\n * @returns A Fetcher instance if found, undefined otherwise\n */\nexport function getFetcher(fetcher?: string | Fetcher): Fetcher | undefined {\n // Return undefined if no fetcher is provided\n if (!fetcher) {\n return undefined;\n }\n\n // Return the fetcher directly if it's already a Fetcher instance,\n // otherwise resolve it through the fetcher registrar\n return fetcher instanceof Fetcher\n ? fetcher\n : fetcherRegistrar.requiredGet(fetcher);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n combineURLs,\n fetcher,\n Fetcher,\n FetchExchange,\n type FetchRequest,\n type FetchRequestInit,\n mergeRequest,\n type NamedCapable,\n type RequestHeaders,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n type ParameterMetadata,\n type ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { ResultExtractor, ResultExtractors } from './resultExtractor';\nimport { ServerSentEventStream } from '@ahoo-wang/fetcher-eventstream';\nimport { getFetcher } from './fetcherCapable';\n\n/**\n * Metadata container for a function with HTTP endpoint decorators.\n *\n * Encapsulates all the metadata needed to execute an HTTP request\n * for a decorated method, including API-level defaults, endpoint-specific\n * configuration, and parameter metadata.\n */\nexport class FunctionMetadata implements NamedCapable {\n /**\n * Name of the function.\n */\n name: string;\n\n /**\n * API-level metadata (class-level configuration).\n */\n api: ApiMetadata;\n\n /**\n * Endpoint-level metadata (method-level configuration).\n */\n endpoint: EndpointMetadata;\n\n /**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter decorated with @path, @query,\n * @header, or @body decorators. Stored as a Map keyed by parameter index.\n *\n * @remarks\n * The metadata is stored as a Map<number, ParameterMetadata> where the key is\n * the parameter index and the value is the parameter metadata. This ensures\n * correct parameter ordering regardless of decorator application order.\n */\n parameters: Map<number, ParameterMetadata>;\n\n /**\n * Creates a new FunctionMetadata instance.\n *\n * @param name - The name of the function\n * @param api - API-level metadata\n * @param endpoint - Endpoint-level metadata\n * @param parameters - Parameter metadata array\n */\n constructor(\n name: string,\n api: ApiMetadata,\n endpoint: EndpointMetadata,\n parameters: Map<number, ParameterMetadata>,\n ) {\n this.name = name;\n this.api = api;\n this.endpoint = endpoint;\n this.parameters = parameters;\n }\n\n /**\n * Gets the fetcher instance to use for this function.\n *\n * Returns the fetcher specified in the endpoint metadata, or the API metadata,\n * or falls back to the default fetcher if none is specified.\n *\n * @returns The fetcher instance\n */\n get fetcher(): Fetcher {\n return getFetcher(this.endpoint.fetcher ?? this.api.fetcher) ?? fetcher;\n }\n\n /**\n * Resolves the request configuration from the method arguments.\n *\n * This method processes the runtime arguments according to the parameter metadata\n * and constructs a FetcherRequest object with path parameters, query parameters,\n * headers, body, and timeout. It handles various parameter types including:\n * - Path parameters (@path decorator)\n * - Query parameters (@query decorator)\n * - Header parameters (@header decorator)\n * - Body parameter (@body decorator)\n * - Complete request object (@request decorator)\n * - AbortSignal for request cancellation\n *\n * The method uses mergeRequest to combine the endpoint-specific configuration\n * with the parameter-provided request object, where the parameter request\n * takes precedence over endpoint configuration.\n *\n * @param args - The runtime arguments passed to the method\n * @returns A FetcherRequest object with all request configuration\n *\n * @example\n * ```typescript\n * // For a method decorated like:\n * @get('/users/{id}')\n * getUser(\n * @path('id') id: number,\n * @query('include') include: string,\n * @header('Authorization') auth: string\n * ): Promise<Response>\n *\n * // Calling with: getUser(123, 'profile', 'Bearer token')\n * // Would produce a request with:\n * // {\n * // method: 'GET',\n * // urlParams: {\n * // path: { id: 123 },\n * // query: { include: 'profile' }\n * // },\n * // headers: {\n * // 'Authorization': 'Bearer token',\n * // ...apiHeaders,\n * // ...endpointHeaders\n * // }\n * // }\n * ```\n */\n resolveRequest(args: any[]): FetchRequest {\n const pathParams: Record<string, any> = {};\n const queryParams: Record<string, any> = {};\n const headers: RequestHeaders = {\n ...this.api.headers,\n ...this.endpoint.headers,\n };\n let body: any = undefined;\n let signal: AbortSignal | null | undefined = undefined;\n let parameterRequest: ParameterRequest = {};\n // Process parameters based on their decorators\n args.forEach((value, index) => {\n if (value instanceof AbortSignal) {\n signal = value;\n return;\n }\n const funParameter = this.parameters.get(index);\n if (!funParameter) {\n return;\n }\n switch (funParameter.type) {\n case ParameterType.PATH:\n this.processPathParam(funParameter, value, pathParams);\n break;\n case ParameterType.QUERY:\n this.processQueryParam(funParameter, value, queryParams);\n break;\n case ParameterType.HEADER:\n this.processHeaderParam(funParameter, value, headers);\n break;\n case ParameterType.BODY:\n body = value;\n break;\n case ParameterType.REQUEST:\n parameterRequest = this.processRequestParam(value);\n break;\n }\n });\n const urlParams: UrlParams = {\n path: pathParams,\n query: queryParams,\n };\n const endpointRequest: FetchRequestInit = {\n method: this.endpoint.method,\n urlParams,\n headers,\n body,\n timeout: this.resolveTimeout(),\n signal,\n };\n const mergedRequest = mergeRequest(\n endpointRequest,\n parameterRequest,\n ) as any;\n const parameterPath = parameterRequest.path;\n mergedRequest.url = this.resolvePath(parameterPath);\n return mergedRequest;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n path[paramName] = value;\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n query[paramName] = value;\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n if (param.name && value !== undefined) {\n headers[param.name] = String(value);\n }\n }\n\n /**\n * Processes a request parameter value.\n *\n * This method handles the @request() decorator parameter by casting\n * the provided value to a FetcherRequest. The @request() decorator\n * allows users to pass a complete FetcherRequest object to customize\n * the request configuration.\n *\n * @param value - The value provided for the @request() parameter\n * @returns The value cast to FetcherRequest type\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: FetcherRequest): Promise<Response>\n *\n * // Usage:\n * const customRequest: FetcherRequest = {\n * headers: { 'X-Custom': 'value' },\n * timeout: 5000\n * };\n * await service.createUsers(customRequest);\n * ```\n */\n private processRequestParam(value: any): ParameterRequest {\n return value as ParameterRequest;\n }\n\n /**\n * Resolves the complete path by combining base path and endpoint path\n *\n * @param parameterPath - Optional path parameter to use instead of endpoint path\n * @returns The combined URL path\n */\n resolvePath(parameterPath?: string): string {\n // Get the base path from endpoint, API, or default to empty string\n const basePath = this.endpoint.basePath || this.api.basePath || '';\n\n // Use provided parameter path or fallback to endpoint path\n const endpointPath = parameterPath || this.endpoint.path || '';\n\n // Combine the base path and endpoint path into a complete URL\n return combineURLs(basePath, endpointPath);\n }\n\n /**\n * Resolves the timeout for the request.\n *\n * Returns the timeout specified in the endpoint metadata, or the API metadata,\n * or undefined if no timeout is specified.\n *\n * @returns The timeout value in milliseconds, or undefined\n */\n resolveTimeout(): number | undefined {\n return this.endpoint.timeout || this.api.timeout;\n }\n\n resolveResultExtractor(): ResultExtractor {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n ResultExtractors.DEFAULT\n );\n }\n}\n\nconst TARGET_FETCHER_PROPERTY = 'fetcher';\n\n/**\n * Executor for HTTP requests based on decorated method metadata.\n *\n * This class is responsible for executing HTTP requests based on the metadata\n * collected from decorators. It resolves the path, constructs the request,\n * and executes it using the appropriate fetcher.\n */\nexport class RequestExecutor {\n private readonly metadata: FunctionMetadata;\n\n /**\n * Creates a new RequestExecutor instance.\n *\n * @param metadata - The function metadata containing all request information\n */\n constructor(metadata: FunctionMetadata) {\n this.metadata = metadata;\n }\n\n /**\n * Retrieves the fetcher instance from the target object.\n *\n * @param target - The target object that may contain a fetcher property\n * @returns The fetcher instance if exists, otherwise undefined\n */\n private getTargetFetcher(target: any): Fetcher | undefined {\n if (!target || typeof target !== 'object') {\n return undefined;\n }\n // Extract the fetcher property from the target object\n const fetcher = target[TARGET_FETCHER_PROPERTY];\n\n // Validate that the fetcher is an instance of the Fetcher class\n if (fetcher instanceof Fetcher) {\n return fetcher;\n }\n\n // Return undefined if no valid fetcher instance is found\n return undefined;\n }\n\n /**\n * Executes the HTTP request.\n *\n * This method resolves the path and request configuration from the metadata\n * and arguments, then executes the request using the configured fetcher.\n *\n * @param target - The target object that the method is called on\n * @param args - The runtime arguments passed to the method\n * @returns A Promise that resolves to the Response\n */\n async execute(\n target: any,\n args: any[],\n ): Promise<FetchExchange | Response | any | ServerSentEventStream> {\n const fetcher = this.getTargetFetcher(target) || this.metadata.fetcher;\n const request = this.metadata.resolveRequest(args);\n const exchange = await fetcher.request(request);\n const extractor = this.metadata.resolveResultExtractor();\n return extractor(exchange);\n }\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Fetcher,\n type RequestHeaders,\n type RequestHeadersCapable,\n type TimeoutCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { FunctionMetadata, RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\nimport { type FetcherCapable } from './fetcherCapable';\n\n/**\n * Metadata for class-level API configuration.\n *\n * Defines the configuration options that can be applied to an entire API class.\n * These settings will be used as defaults for all endpoints within the class unless overridden\n * at the method level.\n */\nexport interface ApiMetadata\n extends TimeoutCapable,\n RequestHeadersCapable,\n ResultExtractorCapable,\n FetcherCapable {\n /**\n * Base path for all endpoints in the class.\n *\n * This path will be prepended to all endpoint paths defined in the class.\n * For example, if basePath is '/api/v1' and an endpoint has path '/users',\n * the full path will be '/api/v1/users'.\n */\n basePath?: string;\n\n /**\n * Default headers for all requests in the class.\n *\n * These headers will be included in every request made by methods in this class.\n * They can be overridden or extended at the method level.\n */\n headers?: RequestHeaders;\n\n /**\n * Default timeout for all requests in the class (in milliseconds).\n *\n * This timeout value will be applied to all requests made by methods in this class.\n * Individual methods can specify their own timeout values to override this default.\n */\n timeout?: number;\n\n /**\n * Name of the fetcher instance to use, default: 'default'.\n *\n * This allows you to specify which fetcher instance should be used for requests\n * from this API class. The fetcher must be registered with the FetcherRegistrar.\n */\n fetcher?: string | Fetcher;\n}\n\nexport const API_METADATA_KEY = Symbol('api:metadata');\n\n/**\n * Binds a request executor to a method, replacing the original method with\n * an implementation that makes HTTP requests based on the decorator metadata.\n *\n * @param constructor - The class constructor\n * @param functionName - The name of the method to bind\n * @param apiMetadata - The API metadata for the class\n */\nfunction bindExecutor<T extends new (...args: any[]) => any>(\n constructor: T,\n functionName: string,\n apiMetadata: ApiMetadata,\n) {\n const endpointFunction = constructor.prototype[functionName];\n if (functionName === 'constructor') {\n return;\n }\n if (typeof endpointFunction !== 'function') {\n return;\n }\n\n const endpointMetadata = Reflect.getMetadata(\n ENDPOINT_METADATA_KEY,\n constructor.prototype,\n functionName,\n );\n if (!endpointMetadata) {\n return;\n }\n // Get parameter metadata for this method\n const parameterMetadata =\n Reflect.getMetadata(\n PARAMETER_METADATA_KEY,\n constructor.prototype,\n functionName,\n ) || new Map();\n\n // Create function metadata\n const functionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n const requestExecutor = new RequestExecutor(functionMetadata);\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = function(...args: unknown[]) {\n return requestExecutor.execute(this, args);\n };\n}\n\nexport function api(\n basePath: string = '',\n metadata: Omit<ApiMetadata, 'basePath'> = {},\n) {\n return function <T extends new (...args: any[]) => any>(constructor: T): T {\n const apiMetadata: ApiMetadata = {\n basePath,\n ...metadata,\n };\n\n // Store metadata directly on the class constructor\n Reflect.defineMetadata(API_METADATA_KEY, apiMetadata, constructor);\n\n // Override prototype methods to implement actual HTTP calls\n Object.getOwnPropertyNames(constructor.prototype).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n\n return constructor;\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Custom error class that indicates a method implementation will be automatically generated.\n *\n * @example\n * ```\n * @post()\n * createUser(@body() user: User):Promise<Response> {\n * throw autoGeneratedError(user);\n * }\n * ```\n */\nexport class AutoGenerated extends Error {\n constructor() {\n super('Implementation will be generated automatically.');\n this.name = 'AutoGenerated';\n }\n}\n\n/**\n * Factory function that creates an AutoGenerated error instance.\n * This is typically used in methods that will be automatically implemented,\n * where a placeholder implementation is needed.\n *\n * @param _ignored - Arguments (such as 'user' in the example) are ignored to prevent\n * ESLint no-unused-vars errors in method signatures that will be auto-generated.\n * @returns A new AutoGenerated error instance\n */\nexport const autoGeneratedError = (..._ignored: any[]): AutoGenerated => {\n return new AutoGenerated();\n};\n"],"names":["ENDPOINT_METADATA_KEY","endpoint","method","path","metadata","target","propertyKey","endpointMetadata","get","HttpMethod","post","put","del","patch","head","options","parameterNameCache","getParameterNames","func","fnStr","paramsStr","extractParameterString","hasParameters","emptyResult","result","parseParameterNames","errorResult","getParameterName","parameterIndex","providedName","paramNames","endParenIndex","findClosingParenthesis","startParenIndex","str","openingParenIndex","parenDepth","i","char","trimWhitespace","isNotEmpty","extractParameterName","param","cleanedParam","removeDefaultValue","removeTypeAnnotation","equalsIndex","colonIndex","ParameterType","PARAMETER_METADATA_KEY","parameter","type","name","paramName","existingParameters","parameterMetadata","query","header","body","request","ExchangeResultExtractor","exchange","ResponseResultExtractor","JsonResultExtractor","TextResultExtractor","EventStreamResultExtractor","JsonEventStreamResultExtractor","ResultExtractors","getFetcher","fetcher","Fetcher","fetcherRegistrar","FunctionMetadata","api","parameters","args","pathParams","queryParams","headers","signal","parameterRequest","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","parameterPath","basePath","endpointPath","combineURLs","TARGET_FETCHER_PROPERTY","RequestExecutor","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","requestExecutor","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/endpointDecorator.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/resultExtractor.ts","../src/fetcherCapable.ts","../src/requestExecutor.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\n\nexport interface PathCapable {\n /**\n * Path for the endpoint (relative to class base path).\n *\n * This path will be appended to the class's base path to form the complete URL.\n * Path parameters can be specified using curly braces, e.g., '/users/{id}'\n */\n path?: string;\n}\n\n/**\n * Metadata for HTTP endpoints.\n *\n * Defines the configuration options for individual HTTP endpoints (methods).\n * These settings will override any corresponding class-level settings from ApiMetadata.\n */\nexport interface EndpointMetadata\n extends ApiMetadata,\n ResultExtractorCapable,\n PathCapable {\n /**\n * HTTP method for the endpoint.\n *\n * Specifies the HTTP verb to be used for this endpoint (GET, POST, PUT, DELETE, etc.)\n */\n method?: HttpMethod;\n}\n\nexport const ENDPOINT_METADATA_KEY = Symbol('endpoint:metadata');\n\nexport type MethodEndpointMetadata = Omit<EndpointMetadata, 'method' | 'path'>;\n\n/**\n * Decorator factory for defining HTTP endpoints.\n *\n * Creates a decorator that can be used to define HTTP endpoints\n * on class methods. It stores metadata about the endpoint that will be used\n * to generate the actual HTTP request.\n *\n * @param method - The HTTP method for this endpoint\n * @param path - The path for this endpoint (relative to class base path)\n * @param metadata - Additional endpoint metadata (headers, timeout, etc.)\n * @returns A method decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1')\n * class UserService {\n * @endpoint(HttpMethod.GET, '/users/{id}')\n * getUser(@path('id') id: string): Promise<Response> {\n * // Implementation will be generated automatically\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function endpoint(\n method?: HttpMethod,\n path?: string,\n metadata: MethodEndpointMetadata = {},\n) {\n return function(target: object, propertyKey: string | symbol): void {\n // Store metadata directly on the method\n const endpointMetadata = {\n method: method,\n path,\n ...metadata,\n };\n Reflect.defineMetadata(\n ENDPOINT_METADATA_KEY,\n endpointMetadata,\n target,\n propertyKey,\n );\n };\n}\n\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\nexport function options(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.OPTIONS, path, metadata);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Cache for storing previously extracted parameter names to improve performance\nconst parameterNameCache = new WeakMap<Function, string[]>();\n\n/**\n * Extracts parameter names from a function.\n *\n * This function parses the string representation of a function to extract\n * the names of its parameters. It handles various function formats including\n * regular functions, arrow functions, and methods.\n *\n * Note: This implementation provides basic parameter name extraction and may not\n * handle all edge cases of complex TypeScript parameter declarations.\n *\n * @param func - The function to extract parameter names from\n * @returns An array of parameter names, or an empty array if extraction fails\n * @throws {TypeError} If the input is not a function\n *\n * @example\n * ```typescript\n * function example(a, b, c) {}\n * const paramNames = getParameterNames(example);\n * // Returns: ['a', 'b', 'c']\n *\n * const arrowFunc = (x, y) => x + y;\n * const arrowParamNames = getParameterNames(arrowFunc);\n * // Returns: ['x', 'y']\n *\n * function complex(param1: string, param2: number = 10, ...rest: any[]) {}\n * const complexParamNames = getParameterNames(complex);\n * // Returns: ['param1', 'param2', '...rest']\n * ```\n */\nexport function getParameterNames(func: (...args: any[]) => any): string[] {\n // Validate that the input is a function\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function');\n }\n\n // Check cache first to improve performance\n if (parameterNameCache.has(func)) {\n return parameterNameCache.get(func)!;\n }\n\n try {\n // Convert function to string and trim whitespace\n const fnStr = func.toString().trim();\n\n // Extract parameter string from the function\n const paramsStr = extractParameterString(fnStr);\n\n // Handle empty parameters\n if (!hasParameters(paramsStr)) {\n const emptyResult: string[] = [];\n parameterNameCache.set(func, emptyResult);\n return emptyResult;\n }\n\n // Parse and clean parameter names\n const result = parseParameterNames(paramsStr);\n parameterNameCache.set(func, result);\n return result;\n } catch {\n // Return empty array on any parsing errors to avoid breaking the application\n const errorResult: string[] = [];\n parameterNameCache.set(func, errorResult);\n return errorResult;\n }\n}\n\n/**\n * Helper function to automatically extract parameter name when not provided.\n *\n * @param target - The target object (class prototype)\n * @param propertyKey - The method name\n * @param parameterIndex - The index of the parameter\n * @param providedName - The name explicitly provided by the user (if any)\n * @returns The parameter name, either provided or automatically extracted\n */\nexport function getParameterName(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n providedName?: string,\n): string | undefined {\n // If a name was explicitly provided, use it\n if (providedName) {\n return providedName;\n }\n\n // Try to automatically extract the parameter name\n try {\n const method = target[propertyKey as keyof typeof target];\n if (method && typeof method === 'function') {\n const paramNames = getParameterNames(method);\n if (parameterIndex < paramNames.length) {\n return paramNames[parameterIndex];\n }\n }\n } catch {\n // If we can't get the parameter name, return undefined\n // This will use default naming in the execution logic\n }\n\n return undefined;\n}\n\n/**\n * Checks if a parameter string contains actual parameters.\n *\n * @param paramsStr - The parameter string to check\n * @returns True if the string contains parameters, false otherwise\n */\nfunction hasParameters(paramsStr: string): boolean {\n return (\n paramsStr !== null && paramsStr !== undefined && paramsStr.trim() !== ''\n );\n}\n\n/**\n * Extracts the parameter string from a function string representation.\n *\n * @param fnStr - The string representation of the function\n * @returns The parameter string, or empty string if not found\n */\nfunction extractParameterString(fnStr: string): string {\n // Handle arrow functions that start with parentheses\n if (fnStr.startsWith('(')) {\n const endParenIndex = findClosingParenthesis(fnStr, 0);\n if (endParenIndex === -1) return '';\n return fnStr.substring(1, endParenIndex);\n }\n\n // Handle regular functions, async functions, and methods\n const startParenIndex = fnStr.indexOf('(');\n if (startParenIndex === -1) return '';\n\n const endParenIndex = findClosingParenthesis(fnStr, startParenIndex);\n if (endParenIndex === -1) return '';\n\n return fnStr.substring(startParenIndex + 1, endParenIndex);\n}\n\n/**\n * Finds the matching closing parenthesis for an opening parenthesis.\n *\n * @param str - The string to search in\n * @param openingParenIndex - The index of the opening parenthesis\n * @returns The index of the matching closing parenthesis, or -1 if not found\n */\nfunction findClosingParenthesis(\n str: string,\n openingParenIndex: number,\n): number {\n let parenDepth = 1;\n\n for (let i = openingParenIndex + 1; i < str.length; i++) {\n const char = str[i];\n\n if (char === '(') {\n parenDepth++;\n } else if (char === ')') {\n parenDepth--;\n if (parenDepth === 0) {\n return i;\n }\n }\n }\n\n return -1; // No matching closing parenthesis found\n}\n\n/**\n * Parses and cleans parameter names from a parameter string.\n *\n * @param paramsStr - The parameter string to parse\n * @returns An array of cleaned parameter names\n */\nfunction parseParameterNames(paramsStr: string): string[] {\n return paramsStr\n .split(',')\n .map(trimWhitespace)\n .filter(isNotEmpty)\n .map(extractParameterName);\n}\n\n/**\n * Trims whitespace from a string.\n *\n * @param str - The string to trim\n * @returns The trimmed string\n */\nfunction trimWhitespace(str: string): string {\n return str.trim();\n}\n\n/**\n * Checks if a string is not empty.\n *\n * @param str - The string to check\n * @returns True if the string is not empty, false otherwise\n */\nfunction isNotEmpty(str: string): boolean {\n return str.length > 0;\n}\n\n/**\n * Extracts a clean parameter name by removing type annotations and default values.\n *\n * @param param - The raw parameter string\n * @returns The cleaned parameter name\n */\nfunction extractParameterName(param: string): string {\n // Remove default value assignment (everything after =)\n let cleanedParam = removeDefaultValue(param);\n\n // Remove type annotations (everything after :)\n cleanedParam = removeTypeAnnotation(cleanedParam);\n\n return cleanedParam.trim();\n}\n\n/**\n * Removes default value from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without default value\n */\nfunction removeDefaultValue(param: string): string {\n const equalsIndex = param.indexOf('=');\n if (equalsIndex !== -1) {\n return param.substring(0, equalsIndex);\n }\n return param;\n}\n\n/**\n * Removes type annotation from a parameter string.\n *\n * @param param - The parameter string\n * @returns The parameter string without type annotation\n */\nfunction removeTypeAnnotation(param: string): string {\n const colonIndex = param.indexOf(':');\n if (colonIndex !== -1) {\n return param.substring(0, colonIndex);\n }\n return param;\n}\n","import { getParameterName } from './reflection';\nimport 'reflect-metadata';\nimport { type PathCapable } from './endpointDecorator';\nimport { type FetchRequestInit } from '@ahoo-wang/fetcher';\n\n/**\n * Parameter types for decorator parameters.\n *\n * Defines the different types of parameters that can be used\n * in API method decorators to specify how arguments should be handled\n * in the HTTP request.\n */\nexport enum ParameterType {\n /**\n * Path parameter that will be inserted into the URL path.\n *\n * Path parameters are used to specify dynamic parts of the URL path.\n * They are defined using curly braces in the endpoint path.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n * ```\n */\n PATH = 'path',\n\n /**\n * Query parameter that will be appended to the URL query string.\n *\n * Query parameters are used to pass non-hierarchical data to the server.\n * They appear after the '?' in the URL.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n * ```\n */\n QUERY = 'query',\n\n /**\n * Header parameter that will be added to the request headers.\n *\n * Header parameters are used to pass metadata about the request,\n * such as authentication tokens or content type information.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n * ```\n */\n HEADER = 'header',\n\n /**\n * Body parameter that will be sent as the request body.\n *\n * The body parameter represents the main data payload of the request.\n * It is typically used with POST, PUT, and PATCH requests.\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\n BODY = 'body',\n\n /**\n * Request parameter that will be used as the request object.\n */\n REQUEST = 'request',\n}\n\n/**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter\n * decorated with @path, @query, @header, or @body decorators.\n */\nexport interface ParameterMetadata {\n /**\n * Type of parameter (path, query, header, body).\n *\n * Specifies how this parameter should be handled in the HTTP request.\n */\n type: ParameterType;\n\n /**\n * Name of the parameter (used for path, query, and header parameters).\n *\n * For path and query parameters, this corresponds to the key in the URL.\n * For header parameters, this corresponds to the header name.\n * For body parameters, this is not used.\n */\n name?: string;\n\n /**\n * Index of the parameter in the method signature.\n *\n * This is used to map the runtime argument values to the correct parameter metadata.\n */\n index: number;\n}\n\nexport const PARAMETER_METADATA_KEY = Symbol('parameter:metadata');\n\n/**\n * Decorator factory for method parameters.\n *\n * Creates a decorator that can be used to specify how a method parameter\n * should be handled in the HTTP request. It stores metadata about the parameter\n * that will be used during request execution.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, or BODY)\n * @param name - The name of the parameter (used for path, query, and header parameters, optional - auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@parameter(ParameterType.PATH, 'id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@parameter(ParameterType.PATH) userId: string): Promise<Response>\n * ```\n */\nexport function parameter(type: ParameterType, name: string = '') {\n return function(\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n ) {\n const paramName = getParameterName(\n target,\n propertyKey as string,\n parameterIndex,\n name,\n );\n\n const existingParameters: Map<number, ParameterMetadata> =\n Reflect.getMetadata(PARAMETER_METADATA_KEY, target, propertyKey) ||\n new Map();\n const parameterMetadata: ParameterMetadata = {\n type: type,\n name: paramName,\n index: parameterIndex,\n };\n existingParameters.set(parameterIndex, parameterMetadata);\n Reflect.defineMetadata(\n PARAMETER_METADATA_KEY,\n existingParameters,\n target,\n propertyKey,\n );\n };\n}\n\n/**\n * Path parameter decorator.\n *\n * Defines a path parameter that will be inserted into the URL path.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the path parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users/{userId}')\n * getUser(@path() userId: string): Promise<Response>\n * ```\n */\nexport function path(name: string = '') {\n return parameter(ParameterType.PATH, name);\n}\n\n/**\n * Query parameter decorator.\n *\n * Defines a query parameter that will be appended to the URL query string.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the query parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@query() limit: number): Promise<Response>\n * ```\n */\nexport function query(name: string = '') {\n return parameter(ParameterType.QUERY, name);\n}\n\n/**\n * Header parameter decorator.\n *\n * Defines a header parameter that will be added to the request headers.\n * The name is optional - if not provided, it will be automatically extracted\n * from the method parameter name using reflection.\n *\n * @param name - The name of the header parameter (optional, auto-extracted if not provided)\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * // With explicit name\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With auto-extracted name\n * @get('/users')\n * getUsers(@header() authorization: string): Promise<Response>\n * ```\n */\nexport function header(name: string = '') {\n return parameter(ParameterType.HEADER, name);\n}\n\n/**\n * Body parameter decorator.\n *\n * Defines a body parameter that will be sent as the request body.\n * Note that body parameters don't have names since there's only one body per request.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUser(@body() user: User): Promise<Response>\n * ```\n */\nexport function body() {\n return parameter(ParameterType.BODY);\n}\n\n/**\n * Interface for request parameter objects.\n *\n * Combines FetchRequestInit and PathCapable interfaces to provide\n * a complete request configuration object that can be used with\n * the @request() decorator. This allows full customization of\n * the HTTP request including method, headers, body, and URL parameters.\n */\nexport interface ParameterRequest extends FetchRequestInit, PathCapable {\n}\n\n/**\n * Request parameter decorator.\n *\n * Defines a request parameter that will be used as the base request object.\n * This allows you to pass a complete ParameterRequest object to customize\n * the request configuration.\n *\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: ParameterRequest): Promise<Response>\n * ```\n */\nexport function request() {\n return parameter(ParameterType.REQUEST);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ExchangeResultExtractor,\n JsonResultExtractor,\n ResponseResultExtractor,\n ResultExtractor, TextResultExtractor,\n} from '@ahoo-wang/fetcher';\nimport {\n EventStreamResultExtractor, JsonEventStreamResultExtractor,\n} from '@ahoo-wang/fetcher-eventstream';\n\n\n/**\n * Interface with result extractor capability\n * Defines an optional resultExtractor property\n */\nexport interface ResultExtractorCapable {\n resultExtractor?: ResultExtractor<any>;\n}\n\n/**\n * ResultExtractors is an object that maps result extractor names to their corresponding\n * extractor functions. These extractors are used to process and extract data from different\n * types of responses or results in the application.\n *\n * Each property represents a specific type of result extractor:\n * - Exchange: Handles exchange-related result extraction\n * - Response: Handles general response result extraction\n * - Json: Handles JSON format result extraction\n * - Text: Handles plain text result extraction\n * - EventStream: Handles server-sent event stream result extraction\n * - JsonEventStream: Handles JSON server-sent event stream result extraction\n */\nexport const ResultExtractors = {\n Exchange: ExchangeResultExtractor,\n Response: ResponseResultExtractor,\n Json: JsonResultExtractor,\n Text: TextResultExtractor,\n EventStream: EventStreamResultExtractor,\n JsonEventStream: JsonEventStreamResultExtractor,\n DEFAULT: JsonResultExtractor,\n};\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Fetcher, fetcherRegistrar } from '@ahoo-wang/fetcher';\n\n/**\n * Interface that defines a capability for objects that can have a fetcher.\n * This interface is typically used to mark components or objects that can perform fetching operations\n * and may need access to fetcher functionality.\n */\nexport interface FetcherCapable {\n /**\n * Optional fetcher property that can be either a string identifier or a Fetcher instance.\n * When present, this property indicates the fetcher associated with the implementing object.\n */\n fetcher?: string | Fetcher;\n}\n\n/**\n * Gets a Fetcher instance based on the provided fetcher parameter.\n *\n * @param fetcher - A string identifier or Fetcher instance to resolve\n * @returns A Fetcher instance if found, undefined otherwise\n */\nexport function getFetcher(fetcher?: string | Fetcher): Fetcher | undefined {\n // Return undefined if no fetcher is provided\n if (!fetcher) {\n return undefined;\n }\n\n // Return the fetcher directly if it's already a Fetcher instance,\n // otherwise resolve it through the fetcher registrar\n return fetcher instanceof Fetcher\n ? fetcher\n : fetcherRegistrar.requiredGet(fetcher);\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n combineURLs,\n fetcher,\n Fetcher,\n type FetchRequest,\n type FetchRequestInit,\n mergeRequest,\n type NamedCapable,\n type RequestHeaders, ResultExtractor,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n type ParameterMetadata,\n type ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { ResultExtractors } from './resultExtractor';\nimport { getFetcher } from './fetcherCapable';\n\n/**\n * Metadata container for a function with HTTP endpoint decorators.\n *\n * Encapsulates all the metadata needed to execute an HTTP request\n * for a decorated method, including API-level defaults, endpoint-specific\n * configuration, and parameter metadata.\n */\nexport class FunctionMetadata implements NamedCapable {\n /**\n * Name of the function.\n */\n name: string;\n\n /**\n * API-level metadata (class-level configuration).\n */\n api: ApiMetadata;\n\n /**\n * Endpoint-level metadata (method-level configuration).\n */\n endpoint: EndpointMetadata;\n\n /**\n * Metadata for method parameters.\n *\n * Defines the metadata stored for each parameter decorated with @path, @query,\n * @header, or @body decorators. Stored as a Map keyed by parameter index.\n *\n * @remarks\n * The metadata is stored as a Map<number, ParameterMetadata> where the key is\n * the parameter index and the value is the parameter metadata. This ensures\n * correct parameter ordering regardless of decorator application order.\n */\n parameters: Map<number, ParameterMetadata>;\n\n /**\n * Creates a new FunctionMetadata instance.\n *\n * @param name - The name of the function\n * @param api - API-level metadata\n * @param endpoint - Endpoint-level metadata\n * @param parameters - Parameter metadata array\n */\n constructor(\n name: string,\n api: ApiMetadata,\n endpoint: EndpointMetadata,\n parameters: Map<number, ParameterMetadata>,\n ) {\n this.name = name;\n this.api = api;\n this.endpoint = endpoint;\n this.parameters = parameters;\n }\n\n /**\n * Gets the fetcher instance to use for this function.\n *\n * Returns the fetcher specified in the endpoint metadata, or the API metadata,\n * or falls back to the default fetcher if none is specified.\n *\n * @returns The fetcher instance\n */\n get fetcher(): Fetcher {\n return getFetcher(this.endpoint.fetcher ?? this.api.fetcher) ?? fetcher;\n }\n\n /**\n * Resolves the request configuration from the method arguments.\n *\n * This method processes the runtime arguments according to the parameter metadata\n * and constructs a FetcherRequest object with path parameters, query parameters,\n * headers, body, and timeout. It handles various parameter types including:\n * - Path parameters (@path decorator)\n * - Query parameters (@query decorator)\n * - Header parameters (@header decorator)\n * - Body parameter (@body decorator)\n * - Complete request object (@request decorator)\n * - AbortSignal for request cancellation\n *\n * The method uses mergeRequest to combine the endpoint-specific configuration\n * with the parameter-provided request object, where the parameter request\n * takes precedence over endpoint configuration.\n *\n * @param args - The runtime arguments passed to the method\n * @returns A FetcherRequest object with all request configuration\n *\n * @example\n * ```typescript\n * // For a method decorated like:\n * @get('/users/{id}')\n * getUser(\n * @path('id') id: number,\n * @query('include') include: string,\n * @header('Authorization') auth: string\n * ): Promise<Response>\n *\n * // Calling with: getUser(123, 'profile', 'Bearer token')\n * // Would produce a request with:\n * // {\n * // method: 'GET',\n * // urlParams: {\n * // path: { id: 123 },\n * // query: { include: 'profile' }\n * // },\n * // headers: {\n * // 'Authorization': 'Bearer token',\n * // ...apiHeaders,\n * // ...endpointHeaders\n * // }\n * // }\n * ```\n */\n resolveRequest(args: any[]): FetchRequest {\n const pathParams: Record<string, any> = {};\n const queryParams: Record<string, any> = {};\n const headers: RequestHeaders = {\n ...this.api.headers,\n ...this.endpoint.headers,\n };\n let body: any = undefined;\n let signal: AbortSignal | null | undefined = undefined;\n let abortController: AbortController | null | undefined = undefined;\n let parameterRequest: ParameterRequest = {};\n // Process parameters based on their decorators\n args.forEach((value, index) => {\n if (value instanceof AbortSignal) {\n signal = value;\n return;\n }\n if (value instanceof AbortController) {\n abortController = value;\n return;\n }\n const funParameter = this.parameters.get(index);\n if (!funParameter) {\n return;\n }\n switch (funParameter.type) {\n case ParameterType.PATH:\n this.processPathParam(funParameter, value, pathParams);\n break;\n case ParameterType.QUERY:\n this.processQueryParam(funParameter, value, queryParams);\n break;\n case ParameterType.HEADER:\n this.processHeaderParam(funParameter, value, headers);\n break;\n case ParameterType.BODY:\n body = value;\n break;\n case ParameterType.REQUEST:\n parameterRequest = this.processRequestParam(value);\n break;\n }\n });\n const urlParams: UrlParams = {\n path: pathParams,\n query: queryParams,\n };\n const endpointRequest: FetchRequestInit = {\n method: this.endpoint.method,\n urlParams,\n headers,\n body,\n timeout: this.resolveTimeout(),\n signal,\n abortController,\n };\n const mergedRequest = mergeRequest(\n endpointRequest,\n parameterRequest,\n ) as any;\n const parameterPath = parameterRequest.path;\n mergedRequest.url = this.resolvePath(parameterPath);\n return mergedRequest;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n path[paramName] = value;\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n const paramName = param.name || `param${param.index}`;\n query[paramName] = value;\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n if (param.name && value !== undefined) {\n headers[param.name] = String(value);\n }\n }\n\n /**\n * Processes a request parameter value.\n *\n * This method handles the @request() decorator parameter by casting\n * the provided value to a FetcherRequest. The @request() decorator\n * allows users to pass a complete FetcherRequest object to customize\n * the request configuration.\n *\n * @param value - The value provided for the @request() parameter\n * @returns The value cast to FetcherRequest type\n *\n * @example\n * ```typescript\n * @post('/users')\n * createUsers(@request() request: FetcherRequest): Promise<Response>\n *\n * // Usage:\n * const customRequest: FetcherRequest = {\n * headers: { 'X-Custom': 'value' },\n * timeout: 5000\n * };\n * await service.createUsers(customRequest);\n * ```\n */\n private processRequestParam(value: any): ParameterRequest {\n return value as ParameterRequest;\n }\n\n /**\n * Resolves the complete path by combining base path and endpoint path\n *\n * @param parameterPath - Optional path parameter to use instead of endpoint path\n * @returns The combined URL path\n */\n resolvePath(parameterPath?: string): string {\n // Get the base path from endpoint, API, or default to empty string\n const basePath = this.endpoint.basePath || this.api.basePath || '';\n\n // Use provided parameter path or fallback to endpoint path\n const endpointPath = parameterPath || this.endpoint.path || '';\n\n // Combine the base path and endpoint path into a complete URL\n return combineURLs(basePath, endpointPath);\n }\n\n /**\n * Resolves the timeout for the request.\n *\n * Returns the timeout specified in the endpoint metadata, or the API metadata,\n * or undefined if no timeout is specified.\n *\n * @returns The timeout value in milliseconds, or undefined\n */\n resolveTimeout(): number | undefined {\n return this.endpoint.timeout || this.api.timeout;\n }\n\n resolveResultExtractor(): ResultExtractor<any> {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n ResultExtractors.DEFAULT\n );\n }\n}\n\nconst TARGET_FETCHER_PROPERTY = 'fetcher';\n\n/**\n * Executor for HTTP requests based on decorated method metadata.\n *\n * This class is responsible for executing HTTP requests based on the metadata\n * collected from decorators. It resolves the path, constructs the request,\n * and executes it using the appropriate fetcher.\n */\nexport class RequestExecutor {\n private readonly metadata: FunctionMetadata;\n\n /**\n * Creates a new RequestExecutor instance.\n *\n * @param metadata - The function metadata containing all request information\n */\n constructor(metadata: FunctionMetadata) {\n this.metadata = metadata;\n }\n\n /**\n * Retrieves the fetcher instance from the target object.\n *\n * @param target - The target object that may contain a fetcher property\n * @returns The fetcher instance if exists, otherwise undefined\n */\n private getTargetFetcher(target: any): Fetcher | undefined {\n if (!target || typeof target !== 'object') {\n return undefined;\n }\n // Extract the fetcher property from the target object\n const fetcher = target[TARGET_FETCHER_PROPERTY];\n\n // Validate that the fetcher is an instance of the Fetcher class\n if (fetcher instanceof Fetcher) {\n return fetcher;\n }\n\n // Return undefined if no valid fetcher instance is found\n return undefined;\n }\n\n /**\n * Executes the HTTP request.\n *\n * This method resolves the path and request configuration from the metadata\n * and arguments, then executes the request using the configured fetcher.\n *\n * @param target - The target object that the method is called on\n * @param args - The runtime arguments passed to the method\n * @returns A Promise that resolves to the Response\n */\n async execute(\n target: any,\n args: any[],\n ): Promise<any> {\n const fetcher = this.getTargetFetcher(target) || this.metadata.fetcher;\n const request = this.metadata.resolveRequest(args);\n const extractor = this.metadata.resolveResultExtractor();\n return fetcher.request(request, extractor);\n }\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Fetcher,\n type RequestHeaders,\n type RequestHeadersCapable,\n type TimeoutCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { FunctionMetadata, RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { type ResultExtractorCapable } from './resultExtractor';\nimport { type FetcherCapable } from './fetcherCapable';\n\n/**\n * Metadata for class-level API configuration.\n *\n * Defines the configuration options that can be applied to an entire API class.\n * These settings will be used as defaults for all endpoints within the class unless overridden\n * at the method level.\n */\nexport interface ApiMetadata\n extends TimeoutCapable,\n RequestHeadersCapable,\n ResultExtractorCapable,\n FetcherCapable {\n /**\n * Base path for all endpoints in the class.\n *\n * This path will be prepended to all endpoint paths defined in the class.\n * For example, if basePath is '/api/v1' and an endpoint has path '/users',\n * the full path will be '/api/v1/users'.\n */\n basePath?: string;\n\n /**\n * Default headers for all requests in the class.\n *\n * These headers will be included in every request made by methods in this class.\n * They can be overridden or extended at the method level.\n */\n headers?: RequestHeaders;\n\n /**\n * Default timeout for all requests in the class (in milliseconds).\n *\n * This timeout value will be applied to all requests made by methods in this class.\n * Individual methods can specify their own timeout values to override this default.\n */\n timeout?: number;\n\n /**\n * Name of the fetcher instance to use, default: 'default'.\n *\n * This allows you to specify which fetcher instance should be used for requests\n * from this API class. The fetcher must be registered with the FetcherRegistrar.\n */\n fetcher?: string | Fetcher;\n}\n\nexport const API_METADATA_KEY = Symbol('api:metadata');\n\n/**\n * Binds a request executor to a method, replacing the original method with\n * an implementation that makes HTTP requests based on the decorator metadata.\n *\n * @param constructor - The class constructor\n * @param functionName - The name of the method to bind\n * @param apiMetadata - The API metadata for the class\n */\nfunction bindExecutor<T extends new (...args: any[]) => any>(\n constructor: T,\n functionName: string,\n apiMetadata: ApiMetadata,\n) {\n const endpointFunction = constructor.prototype[functionName];\n if (functionName === 'constructor') {\n return;\n }\n if (typeof endpointFunction !== 'function') {\n return;\n }\n\n const endpointMetadata = Reflect.getMetadata(\n ENDPOINT_METADATA_KEY,\n constructor.prototype,\n functionName,\n );\n if (!endpointMetadata) {\n return;\n }\n // Get parameter metadata for this method\n const parameterMetadata =\n Reflect.getMetadata(\n PARAMETER_METADATA_KEY,\n constructor.prototype,\n functionName,\n ) || new Map();\n\n // Create function metadata\n const functionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n const requestExecutor = new RequestExecutor(functionMetadata);\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = function(...args: unknown[]) {\n return requestExecutor.execute(this, args);\n };\n}\n\nexport function api(\n basePath: string = '',\n metadata: Omit<ApiMetadata, 'basePath'> = {},\n) {\n return function <T extends new (...args: any[]) => any>(constructor: T): T {\n const apiMetadata: ApiMetadata = {\n basePath,\n ...metadata,\n };\n\n // Store metadata directly on the class constructor\n Reflect.defineMetadata(API_METADATA_KEY, apiMetadata, constructor);\n\n // Override prototype methods to implement actual HTTP calls\n Object.getOwnPropertyNames(constructor.prototype).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n\n return constructor;\n };\n}\n","/*\n * Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Custom error class that indicates a method implementation will be automatically generated.\n *\n * @example\n * ```\n * @post()\n * createUser(@body() user: User):Promise<Response> {\n * throw autoGeneratedError(user);\n * }\n * ```\n */\nexport class AutoGenerated extends Error {\n constructor() {\n super('Implementation will be generated automatically.');\n this.name = 'AutoGenerated';\n }\n}\n\n/**\n * Factory function that creates an AutoGenerated error instance.\n * This is typically used in methods that will be automatically implemented,\n * where a placeholder implementation is needed.\n *\n * @param _ignored - Arguments (such as 'user' in the example) are ignored to prevent\n * ESLint no-unused-vars errors in method signatures that will be auto-generated.\n * @returns A new AutoGenerated error instance\n */\nexport const autoGeneratedError = (..._ignored: any[]): AutoGenerated => {\n return new AutoGenerated();\n};\n"],"names":["ENDPOINT_METADATA_KEY","endpoint","method","path","metadata","target","propertyKey","endpointMetadata","get","HttpMethod","post","put","del","patch","head","options","parameterNameCache","getParameterNames","func","fnStr","paramsStr","extractParameterString","hasParameters","emptyResult","result","parseParameterNames","errorResult","getParameterName","parameterIndex","providedName","paramNames","endParenIndex","findClosingParenthesis","startParenIndex","str","openingParenIndex","parenDepth","i","char","trimWhitespace","isNotEmpty","extractParameterName","param","cleanedParam","removeDefaultValue","removeTypeAnnotation","equalsIndex","colonIndex","ParameterType","PARAMETER_METADATA_KEY","parameter","type","name","paramName","existingParameters","parameterMetadata","query","header","body","request","ResultExtractors","ExchangeResultExtractor","ResponseResultExtractor","JsonResultExtractor","TextResultExtractor","EventStreamResultExtractor","JsonEventStreamResultExtractor","getFetcher","fetcher","Fetcher","fetcherRegistrar","FunctionMetadata","api","parameters","args","pathParams","queryParams","headers","signal","abortController","parameterRequest","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","parameterPath","basePath","endpointPath","combineURLs","TARGET_FETCHER_PROPERTY","RequestExecutor","extractor","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","requestExecutor","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"kdAiCO,MAAMA,EAAwB,OAAO,mBAAmB,EA4BxD,SAASC,EACdC,EACAC,EACAC,EAAmC,CAAA,EACnC,CACA,OAAO,SAASC,EAAgBC,EAAoC,CAElE,MAAMC,EAAmB,CACvB,OAAAL,EACA,KAAAC,EACA,GAAGC,CAAA,EAEL,QAAQ,eACNJ,EACAO,EACAF,EACAC,CAAA,CAEJ,CACF,CAEO,SAASE,EAAIL,EAAe,GAAIC,EAAmC,CAAA,EAAI,CAC5E,OAAOH,EAASQ,EAAAA,WAAW,IAAKN,EAAMC,CAAQ,CAChD,CAEO,SAASM,EAAKP,EAAe,GAAIC,EAAmC,CAAA,EAAI,CAC7E,OAAOH,EAASQ,EAAAA,WAAW,KAAMN,EAAMC,CAAQ,CACjD,CAEO,SAASO,EAAIR,EAAe,GAAIC,EAAmC,CAAA,EAAI,CAC5E,OAAOH,EAASQ,EAAAA,WAAW,IAAKN,EAAMC,CAAQ,CAChD,CAEO,SAASQ,EAAIT,EAAe,GAAIC,EAAmC,CAAA,EAAI,CAC5E,OAAOH,EAASQ,EAAAA,WAAW,OAAQN,EAAMC,CAAQ,CACnD,CAEO,SAASS,EACdV,EAAe,GACfC,EAAmC,CAAA,EACnC,CACA,OAAOH,EAASQ,EAAAA,WAAW,MAAON,EAAMC,CAAQ,CAClD,CAEO,SAASU,EAAKX,EAAe,GAAIC,EAAmC,CAAA,EAAI,CAC7E,OAAOH,EAASQ,EAAAA,WAAW,KAAMN,EAAMC,CAAQ,CACjD,CAEO,SAASW,EACdZ,EAAe,GACfC,EAAmC,CAAA,EACnC,CACA,OAAOH,EAASQ,EAAAA,WAAW,QAASN,EAAMC,CAAQ,CACpD,CCpGA,MAAMY,MAAyB,QA+BxB,SAASC,EAAkBC,EAAyC,CAEzE,GAAI,OAAOA,GAAS,WAClB,MAAM,IAAI,UAAU,qBAAqB,EAI3C,GAAIF,EAAmB,IAAIE,CAAI,EAC7B,OAAOF,EAAmB,IAAIE,CAAI,EAGpC,GAAI,CAEF,MAAMC,EAAQD,EAAK,SAAA,EAAW,KAAA,EAGxBE,EAAYC,EAAuBF,CAAK,EAG9C,GAAI,CAACG,EAAcF,CAAS,EAAG,CAC7B,MAAMG,EAAwB,CAAA,EAC9B,OAAAP,EAAmB,IAAIE,EAAMK,CAAW,EACjCA,CACT,CAGA,MAAMC,EAASC,EAAoBL,CAAS,EAC5C,OAAAJ,EAAmB,IAAIE,EAAMM,CAAM,EAC5BA,CACT,MAAQ,CAEN,MAAME,EAAwB,CAAA,EAC9B,OAAAV,EAAmB,IAAIE,EAAMQ,CAAW,EACjCA,CACT,CACF,CAWO,SAASC,EACdtB,EACAC,EACAsB,EACAC,EACoB,CAEpB,GAAIA,EACF,OAAOA,EAIT,GAAI,CACF,MAAM3B,EAASG,EAAOC,CAAkC,EACxD,GAAIJ,GAAU,OAAOA,GAAW,WAAY,CAC1C,MAAM4B,EAAab,EAAkBf,CAAM,EAC3C,GAAI0B,EAAiBE,EAAW,OAC9B,OAAOA,EAAWF,CAAc,CAEpC,CACF,MAAQ,CAGR,CAGF,CAQA,SAASN,EAAcF,EAA4B,CACjD,OACEA,GAAc,MAAmCA,EAAU,SAAW,EAE1E,CAQA,SAASC,EAAuBF,EAAuB,CAErD,GAAIA,EAAM,WAAW,GAAG,EAAG,CACzB,MAAMY,EAAgBC,EAAuBb,EAAO,CAAC,EACrD,OAAIY,IAAkB,GAAW,GAC1BZ,EAAM,UAAU,EAAGY,CAAa,CACzC,CAGA,MAAME,EAAkBd,EAAM,QAAQ,GAAG,EACzC,GAAIc,IAAoB,GAAI,MAAO,GAEnC,MAAMF,EAAgBC,EAAuBb,EAAOc,CAAe,EACnE,OAAIF,IAAkB,GAAW,GAE1BZ,EAAM,UAAUc,EAAkB,EAAGF,CAAa,CAC3D,CASA,SAASC,EACPE,EACAC,EACQ,CACR,IAAIC,EAAa,EAEjB,QAASC,EAAIF,EAAoB,EAAGE,EAAIH,EAAI,OAAQG,IAAK,CACvD,MAAMC,EAAOJ,EAAIG,CAAC,EAElB,GAAIC,IAAS,IACXF,YACSE,IAAS,MAClBF,IACIA,IAAe,GACjB,OAAOC,CAGb,CAEA,MAAO,EACT,CAQA,SAASZ,EAAoBL,EAA6B,CACxD,OAAOA,EACJ,MAAM,GAAG,EACT,IAAImB,CAAc,EAClB,OAAOC,CAAU,EACjB,IAAIC,CAAoB,CAC7B,CAQA,SAASF,EAAeL,EAAqB,CAC3C,OAAOA,EAAI,KAAA,CACb,CAQA,SAASM,EAAWN,EAAsB,CACxC,OAAOA,EAAI,OAAS,CACtB,CAQA,SAASO,EAAqBC,EAAuB,CAEnD,IAAIC,EAAeC,EAAmBF,CAAK,EAG3C,OAAAC,EAAeE,EAAqBF,CAAY,EAEzCA,EAAa,KAAA,CACtB,CAQA,SAASC,EAAmBF,EAAuB,CACjD,MAAMI,EAAcJ,EAAM,QAAQ,GAAG,EACrC,OAAII,IAAgB,GACXJ,EAAM,UAAU,EAAGI,CAAW,EAEhCJ,CACT,CAQA,SAASG,EAAqBH,EAAuB,CACnD,MAAMK,EAAaL,EAAM,QAAQ,GAAG,EACpC,OAAIK,IAAe,GACVL,EAAM,UAAU,EAAGK,CAAU,EAE/BL,CACT,CCxPO,IAAKM,GAAAA,IAaVA,EAAA,KAAO,OAcPA,EAAA,MAAQ,QAcRA,EAAA,OAAS,SAcTA,EAAA,KAAO,OAKPA,EAAA,QAAU,UA5DAA,IAAAA,GAAA,CAAA,CAAA,EA8FL,MAAMC,EAAyB,OAAO,oBAAoB,EA0B1D,SAASC,EAAUC,EAAqBC,EAAe,GAAI,CAChE,OAAO,SACL/C,EACAC,EACAsB,EACA,CACA,MAAMyB,EAAY1B,EAChBtB,EACAC,EACAsB,EACAwB,CAAA,EAGIE,EACJ,QAAQ,YAAYL,EAAwB5C,EAAQC,CAAW,OAC3D,IACAiD,EAAuC,CAC3C,KAAAJ,EACA,KAAME,EACN,MAAOzB,CAAA,EAET0B,EAAmB,IAAI1B,EAAgB2B,CAAiB,EACxD,QAAQ,eACNN,EACAK,EACAjD,EACAC,CAAA,CAEJ,CACF,CAuBO,SAASH,EAAKiD,EAAe,GAAI,CACtC,OAAOF,EAAU,OAAoBE,CAAI,CAC3C,CAuBO,SAASI,EAAMJ,EAAe,GAAI,CACvC,OAAOF,EAAU,QAAqBE,CAAI,CAC5C,CAuBO,SAASK,EAAOL,EAAe,GAAI,CACxC,OAAOF,EAAU,SAAsBE,CAAI,CAC7C,CAgBO,SAASM,GAAO,CACrB,OAAOR,EAAU,MAAA,CACnB,CA4BO,SAASS,GAAU,CACxB,OAAOT,EAAU,SAAA,CACnB,CC/OO,MAAMU,EAAmB,CAC9B,SAAUC,EAAAA,wBACV,SAAUC,EAAAA,wBACV,KAAMC,EAAAA,oBACN,KAAMC,EAAAA,oBACN,YAAaC,EAAAA,2BACb,gBAAiBC,EAAAA,+BACjB,QAASH,EAAAA,mBACX,ECnBO,SAASI,EAAWC,EAAiD,CAE1E,GAAKA,EAML,OAAOA,aAAmBC,EAAAA,QACtBD,EACAE,EAAAA,iBAAiB,YAAYF,CAAO,CAC1C,CCLO,MAAMG,CAAyC,CAqCpD,YACEnB,EACAoB,EACAvE,EACAwE,EACA,CACA,KAAK,KAAOrB,EACZ,KAAK,IAAMoB,EACX,KAAK,SAAWvE,EAChB,KAAK,WAAawE,CACpB,CAUA,IAAI,SAAmB,CACrB,OAAON,EAAW,KAAK,SAAS,SAAW,KAAK,IAAI,OAAO,GAAKC,EAAAA,OAClE,CAgDA,eAAeM,EAA2B,CACxC,MAAMC,EAAkC,CAAA,EAClCC,EAAmC,CAAA,EACnCC,EAA0B,CAC9B,GAAG,KAAK,IAAI,QACZ,GAAG,KAAK,SAAS,OAAA,EAEnB,IAAInB,EACAoB,EACAC,EACAC,EAAqC,CAAA,EAEzCN,EAAK,QAAQ,CAACO,EAAOC,KAAU,CAC7B,GAAID,aAAiB,YAAa,CAChCH,EAASG,EACT,MACF,CACA,GAAIA,aAAiB,gBAAiB,CACpCF,EAAkBE,EAClB,MACF,CACA,MAAME,EAAe,KAAK,WAAW,IAAID,EAAK,EAC9C,GAAKC,EAGL,OAAQA,EAAa,KAAA,CACnB,KAAKnC,EAAc,KACjB,KAAK,iBAAiBmC,EAAcF,EAAON,CAAU,EACrD,MACF,KAAK3B,EAAc,MACjB,KAAK,kBAAkBmC,EAAcF,EAAOL,CAAW,EACvD,MACF,KAAK5B,EAAc,OACjB,KAAK,mBAAmBmC,EAAcF,EAAOJ,CAAO,EACpD,MACF,KAAK7B,EAAc,KACjBU,EAAOuB,EACP,MACF,KAAKjC,EAAc,QACjBgC,EAAmB,KAAK,oBAAoBC,CAAK,EACjD,KAAA,CAEN,CAAC,EACD,MAAMG,GAAuB,CAC3B,KAAMT,EACN,MAAOC,CAAA,EAEHS,GAAoC,CACxC,OAAQ,KAAK,SAAS,OACtB,UAAAD,GACA,QAAAP,EACA,KAAAnB,EACA,QAAS,KAAK,eAAA,EACd,OAAAoB,EACA,gBAAAC,CAAA,EAEIO,EAAgBC,EAAAA,aACpBF,GACAL,CAAA,EAEIQ,GAAgBR,EAAiB,KACvC,OAAAM,EAAc,IAAM,KAAK,YAAYE,EAAa,EAC3CF,CACT,CAEQ,iBACN5C,EACAuC,EACA9E,EACA,CACA,MAAMkD,EAAYX,EAAM,MAAQ,QAAQA,EAAM,KAAK,GACnDvC,EAAKkD,CAAS,EAAI4B,CACpB,CAEQ,kBACNvC,EACAuC,EACAzB,EACA,CACA,MAAMH,EAAYX,EAAM,MAAQ,QAAQA,EAAM,KAAK,GACnDc,EAAMH,CAAS,EAAI4B,CACrB,CAEQ,mBACNvC,EACAuC,EACAJ,EACA,CACInC,EAAM,MAAQuC,IAAU,SAC1BJ,EAAQnC,EAAM,IAAI,EAAI,OAAOuC,CAAK,EAEtC,CA0BQ,oBAAoBA,EAA8B,CACxD,OAAOA,CACT,CAQA,YAAYO,EAAgC,CAE1C,MAAMC,EAAW,KAAK,SAAS,UAAY,KAAK,IAAI,UAAY,GAG1DC,EAAeF,GAAiB,KAAK,SAAS,MAAQ,GAG5D,OAAOG,EAAAA,YAAYF,EAAUC,CAAY,CAC3C,CAUA,gBAAqC,CACnC,OAAO,KAAK,SAAS,SAAW,KAAK,IAAI,OAC3C,CAEA,wBAA+C,CAC7C,OACE,KAAK,SAAS,iBACd,KAAK,IAAI,iBACT9B,EAAiB,OAErB,CACF,CAEA,MAAMgC,EAA0B,UASzB,MAAMC,CAAgB,CAQ3B,YAAYzF,EAA4B,CACtC,KAAK,SAAWA,CAClB,CAQQ,iBAAiBC,EAAkC,CACzD,GAAI,CAACA,GAAU,OAAOA,GAAW,SAC/B,OAGF,MAAM+D,EAAU/D,EAAOuF,CAAuB,EAG9C,GAAIxB,aAAmBC,EAAAA,QACrB,OAAOD,CAKX,CAYA,MAAM,QACJ/D,EACAqE,EACc,CACd,MAAMN,EAAU,KAAK,iBAAiB/D,CAAM,GAAK,KAAK,SAAS,QACzDsD,EAAU,KAAK,SAAS,eAAee,CAAI,EAC3CoB,EAAY,KAAK,SAAS,uBAAA,EAChC,OAAO1B,EAAQ,QAAQT,EAASmC,CAAS,CAC3C,CACF,CCxSO,MAAMC,EAAmB,OAAO,cAAc,EAUrD,SAASC,EACPC,EACAC,EACAC,EACA,CACA,MAAMC,EAAmBH,EAAY,UAAUC,CAAY,EAI3D,GAHIA,IAAiB,eAGjB,OAAOE,GAAqB,WAC9B,OAGF,MAAM7F,EAAmB,QAAQ,YAC/BP,EACAiG,EAAY,UACZC,CAAA,EAEF,GAAI,CAAC3F,EACH,OAGF,MAAMgD,EACJ,QAAQ,YACNN,EACAgD,EAAY,UACZC,CAAA,OACO,IAGLG,EAAmB,IAAI9B,EAC3B2B,EACAC,EACA5F,EACAgD,CAAA,EAII+C,EAAkB,IAAIT,EAAgBQ,CAAgB,EAG5DJ,EAAY,UAAUC,CAAY,EAAI,YAAYxB,EAAiB,CACjE,OAAO4B,EAAgB,QAAQ,KAAM5B,CAAI,CAC3C,CACF,CAEO,SAASF,EACdiB,EAAmB,GACnBrF,EAA0C,CAAA,EAC1C,CACA,OAAO,SAAiD6F,EAAmB,CACzE,MAAME,EAA2B,CAC/B,SAAAV,EACA,GAAGrF,CAAA,EAIL,eAAQ,eAAe2F,EAAkBI,EAAaF,CAAW,EAGjE,OAAO,oBAAoBA,EAAY,SAAS,EAAE,QAAQC,GAAgB,CACxEF,EAAaC,EAAaC,EAAcC,CAAW,CACrD,CAAC,EAEMF,CACT,CACF,CC5HO,MAAMM,UAAsB,KAAM,CACvC,aAAc,CACZ,MAAM,iDAAiD,EACvD,KAAK,KAAO,eACd,CACF,CAWO,MAAMC,EAAqB,IAAIC,IAC7B,IAAIF"}
@@ -1,9 +1,7 @@
1
- import { Fetcher, FetchExchange, FetchRequest, NamedCapable } from '@ahoo-wang/fetcher';
1
+ import { Fetcher, FetchRequest, NamedCapable, ResultExtractor } from '@ahoo-wang/fetcher';
2
2
  import { ApiMetadata } from './apiDecorator';
3
3
  import { EndpointMetadata } from './endpointDecorator';
4
4
  import { ParameterMetadata } from './parameterDecorator';
5
- import { ResultExtractor } from './resultExtractor';
6
- import { ServerSentEventStream } from '@ahoo-wang/fetcher-eventstream';
7
5
  /**
8
6
  * Metadata container for a function with HTTP endpoint decorators.
9
7
  *
@@ -145,7 +143,7 @@ export declare class FunctionMetadata implements NamedCapable {
145
143
  * @returns The timeout value in milliseconds, or undefined
146
144
  */
147
145
  resolveTimeout(): number | undefined;
148
- resolveResultExtractor(): ResultExtractor;
146
+ resolveResultExtractor(): ResultExtractor<any>;
149
147
  }
150
148
  /**
151
149
  * Executor for HTTP requests based on decorated method metadata.
@@ -179,6 +177,6 @@ export declare class RequestExecutor {
179
177
  * @param args - The runtime arguments passed to the method
180
178
  * @returns A Promise that resolves to the Response
181
179
  */
182
- execute(target: any, args: any[]): Promise<FetchExchange | Response | any | ServerSentEventStream>;
180
+ execute(target: any, args: any[]): Promise<any>;
183
181
  }
184
182
  //# sourceMappingURL=requestExecutor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"requestExecutor.d.ts","sourceRoot":"","sources":["../src/requestExecutor.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,OAAO,EACP,aAAa,EACb,KAAK,YAAY,EAGjB,KAAK,YAAY,EAGlB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAoB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAGvE;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,GAAG,EAAE,WAAW,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAC;IAE3B;;;;;;;;;;OAUG;IACH,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAE3C;;;;;;;OAOG;gBAED,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAQ5C;;;;;;;OAOG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY;IA2DzC,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,kBAAkB;IAU1B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;;;;OAKG;IACH,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM;IAW3C;;;;;;;OAOG;IACH,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,sBAAsB,IAAI,eAAe;CAO1C;AAID;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAE5C;;;;OAIG;gBACS,QAAQ,EAAE,gBAAgB;IAItC;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;;;;OASG;IACG,OAAO,CACX,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,GAAG,EAAE,GACV,OAAO,CAAC,aAAa,GAAG,QAAQ,GAAG,GAAG,GAAG,qBAAqB,CAAC;CAOnE"}
1
+ {"version":3,"file":"requestExecutor.d.ts","sourceRoot":"","sources":["../src/requestExecutor.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,OAAO,EACP,KAAK,YAAY,EAGjB,KAAK,YAAY,EACI,eAAe,EAErC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,sBAAsB,CAAC;AAI9B;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,GAAG,EAAE,WAAW,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAC;IAE3B;;;;;;;;;;OAUG;IACH,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAE3C;;;;;;;OAOG;gBAED,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAQ5C;;;;;;;OAOG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY;IAiEzC,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,kBAAkB;IAU1B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;;;;OAKG;IACH,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM;IAW3C;;;;;;;OAOG;IACH,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,sBAAsB,IAAI,eAAe,CAAC,GAAG,CAAC;CAO/C;AAID;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAE5C;;;;OAIG;gBACS,QAAQ,EAAE,gBAAgB;IAItC;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;;;;OASG;IACG,OAAO,CACX,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,GAAG,EAAE,GACV,OAAO,CAAC,GAAG,CAAC;CAMhB"}
@@ -1,61 +1,11 @@
1
- import { FetchExchange } from '@ahoo-wang/fetcher';
2
- import { JsonServerSentEventStream, ServerSentEventStream } from '@ahoo-wang/fetcher-eventstream';
3
- /**
4
- * Result extractor interface
5
- * Defines a function type for extracting results from a FetchExchange
6
- * @param exchange - FetchExchange object containing request and response information
7
- * @returns Returns a value of type FetchExchange, Response, or Promise<any>
8
- */
9
- export interface ResultExtractor {
10
- (exchange: FetchExchange): FetchExchange | Response | Promise<any> | ServerSentEventStream | JsonServerSentEventStream<any>;
11
- }
1
+ import { ResultExtractor } from '@ahoo-wang/fetcher';
12
2
  /**
13
3
  * Interface with result extractor capability
14
4
  * Defines an optional resultExtractor property
15
5
  */
16
6
  export interface ResultExtractorCapable {
17
- resultExtractor?: ResultExtractor;
7
+ resultExtractor?: ResultExtractor<any>;
18
8
  }
19
- /**
20
- * Returns the original FetchExchange object
21
- * @param exchange - FetchExchange object
22
- * @returns The original FetchExchange object
23
- */
24
- export declare const ExchangeResultExtractor: ResultExtractor;
25
- /**
26
- * Returns the response object from FetchExchange
27
- * @param exchange - FetchExchange object
28
- * @returns The response object from FetchExchange
29
- */
30
- export declare const ResponseResultExtractor: ResultExtractor;
31
- /**
32
- * Parses the response content as JSON format
33
- * @param exchange - FetchExchange object
34
- * @returns Promise of parsed JSON data
35
- */
36
- export declare const JsonResultExtractor: ResultExtractor;
37
- /**
38
- * Parses the response content as text format
39
- * @param exchange - FetchExchange object
40
- * @returns Promise of parsed text data
41
- */
42
- export declare const TextResultExtractor: ResultExtractor;
43
- /**
44
- * ServerSentEventStream result extractor, used to extract server-sent event stream from FetchExchange
45
- *
46
- * @param exchange - FetchExchange object containing request and response information
47
- * @returns Readable stream object of server-sent event stream
48
- * @throws ExchangeError exception when server does not support ServerSentEventStream
49
- */
50
- export declare const EventStreamResultExtractor: ResultExtractor;
51
- /**
52
- * JsonServerSentEventStream result extractor, used to extract JSON server-sent event stream from FetchExchange
53
- *
54
- * @param exchange - FetchExchange object containing request and response information
55
- * @returns Readable stream object of JSON server-sent event stream
56
- * @throws ExchangeError exception when server does not support JsonServerSentEventStream
57
- */
58
- export declare const JsonEventStreamResultExtractor: ResultExtractor;
59
9
  /**
60
10
  * ResultExtractors is an object that maps result extractor names to their corresponding
61
11
  * extractor functions. These extractors are used to process and extract data from different
@@ -70,12 +20,12 @@ export declare const JsonEventStreamResultExtractor: ResultExtractor;
70
20
  * - JsonEventStream: Handles JSON server-sent event stream result extraction
71
21
  */
72
22
  export declare const ResultExtractors: {
73
- Exchange: ResultExtractor;
74
- Response: ResultExtractor;
75
- Json: ResultExtractor;
76
- Text: ResultExtractor;
77
- EventStream: ResultExtractor;
78
- JsonEventStream: ResultExtractor;
79
- DEFAULT: ResultExtractor;
23
+ Exchange: ResultExtractor<import('@ahoo-wang/fetcher').FetchExchange>;
24
+ Response: ResultExtractor<Response>;
25
+ Json: ResultExtractor<Promise<any>>;
26
+ Text: ResultExtractor<Promise<string>>;
27
+ EventStream: ResultExtractor<import('@ahoo-wang/fetcher-eventstream').ServerSentEventStream>;
28
+ JsonEventStream: ResultExtractor<import('@ahoo-wang/fetcher-eventstream').JsonServerSentEventStream<any>>;
29
+ DEFAULT: ResultExtractor<Promise<any>>;
80
30
  };
81
31
  //# sourceMappingURL=resultExtractor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resultExtractor.d.ts","sourceRoot":"","sources":["../src/resultExtractor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EACV,yBAAyB,EACzB,qBAAqB,EACtB,MAAM,gCAAgC,CAAC;AAExC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,CACE,QAAQ,EAAE,aAAa,GAErB,aAAa,GACb,QAAQ,GACR,OAAO,CAAC,GAAG,CAAC,GACZ,qBAAqB,GACrB,yBAAyB,CAAC,GAAG,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,eAIrC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,eAIrC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAIjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAIjC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,eAIxC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,eAI5C,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;CAQ5B,CAAC"}
1
+ {"version":3,"file":"resultExtractor.d.ts","sourceRoot":"","sources":["../src/resultExtractor.ts"],"names":[],"mappings":"AAaA,OAAO,EAIL,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAM5B;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;CACxC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;CAQ5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher-decorator",
3
- "version": "1.3.3",
3
+ "version": "1.5.0",
4
4
  "description": "TypeScript decorators for clean, declarative API service definitions with Fetcher HTTP client. Enables automatic parameter binding, method mapping, and type-safe API interactions.",
5
5
  "keywords": [
6
6
  "fetch",
@@ -40,8 +40,8 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "reflect-metadata": "^0.2.2",
43
- "@ahoo-wang/fetcher": "1.3.3",
44
- "@ahoo-wang/fetcher-eventstream": "1.3.3"
43
+ "@ahoo-wang/fetcher-eventstream": "1.5.0",
44
+ "@ahoo-wang/fetcher": "1.5.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@vitest/coverage-v8": "^3.2.4",