@ahoo-wang/fetcher-decorator 3.8.5 → 3.8.8

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,6 +1,6 @@
1
1
  import { HttpMethod as p, getFetcher as O, combineURLs as w, JsonResultExtractor as D, mergeRecordToMap as l, mergeRequest as H } from "@ahoo-wang/fetcher";
2
2
  import "reflect-metadata";
3
- const T = Symbol("endpoint:metadata");
3
+ const T = /* @__PURE__ */ Symbol("endpoint:metadata");
4
4
  function h(t, e, r = {}) {
5
5
  return function(n, a) {
6
6
  const s = {
@@ -181,7 +181,7 @@ function L(t) {
181
181
  return e !== -1 ? t.substring(0, e) : t;
182
182
  }
183
183
  var u = /* @__PURE__ */ ((t) => (t.PATH = "path", t.QUERY = "query", t.HEADER = "header", t.BODY = "body", t.REQUEST = "request", t.ATTRIBUTE = "attribute", t))(u || {});
184
- const P = Symbol("parameter:metadata");
184
+ const P = /* @__PURE__ */ Symbol("parameter:metadata");
185
185
  function f(t, e = "") {
186
186
  return function(r, n, a) {
187
187
  const s = Y(
@@ -478,7 +478,7 @@ class g {
478
478
  e.name && r !== void 0 && n.set(e.name, r);
479
479
  }
480
480
  }
481
- const K = Symbol("api:metadata");
481
+ const K = /* @__PURE__ */ Symbol("api:metadata");
482
482
  function W(t, e, r) {
483
483
  const n = t.prototype[e];
484
484
  if (e === "constructor" || typeof n != "function")
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/endpointDecorator.ts","../src/endpointReturnTypeCapable.ts","../src/requestExecutor.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/functionMetadata.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod, type ResultExtractorCapable } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\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\n/**\n * Convenience decorator for GET HTTP requests.\n *\n * Creates an endpoint decorator configured for GET requests. GET requests\n * are used to retrieve data from a server without modifying it.\n *\n * @param path - The endpoint path (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 * @get('/users/{id}')\n * getUser(@path('id') id: string): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\n/**\n * Convenience decorator for POST HTTP requests.\n *\n * Creates an endpoint decorator configured for POST requests. POST requests\n * are used to create new resources on the server.\n *\n * @param path - The endpoint path (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 * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\n/**\n * Convenience decorator for PUT HTTP requests.\n *\n * Creates an endpoint decorator configured for PUT requests. PUT requests\n * are used to update existing resources on the server.\n *\n * @param path - The endpoint path (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 * @put('/users/{id}')\n * updateUser(@path('id') id: string, @body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\n/**\n * Convenience decorator for DELETE HTTP requests.\n *\n * Creates an endpoint decorator configured for DELETE requests. DELETE requests\n * are used to remove resources from the server.\n *\n * @param path - The endpoint path (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 * @del('/users/{id}')\n * deleteUser(@path('id') id: string): Promise<void> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\n/**\n * Convenience decorator for PATCH HTTP requests.\n *\n * Creates an endpoint decorator configured for PATCH requests. PATCH requests\n * are used to apply partial updates to existing resources.\n *\n * @param path - The endpoint path (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 * @patch('/users/{id}')\n * updateUserPartial(@path('id') id: string, @body() updates: Partial<User>): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\n/**\n * Convenience decorator for HEAD HTTP requests.\n *\n * Creates an endpoint decorator configured for HEAD requests. HEAD requests\n * are used to retrieve headers only, without the response body.\n *\n * @param path - The endpoint path (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 * @head('/users/{id}')\n * checkUserExists(@path('id') id: string): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\n/**\n * Convenience decorator for OPTIONS HTTP requests.\n *\n * Creates an endpoint decorator configured for OPTIONS requests. OPTIONS requests\n * are used to describe the communication options for the target resource.\n *\n * @param path - The endpoint path (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 * @options('/users')\n * getUserOptions(): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\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\nexport enum EndpointReturnType {\n EXCHANGE = 'Exchange',\n RESULT = 'Result',\n}\n\nexport interface EndpointReturnTypeCapable {\n returnType?: EndpointReturnType;\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 { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\nimport { ExecuteLifeCycle } from './executeLifeCycle';\n\nexport const DECORATOR_TARGET_ATTRIBUTE_KEY = '__decorator_target__';\nexport const DECORATOR_METADATA_ATTRIBUTE_KEY = '__decorator_metadata__';\n\n/**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\nexport class RequestExecutor {\n /**\n * Creates a new RequestExecutor instance.\n * @param target - The target object that the method is called on.\n * This can contain a custom fetcher instance in its 'fetcher' property.\n * @param metadata - The function metadata containing all request information\n */\n constructor(\n private readonly target: any,\n private readonly metadata: FunctionMetadata,\n ) {}\n\n /**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\n async execute(args: any[]): Promise<any> {\n const fetcher = this.metadata.fetcher;\n const exchangeInit = this.metadata.resolveExchangeInit(args);\n exchangeInit.attributes.set(DECORATOR_TARGET_ATTRIBUTE_KEY, this.target);\n exchangeInit.attributes.set(\n DECORATOR_METADATA_ATTRIBUTE_KEY,\n this.metadata,\n );\n const resultExtractor = this.metadata.resolveResultExtractor();\n const endpointReturnType = this.metadata.resolveEndpointReturnType();\n\n const exchange = fetcher.resolveExchange(exchangeInit.request, {\n resultExtractor: resultExtractor,\n attributes: exchangeInit.attributes,\n });\n const executeLifeCycle = this.target as ExecuteLifeCycle;\n // Call lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.beforeExecute) {\n await executeLifeCycle.beforeExecute(exchange);\n }\n // Process through interceptor chain\n await fetcher.interceptors.exchange(exchange);\n // Call afterExecute lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.afterExecute) {\n await executeLifeCycle.afterExecute(exchange);\n }\n\n if (endpointReturnType === EndpointReturnType.EXCHANGE) {\n return exchange;\n }\n return await exchange.extractResult();\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// 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, RequestBodyType } 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 *\n * PATH, QUERY, and HEADER parameter types support plain objects (Record) which will be expanded\n * into multiple parameters with the object's key-value pairs.\n *\n * ATTRIBUTE parameter type supports primitive types, plain objects (Record), and Map objects.\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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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 * Attribute parameter that will be used as a single attribute in the request attributes.\n *\n * The attribute parameter allows passing a single key-value pair that will be added\n * to the request attributes object. This is useful for passing specific contextual\n * information that can be accessed by interceptors.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\n ATTRIBUTE = 'attribute',\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 * Different parameter types support different value types:\n * - PATH, QUERY, HEADER: Support primitive types and plain objects (Record).\n * Plain objects will be expanded into multiple parameters.\n * - BODY: Accepts any value to be sent as the request body.\n * - ATTRIBUTE: Supports primitive types, plain objects (Record), and Map objects.\n * Plain objects will be expanded into multiple attributes, and Map objects will\n * have their entries added to the attributes collection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, BODY, REQUEST, ATTRIBUTE)\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 * // With object expansion for PATH parameters\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@parameter(ParameterType.PATH) params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\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 * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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<\n BODY extends RequestBodyType = RequestBodyType,\n> extends FetchRequestInit<BODY>,\n PathCapable {}\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/**\n * Parameter decorator for adding a single attribute to the request attributes.\n *\n * This decorator allows you to pass a key-value pair as an attribute that can be accessed\n * by interceptors during the request lifecycle. If no name is provided, the parameter's\n * property name will be used as the attribute key.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes collection.\n *\n * @param name - Optional name for the attribute. If not provided, the parameter's property name will be used.\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // Using property name as attribute key\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\nexport function attribute(name: string = '') {\n return parameter(ParameterType.ATTRIBUTE, name);\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 combineURLs,\n Fetcher,\n type FetchExchangeInit,\n FetchRequestInit,\n getFetcher,\n JsonResultExtractor,\n mergeRecordToMap,\n mergeRequest,\n NamedCapable,\n type RequestHeaders,\n ResultExtractor,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n ParameterMetadata,\n ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\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);\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 /**\n * Resolves the result extractor for the request.\n *\n * Returns the result extractor specified in the endpoint metadata, or the API metadata,\n * or falls back to the default JsonResultExtractor if none is specified.\n *\n * @returns The result extractor function to use for processing responses\n */\n resolveResultExtractor(): ResultExtractor<any> {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n JsonResultExtractor\n );\n }\n\n /**\n * Resolves the attributes for the request.\n *\n * Merges attributes from API-level and endpoint-level metadata into a single Map.\n * API-level attributes are applied first, then endpoint-level attributes can override them.\n *\n * @returns A Map containing all resolved attributes for the request\n */\n resolveAttributes(): Map<string, any> {\n const resolvedAttributes = mergeRecordToMap(this.api.attributes);\n return mergeRecordToMap(this.endpoint.attributes, resolvedAttributes);\n }\n\n /**\n * Resolves the endpoint return type for the request.\n *\n * Returns the return type specified in the endpoint metadata, or the API metadata,\n * or falls back to EndpointReturnType.RESULT if none is specified.\n *\n * @returns The endpoint return type determining what the method should return\n */\n resolveEndpointReturnType(): EndpointReturnType {\n return (\n this.endpoint.returnType ||\n this.api.returnType ||\n EndpointReturnType.RESULT\n );\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 resolveExchangeInit(\n args: any[],\n ): Required<Pick<FetchExchangeInit, 'request' | 'attributes'>> {\n const pathParams: Record<string, any> = {\n ...this.api.urlParams?.path,\n ...this.endpoint.urlParams?.path,\n };\n const queryParams: Record<string, any> = {\n ...this.api.urlParams?.query,\n ...this.endpoint.urlParams?.query,\n };\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 const attributes: Map<string, any> = this.resolveAttributes();\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 case ParameterType.ATTRIBUTE:\n this.processAttributeParam(funParameter, value, attributes);\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 {\n request: mergedRequest,\n attributes,\n };\n }\n\n private processHttpParam(\n param: ParameterMetadata,\n value: any,\n params: Record<string, any>,\n ) {\n if (value === undefined || value === null) {\n return;\n }\n if (typeof value === 'object') {\n Object.entries(value).forEach(([key, value]) => {\n params[key] = value;\n });\n return;\n }\n const paramName = param.name || `param${param.index}`;\n params[paramName] = value;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n this.processHttpParam(param, value, path);\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n this.processHttpParam(param, value, query);\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n this.processHttpParam(param, value, headers);\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 if (!value) {\n return {};\n }\n\n const request = value as ParameterRequest;\n // 确保请求对象中的属性被正确保留\n return {\n ...request,\n headers: request.headers || {},\n urlParams: request.urlParams || { path: {}, query: {} },\n };\n }\n\n private processAttributeParam(\n param: ParameterMetadata,\n value: any,\n attributes: Map<string, any>,\n ) {\n if (typeof value === 'object' || value instanceof Map) {\n mergeRecordToMap(value, attributes);\n return;\n }\n if (param.name && value !== undefined) {\n attributes.set(param.name, value);\n }\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 type AttributesCapable,\n Fetcher,\n FetcherCapable,\n type RequestHeaders,\n type RequestHeadersCapable,\n type ResultExtractorCapable,\n type TimeoutCapable,\n UrlParamsCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnTypeCapable } from './endpointReturnTypeCapable';\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 AttributesCapable,\n EndpointReturnTypeCapable,\n UrlParamsCapable {\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 interface ApiMetadataCapable {\n /**\n * API metadata for the class.\n */\n readonly apiMetadata?: ApiMetadata;\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 * This internal function is called during class decoration to replace placeholder\n * method implementations with actual HTTP request execution logic. It creates\n * a RequestExecutor instance and assigns it to replace the original method.\n *\n * @param constructor - The class constructor being decorated\n * @param functionName - The name of the method to bind the executor to\n * @param apiMetadata - The API metadata for the class containing configuration\n * @internal This function is used internally during class decoration\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: FunctionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = async function (...args: unknown[]) {\n const requestExecutor: RequestExecutor = buildRequestExecutor(\n this,\n functionMetadata,\n );\n return await requestExecutor.execute(args);\n };\n}\n\n/**\n * Builds or retrieves a cached RequestExecutor for the given function metadata.\n *\n * This function implements a caching mechanism to ensure that each decorated method\n * gets a consistent RequestExecutor instance. If an executor already exists for the\n * function, it returns the cached instance; otherwise, it creates a new one.\n *\n * The function merges API metadata from the target instance with the default metadata\n * to allow runtime customization of API behavior.\n *\n * @param target - The target object instance that contains the method\n * @param defaultFunctionMetadata - The function metadata containing endpoint configuration\n * @returns A RequestExecutor instance for executing the HTTP request\n */\nexport function buildRequestExecutor(\n target: any,\n defaultFunctionMetadata: FunctionMetadata,\n): RequestExecutor {\n let requestExecutors: Map<string, RequestExecutor> =\n target['requestExecutors'];\n if (!requestExecutors) {\n requestExecutors = new Map<string, RequestExecutor>();\n target['requestExecutors'] = requestExecutors;\n }\n let requestExecutor = requestExecutors.get(defaultFunctionMetadata.name);\n if (requestExecutor) {\n return requestExecutor;\n }\n const targetApiMetadata: ApiMetadata = target['apiMetadata'];\n const mergedApiMetadata: ApiMetadata = {\n ...defaultFunctionMetadata.api,\n ...targetApiMetadata,\n };\n requestExecutor = new RequestExecutor(\n target,\n new FunctionMetadata(\n defaultFunctionMetadata.name,\n mergedApiMetadata,\n defaultFunctionMetadata.endpoint,\n defaultFunctionMetadata.parameters,\n ),\n );\n requestExecutors.set(defaultFunctionMetadata.name, requestExecutor);\n return requestExecutor;\n}\n\n/**\n * Class decorator for defining API configurations.\n *\n * The @api decorator configures a class as an API client with shared settings\n * like base URL, default headers, timeout, and fetcher instance. All methods\n * in the decorated class that use HTTP method decorators (@get, @post, etc.)\n * will inherit these settings.\n *\n * @param basePath - Base path to prepend to all endpoint paths in the class\n * @param metadata - Additional API configuration including headers, timeout, fetcher, etc.\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1', {\n * headers: { 'Authorization': 'Bearer token' },\n * timeout: 5000,\n * fetcher: 'myFetcher'\n * })\n * class UserService {\n * @get('/users')\n * getUsers(): Promise<User[]> {\n * throw autoGeneratedError();\n * }\n *\n * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\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 bindAllExecutors(constructor, apiMetadata);\n return constructor;\n };\n}\n\nfunction bindAllExecutors<T extends new (...args: any[]) => any>(\n constructor: T,\n apiMetadata: ApiMetadata,\n) {\n const boundProto = new Set();\n let proto = constructor.prototype;\n while (proto && proto !== Object.prototype) {\n if (boundProto.has(proto)) {\n proto = Object.getPrototypeOf(proto);\n continue;\n }\n boundProto.add(proto);\n Object.getOwnPropertyNames(proto).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n proto = Object.getPrototypeOf(proto);\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","EndpointReturnType","DECORATOR_TARGET_ATTRIBUTE_KEY","DECORATOR_METADATA_ATTRIBUTE_KEY","RequestExecutor","args","fetcher","exchangeInit","resultExtractor","endpointReturnType","exchange","executeLifeCycle","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","attribute","FunctionMetadata","api","parameters","getFetcher","parameterPath","basePath","endpointPath","combineURLs","JsonResultExtractor","resolvedAttributes","mergeRecordToMap","pathParams","queryParams","headers","signal","abortController","parameterRequest","attributes","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","params","key","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","buildRequestExecutor","defaultFunctionMetadata","requestExecutors","requestExecutor","targetApiMetadata","mergedApiMetadata","bindAllExecutors","boundProto","proto","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/endpointDecorator.ts","../src/endpointReturnTypeCapable.ts","../src/requestExecutor.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/functionMetadata.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod, type ResultExtractorCapable } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\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\n/**\n * Convenience decorator for GET HTTP requests.\n *\n * Creates an endpoint decorator configured for GET requests. GET requests\n * are used to retrieve data from a server without modifying it.\n *\n * @param path - The endpoint path (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 * @get('/users/{id}')\n * getUser(@path('id') id: string): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\n/**\n * Convenience decorator for POST HTTP requests.\n *\n * Creates an endpoint decorator configured for POST requests. POST requests\n * are used to create new resources on the server.\n *\n * @param path - The endpoint path (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 * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\n/**\n * Convenience decorator for PUT HTTP requests.\n *\n * Creates an endpoint decorator configured for PUT requests. PUT requests\n * are used to update existing resources on the server.\n *\n * @param path - The endpoint path (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 * @put('/users/{id}')\n * updateUser(@path('id') id: string, @body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\n/**\n * Convenience decorator for DELETE HTTP requests.\n *\n * Creates an endpoint decorator configured for DELETE requests. DELETE requests\n * are used to remove resources from the server.\n *\n * @param path - The endpoint path (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 * @del('/users/{id}')\n * deleteUser(@path('id') id: string): Promise<void> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\n/**\n * Convenience decorator for PATCH HTTP requests.\n *\n * Creates an endpoint decorator configured for PATCH requests. PATCH requests\n * are used to apply partial updates to existing resources.\n *\n * @param path - The endpoint path (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 * @patch('/users/{id}')\n * updateUserPartial(@path('id') id: string, @body() updates: Partial<User>): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\n/**\n * Convenience decorator for HEAD HTTP requests.\n *\n * Creates an endpoint decorator configured for HEAD requests. HEAD requests\n * are used to retrieve headers only, without the response body.\n *\n * @param path - The endpoint path (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 * @head('/users/{id}')\n * checkUserExists(@path('id') id: string): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\n/**\n * Convenience decorator for OPTIONS HTTP requests.\n *\n * Creates an endpoint decorator configured for OPTIONS requests. OPTIONS requests\n * are used to describe the communication options for the target resource.\n *\n * @param path - The endpoint path (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 * @options('/users')\n * getUserOptions(): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\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\nexport enum EndpointReturnType {\n EXCHANGE = 'Exchange',\n RESULT = 'Result',\n}\n\nexport interface EndpointReturnTypeCapable {\n returnType?: EndpointReturnType;\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 { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\nimport { ExecuteLifeCycle } from './executeLifeCycle';\n\nexport const DECORATOR_TARGET_ATTRIBUTE_KEY = '__decorator_target__';\nexport const DECORATOR_METADATA_ATTRIBUTE_KEY = '__decorator_metadata__';\n\n/**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\nexport class RequestExecutor {\n /**\n * Creates a new RequestExecutor instance.\n * @param target - The target object that the method is called on.\n * This can contain a custom fetcher instance in its 'fetcher' property.\n * @param metadata - The function metadata containing all request information\n */\n constructor(\n private readonly target: any,\n private readonly metadata: FunctionMetadata,\n ) {}\n\n /**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\n async execute(args: any[]): Promise<any> {\n const fetcher = this.metadata.fetcher;\n const exchangeInit = this.metadata.resolveExchangeInit(args);\n exchangeInit.attributes.set(DECORATOR_TARGET_ATTRIBUTE_KEY, this.target);\n exchangeInit.attributes.set(\n DECORATOR_METADATA_ATTRIBUTE_KEY,\n this.metadata,\n );\n const resultExtractor = this.metadata.resolveResultExtractor();\n const endpointReturnType = this.metadata.resolveEndpointReturnType();\n\n const exchange = fetcher.resolveExchange(exchangeInit.request, {\n resultExtractor: resultExtractor,\n attributes: exchangeInit.attributes,\n });\n const executeLifeCycle = this.target as ExecuteLifeCycle;\n // Call lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.beforeExecute) {\n await executeLifeCycle.beforeExecute(exchange);\n }\n // Process through interceptor chain\n await fetcher.interceptors.exchange(exchange);\n // Call afterExecute lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.afterExecute) {\n await executeLifeCycle.afterExecute(exchange);\n }\n\n if (endpointReturnType === EndpointReturnType.EXCHANGE) {\n return exchange;\n }\n return await exchange.extractResult();\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// 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, RequestBodyType } 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 *\n * PATH, QUERY, and HEADER parameter types support plain objects (Record) which will be expanded\n * into multiple parameters with the object's key-value pairs.\n *\n * ATTRIBUTE parameter type supports primitive types, plain objects (Record), and Map objects.\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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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 * Attribute parameter that will be used as a single attribute in the request attributes.\n *\n * The attribute parameter allows passing a single key-value pair that will be added\n * to the request attributes object. This is useful for passing specific contextual\n * information that can be accessed by interceptors.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\n ATTRIBUTE = 'attribute',\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 * Different parameter types support different value types:\n * - PATH, QUERY, HEADER: Support primitive types and plain objects (Record).\n * Plain objects will be expanded into multiple parameters.\n * - BODY: Accepts any value to be sent as the request body.\n * - ATTRIBUTE: Supports primitive types, plain objects (Record), and Map objects.\n * Plain objects will be expanded into multiple attributes, and Map objects will\n * have their entries added to the attributes collection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, BODY, REQUEST, ATTRIBUTE)\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 * // With object expansion for PATH parameters\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@parameter(ParameterType.PATH) params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\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 * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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<\n BODY extends RequestBodyType = RequestBodyType,\n> extends FetchRequestInit<BODY>,\n PathCapable {}\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/**\n * Parameter decorator for adding a single attribute to the request attributes.\n *\n * This decorator allows you to pass a key-value pair as an attribute that can be accessed\n * by interceptors during the request lifecycle. If no name is provided, the parameter's\n * property name will be used as the attribute key.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes collection.\n *\n * @param name - Optional name for the attribute. If not provided, the parameter's property name will be used.\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // Using property name as attribute key\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\nexport function attribute(name: string = '') {\n return parameter(ParameterType.ATTRIBUTE, name);\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 combineURLs,\n Fetcher,\n type FetchExchangeInit,\n FetchRequestInit,\n getFetcher,\n JsonResultExtractor,\n mergeRecordToMap,\n mergeRequest,\n NamedCapable,\n type RequestHeaders,\n ResultExtractor,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n ParameterMetadata,\n ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\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);\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 /**\n * Resolves the result extractor for the request.\n *\n * Returns the result extractor specified in the endpoint metadata, or the API metadata,\n * or falls back to the default JsonResultExtractor if none is specified.\n *\n * @returns The result extractor function to use for processing responses\n */\n resolveResultExtractor(): ResultExtractor<any> {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n JsonResultExtractor\n );\n }\n\n /**\n * Resolves the attributes for the request.\n *\n * Merges attributes from API-level and endpoint-level metadata into a single Map.\n * API-level attributes are applied first, then endpoint-level attributes can override them.\n *\n * @returns A Map containing all resolved attributes for the request\n */\n resolveAttributes(): Map<string, any> {\n const resolvedAttributes = mergeRecordToMap(this.api.attributes);\n return mergeRecordToMap(this.endpoint.attributes, resolvedAttributes);\n }\n\n /**\n * Resolves the endpoint return type for the request.\n *\n * Returns the return type specified in the endpoint metadata, or the API metadata,\n * or falls back to EndpointReturnType.RESULT if none is specified.\n *\n * @returns The endpoint return type determining what the method should return\n */\n resolveEndpointReturnType(): EndpointReturnType {\n return (\n this.endpoint.returnType ||\n this.api.returnType ||\n EndpointReturnType.RESULT\n );\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 resolveExchangeInit(\n args: any[],\n ): Required<Pick<FetchExchangeInit, 'request' | 'attributes'>> {\n const pathParams: Record<string, any> = {\n ...this.api.urlParams?.path,\n ...this.endpoint.urlParams?.path,\n };\n const queryParams: Record<string, any> = {\n ...this.api.urlParams?.query,\n ...this.endpoint.urlParams?.query,\n };\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 const attributes: Map<string, any> = this.resolveAttributes();\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 case ParameterType.ATTRIBUTE:\n this.processAttributeParam(funParameter, value, attributes);\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 {\n request: mergedRequest,\n attributes,\n };\n }\n\n private processHttpParam(\n param: ParameterMetadata,\n value: any,\n params: Record<string, any>,\n ) {\n if (value === undefined || value === null) {\n return;\n }\n if (typeof value === 'object') {\n Object.entries(value).forEach(([key, value]) => {\n params[key] = value;\n });\n return;\n }\n const paramName = param.name || `param${param.index}`;\n params[paramName] = value;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n this.processHttpParam(param, value, path);\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n this.processHttpParam(param, value, query);\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n this.processHttpParam(param, value, headers);\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 if (!value) {\n return {};\n }\n\n const request = value as ParameterRequest;\n // 确保请求对象中的属性被正确保留\n return {\n ...request,\n headers: request.headers || {},\n urlParams: request.urlParams || { path: {}, query: {} },\n };\n }\n\n private processAttributeParam(\n param: ParameterMetadata,\n value: any,\n attributes: Map<string, any>,\n ) {\n if (typeof value === 'object' || value instanceof Map) {\n mergeRecordToMap(value, attributes);\n return;\n }\n if (param.name && value !== undefined) {\n attributes.set(param.name, value);\n }\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 type AttributesCapable,\n Fetcher,\n FetcherCapable,\n type RequestHeaders,\n type RequestHeadersCapable,\n type ResultExtractorCapable,\n type TimeoutCapable,\n UrlParamsCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnTypeCapable } from './endpointReturnTypeCapable';\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 AttributesCapable,\n EndpointReturnTypeCapable,\n UrlParamsCapable {\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 interface ApiMetadataCapable {\n /**\n * API metadata for the class.\n */\n readonly apiMetadata?: ApiMetadata;\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 * This internal function is called during class decoration to replace placeholder\n * method implementations with actual HTTP request execution logic. It creates\n * a RequestExecutor instance and assigns it to replace the original method.\n *\n * @param constructor - The class constructor being decorated\n * @param functionName - The name of the method to bind the executor to\n * @param apiMetadata - The API metadata for the class containing configuration\n * @internal This function is used internally during class decoration\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: FunctionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = async function (...args: unknown[]) {\n const requestExecutor: RequestExecutor = buildRequestExecutor(\n this,\n functionMetadata,\n );\n return await requestExecutor.execute(args);\n };\n}\n\n/**\n * Builds or retrieves a cached RequestExecutor for the given function metadata.\n *\n * This function implements a caching mechanism to ensure that each decorated method\n * gets a consistent RequestExecutor instance. If an executor already exists for the\n * function, it returns the cached instance; otherwise, it creates a new one.\n *\n * The function merges API metadata from the target instance with the default metadata\n * to allow runtime customization of API behavior.\n *\n * @param target - The target object instance that contains the method\n * @param defaultFunctionMetadata - The function metadata containing endpoint configuration\n * @returns A RequestExecutor instance for executing the HTTP request\n */\nexport function buildRequestExecutor(\n target: any,\n defaultFunctionMetadata: FunctionMetadata,\n): RequestExecutor {\n let requestExecutors: Map<string, RequestExecutor> =\n target['requestExecutors'];\n if (!requestExecutors) {\n requestExecutors = new Map<string, RequestExecutor>();\n target['requestExecutors'] = requestExecutors;\n }\n let requestExecutor = requestExecutors.get(defaultFunctionMetadata.name);\n if (requestExecutor) {\n return requestExecutor;\n }\n const targetApiMetadata: ApiMetadata = target['apiMetadata'];\n const mergedApiMetadata: ApiMetadata = {\n ...defaultFunctionMetadata.api,\n ...targetApiMetadata,\n };\n requestExecutor = new RequestExecutor(\n target,\n new FunctionMetadata(\n defaultFunctionMetadata.name,\n mergedApiMetadata,\n defaultFunctionMetadata.endpoint,\n defaultFunctionMetadata.parameters,\n ),\n );\n requestExecutors.set(defaultFunctionMetadata.name, requestExecutor);\n return requestExecutor;\n}\n\n/**\n * Class decorator for defining API configurations.\n *\n * The @api decorator configures a class as an API client with shared settings\n * like base URL, default headers, timeout, and fetcher instance. All methods\n * in the decorated class that use HTTP method decorators (@get, @post, etc.)\n * will inherit these settings.\n *\n * @param basePath - Base path to prepend to all endpoint paths in the class\n * @param metadata - Additional API configuration including headers, timeout, fetcher, etc.\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1', {\n * headers: { 'Authorization': 'Bearer token' },\n * timeout: 5000,\n * fetcher: 'myFetcher'\n * })\n * class UserService {\n * @get('/users')\n * getUsers(): Promise<User[]> {\n * throw autoGeneratedError();\n * }\n *\n * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\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 bindAllExecutors(constructor, apiMetadata);\n return constructor;\n };\n}\n\nfunction bindAllExecutors<T extends new (...args: any[]) => any>(\n constructor: T,\n apiMetadata: ApiMetadata,\n) {\n const boundProto = new Set();\n let proto = constructor.prototype;\n while (proto && proto !== Object.prototype) {\n if (boundProto.has(proto)) {\n proto = Object.getPrototypeOf(proto);\n continue;\n }\n boundProto.add(proto);\n Object.getOwnPropertyNames(proto).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n proto = Object.getPrototypeOf(proto);\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","EndpointReturnType","DECORATOR_TARGET_ATTRIBUTE_KEY","DECORATOR_METADATA_ATTRIBUTE_KEY","RequestExecutor","args","fetcher","exchangeInit","resultExtractor","endpointReturnType","exchange","executeLifeCycle","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","attribute","FunctionMetadata","api","parameters","getFetcher","parameterPath","basePath","endpointPath","combineURLs","JsonResultExtractor","resolvedAttributes","mergeRecordToMap","pathParams","queryParams","headers","signal","abortController","parameterRequest","attributes","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","params","key","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","buildRequestExecutor","defaultFunctionMetadata","requestExecutors","requestExecutor","targetApiMetadata","mergedApiMetadata","bindAllExecutors","boundProto","proto","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/endpointDecorator.ts","../src/endpointReturnTypeCapable.ts","../src/requestExecutor.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/functionMetadata.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod, type ResultExtractorCapable } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\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\n/**\n * Convenience decorator for GET HTTP requests.\n *\n * Creates an endpoint decorator configured for GET requests. GET requests\n * are used to retrieve data from a server without modifying it.\n *\n * @param path - The endpoint path (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 * @get('/users/{id}')\n * getUser(@path('id') id: string): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\n/**\n * Convenience decorator for POST HTTP requests.\n *\n * Creates an endpoint decorator configured for POST requests. POST requests\n * are used to create new resources on the server.\n *\n * @param path - The endpoint path (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 * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\n/**\n * Convenience decorator for PUT HTTP requests.\n *\n * Creates an endpoint decorator configured for PUT requests. PUT requests\n * are used to update existing resources on the server.\n *\n * @param path - The endpoint path (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 * @put('/users/{id}')\n * updateUser(@path('id') id: string, @body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\n/**\n * Convenience decorator for DELETE HTTP requests.\n *\n * Creates an endpoint decorator configured for DELETE requests. DELETE requests\n * are used to remove resources from the server.\n *\n * @param path - The endpoint path (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 * @del('/users/{id}')\n * deleteUser(@path('id') id: string): Promise<void> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\n/**\n * Convenience decorator for PATCH HTTP requests.\n *\n * Creates an endpoint decorator configured for PATCH requests. PATCH requests\n * are used to apply partial updates to existing resources.\n *\n * @param path - The endpoint path (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 * @patch('/users/{id}')\n * updateUserPartial(@path('id') id: string, @body() updates: Partial<User>): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\n/**\n * Convenience decorator for HEAD HTTP requests.\n *\n * Creates an endpoint decorator configured for HEAD requests. HEAD requests\n * are used to retrieve headers only, without the response body.\n *\n * @param path - The endpoint path (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 * @head('/users/{id}')\n * checkUserExists(@path('id') id: string): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\n/**\n * Convenience decorator for OPTIONS HTTP requests.\n *\n * Creates an endpoint decorator configured for OPTIONS requests. OPTIONS requests\n * are used to describe the communication options for the target resource.\n *\n * @param path - The endpoint path (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 * @options('/users')\n * getUserOptions(): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\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\nexport enum EndpointReturnType {\n EXCHANGE = 'Exchange',\n RESULT = 'Result',\n}\n\nexport interface EndpointReturnTypeCapable {\n returnType?: EndpointReturnType;\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 { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\nimport { ExecuteLifeCycle } from './executeLifeCycle';\n\nexport const DECORATOR_TARGET_ATTRIBUTE_KEY = '__decorator_target__';\nexport const DECORATOR_METADATA_ATTRIBUTE_KEY = '__decorator_metadata__';\n\n/**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\nexport class RequestExecutor {\n /**\n * Creates a new RequestExecutor instance.\n * @param target - The target object that the method is called on.\n * This can contain a custom fetcher instance in its 'fetcher' property.\n * @param metadata - The function metadata containing all request information\n */\n constructor(\n private readonly target: any,\n private readonly metadata: FunctionMetadata,\n ) {}\n\n /**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\n async execute(args: any[]): Promise<any> {\n const fetcher = this.metadata.fetcher;\n const exchangeInit = this.metadata.resolveExchangeInit(args);\n exchangeInit.attributes.set(DECORATOR_TARGET_ATTRIBUTE_KEY, this.target);\n exchangeInit.attributes.set(\n DECORATOR_METADATA_ATTRIBUTE_KEY,\n this.metadata,\n );\n const resultExtractor = this.metadata.resolveResultExtractor();\n const endpointReturnType = this.metadata.resolveEndpointReturnType();\n\n const exchange = fetcher.resolveExchange(exchangeInit.request, {\n resultExtractor: resultExtractor,\n attributes: exchangeInit.attributes,\n });\n const executeLifeCycle = this.target as ExecuteLifeCycle;\n // Call lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.beforeExecute) {\n await executeLifeCycle.beforeExecute(exchange);\n }\n // Process through interceptor chain\n await fetcher.interceptors.exchange(exchange);\n // Call afterExecute lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.afterExecute) {\n await executeLifeCycle.afterExecute(exchange);\n }\n\n if (endpointReturnType === EndpointReturnType.EXCHANGE) {\n return exchange;\n }\n return await exchange.extractResult();\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// 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, RequestBodyType } 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 *\n * PATH, QUERY, and HEADER parameter types support plain objects (Record) which will be expanded\n * into multiple parameters with the object's key-value pairs.\n *\n * ATTRIBUTE parameter type supports primitive types, plain objects (Record), and Map objects.\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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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 * Attribute parameter that will be used as a single attribute in the request attributes.\n *\n * The attribute parameter allows passing a single key-value pair that will be added\n * to the request attributes object. This is useful for passing specific contextual\n * information that can be accessed by interceptors.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\n ATTRIBUTE = 'attribute',\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 * Different parameter types support different value types:\n * - PATH, QUERY, HEADER: Support primitive types and plain objects (Record).\n * Plain objects will be expanded into multiple parameters.\n * - BODY: Accepts any value to be sent as the request body.\n * - ATTRIBUTE: Supports primitive types, plain objects (Record), and Map objects.\n * Plain objects will be expanded into multiple attributes, and Map objects will\n * have their entries added to the attributes collection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, BODY, REQUEST, ATTRIBUTE)\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 * // With object expansion for PATH parameters\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@parameter(ParameterType.PATH) params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\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 * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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<\n BODY extends RequestBodyType = RequestBodyType,\n> extends FetchRequestInit<BODY>,\n PathCapable {}\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/**\n * Parameter decorator for adding a single attribute to the request attributes.\n *\n * This decorator allows you to pass a key-value pair as an attribute that can be accessed\n * by interceptors during the request lifecycle. If no name is provided, the parameter's\n * property name will be used as the attribute key.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes collection.\n *\n * @param name - Optional name for the attribute. If not provided, the parameter's property name will be used.\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // Using property name as attribute key\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\nexport function attribute(name: string = '') {\n return parameter(ParameterType.ATTRIBUTE, name);\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 combineURLs,\n Fetcher,\n type FetchExchangeInit,\n FetchRequestInit,\n getFetcher,\n JsonResultExtractor,\n mergeRecordToMap,\n mergeRequest,\n NamedCapable,\n type RequestHeaders,\n ResultExtractor,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n ParameterMetadata,\n ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\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);\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 /**\n * Resolves the result extractor for the request.\n *\n * Returns the result extractor specified in the endpoint metadata, or the API metadata,\n * or falls back to the default JsonResultExtractor if none is specified.\n *\n * @returns The result extractor function to use for processing responses\n */\n resolveResultExtractor(): ResultExtractor<any> {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n JsonResultExtractor\n );\n }\n\n /**\n * Resolves the attributes for the request.\n *\n * Merges attributes from API-level and endpoint-level metadata into a single Map.\n * API-level attributes are applied first, then endpoint-level attributes can override them.\n *\n * @returns A Map containing all resolved attributes for the request\n */\n resolveAttributes(): Map<string, any> {\n const resolvedAttributes = mergeRecordToMap(this.api.attributes);\n return mergeRecordToMap(this.endpoint.attributes, resolvedAttributes);\n }\n\n /**\n * Resolves the endpoint return type for the request.\n *\n * Returns the return type specified in the endpoint metadata, or the API metadata,\n * or falls back to EndpointReturnType.RESULT if none is specified.\n *\n * @returns The endpoint return type determining what the method should return\n */\n resolveEndpointReturnType(): EndpointReturnType {\n return (\n this.endpoint.returnType ||\n this.api.returnType ||\n EndpointReturnType.RESULT\n );\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 resolveExchangeInit(\n args: any[],\n ): Required<Pick<FetchExchangeInit, 'request' | 'attributes'>> {\n const pathParams: Record<string, any> = {\n ...this.api.urlParams?.path,\n ...this.endpoint.urlParams?.path,\n };\n const queryParams: Record<string, any> = {\n ...this.api.urlParams?.query,\n ...this.endpoint.urlParams?.query,\n };\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 const attributes: Map<string, any> = this.resolveAttributes();\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 case ParameterType.ATTRIBUTE:\n this.processAttributeParam(funParameter, value, attributes);\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 {\n request: mergedRequest,\n attributes,\n };\n }\n\n private processHttpParam(\n param: ParameterMetadata,\n value: any,\n params: Record<string, any>,\n ) {\n if (value === undefined || value === null) {\n return;\n }\n if (typeof value === 'object') {\n Object.entries(value).forEach(([key, value]) => {\n params[key] = value;\n });\n return;\n }\n const paramName = param.name || `param${param.index}`;\n params[paramName] = value;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n this.processHttpParam(param, value, path);\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n this.processHttpParam(param, value, query);\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n this.processHttpParam(param, value, headers);\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 if (!value) {\n return {};\n }\n\n const request = value as ParameterRequest;\n // 确保请求对象中的属性被正确保留\n return {\n ...request,\n headers: request.headers || {},\n urlParams: request.urlParams || { path: {}, query: {} },\n };\n }\n\n private processAttributeParam(\n param: ParameterMetadata,\n value: any,\n attributes: Map<string, any>,\n ) {\n if (typeof value === 'object' || value instanceof Map) {\n mergeRecordToMap(value, attributes);\n return;\n }\n if (param.name && value !== undefined) {\n attributes.set(param.name, value);\n }\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 type AttributesCapable,\n Fetcher,\n FetcherCapable,\n type RequestHeaders,\n type RequestHeadersCapable,\n type ResultExtractorCapable,\n type TimeoutCapable,\n UrlParamsCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnTypeCapable } from './endpointReturnTypeCapable';\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 AttributesCapable,\n EndpointReturnTypeCapable,\n UrlParamsCapable {\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 interface ApiMetadataCapable {\n /**\n * API metadata for the class.\n */\n readonly apiMetadata?: ApiMetadata;\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 * This internal function is called during class decoration to replace placeholder\n * method implementations with actual HTTP request execution logic. It creates\n * a RequestExecutor instance and assigns it to replace the original method.\n *\n * @param constructor - The class constructor being decorated\n * @param functionName - The name of the method to bind the executor to\n * @param apiMetadata - The API metadata for the class containing configuration\n * @internal This function is used internally during class decoration\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: FunctionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = async function (...args: unknown[]) {\n const requestExecutor: RequestExecutor = buildRequestExecutor(\n this,\n functionMetadata,\n );\n return await requestExecutor.execute(args);\n };\n}\n\n/**\n * Builds or retrieves a cached RequestExecutor for the given function metadata.\n *\n * This function implements a caching mechanism to ensure that each decorated method\n * gets a consistent RequestExecutor instance. If an executor already exists for the\n * function, it returns the cached instance; otherwise, it creates a new one.\n *\n * The function merges API metadata from the target instance with the default metadata\n * to allow runtime customization of API behavior.\n *\n * @param target - The target object instance that contains the method\n * @param defaultFunctionMetadata - The function metadata containing endpoint configuration\n * @returns A RequestExecutor instance for executing the HTTP request\n */\nexport function buildRequestExecutor(\n target: any,\n defaultFunctionMetadata: FunctionMetadata,\n): RequestExecutor {\n let requestExecutors: Map<string, RequestExecutor> =\n target['requestExecutors'];\n if (!requestExecutors) {\n requestExecutors = new Map<string, RequestExecutor>();\n target['requestExecutors'] = requestExecutors;\n }\n let requestExecutor = requestExecutors.get(defaultFunctionMetadata.name);\n if (requestExecutor) {\n return requestExecutor;\n }\n const targetApiMetadata: ApiMetadata = target['apiMetadata'];\n const mergedApiMetadata: ApiMetadata = {\n ...defaultFunctionMetadata.api,\n ...targetApiMetadata,\n };\n requestExecutor = new RequestExecutor(\n target,\n new FunctionMetadata(\n defaultFunctionMetadata.name,\n mergedApiMetadata,\n defaultFunctionMetadata.endpoint,\n defaultFunctionMetadata.parameters,\n ),\n );\n requestExecutors.set(defaultFunctionMetadata.name, requestExecutor);\n return requestExecutor;\n}\n\n/**\n * Class decorator for defining API configurations.\n *\n * The @api decorator configures a class as an API client with shared settings\n * like base URL, default headers, timeout, and fetcher instance. All methods\n * in the decorated class that use HTTP method decorators (@get, @post, etc.)\n * will inherit these settings.\n *\n * @param basePath - Base path to prepend to all endpoint paths in the class\n * @param metadata - Additional API configuration including headers, timeout, fetcher, etc.\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1', {\n * headers: { 'Authorization': 'Bearer token' },\n * timeout: 5000,\n * fetcher: 'myFetcher'\n * })\n * class UserService {\n * @get('/users')\n * getUsers(): Promise<User[]> {\n * throw autoGeneratedError();\n * }\n *\n * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\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 bindAllExecutors(constructor, apiMetadata);\n return constructor;\n };\n}\n\nfunction bindAllExecutors<T extends new (...args: any[]) => any>(\n constructor: T,\n apiMetadata: ApiMetadata,\n) {\n const boundProto = new Set();\n let proto = constructor.prototype;\n while (proto && proto !== Object.prototype) {\n if (boundProto.has(proto)) {\n proto = Object.getPrototypeOf(proto);\n continue;\n }\n boundProto.add(proto);\n Object.getOwnPropertyNames(proto).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n proto = Object.getPrototypeOf(proto);\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","EndpointReturnType","DECORATOR_TARGET_ATTRIBUTE_KEY","DECORATOR_METADATA_ATTRIBUTE_KEY","RequestExecutor","args","fetcher","exchangeInit","resultExtractor","endpointReturnType","exchange","executeLifeCycle","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","attribute","FunctionMetadata","api","parameters","getFetcher","parameterPath","basePath","endpointPath","combineURLs","JsonResultExtractor","resolvedAttributes","mergeRecordToMap","pathParams","queryParams","headers","signal","abortController","parameterRequest","attributes","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","params","key","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","buildRequestExecutor","defaultFunctionMetadata","requestExecutors","requestExecutor","targetApiMetadata","mergedApiMetadata","bindAllExecutors","boundProto","proto","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/endpointDecorator.ts","../src/endpointReturnTypeCapable.ts","../src/requestExecutor.ts","../src/reflection.ts","../src/parameterDecorator.ts","../src/functionMetadata.ts","../src/apiDecorator.ts","../src/generated.ts"],"sourcesContent":["import { HttpMethod, type ResultExtractorCapable } from '@ahoo-wang/fetcher';\nimport { type ApiMetadata } from './apiDecorator';\nimport 'reflect-metadata';\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\n/**\n * Convenience decorator for GET HTTP requests.\n *\n * Creates an endpoint decorator configured for GET requests. GET requests\n * are used to retrieve data from a server without modifying it.\n *\n * @param path - The endpoint path (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 * @get('/users/{id}')\n * getUser(@path('id') id: string): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function get(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.GET, path, metadata);\n}\n\n/**\n * Convenience decorator for POST HTTP requests.\n *\n * Creates an endpoint decorator configured for POST requests. POST requests\n * are used to create new resources on the server.\n *\n * @param path - The endpoint path (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 * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function post(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.POST, path, metadata);\n}\n\n/**\n * Convenience decorator for PUT HTTP requests.\n *\n * Creates an endpoint decorator configured for PUT requests. PUT requests\n * are used to update existing resources on the server.\n *\n * @param path - The endpoint path (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 * @put('/users/{id}')\n * updateUser(@path('id') id: string, @body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function put(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.PUT, path, metadata);\n}\n\n/**\n * Convenience decorator for DELETE HTTP requests.\n *\n * Creates an endpoint decorator configured for DELETE requests. DELETE requests\n * are used to remove resources from the server.\n *\n * @param path - The endpoint path (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 * @del('/users/{id}')\n * deleteUser(@path('id') id: string): Promise<void> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function del(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.DELETE, path, metadata);\n}\n\n/**\n * Convenience decorator for PATCH HTTP requests.\n *\n * Creates an endpoint decorator configured for PATCH requests. PATCH requests\n * are used to apply partial updates to existing resources.\n *\n * @param path - The endpoint path (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 * @patch('/users/{id}')\n * updateUserPartial(@path('id') id: string, @body() updates: Partial<User>): Promise<User> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function patch(\n path: string = '',\n metadata: MethodEndpointMetadata = {},\n) {\n return endpoint(HttpMethod.PATCH, path, metadata);\n}\n\n/**\n * Convenience decorator for HEAD HTTP requests.\n *\n * Creates an endpoint decorator configured for HEAD requests. HEAD requests\n * are used to retrieve headers only, without the response body.\n *\n * @param path - The endpoint path (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 * @head('/users/{id}')\n * checkUserExists(@path('id') id: string): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\n * ```\n */\nexport function head(path: string = '', metadata: MethodEndpointMetadata = {}) {\n return endpoint(HttpMethod.HEAD, path, metadata);\n}\n\n/**\n * Convenience decorator for OPTIONS HTTP requests.\n *\n * Creates an endpoint decorator configured for OPTIONS requests. OPTIONS requests\n * are used to describe the communication options for the target resource.\n *\n * @param path - The endpoint path (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 * @options('/users')\n * getUserOptions(): Promise<Response> {\n * throw autoGeneratedError();\n * }\n * }\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\nexport enum EndpointReturnType {\n EXCHANGE = 'Exchange',\n RESULT = 'Result',\n}\n\nexport interface EndpointReturnTypeCapable {\n returnType?: EndpointReturnType;\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 { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\nimport { ExecuteLifeCycle } from './executeLifeCycle';\n\nexport const DECORATOR_TARGET_ATTRIBUTE_KEY = '__decorator_target__';\nexport const DECORATOR_METADATA_ATTRIBUTE_KEY = '__decorator_metadata__';\n\n/**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\nexport class RequestExecutor {\n /**\n * Creates a new RequestExecutor instance.\n * @param target - The target object that the method is called on.\n * This can contain a custom fetcher instance in its 'fetcher' property.\n * @param metadata - The function metadata containing all request information\n */\n constructor(\n private readonly target: any,\n private readonly metadata: FunctionMetadata,\n ) {}\n\n /**\n * Executes the HTTP request based on the decorated method metadata.\n *\n * This method orchestrates the complete HTTP request lifecycle:\n * 1. Resolves request configuration from metadata and runtime arguments\n * 2. Sets up request attributes for interceptor access\n * 3. Creates the FetchExchange object\n * 4. Executes lifecycle hooks (beforeExecute)\n * 5. Processes the request through the interceptor chain\n * 6. Executes lifecycle hooks (afterExecute)\n * 7. Extracts and returns the result based on endpoint return type\n *\n * @param args - The runtime arguments passed to the decorated method.\n * These are mapped to request components (path variables, query params, body, etc.)\n * based on parameter decorators applied to the method.\n * @returns A Promise that resolves to the extracted result. The return type depends on:\n * - EndpointReturnType.EXCHANGE: Returns the FetchExchange object directly\n * - Otherwise: Returns the result of exchange.extractResult() (e.g., Response, parsed JSON)\n * @throws Error if the request fails during execution or if lifecycle hooks/interceptors throw\n *\n * @example\n * ```typescript\n * // Given a decorated service method:\n * class UserService {\n * @get('/users/{id}')\n * getUser(@path('id') id: number): Promise<User> {\n * // This method body is replaced by the executor at runtime\n * }\n * }\n *\n * // When calling:\n * const userService = new UserService();\n * const user = await userService.getUser(123);\n *\n * // The execute method will:\n * // 1. Resolve the path to '/users/123'\n * // 2. Create a GET request\n * // 3. Execute the request using the configured fetcher\n * // 4. Extract and return the parsed User object\n * ```\n */\n async execute(args: any[]): Promise<any> {\n const fetcher = this.metadata.fetcher;\n const exchangeInit = this.metadata.resolveExchangeInit(args);\n exchangeInit.attributes.set(DECORATOR_TARGET_ATTRIBUTE_KEY, this.target);\n exchangeInit.attributes.set(\n DECORATOR_METADATA_ATTRIBUTE_KEY,\n this.metadata,\n );\n const resultExtractor = this.metadata.resolveResultExtractor();\n const endpointReturnType = this.metadata.resolveEndpointReturnType();\n\n const exchange = fetcher.resolveExchange(exchangeInit.request, {\n resultExtractor: resultExtractor,\n attributes: exchangeInit.attributes,\n });\n const executeLifeCycle = this.target as ExecuteLifeCycle;\n // Call lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.beforeExecute) {\n await executeLifeCycle.beforeExecute(exchange);\n }\n // Process through interceptor chain\n await fetcher.interceptors.exchange(exchange);\n // Call afterExecute lifecycle hook if target implements ExecuteLifeCycle\n if (executeLifeCycle.afterExecute) {\n await executeLifeCycle.afterExecute(exchange);\n }\n\n if (endpointReturnType === EndpointReturnType.EXCHANGE) {\n return exchange;\n }\n return await exchange.extractResult();\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// 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, RequestBodyType } 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 *\n * PATH, QUERY, and HEADER parameter types support plain objects (Record) which will be expanded\n * into multiple parameters with the object's key-value pairs.\n *\n * ATTRIBUTE parameter type supports primitive types, plain objects (Record), and Map objects.\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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@query('limit') limit: number): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\n *\n * @example\n * ```typescript\n * @get('/users')\n * getUsers(@header('Authorization') token: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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 * Attribute parameter that will be used as a single attribute in the request attributes.\n *\n * The attribute parameter allows passing a single key-value pair that will be added\n * to the request attributes object. This is useful for passing specific contextual\n * information that can be accessed by interceptors.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes.\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\n ATTRIBUTE = 'attribute',\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 * Different parameter types support different value types:\n * - PATH, QUERY, HEADER: Support primitive types and plain objects (Record).\n * Plain objects will be expanded into multiple parameters.\n * - BODY: Accepts any value to be sent as the request body.\n * - ATTRIBUTE: Supports primitive types, plain objects (Record), and Map objects.\n * Plain objects will be expanded into multiple attributes, and Map objects will\n * have their entries added to the attributes collection.\n *\n * @param type - The type of parameter (PATH, QUERY, HEADER, BODY, REQUEST, ATTRIBUTE)\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 * // With object expansion for PATH parameters\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@parameter(ParameterType.PATH) params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple path parameters.\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 * // With object expansion\n * @get('/users/{id}/posts/{postId}')\n * getUserPost(@path() params: { id: string, postId: 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple query parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@query() filters: { limit: number, offset: number, sort: string }): 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 * Supports both primitive values and plain objects. When a plain object is passed,\n * its key-value pairs will be expanded into multiple header parameters.\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 * // With object expansion\n * @get('/users')\n * getUsers(@header() headers: { 'X-API-Key': string, 'X-Version': 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<\n BODY extends RequestBodyType = RequestBodyType,\n> extends FetchRequestInit<BODY>,\n PathCapable {}\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/**\n * Parameter decorator for adding a single attribute to the request attributes.\n *\n * This decorator allows you to pass a key-value pair as an attribute that can be accessed\n * by interceptors during the request lifecycle. If no name is provided, the parameter's\n * property name will be used as the attribute key.\n *\n * Supports primitive types, plain objects (Record), and Map objects.\n * When a plain object is passed, its key-value pairs will be expanded into multiple attributes.\n * When a Map is passed, its entries will be added to the attributes collection.\n *\n * @param name - Optional name for the attribute. If not provided, the parameter's property name will be used.\n * @returns A parameter decorator function\n *\n * @example\n * ```typescript\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute('userId') userId: string): Promise<Response>\n *\n * // Using property name as attribute key\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() userId: string): Promise<Response>\n *\n * // With object expansion\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() metadata: { userId: string, timestamp: number }): Promise<Response>\n *\n * // With Map\n * @get('/users/{id}')\n * getUser(@path('id') id: string, @attribute() attributes: Map<string, any>): Promise<Response>\n * ```\n */\nexport function attribute(name: string = '') {\n return parameter(ParameterType.ATTRIBUTE, name);\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 combineURLs,\n Fetcher,\n type FetchExchangeInit,\n FetchRequestInit,\n getFetcher,\n JsonResultExtractor,\n mergeRecordToMap,\n mergeRequest,\n NamedCapable,\n type RequestHeaders,\n ResultExtractor,\n type UrlParams,\n} from '@ahoo-wang/fetcher';\nimport { ApiMetadata } from './apiDecorator';\nimport { EndpointMetadata } from './endpointDecorator';\nimport {\n ParameterMetadata,\n ParameterRequest,\n ParameterType,\n} from './parameterDecorator';\nimport { EndpointReturnType } from './endpointReturnTypeCapable';\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);\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 /**\n * Resolves the result extractor for the request.\n *\n * Returns the result extractor specified in the endpoint metadata, or the API metadata,\n * or falls back to the default JsonResultExtractor if none is specified.\n *\n * @returns The result extractor function to use for processing responses\n */\n resolveResultExtractor(): ResultExtractor<any> {\n return (\n this.endpoint.resultExtractor ||\n this.api.resultExtractor ||\n JsonResultExtractor\n );\n }\n\n /**\n * Resolves the attributes for the request.\n *\n * Merges attributes from API-level and endpoint-level metadata into a single Map.\n * API-level attributes are applied first, then endpoint-level attributes can override them.\n *\n * @returns A Map containing all resolved attributes for the request\n */\n resolveAttributes(): Map<string, any> {\n const resolvedAttributes = mergeRecordToMap(this.api.attributes);\n return mergeRecordToMap(this.endpoint.attributes, resolvedAttributes);\n }\n\n /**\n * Resolves the endpoint return type for the request.\n *\n * Returns the return type specified in the endpoint metadata, or the API metadata,\n * or falls back to EndpointReturnType.RESULT if none is specified.\n *\n * @returns The endpoint return type determining what the method should return\n */\n resolveEndpointReturnType(): EndpointReturnType {\n return (\n this.endpoint.returnType ||\n this.api.returnType ||\n EndpointReturnType.RESULT\n );\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 resolveExchangeInit(\n args: any[],\n ): Required<Pick<FetchExchangeInit, 'request' | 'attributes'>> {\n const pathParams: Record<string, any> = {\n ...this.api.urlParams?.path,\n ...this.endpoint.urlParams?.path,\n };\n const queryParams: Record<string, any> = {\n ...this.api.urlParams?.query,\n ...this.endpoint.urlParams?.query,\n };\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 const attributes: Map<string, any> = this.resolveAttributes();\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 case ParameterType.ATTRIBUTE:\n this.processAttributeParam(funParameter, value, attributes);\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 {\n request: mergedRequest,\n attributes,\n };\n }\n\n private processHttpParam(\n param: ParameterMetadata,\n value: any,\n params: Record<string, any>,\n ) {\n if (value === undefined || value === null) {\n return;\n }\n if (typeof value === 'object') {\n Object.entries(value).forEach(([key, value]) => {\n params[key] = value;\n });\n return;\n }\n const paramName = param.name || `param${param.index}`;\n params[paramName] = value;\n }\n\n private processPathParam(\n param: ParameterMetadata,\n value: any,\n path: Record<string, any>,\n ) {\n this.processHttpParam(param, value, path);\n }\n\n private processQueryParam(\n param: ParameterMetadata,\n value: any,\n query: Record<string, any>,\n ) {\n this.processHttpParam(param, value, query);\n }\n\n private processHeaderParam(\n param: ParameterMetadata,\n value: any,\n headers: RequestHeaders,\n ) {\n this.processHttpParam(param, value, headers);\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 if (!value) {\n return {};\n }\n\n const request = value as ParameterRequest;\n // 确保请求对象中的属性被正确保留\n return {\n ...request,\n headers: request.headers || {},\n urlParams: request.urlParams || { path: {}, query: {} },\n };\n }\n\n private processAttributeParam(\n param: ParameterMetadata,\n value: any,\n attributes: Map<string, any>,\n ) {\n if (typeof value === 'object' || value instanceof Map) {\n mergeRecordToMap(value, attributes);\n return;\n }\n if (param.name && value !== undefined) {\n attributes.set(param.name, value);\n }\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 type AttributesCapable,\n Fetcher,\n FetcherCapable,\n type RequestHeaders,\n type RequestHeadersCapable,\n type ResultExtractorCapable,\n type TimeoutCapable,\n UrlParamsCapable,\n} from '@ahoo-wang/fetcher';\nimport { ENDPOINT_METADATA_KEY } from './endpointDecorator';\nimport { RequestExecutor } from './requestExecutor';\nimport { PARAMETER_METADATA_KEY } from './parameterDecorator';\nimport 'reflect-metadata';\nimport { FunctionMetadata } from './functionMetadata';\nimport { EndpointReturnTypeCapable } from './endpointReturnTypeCapable';\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 AttributesCapable,\n EndpointReturnTypeCapable,\n UrlParamsCapable {\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 interface ApiMetadataCapable {\n /**\n * API metadata for the class.\n */\n readonly apiMetadata?: ApiMetadata;\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 * This internal function is called during class decoration to replace placeholder\n * method implementations with actual HTTP request execution logic. It creates\n * a RequestExecutor instance and assigns it to replace the original method.\n *\n * @param constructor - The class constructor being decorated\n * @param functionName - The name of the method to bind the executor to\n * @param apiMetadata - The API metadata for the class containing configuration\n * @internal This function is used internally during class decoration\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: FunctionMetadata = new FunctionMetadata(\n functionName,\n apiMetadata,\n endpointMetadata,\n parameterMetadata,\n );\n\n // Create request executor\n\n // Replace method with actual implementation\n constructor.prototype[functionName] = async function (...args: unknown[]) {\n const requestExecutor: RequestExecutor = buildRequestExecutor(\n this,\n functionMetadata,\n );\n return await requestExecutor.execute(args);\n };\n}\n\n/**\n * Builds or retrieves a cached RequestExecutor for the given function metadata.\n *\n * This function implements a caching mechanism to ensure that each decorated method\n * gets a consistent RequestExecutor instance. If an executor already exists for the\n * function, it returns the cached instance; otherwise, it creates a new one.\n *\n * The function merges API metadata from the target instance with the default metadata\n * to allow runtime customization of API behavior.\n *\n * @param target - The target object instance that contains the method\n * @param defaultFunctionMetadata - The function metadata containing endpoint configuration\n * @returns A RequestExecutor instance for executing the HTTP request\n */\nexport function buildRequestExecutor(\n target: any,\n defaultFunctionMetadata: FunctionMetadata,\n): RequestExecutor {\n let requestExecutors: Map<string, RequestExecutor> =\n target['requestExecutors'];\n if (!requestExecutors) {\n requestExecutors = new Map<string, RequestExecutor>();\n target['requestExecutors'] = requestExecutors;\n }\n let requestExecutor = requestExecutors.get(defaultFunctionMetadata.name);\n if (requestExecutor) {\n return requestExecutor;\n }\n const targetApiMetadata: ApiMetadata = target['apiMetadata'];\n const mergedApiMetadata: ApiMetadata = {\n ...defaultFunctionMetadata.api,\n ...targetApiMetadata,\n };\n requestExecutor = new RequestExecutor(\n target,\n new FunctionMetadata(\n defaultFunctionMetadata.name,\n mergedApiMetadata,\n defaultFunctionMetadata.endpoint,\n defaultFunctionMetadata.parameters,\n ),\n );\n requestExecutors.set(defaultFunctionMetadata.name, requestExecutor);\n return requestExecutor;\n}\n\n/**\n * Class decorator for defining API configurations.\n *\n * The @api decorator configures a class as an API client with shared settings\n * like base URL, default headers, timeout, and fetcher instance. All methods\n * in the decorated class that use HTTP method decorators (@get, @post, etc.)\n * will inherit these settings.\n *\n * @param basePath - Base path to prepend to all endpoint paths in the class\n * @param metadata - Additional API configuration including headers, timeout, fetcher, etc.\n * @returns A class decorator function\n *\n * @example\n * ```typescript\n * @api('/api/v1', {\n * headers: { 'Authorization': 'Bearer token' },\n * timeout: 5000,\n * fetcher: 'myFetcher'\n * })\n * class UserService {\n * @get('/users')\n * getUsers(): Promise<User[]> {\n * throw autoGeneratedError();\n * }\n *\n * @post('/users')\n * createUser(@body() user: User): Promise<User> {\n * throw autoGeneratedError();\n * }\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 bindAllExecutors(constructor, apiMetadata);\n return constructor;\n };\n}\n\nfunction bindAllExecutors<T extends new (...args: any[]) => any>(\n constructor: T,\n apiMetadata: ApiMetadata,\n) {\n const boundProto = new Set();\n let proto = constructor.prototype;\n while (proto && proto !== Object.prototype) {\n if (boundProto.has(proto)) {\n proto = Object.getPrototypeOf(proto);\n continue;\n }\n boundProto.add(proto);\n Object.getOwnPropertyNames(proto).forEach(functionName => {\n bindExecutor(constructor, functionName, apiMetadata);\n });\n proto = Object.getPrototypeOf(proto);\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","EndpointReturnType","DECORATOR_TARGET_ATTRIBUTE_KEY","DECORATOR_METADATA_ATTRIBUTE_KEY","RequestExecutor","args","fetcher","exchangeInit","resultExtractor","endpointReturnType","exchange","executeLifeCycle","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","attribute","FunctionMetadata","api","parameters","getFetcher","parameterPath","basePath","endpointPath","combineURLs","JsonResultExtractor","resolvedAttributes","mergeRecordToMap","pathParams","queryParams","headers","signal","abortController","parameterRequest","attributes","value","index","funParameter","urlParams","endpointRequest","mergedRequest","mergeRequest","params","key","API_METADATA_KEY","bindExecutor","constructor","functionName","apiMetadata","endpointFunction","functionMetadata","buildRequestExecutor","defaultFunctionMetadata","requestExecutors","requestExecutor","targetApiMetadata","mergedApiMetadata","bindAllExecutors","boundProto","proto","AutoGenerated","autoGeneratedError","_ignored"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher-decorator",
3
- "version": "3.8.5",
3
+ "version": "3.8.8",
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",