@longzai-intelligence-transport/http-core 0.1.0 → 0.1.1

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.d.ts CHANGED
@@ -430,18 +430,48 @@ type RequestConfig = {
430
430
  withCsrf?: boolean;
431
431
  };
432
432
  /**
433
- * 路由定义类型
433
+ * 流式响应元数据
434
434
  *
435
- * 描述一个 API 路由的完整契约,包括方法、路径、参数、请求体和响应
435
+ * 描述二进制流响应(文件下载、图片返回等)的附加信息,供 OpenAPI 文档生成、
436
+ * 响应头设置和客户端下载命名使用。
437
+ */
438
+ type StreamResponseMeta = {
439
+ /**
440
+ * MIME 类型,如 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;
441
+ * 省略时按 application/octet-stream 处理
442
+ */
443
+ mimeType?: string;
444
+ /**
445
+ * 建议下载文件名,用于 Content-Disposition 响应头
446
+ */
447
+ fileName?: string;
448
+ /**
449
+ * 文件大小(字节),可选,用于 Content-Length
450
+ */
451
+ fileSize?: number;
452
+ };
453
+ /**
454
+ * 平台无关的二进制流响应标记类型
455
+ *
456
+ * core 层不绑定具体运行时(StreamableFile / ReadableStream / Blob),
457
+ * 各 adapter 通过 InferStreamRouteResponse<T> 将其映射为平台具体类型。
458
+ * phantom 类型,不含运行时数据,仅供类型推导占位。
459
+ */
460
+ type BinaryStreamMarker = {
461
+ readonly __binaryStreamResponse: unique symbol;
462
+ };
463
+ /**
464
+ * 路由基础定义
465
+ *
466
+ * 承载与响应形态无关的公共字段,由 JsonResponseRoute 与 StreamResponseRoute 复用。
436
467
  *
437
468
  * @typeParam TMethod - HTTP 方法类型
438
469
  * @typeParam TPath - 路径模板字符串
439
470
  * @typeParam TParams - 路径参数 Zod Schema
440
471
  * @typeParam TQuery - 查询参数 Zod Schema
441
472
  * @typeParam TBody - 请求体 Zod Schema
442
- * @typeParam TResponse - 响应 Zod Schema
443
473
  */
444
- type RouteDefinition<TMethod extends HttpMethod = HttpMethod, TPath extends string = string, TParams extends ZodType | undefined = ZodType | undefined, TQuery extends ZodType | undefined = ZodType | undefined, TBody extends ZodType | undefined = ZodType | undefined, TResponse extends ZodType = ZodType> = {
474
+ type RouteBaseDef<TMethod extends HttpMethod = HttpMethod, TPath extends string = string, TParams extends ZodType | undefined = ZodType | undefined, TQuery extends ZodType | undefined = ZodType | undefined, TBody extends ZodType | undefined = ZodType | undefined> = {
445
475
  /**
446
476
  * HTTP 方法
447
477
  */
@@ -462,10 +492,6 @@ type RouteDefinition<TMethod extends HttpMethod = HttpMethod, TPath extends stri
462
492
  * 请求体 Schema
463
493
  */
464
494
  body?: TBody;
465
- /**
466
- * 响应 Schema
467
- */
468
- response: TResponse;
469
495
  /**
470
496
  * 接口摘要描述
471
497
  */
@@ -493,6 +519,67 @@ type RouteDefinition<TMethod extends HttpMethod = HttpMethod, TPath extends stri
493
519
  */
494
520
  basePath?: string;
495
521
  };
522
+ /**
523
+ * JSON 响应路由
524
+ *
525
+ * 响应经 ApiResponse<T> 包装的 JSON 信封,response 字段为必填 Zod Schema,
526
+ * 描述 ApiResponse<T> 中的 T。responseType 默认 'json',现有路由字面量无需显式声明。
527
+ *
528
+ * @typeParam TMethod - HTTP 方法类型
529
+ * @typeParam TPath - 路径模板字符串
530
+ * @typeParam TParams - 路径参数 Zod Schema
531
+ * @typeParam TQuery - 查询参数 Zod Schema
532
+ * @typeParam TBody - 请求体 Zod Schema
533
+ * @typeParam TResponse - 响应 Zod Schema
534
+ */
535
+ type JsonResponseRoute<TMethod extends HttpMethod = HttpMethod, TPath extends string = string, TParams extends ZodType | undefined = ZodType | undefined, TQuery extends ZodType | undefined = ZodType | undefined, TBody extends ZodType | undefined = ZodType | undefined, TResponse extends ZodType = ZodType> = RouteBaseDef<TMethod, TPath, TParams, TQuery, TBody> & {
536
+ /**
537
+ * 响应类型标记,默认 'json' 可省略
538
+ */
539
+ responseType?: 'json';
540
+ /**
541
+ * 响应 Schema,描述 ApiResponse<T> 中的 T
542
+ */
543
+ response: TResponse;
544
+ };
545
+ /**
546
+ * 流式响应路由
547
+ *
548
+ * 响应为二进制流(文件下载、图片返回等),无 Zod Schema。
549
+ * responseType 必填 'stream',stream 字段描述响应元数据。
550
+ *
551
+ * @typeParam TMethod - HTTP 方法类型
552
+ * @typeParam TPath - 路径模板字符串
553
+ * @typeParam TParams - 路径参数 Zod Schema
554
+ * @typeParam TQuery - 查询参数 Zod Schema
555
+ * @typeParam TBody - 请求体 Zod Schema
556
+ */
557
+ type StreamResponseRoute<TMethod extends HttpMethod = HttpMethod, TPath extends string = string, TParams extends ZodType | undefined = ZodType | undefined, TQuery extends ZodType | undefined = ZodType | undefined, TBody extends ZodType | undefined = ZodType | undefined> = RouteBaseDef<TMethod, TPath, TParams, TQuery, TBody> & {
558
+ /**
559
+ * 响应类型标记:二进制流,显式必填
560
+ */
561
+ responseType: 'stream';
562
+ /**
563
+ * 流式响应元数据
564
+ */
565
+ stream: StreamResponseMeta;
566
+ };
567
+ /**
568
+ * 路由定义类型
569
+ *
570
+ * 描述一个 API 路由的完整契约,包括方法、路径、参数、请求体和响应。
571
+ * 为 JsonResponseRoute 与 StreamResponseRoute 的 discriminated union,
572
+ * 通过 responseType 字段判别。现有 JSON 路由字面量(无 responseType 字段)
573
+ * 自动归属 JsonResponseRoute 分支。
574
+ *
575
+ * @typeParam TMethod - HTTP 方法类型
576
+ * @typeParam TPath - 路径模板字符串
577
+ * @typeParam TParams - 路径参数 Zod Schema
578
+ * @typeParam TQuery - 查询参数 Zod Schema
579
+ * @typeParam TBody - 请求体 Zod Schema
580
+ * @typeParam TResponse - 响应 Zod Schema(仅 JsonResponseRoute 分支使用)
581
+ */
582
+ type RouteDefinition<TMethod extends HttpMethod = HttpMethod, TPath extends string = string, TParams extends ZodType | undefined = ZodType | undefined, TQuery extends ZodType | undefined = ZodType | undefined, TBody extends ZodType | undefined = ZodType | undefined, TResponse extends ZodType = ZodType> = JsonResponseRoute<TMethod, TPath, TParams, TQuery, TBody, TResponse> | StreamResponseRoute<TMethod, TPath, TParams, TQuery, TBody>;
496
583
  /**
497
584
  * 从路由定义中推断路径参数类型
498
585
  *
@@ -502,7 +589,9 @@ type RouteDefinition<TMethod extends HttpMethod = HttpMethod, TPath extends stri
502
589
  *
503
590
  * @typeParam T - 路由定义类型
504
591
  */
505
- type InferRouteParams<T extends RouteDefinition> = T extends RouteDefinition<HttpMethod, string, infer P, ZodType | undefined, ZodType | undefined, ZodType> ? [P] extends [ZodType] ? P['_output'] : undefined : undefined;
592
+ type InferRouteParams<T extends RouteDefinition> = T extends {
593
+ params?: infer P;
594
+ } ? P extends ZodType ? P['_output'] : undefined : undefined;
506
595
  /**
507
596
  * 从路由定义中推断查询参数类型
508
597
  *
@@ -512,7 +601,9 @@ type InferRouteParams<T extends RouteDefinition> = T extends RouteDefinition<Htt
512
601
  *
513
602
  * @typeParam T - 路由定义类型
514
603
  */
515
- type InferRouteQuery<T extends RouteDefinition> = T extends RouteDefinition<HttpMethod, string, ZodType | undefined, infer Q, ZodType | undefined, ZodType> ? [Q] extends [ZodType] ? Q['_output'] : undefined : undefined;
604
+ type InferRouteQuery<T extends RouteDefinition> = T extends {
605
+ query?: infer Q;
606
+ } ? Q extends ZodType ? Q['_output'] : undefined : undefined;
516
607
  /**
517
608
  * 从路由定义中推断请求体类型
518
609
  *
@@ -522,7 +613,9 @@ type InferRouteQuery<T extends RouteDefinition> = T extends RouteDefinition<Http
522
613
  *
523
614
  * @typeParam T - 路由定义类型
524
615
  */
525
- type InferRouteBody<T extends RouteDefinition> = T extends RouteDefinition<HttpMethod, string, ZodType | undefined, ZodType | undefined, infer B, ZodType> ? [B] extends [ZodType] ? B['_output'] : undefined : undefined;
616
+ type InferRouteBody<T extends RouteDefinition> = T extends {
617
+ body?: infer B;
618
+ } ? B extends ZodType ? B['_output'] : undefined : undefined;
526
619
  /**
527
620
  * 从路由定义中推断响应数据类型
528
621
  *
@@ -534,7 +627,11 @@ type InferRouteBody<T extends RouteDefinition> = T extends RouteDefinition<HttpM
534
627
  *
535
628
  * @typeParam T - 路由定义类型
536
629
  */
537
- type InferRouteResponse<T extends RouteDefinition> = T extends RouteDefinition<HttpMethod, string, ZodType | undefined, ZodType | undefined, ZodType | undefined, infer R> ? [R] extends [ZodType] ? ExtractData<R['_output']> : never : never;
630
+ type InferRouteResponse<T extends RouteDefinition> = T extends {
631
+ responseType: 'stream';
632
+ } ? BinaryStreamMarker : T extends {
633
+ response: infer R;
634
+ } ? R extends ZodType ? ExtractData<R['_output']> : never : never;
538
635
  /**
539
636
  * 从路由定义中推断完整的响应类型
540
637
  *
@@ -546,7 +643,11 @@ type InferRouteResponse<T extends RouteDefinition> = T extends RouteDefinition<H
546
643
  *
547
644
  * @typeParam T - 路由定义类型
548
645
  */
549
- type InferRouteFullResponse<T extends RouteDefinition> = T extends RouteDefinition<HttpMethod, string, ZodType | undefined, ZodType | undefined, ZodType | undefined, infer R> ? [R] extends [ZodType] ? ApiResponse<ExtractData<R['_output']>> : never : never;
646
+ type InferRouteFullResponse<T extends RouteDefinition> = T extends {
647
+ responseType: 'stream';
648
+ } ? BinaryStreamMarker : T extends {
649
+ response: infer R;
650
+ } ? R extends ZodType ? ApiResponse<ExtractData<R['_output']>> : never : never;
550
651
  /**
551
652
  * 从路由定义中推断分页响应的项类型
552
653
  *
@@ -1764,6 +1865,56 @@ type DefineRouteConfig<TMethod extends HttpMethod, TPath extends string, TParams
1764
1865
  */
1765
1866
  tags?: string[];
1766
1867
  };
1868
+ /**
1869
+ * 流式路由配置类型
1870
+ *
1871
+ * 用于 defineRoute 创建二进制流响应路由,responseType 必填 'stream',
1872
+ * stream 字段描述响应元数据,无 response Zod Schema。
1873
+ *
1874
+ * @typeParam TMethod - HTTP 方法类型
1875
+ * @typeParam TPath - 路径模板字符串
1876
+ * @typeParam TParams - 路径参数 Schema 类型
1877
+ * @typeParam TQuery - 查询参数 Schema 类型
1878
+ * @typeParam TBody - 请求体 Schema 类型
1879
+ */
1880
+ type StreamRouteDefineConfig<TMethod extends HttpMethod, TPath extends string, TParams extends ZodType | undefined, TQuery extends ZodType | undefined, TBody extends ZodType | undefined> = {
1881
+ /**
1882
+ * HTTP 请求方法
1883
+ */
1884
+ method: TMethod;
1885
+ /**
1886
+ * API 路径模板
1887
+ */
1888
+ path: TPath;
1889
+ /**
1890
+ * 路径参数 Schema
1891
+ */
1892
+ params?: TParams;
1893
+ /**
1894
+ * 查询参数 Schema
1895
+ */
1896
+ query?: TQuery;
1897
+ /**
1898
+ * 请求体 Schema
1899
+ */
1900
+ body?: TBody;
1901
+ /**
1902
+ * 响应类型标记:二进制流,显式必填
1903
+ */
1904
+ responseType: 'stream';
1905
+ /**
1906
+ * 流式响应元数据
1907
+ */
1908
+ stream: StreamResponseMeta;
1909
+ /**
1910
+ * 接口描述信息
1911
+ */
1912
+ summary?: string;
1913
+ /**
1914
+ * 接口标签
1915
+ */
1916
+ tags?: string[];
1917
+ };
1767
1918
  /**
1768
1919
  * 定义 API 路由
1769
1920
  *
@@ -1789,7 +1940,31 @@ type DefineRouteConfig<TMethod extends HttpMethod, TPath extends string, TParams
1789
1940
  * @returns 类型安全的路由定义
1790
1941
  * @throws {@link Error} 当路由定义创建失败时抛出错误
1791
1942
  */
1792
- declare function defineRoute<TMethod extends HttpMethod, TPath extends string, TParams extends ZodType | undefined, TQuery extends ZodType | undefined, TBody extends ZodType | undefined, TResponse extends ZodType>(config: DefineRouteConfig<TMethod, TPath, TParams, TQuery, TBody, TResponse>): RouteDefinition<TMethod, TPath, TParams, TQuery, TBody, TResponse>;
1943
+ /**
1944
+ * defineRoute 重载:流式响应路由
1945
+ *
1946
+ * config 包含 responseType: 'stream' 与 stream 元数据,返回 StreamResponseRoute。
1947
+ *
1948
+ * @typeParam TMethod - HTTP 方法类型
1949
+ * @typeParam TPath - 路径模板字符串
1950
+ * @typeParam TParams - 路径参数 Schema 类型
1951
+ * @typeParam TQuery - 查询参数 Schema 类型
1952
+ * @typeParam TBody - 请求体 Schema 类型
1953
+ */
1954
+ declare function defineRoute<TMethod extends HttpMethod, TPath extends string, TParams extends ZodType | undefined, TQuery extends ZodType | undefined, TBody extends ZodType | undefined>(config: StreamRouteDefineConfig<TMethod, TPath, TParams, TQuery, TBody>): StreamResponseRoute<TMethod, TPath, TParams, TQuery, TBody>;
1955
+ /**
1956
+ * defineRoute 重载:JSON 响应路由(原有形态)
1957
+ *
1958
+ * config 包含 response Zod Schema,返回 JsonResponseRoute。
1959
+ *
1960
+ * @typeParam TMethod - HTTP 方法类型
1961
+ * @typeParam TPath - 路径模板字符串
1962
+ * @typeParam TParams - 路径参数 Schema 类型
1963
+ * @typeParam TQuery - 查询参数 Schema 类型
1964
+ * @typeParam TBody - 请求体 Schema 类型
1965
+ * @typeParam TResponse - 响应 Schema 类型
1966
+ */
1967
+ declare function defineRoute<TMethod extends HttpMethod, TPath extends string, TParams extends ZodType | undefined, TQuery extends ZodType | undefined, TBody extends ZodType | undefined, TResponse extends ZodType>(config: DefineRouteConfig<TMethod, TPath, TParams, TQuery, TBody, TResponse>): JsonResponseRoute<TMethod, TPath, TParams, TQuery, TBody, TResponse>;
1793
1968
  /**
1794
1969
  * 构建完整 URL 路径
1795
1970
  *
@@ -2091,32 +2266,45 @@ type ProcessedRoute<T extends RouteDefinition = RouteDefinition> = T & {
2091
2266
  *
2092
2267
  * @typeParam T - 路由配置值类型
2093
2268
  */
2094
- type InferRouteDefinitionFromValue<T> = T extends {
2095
- /**
2096
- * HTTP 方法
2097
- */
2269
+ type InferRouteDefinitionFromValue<T> =
2270
+ /**
2271
+ * 流式响应分支:config 含 responseType: 'stream'
2272
+ */
2273
+ T extends {
2274
+ responseType: 'stream';
2098
2275
  method: infer M extends HttpMethod;
2099
- /**
2100
- * 请求路径
2101
- */
2102
2276
  path: string;
2277
+ } ? StreamResponseRoute<M, string, T extends {
2278
+ params?: infer PA;
2279
+ } ? ([PA] extends [ZodType] ? PA : undefined) : undefined, T extends {
2280
+ query?: infer Q;
2281
+ } ? ([Q] extends [ZodType] ? Q : undefined) : undefined, T extends {
2282
+ body?: infer B;
2283
+ } ? ([B] extends [ZodType] ? B : undefined) : undefined> & {
2103
2284
  /**
2104
- * 响应 Schema
2285
+ * 接口摘要描述
2105
2286
  */
2106
- response: infer R extends ZodType;
2287
+ summary?: string;
2107
2288
  /**
2108
- * 路径参数 Schema
2289
+ * 接口标签分组
2109
2290
  */
2110
- params?: infer PA;
2291
+ tags?: string[];
2111
2292
  /**
2112
- * 查询参数 Schema
2293
+ * 是否需要 CSRF 令牌保护
2113
2294
  */
2114
- query?: infer Q;
2295
+ csrf?: boolean;
2115
2296
  /**
2116
- * 请求体 Schema
2297
+ * 请求内容类型
2117
2298
  */
2299
+ contentType?: 'json' | 'formData';
2300
+ } : T extends {
2301
+ method: infer M extends HttpMethod;
2302
+ path: string;
2303
+ response: infer R extends ZodType;
2304
+ params?: infer PA;
2305
+ query?: infer Q;
2118
2306
  body?: infer B;
2119
- } ? RouteDefinition<M, string, [PA] extends [ZodType] ? PA : undefined, [Q] extends [ZodType] ? Q : undefined, [B] extends [ZodType] ? B : undefined, R> & {
2307
+ } ? JsonResponseRoute<M, string, [PA] extends [ZodType] ? PA : undefined, [Q] extends [ZodType] ? Q : undefined, [B] extends [ZodType] ? B : undefined, R> & {
2120
2308
  /**
2121
2309
  * 接口摘要描述
2122
2310
  */
@@ -2561,6 +2749,32 @@ declare function createTypedResponse<R extends RouteDefinition>(_route: R): Type
2561
2749
  * @returns 无参函数,返回空 ApiResponse
2562
2750
  */
2563
2751
  declare function createTypedEmpty<R extends RouteDefinition>(_route: R): TypedEmptyFunction;
2752
+ /**
2753
+ * 类型安全的流式响应函数类型
2754
+ *
2755
+ * 接受平台无关的 BinaryStreamMarker 并透传。
2756
+ * 各 adapter 通过 InferStreamRouteResponse<T> 映射为平台具体流类型
2757
+ * (NestJS 的 StreamableFile、Bun 的 ReadableStream、客户端的 Blob 等)。
2758
+ */
2759
+ type TypedStreamFunction = (stream: BinaryStreamMarker) => BinaryStreamMarker;
2760
+ /**
2761
+ * 创建类型安全的流式响应函数
2762
+ *
2763
+ * 工厂模式:创建时绑定路由定义,返回的函数接受流数据并透传。
2764
+ * 仅对 StreamResponseRoute 有效,传入 JsonResponseRoute 会编译报错,
2765
+ * 与 createTypedResponse 形成错用保护。
2766
+ *
2767
+ * @example
2768
+ * ```typescript
2769
+ * const typedStream = createTypedStream(downloadRoute);
2770
+ * return typedStream(streamableFile);
2771
+ * ```
2772
+ *
2773
+ * @typeParam R - 流式路由定义类型,约束为 StreamResponseRoute
2774
+ * @param _route - 路由定义(创建时绑定,用于类型约束)
2775
+ * @returns 流式响应函数,接受流数据并透传
2776
+ */
2777
+ declare function createTypedStream<R extends StreamResponseRoute>(_route: R): TypedStreamFunction;
2564
2778
  //#endregion
2565
2779
  //#region src/utils/unwrap-result.util.d.ts
2566
2780
  /**
@@ -2603,6 +2817,46 @@ declare function isRecord(value: unknown): value is Record<string, unknown>;
2603
2817
  */
2604
2818
  declare function isType<T>(value: unknown): value is T;
2605
2819
  //#endregion
2820
+ //#region src/utils/route-type-guards.util.d.ts
2821
+ /**
2822
+ * 判断路由是否为流式响应路由
2823
+ *
2824
+ * 通过 responseType 字段判别 StreamResponseRoute 分支。
2825
+ * 窄化后 route 为 Extract<T, StreamResponseRoute>,可安全访问 stream 字段。
2826
+ *
2827
+ * @typeParam T - 路由定义类型
2828
+ * @param route - 路由定义
2829
+ * @returns 若 responseType 为 'stream' 则为流式路由
2830
+ *
2831
+ * @example
2832
+ * ```typescript
2833
+ * if (isStreamRoute(route)) {
2834
+ * // route 窄化为 StreamResponseRoute,可访问 route.stream
2835
+ * console.log(route.stream.mimeType);
2836
+ * }
2837
+ * ```
2838
+ */
2839
+ declare function isStreamRoute<T extends RouteDefinition>(route: T): route is Extract<T, StreamResponseRoute>;
2840
+ /**
2841
+ * 判断路由是否为 JSON 响应路由
2842
+ *
2843
+ * 通过 responseType 字段判别 JsonResponseRoute 分支(含默认情况)。
2844
+ * 窄化后 route 为 Extract<T, JsonResponseRoute>,可安全访问 response 字段。
2845
+ *
2846
+ * @typeParam T - 路由定义类型
2847
+ * @param route - 路由定义
2848
+ * @returns 若 responseType 不为 'stream' 则为 JSON 路由
2849
+ *
2850
+ * @example
2851
+ * ```typescript
2852
+ * if (isJsonRoute(route)) {
2853
+ * // route 窄化为 JsonResponseRoute,可访问 route.response
2854
+ * validateResponse(data, route.response);
2855
+ * }
2856
+ * ```
2857
+ */
2858
+ declare function isJsonRoute<T extends RouteDefinition>(route: T): route is Extract<T, JsonResponseRoute>;
2859
+ //#endregion
2606
2860
  //#region src/client/create-http-client.utils.d.ts
2607
2861
  /**
2608
2862
  * 创建 HTTP 客户端
@@ -3133,4 +3387,4 @@ type RouteConfig<T extends RouteDefinition> = {
3133
3387
  handler: RouteHandler<T>;
3134
3388
  };
3135
3389
  //#endregion
3136
- export { type ApiCompactPaginatedListData, ApiCompactPaginatedListDataSchema, type ApiError, type ApiErrorResponse, ApiErrorResponseSchema, ApiErrorSchema, type ApiFailResponse, type ApiFunctions, type ApiListData, ApiListDataSchema, ApiListDataUtil, type ApiPaginatedListData, ApiPaginatedListDataSchema, type ApiResponse, ApiResponseSchema, ApiResponseUtil, type ApiSuccessResponse, type ApiVersion, type ArrayElement, type AuthInterceptorConfig, type AuthStrategy, type AwaitedData, type AxiosAdapterConfig, type CreateApiFunction, type CreateDeleteFunction, type CreateGetFunction, type CreatePostFunction, type CreateUpdateFunction, type CsrfInterceptorConfig, type CsrfProvider, type CursorPaginatedResult, type CursorPaginationParams, CursorPaginationParamsSchema, DEFAULT_RETRY_STATUS_CODES, type DateRangeQuery, DateRangeQuerySchema, type DeepPartial, type DeepReadonly, type DeepRequired, ERROR_HTTP_STATUS, ERROR_MESSAGES, type EmptyResponse, EmptyResponseSchema, ErrorCode, type ErrorCodeConfig, ErrorCodeSchema, type ExtractData, type FilterQuery, FilterQuerySchema, type FormDataConvertConfig, type HttpAdapter, type HttpClient, type HttpClientConfig, type HttpMethod, type HttpPaginationConfig, type IdParams, IdParamsSchema, type InferRouteBody, type InferRouteFullResponse, type InferRouteItem, type InferRouteParams, type InferRouteQuery, type InferRouteResponse, type InferRouteReturn, type InterceptorExecutorConfig, type LoggingInterceptorConfig, type Merge, type MockRequest, type MockRequestContext, type NonNullableData, type ObjectKeys, type ObjectValues, type OffsetPaginatedResult, type OffsetPaginationParams, OffsetPaginationParamsSchema, type OmitByValue, type OptionalKeyOf, type OptionalKeys, type PaginatedResult, type PaginationParams, PaginationParamsSchema, type PaginationQuery, PaginationQuerySchema, type PickByValue, type RequestConfig, type RequestDataToValidate, type RequestInterceptor, type RequestInterceptorContext, type RequiredKeyOf, type RequiredKeys, type ResponseInterceptor, type ResponseInterceptorContext, type ResponseTransformer, type RetryConfig, type ReturnDataType, type RouteConfig, type RouteDefineConfig, type RouteDefineResult, type RouteDefinition, type RouteGroup, type RouteGroupConfig, type RouteHandler, type RouteMockRequestOptions, type RouteResponseBuilder, type SchemaValidationFailure, type SchemaValidationResult, type SchemaValidationSuccess, type SearchQuery, SearchQuerySchema, type TaroAdapterConfig, type TokenProvider, type UnwrapApiListData, type UnwrapApiPaginatedListData, type UnwrapApiResponse, type ValidationError, type ValidationErrorDetail, type ValidationInterceptorConfig, type ValidationResult, type VersionedPrefix, buildPath, buildQuery, calculateOffset, calculateTotalPages, concatPath, createApiClientFactory, createAuthStrategyInterceptor, createAuthTokenInterceptor, createAxiosAdapter, createAxiosInstance, createBearerAuthStrategy, createConfigurableMockHttpClient, createCookieAuthStrategy, createCsrfInterceptor, createCustomAuthStrategy, createDelayedMockHttpClient, createErrorCodeSchema, createErrorMockHttpClient, createExecutorConfigFromClientConfig, createFilterQuerySchema, createHttpClient, createHttpPaginationSchema, createInterceptorExecutor, createLoggingInterceptor, createLoggingRequestInterceptor, createLoggingResponseInterceptor, createMockHttpClient, createNoneAuthStrategy, createPaginatedResult, createRequestInterceptorsFromConfig, createResponseInterceptorsFromConfig, createResponseTransformerInterceptor, createRetryInterceptor, createRouteMock, createRouteResponseBuilder, createTypedEmpty, createTypedResponse, createValidationErrorResponse, createValidationErrorResponseFromError, createValidationInterceptor, defaultLogger, defineRoute, defineRouteGroup, exponentialBackoff, extractErrorDetails, getErrorMessage, getHttpStatus, isBlob, isFile, isFormDataContentType, isLegacyConfig, isRecord, isType, normalizePagination, objectToFormData, setHttpClientConfig, unwrapResult, validateRequest, warnDeprecatedConfig };
3390
+ export { type ApiCompactPaginatedListData, ApiCompactPaginatedListDataSchema, type ApiError, type ApiErrorResponse, ApiErrorResponseSchema, ApiErrorSchema, type ApiFailResponse, type ApiFunctions, type ApiListData, ApiListDataSchema, ApiListDataUtil, type ApiPaginatedListData, ApiPaginatedListDataSchema, type ApiResponse, ApiResponseSchema, ApiResponseUtil, type ApiSuccessResponse, type ApiVersion, type ArrayElement, type AuthInterceptorConfig, type AuthStrategy, type AwaitedData, type AxiosAdapterConfig, type BinaryStreamMarker, type CreateApiFunction, type CreateDeleteFunction, type CreateGetFunction, type CreatePostFunction, type CreateUpdateFunction, type CsrfInterceptorConfig, type CsrfProvider, type CursorPaginatedResult, type CursorPaginationParams, CursorPaginationParamsSchema, DEFAULT_RETRY_STATUS_CODES, type DateRangeQuery, DateRangeQuerySchema, type DeepPartial, type DeepReadonly, type DeepRequired, ERROR_HTTP_STATUS, ERROR_MESSAGES, type EmptyResponse, EmptyResponseSchema, ErrorCode, type ErrorCodeConfig, ErrorCodeSchema, type ExtractData, type FilterQuery, FilterQuerySchema, type FormDataConvertConfig, type HttpAdapter, type HttpClient, type HttpClientConfig, type HttpMethod, type HttpPaginationConfig, type IdParams, IdParamsSchema, type InferRouteBody, type InferRouteFullResponse, type InferRouteItem, type InferRouteParams, type InferRouteQuery, type InferRouteResponse, type InferRouteReturn, type InterceptorExecutorConfig, type JsonResponseRoute, type LoggingInterceptorConfig, type Merge, type MockRequest, type MockRequestContext, type NonNullableData, type ObjectKeys, type ObjectValues, type OffsetPaginatedResult, type OffsetPaginationParams, OffsetPaginationParamsSchema, type OmitByValue, type OptionalKeyOf, type OptionalKeys, type PaginatedResult, type PaginationParams, PaginationParamsSchema, type PaginationQuery, PaginationQuerySchema, type PickByValue, type RequestConfig, type RequestDataToValidate, type RequestInterceptor, type RequestInterceptorContext, type RequiredKeyOf, type RequiredKeys, type ResponseInterceptor, type ResponseInterceptorContext, type ResponseTransformer, type RetryConfig, type ReturnDataType, type RouteBaseDef, type RouteConfig, type RouteDefineConfig, type RouteDefineResult, type RouteDefinition, type RouteGroup, type RouteGroupConfig, type RouteHandler, type RouteMockRequestOptions, type RouteResponseBuilder, type SchemaValidationFailure, type SchemaValidationResult, type SchemaValidationSuccess, type SearchQuery, SearchQuerySchema, type StreamResponseMeta, type StreamResponseRoute, type TaroAdapterConfig, type TokenProvider, type UnwrapApiListData, type UnwrapApiPaginatedListData, type UnwrapApiResponse, type ValidationError, type ValidationErrorDetail, type ValidationInterceptorConfig, type ValidationResult, type VersionedPrefix, buildPath, buildQuery, calculateOffset, calculateTotalPages, concatPath, createApiClientFactory, createAuthStrategyInterceptor, createAuthTokenInterceptor, createAxiosAdapter, createAxiosInstance, createBearerAuthStrategy, createConfigurableMockHttpClient, createCookieAuthStrategy, createCsrfInterceptor, createCustomAuthStrategy, createDelayedMockHttpClient, createErrorCodeSchema, createErrorMockHttpClient, createExecutorConfigFromClientConfig, createFilterQuerySchema, createHttpClient, createHttpPaginationSchema, createInterceptorExecutor, createLoggingInterceptor, createLoggingRequestInterceptor, createLoggingResponseInterceptor, createMockHttpClient, createNoneAuthStrategy, createPaginatedResult, createRequestInterceptorsFromConfig, createResponseInterceptorsFromConfig, createResponseTransformerInterceptor, createRetryInterceptor, createRouteMock, createRouteResponseBuilder, createTypedEmpty, createTypedResponse, createTypedStream, createValidationErrorResponse, createValidationErrorResponseFromError, createValidationInterceptor, defaultLogger, defineRoute, defineRouteGroup, exponentialBackoff, extractErrorDetails, getErrorMessage, getHttpStatus, isBlob, isFile, isFormDataContentType, isJsonRoute, isLegacyConfig, isRecord, isStreamRoute, isType, normalizePagination, objectToFormData, setHttpClientConfig, unwrapResult, validateRequest, warnDeprecatedConfig };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import*as e from"zod";import{CursorPaginationParamsSchema as t,OffsetPaginationParamsSchema as n,PAGINATION_DEFAULTS as r,PaginationParamsSchema as i,SortParamsSchema as a,calculateOffset as o,calculateTotalPages as s,createCompactPaginatedResultSchema as c,createPaginatedResult as l,createPaginatedResult as u,createPaginatedResultSchema as d,createPaginationDefaults as f,createSortParamsSchema as p,normalizePagination as ee}from"@longzai-intelligence/pagination";import{createOptionalStringSchema as m,defineEnumSchema as h}from"@longzai-intelligence/zod-utils";import{isSuccess as te}from"@longzai-intelligence/shared-kernel";import g from"axios";const _=e.object({code:e.string(),message:e.string(),details:e.record(e.string(),e.unknown()).optional()}),v=t=>e.object({success:e.boolean(),data:t.optional(),message:e.string().optional(),error:_.optional(),timestamp:e.number().optional()}),ne=t=>e.object({items:e.array(t),total:e.number()}),re=e=>d(e),ie=e=>c(e),ae=v(e.void()),oe=e.object({id:e.string()}),se=i.extend({page:e.coerce.number().int().min(1).optional().default(r.page),pageSize:e.coerce.number().int().min(r.minPageSize).max(r.maxPageSize).optional().default(r.pageSize)});function ce(t){let n=t?.pageSizeField??`pageSize`,r=f({page:t?.defaultPage,pageSize:t?.defaultPageSize,maxPageSize:t?.maxPageSize,minPageSize:t?.minPageSize});return e.object({page:e.coerce.number().int().min(1).optional().default(r.page),[n]:e.coerce.number().int().min(r.minPageSize).max(r.maxPageSize).optional().default(r.pageSize)})}const le=e.object({filter:m(),sortBy:a.shape.sortBy,sortOrder:a.shape.sortOrder});function ue(t){let n=p(t);return e.object({filter:m(),sortBy:n.shape.sortBy,sortOrder:n.shape.sortOrder})}const de=e.object({startDate:m(),endDate:m()}),fe=e.object({keyword:m()});function y(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function b(e){return e!=null}const x=h([`UNKNOWN`,`INVALID_PARAMETER`,`RESOURCE_NOT_FOUND`,`RESOURCE_ALREADY_EXISTS`,`OPERATION_FAILED`,`PERMISSION_DENIED`,`UNAUTHORIZED`,`TOKEN_EXPIRED`,`TOKEN_INVALID`,`LOGIN_FAILED`,`ACCOUNT_DISABLED`,`PASSWORD_INCORRECT`,`DATABASE_ERROR`,`EXTERNAL_SERVICE_ERROR`,`RATE_LIMIT_EXCEEDED`,`DUPLICATE_REQUEST`,`VALIDATION_ERROR`],`通用错误码`),S={UNKNOWN:`未知错误`,INVALID_PARAMETER:`参数无效`,RESOURCE_NOT_FOUND:`资源不存在`,RESOURCE_ALREADY_EXISTS:`资源已存在`,OPERATION_FAILED:`操作失败`,PERMISSION_DENIED:`权限不足`,UNAUTHORIZED:`未授权`,TOKEN_EXPIRED:`令牌已过期`,TOKEN_INVALID:`令牌无效`,LOGIN_FAILED:`登录失败`,ACCOUNT_DISABLED:`账户已禁用`,PASSWORD_INCORRECT:`密码错误`,DATABASE_ERROR:`数据库错误`,EXTERNAL_SERVICE_ERROR:`外部服务错误`,RATE_LIMIT_EXCEEDED:`请求频率超限`,DUPLICATE_REQUEST:`重复请求`,VALIDATION_ERROR:`参数验证失败`};function pe(e){return S[e]||S.UNKNOWN}const C={UNAUTHORIZED:401,TOKEN_EXPIRED:401,TOKEN_INVALID:401,LOGIN_FAILED:401,ACCOUNT_DISABLED:401,PASSWORD_INCORRECT:401,PERMISSION_DENIED:403,RESOURCE_NOT_FOUND:404,INVALID_PARAMETER:400,VALIDATION_ERROR:400,DATABASE_ERROR:500,EXTERNAL_SERVICE_ERROR:500};function me(e){return C[e]??400}function he(e,t){let n=[...x.options,...e];if(b(n))return h(n,t??`错误码`);throw Error(`错误码合并失败`)}const ge=e.object({code:x,message:e.string(),data:e.unknown().nullable()});function _e(e){if(b(e))return e;throw Error(`路由定义创建失败`)}function ve(e,t,n){let r=e;if(t)for(let[e,n]of Object.entries(t))r=r.replace(`:${e}`,String(n));if(n){let e=new URLSearchParams;for(let[t,r]of Object.entries(n))r!==void 0&&e.append(t,String(r));let t=e.toString();t&&(r=`${r}?${t}`)}return r}function ye(e){if(!e)return``;let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&t.append(n,String(r));let n=t.toString();return n?`?${n}`:``}function w(e,t){return`${e}${t}`}function be(e){return`basePath`in e?typeof e.basePath==`string`:!1}function xe(e){let{parent:t,prefix:n,version:r,auth:i,tags:a}=e,o=n??``,s,c,l;return t?(s=o===``?t.prefix:`${t.prefix}/${o}`,c=i??t.auth,l=a??t.tags):(s=r?o.startsWith(`/`)?`/${r}${o}`:o===``?`/${r}`:`/${r}/${o}`:o,c=i,l=a),{fullPrefix:s,finalAuth:c,finalTags:l}}function Se(e,t){let n={};for(let[r,i]of Object.entries(e))be(i)?n[r]=i:n[r]=t(i);return n}function Ce(e,t,n){function r(r){let i=[...n??[],...r.tags??[]],a=r.auth??t,o={...r,path:w(e,r.path),basePath:r.path,tags:i.length>0?i:void 0,auth:a};if(b(o))return o;throw Error(`路由定义创建失败`)}return r}function we(e){let{routes:t}=e,{fullPrefix:n,finalAuth:r,finalTags:i}=xe(e),a=Ce(n,r,i),o=b(n)?n:void 0;if(o===void 0)throw Error(`路径前缀类型推断失败`);let s={prefix:o,version:e.version,auth:r,tags:i,defineRoute:a};if(!t){if(b(s))return s;throw Error(`路由分组创建失败`)}let c=Se(t,e=>a(e)),l={...s,routes:Object.freeze(c)};if(b(l))return l;throw Error(`路由分组创建失败`)}function T(e){return e instanceof File}function E(e){return e instanceof Blob}function D(e,t){let n=new FormData,r=new Set(t?.fileFields??[]),i=t?.arrayFormat??`brackets`,a=(e,t)=>{if(t!=null){if(T(t)||E(t)){n.append(e,t);return}if(r.has(e)&&typeof t==`string`){n.append(e,t);return}if(Array.isArray(t)){t.forEach((t,n)=>{a(i===`indices`?`${e}[${n}]`:i===`brackets`?`${e}[]`:e,t)});return}if(typeof t==`object`&&t){y(t)&&Object.entries(t).forEach(([t,n])=>{a(`${e}[${t}]`,n)});return}n.append(e,String(t))}};return Object.entries(e).forEach(([e,t])=>{a(e,t)}),n}function O(e){return e===`formData`}function Te(e){return{hasParams:`params`in e&&e.params!==void 0,hasQuery:`query`in e&&e.query!==void 0,hasBody:`body`in e&&e.body!==void 0}}function Ee(e,t){return t&&y(e)&&!(e instanceof FormData)?D(e):e}function De(e,t){let n=Te(e),r=O(e.contentType),i=e.method!==`GET`&&e.method!==`DELETE`,a=(...a)=>{let o=0,s=n.hasParams?a[o++]:void 0,c=i&&n.hasBody?a[o++]:void 0,l=n.hasQuery?a[o]:void 0,u=Ee(c,r),d=b(s)?s:void 0,f=b(l)?l:void 0,p=b(u)?u:void 0;return t.request({route:e,params:d,query:f,body:p})};if(b(a))return a;throw Error(`路由函数创建失败`)}function Oe(e,t){let n={};for(let r in e)if(Object.prototype.hasOwnProperty.call(e,r)){let i=e[r];i&&(n[r]=De(i,t))}if(b(n))return n;throw Error(`API 函数集合创建失败`)}function ke(e,t){return Oe(e,t)}function Ae(e){return t=>ke(t,e)}const k={success(e,t){return{success:!0,data:e,message:t,timestamp:Date.now()}},data(e){return{success:!0,data:e,timestamp:Date.now()}},message(e){return{success:!0,data:void 0,message:e,timestamp:Date.now()}},fail(e,t){return{success:!1,message:e,data:t,timestamp:Date.now()}},empty(){return{success:!0,data:void 0,timestamp:Date.now()}}},je={empty(){return{items:[],total:0}},from(e){return{items:e,total:e.length}},withTotal(e,t){return{items:e,total:t}},paginated(e,t,n,r){return u(e,t,n,r)}};function Me(e){return{success:e=>k.data(e),successWithMessage:(e,t)=>k.success(e,t),fail:(e,t)=>t?{success:!1,error:t,message:e,timestamp:Date.now()}:k.fail(e),empty:()=>k.empty()}}function Ne(e){return e=>k.data(e)}function Pe(e){return()=>k.empty()}function Fe(e){if(te(e))return k.data(e.value);throw e.error}function A(e){let t=g.create({timeout:e?.timeout??3e4});return{async execute(e){let n=await t.request({url:e.url,method:e.method,headers:e.headers,data:e.body,params:e.query,signal:e.config?.signal,timeout:e.config?.timeout});return{status:n.status,headers:b(n.headers)?n.headers:{},data:n.data}}}}async function j(e,t){let n=e;for(let e of t)e.onRequest&&(n=await e.onRequest(n));return n}async function M(e,t,n){let r=e;for(let e=n.length-1;e>=0;e--){let i=n[e];i?.onError&&(r=await i.onError(r,t))}return r}async function N(e,t,n){let r=e;for(let e of n)e.onResponse&&(r=await e.onResponse(r,t));return r}async function P(e,t,n){let r=e;for(let e=n.length-1;e>=0;e--){let i=n[e];if(i?.onError){let e=await i.onError(r,t);if(F(e))return e;r=e}}return r}function F(e){return typeof e==`object`&&!!e&&`success`in e&&typeof e.success==`boolean`}function I(e){let t={code:`UNKNOWN_ERROR`,message:`请求失败`};return e instanceof Error&&(e.message.includes(`timeout`)?(t.code=`TIMEOUT`,t.message=`请求超时`):e.message.includes(`network`)||e.message.includes(`Network`)?(t.code=`NETWORK_ERROR`,t.message=`网络错误`):t.message=e.message),{success:!1,error:t}}async function Ie(e,t){try{return await j(e,t)}catch(n){return I(await M(n,e,t))}}async function Le(e,t,n){try{return{response:await t.execute(e)}}catch(t){let r=await P(t,{status:0,headers:{},request:e},n);return F(r)?{error:r}:{error:I(r)}}}function Re(e,t,n){let{status:r,headers:i,data:a}=e,o={status:r,headers:i,request:t},s;return s=F(a)?a:{success:!0,data:a},r===401&&n&&n(),{response:s,context:o}}async function ze(e,t,n){let r=await Ie(e,t.requestInterceptors);if(!(`method`in r))return r;let i=r,a=await Le(i,n,t.responseInterceptors);if(a.error)return a.error;let{response:o,context:s}=Re(a.response,i,t.onUnauthorized);try{return await N(o,s,t.responseInterceptors)}catch(e){let n=await P(e,s,t.responseInterceptors);return F(n)?n:I(n)}}function L(e,t){return{execute:n=>ze(n,e,t),executeRequestInterceptors:t=>j(t,e.requestInterceptors),executeResponseInterceptors:(t,n)=>N(t,n,e.responseInterceptors),handleRequestError:(t,n)=>M(t,n,e.requestInterceptors),handleResponseError:(t,n)=>P(t,n,e.responseInterceptors)}}function Be(e){return{requestInterceptors:e.requestInterceptors??[],responseInterceptors:e.responseInterceptors??[],onUnauthorized:e.onUnauthorized}}function R(e,t){let n=t?.withAuth??!0,r=t?.tokenPrefix??`Bearer`,i=t?.headerName??`Authorization`;return{async onRequest(t){if(!(t.config?.withAuth??n))return t;let a=await e.getToken();return a&&(t.headers[i]=`${r} ${a}`),t}}}function z(e){return{async onRequest(t){switch(e.type){case`bearer`:{let n=await e.tokenProvider.getToken();n&&(t.headers.Authorization=`Bearer ${n}`);break}case`cookie`:t.metadata.credentials=e.credentials??`include`;break;case`custom`:{let n=e.injector({url:t.url,method:t.method,headers:t.headers,params:t.params,query:t.query,body:t.body});n.headers&&Object.assign(t.headers,n.headers);break}case`none`:break}return t}}}function Ve(e){return{type:`bearer`,tokenProvider:e}}function He(e){return{type:`cookie`,credentials:e}}function Ue(e){return{type:`custom`,injector:e}}function We(){return{type:`none`}}function B(e,t){let n=t?.headerName??`X-CSRF-Token`,r=t?.injectAll??!1,i=t?.onTokenError??`warn`;return{async onRequest(t){return!(r||(t.route?.csrf??!1))||!(t.config?.withCsrf??!0)?t:Ge(t,e,n,i)}}}async function Ge(e,t,n,r){try{let r=await t.getToken();r&&(e.headers[n]=r)}catch(e){switch(r){case`warn`:console.warn(`[http-utils] CSRF 令牌获取失败:`,e);break;case`throw`:throw e;case`ignore`:break}}return e}function V(e){return{async onResponse(t,n){try{let n=e(t.data);return{success:n.success,data:n.data,message:n.message,error:n.error,timestamp:n.timestamp}}catch{return{success:!1,error:{code:`TRANSFORM_ERROR`,message:`响应转换失败`}}}}}}const H=[408,429,500,502,503,504];function Ke(e){let t=e?.maxRetries??0,n=e?.baseDelay??1e3,r=e?.retryOn??H,i=e?.retryCondition,a=typeof e?.retryDelay==`function`?e.retryDelay:t=>{let r=e?.retryDelay??n*2**t;return typeof r==`number`?r:n*2**t};return{onError(e,n){let o=Number(n.request.metadata.retryCount);return o>=t||!(i?i(e,n):r.includes(n.status))?e:(n.request.metadata.retryCount=o+1,{success:!1,error:{code:`RETRY_PENDING`,message:`请求将在 ${a(o)}ms 后重试 (${o+1}/${t})`},metadata:{retryCount:o+1,retryDelay:a(o)}})}}}function qe(e,t=1e3){return t*2**e}function U(e){let t=e?.mode??`development`,n=e?.onValidationError??`warn`,r=e?.logger,i=()=>t===!0?!0:t===!1?!1:t===`development`?process.env.NODE_ENV===`development`:!1;return{async onResponse(e,t){if(!i())return e;let a=t.request.route;return a?.response?Je(e,a.response,t,n,r):e}}}function Je(e,t,n,r,i){if(e.success&&e.data!==void 0){let a=t.safeParse(e.data);if(!a.success){let e=`响应验证失败: ${n.request.url}`;switch(r){case`warn`:i&&i.warn(e,{error:a.error});break;case`throw`:throw Error(`${e}: ${a.error}`,{cause:a.error});case`ignore`:break}}}return e}function W(e,t,n){let r=`[${new Date().toISOString()}] [${e.toUpperCase()}]`;n===void 0?console.log(r,t):console.log(r,t,n)}function G(e){let t=e?.level??`info`,n=e?.logBody??!1,r=e?.logger??W;return{onRequest(e){let i=Date.now();e.metadata.startTime=i;let a={method:e.method,url:e.url};return n&&e.body&&(a.body=e.body),r(t,`请求开始`,a),e},onError(e,t){let n=Date.now()-Number(t.metadata.startTime);return r(`error`,`请求失败`,{method:t.method,url:t.url,duration:`${n}ms`,error:e}),e}}}function K(e){let t=e?.level??`info`,n=e?.logResponse??!1,r=e?.logger??W;return{onResponse(e,i){let a=Date.now()-Number(i.request.metadata.startTime),o={method:i.request.method,url:i.request.url,status:i.status,duration:`${a}ms`,success:e.success};return n&&e.data&&(o.data=e.data),!e.success&&e.error?(o.error=e.error,r(`warn`,`请求完成(失败)`,o)):r(t,`请求完成`,o),e},onError(e,t){let n=Date.now()-Number(t.request.metadata.startTime);return r(`error`,`响应处理失败`,{method:t.request.method,url:t.request.url,status:t.status,duration:`${n}ms`,error:e}),e}}}function Ye(e){return{request:G(e),response:K(e)}}function q(e){let t=[];return e.requestInterceptors&&t.push(...e.requestInterceptors),e.authStrategy?t.push(z(e.authStrategy)):e.tokenProvider&&t.push(R(e.tokenProvider)),e.csrfProvider&&t.push(B(e.csrfProvider,{headerName:e.csrfHeaderName})),t}function J(e){let t=[];return e.validation!==!1&&t.push(U(e.validation===void 0?void 0:e.validation)),e.responseInterceptors&&t.push(...e.responseInterceptors),e.responseTransformer&&t.push(V(e.responseTransformer)),t}function Y(e){return e.tokenProvider!==void 0||e.authStrategy!==void 0||e.responseTransformer!==void 0||e.csrfProvider!==void 0}function Xe(e){let t=[];e.tokenProvider&&t.push(`tokenProvider (使用 createAuthTokenInterceptor)`),e.authStrategy&&t.push(`authStrategy (使用 createAuthStrategyInterceptor)`),e.responseTransformer&&t.push(`responseTransformer (使用 createResponseTransformerInterceptor)`),e.csrfProvider&&t.push(`csrfProvider (使用 createCsrfInterceptor)`),t.length>0&&console.warn(`[http-utils] 以下配置项已弃用,将在未来版本中移除:
1
+ import*as e from"zod";import{CursorPaginationParamsSchema as t,OffsetPaginationParamsSchema as n,PAGINATION_DEFAULTS as r,PaginationParamsSchema as i,SortParamsSchema as a,calculateOffset as o,calculateTotalPages as s,createCompactPaginatedResultSchema as c,createPaginatedResult as l,createPaginatedResult as u,createPaginatedResultSchema as d,createPaginationDefaults as f,createSortParamsSchema as p,normalizePagination as ee}from"@longzai-intelligence/pagination";import{createOptionalStringSchema as m,defineEnumSchema as h}from"@longzai-intelligence/zod-utils";import{isSuccess as te}from"@longzai-intelligence/shared-kernel";import g from"axios";const _=e.object({code:e.string(),message:e.string(),details:e.record(e.string(),e.unknown()).optional()}),v=t=>e.object({success:e.boolean(),data:t.optional(),message:e.string().optional(),error:_.optional(),timestamp:e.number().optional()}),ne=t=>e.object({items:e.array(t),total:e.number()}),re=e=>d(e),ie=e=>c(e),ae=v(e.void()),oe=e.object({id:e.string()}),se=i.extend({page:e.coerce.number().int().min(1).optional().default(r.page),pageSize:e.coerce.number().int().min(r.minPageSize).max(r.maxPageSize).optional().default(r.pageSize)});function ce(t){let n=t?.pageSizeField??`pageSize`,r=f({page:t?.defaultPage,pageSize:t?.defaultPageSize,maxPageSize:t?.maxPageSize,minPageSize:t?.minPageSize});return e.object({page:e.coerce.number().int().min(1).optional().default(r.page),[n]:e.coerce.number().int().min(r.minPageSize).max(r.maxPageSize).optional().default(r.pageSize)})}const le=e.object({filter:m(),sortBy:a.shape.sortBy,sortOrder:a.shape.sortOrder});function ue(t){let n=p(t);return e.object({filter:m(),sortBy:n.shape.sortBy,sortOrder:n.shape.sortOrder})}const de=e.object({startDate:m(),endDate:m()}),fe=e.object({keyword:m()});function y(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function b(e){return e!=null}const x=h([`UNKNOWN`,`INVALID_PARAMETER`,`RESOURCE_NOT_FOUND`,`RESOURCE_ALREADY_EXISTS`,`OPERATION_FAILED`,`PERMISSION_DENIED`,`UNAUTHORIZED`,`TOKEN_EXPIRED`,`TOKEN_INVALID`,`LOGIN_FAILED`,`ACCOUNT_DISABLED`,`PASSWORD_INCORRECT`,`DATABASE_ERROR`,`EXTERNAL_SERVICE_ERROR`,`RATE_LIMIT_EXCEEDED`,`DUPLICATE_REQUEST`,`VALIDATION_ERROR`],`通用错误码`),S={UNKNOWN:`未知错误`,INVALID_PARAMETER:`参数无效`,RESOURCE_NOT_FOUND:`资源不存在`,RESOURCE_ALREADY_EXISTS:`资源已存在`,OPERATION_FAILED:`操作失败`,PERMISSION_DENIED:`权限不足`,UNAUTHORIZED:`未授权`,TOKEN_EXPIRED:`令牌已过期`,TOKEN_INVALID:`令牌无效`,LOGIN_FAILED:`登录失败`,ACCOUNT_DISABLED:`账户已禁用`,PASSWORD_INCORRECT:`密码错误`,DATABASE_ERROR:`数据库错误`,EXTERNAL_SERVICE_ERROR:`外部服务错误`,RATE_LIMIT_EXCEEDED:`请求频率超限`,DUPLICATE_REQUEST:`重复请求`,VALIDATION_ERROR:`参数验证失败`};function pe(e){return S[e]||S.UNKNOWN}const C={UNAUTHORIZED:401,TOKEN_EXPIRED:401,TOKEN_INVALID:401,LOGIN_FAILED:401,ACCOUNT_DISABLED:401,PASSWORD_INCORRECT:401,PERMISSION_DENIED:403,RESOURCE_NOT_FOUND:404,INVALID_PARAMETER:400,VALIDATION_ERROR:400,DATABASE_ERROR:500,EXTERNAL_SERVICE_ERROR:500};function me(e){return C[e]??400}function he(e,t){let n=[...x.options,...e];if(b(n))return h(n,t??`错误码`);throw Error(`错误码合并失败`)}const ge=e.object({code:x,message:e.string(),data:e.unknown().nullable()});function _e(e){if(b(e))return e;throw Error(`路由定义创建失败`)}function ve(e,t,n){let r=e;if(t)for(let[e,n]of Object.entries(t))r=r.replace(`:${e}`,String(n));if(n){let e=new URLSearchParams;for(let[t,r]of Object.entries(n))r!==void 0&&e.append(t,String(r));let t=e.toString();t&&(r=`${r}?${t}`)}return r}function ye(e){if(!e)return``;let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&t.append(n,String(r));let n=t.toString();return n?`?${n}`:``}function w(e,t){return`${e}${t}`}function be(e){return`basePath`in e?typeof e.basePath==`string`:!1}function xe(e){let{parent:t,prefix:n,version:r,auth:i,tags:a}=e,o=n??``,s,c,l;return t?(s=o===``?t.prefix:`${t.prefix}/${o}`,c=i??t.auth,l=a??t.tags):(s=r?o.startsWith(`/`)?`/${r}${o}`:o===``?`/${r}`:`/${r}/${o}`:o,c=i,l=a),{fullPrefix:s,finalAuth:c,finalTags:l}}function Se(e,t){let n={};for(let[r,i]of Object.entries(e))be(i)?n[r]=i:n[r]=t(i);return n}function Ce(e,t,n){function r(r){let i=[...n??[],...r.tags??[]],a=r.auth??t,o={...r,path:w(e,r.path),basePath:r.path,tags:i.length>0?i:void 0,auth:a};if(b(o))return o;throw Error(`路由定义创建失败`)}return r}function we(e){let{routes:t}=e,{fullPrefix:n,finalAuth:r,finalTags:i}=xe(e),a=Ce(n,r,i),o=b(n)?n:void 0;if(o===void 0)throw Error(`路径前缀类型推断失败`);let s={prefix:o,version:e.version,auth:r,tags:i,defineRoute:a};if(!t){if(b(s))return s;throw Error(`路由分组创建失败`)}let c=Se(t,e=>a(e)),l={...s,routes:Object.freeze(c)};if(b(l))return l;throw Error(`路由分组创建失败`)}function T(e){return e instanceof File}function E(e){return e instanceof Blob}function D(e,t){let n=new FormData,r=new Set(t?.fileFields??[]),i=t?.arrayFormat??`brackets`,a=(e,t)=>{if(t!=null){if(T(t)||E(t)){n.append(e,t);return}if(r.has(e)&&typeof t==`string`){n.append(e,t);return}if(Array.isArray(t)){t.forEach((t,n)=>{a(i===`indices`?`${e}[${n}]`:i===`brackets`?`${e}[]`:e,t)});return}if(typeof t==`object`&&t){y(t)&&Object.entries(t).forEach(([t,n])=>{a(`${e}[${t}]`,n)});return}n.append(e,String(t))}};return Object.entries(e).forEach(([e,t])=>{a(e,t)}),n}function O(e){return e===`formData`}function Te(e){return{hasParams:`params`in e&&e.params!==void 0,hasQuery:`query`in e&&e.query!==void 0,hasBody:`body`in e&&e.body!==void 0}}function Ee(e,t){return t&&y(e)&&!(e instanceof FormData)?D(e):e}function De(e,t){let n=Te(e),r=O(e.contentType),i=e.method!==`GET`&&e.method!==`DELETE`,a=(...a)=>{let o=0,s=n.hasParams?a[o++]:void 0,c=i&&n.hasBody?a[o++]:void 0,l=n.hasQuery?a[o]:void 0,u=Ee(c,r),d=b(s)?s:void 0,f=b(l)?l:void 0,p=b(u)?u:void 0;return t.request({route:e,params:d,query:f,body:p})};if(b(a))return a;throw Error(`路由函数创建失败`)}function Oe(e,t){let n={};for(let r in e)if(Object.prototype.hasOwnProperty.call(e,r)){let i=e[r];i&&(n[r]=De(i,t))}if(b(n))return n;throw Error(`API 函数集合创建失败`)}function ke(e,t){return Oe(e,t)}function Ae(e){return t=>ke(t,e)}const k={success(e,t){return{success:!0,data:e,message:t,timestamp:Date.now()}},data(e){return{success:!0,data:e,timestamp:Date.now()}},message(e){return{success:!0,data:void 0,message:e,timestamp:Date.now()}},fail(e,t){return{success:!1,message:e,data:t,timestamp:Date.now()}},empty(){return{success:!0,data:void 0,timestamp:Date.now()}}},je={empty(){return{items:[],total:0}},from(e){return{items:e,total:e.length}},withTotal(e,t){return{items:e,total:t}},paginated(e,t,n,r){return u(e,t,n,r)}};function Me(e){return{success:e=>k.data(e),successWithMessage:(e,t)=>k.success(e,t),fail:(e,t)=>t?{success:!1,error:t,message:e,timestamp:Date.now()}:k.fail(e),empty:()=>k.empty()}}function Ne(e){return e=>k.data(e)}function Pe(e){return()=>k.empty()}function Fe(e){return e=>e}function Ie(e){if(te(e))return k.data(e.value);throw e.error}function A(e){return e.responseType===`stream`}function Le(e){return e.responseType!==`stream`}function j(e){let t=g.create({timeout:e?.timeout??3e4});return{async execute(e){let n=await t.request({url:e.url,method:e.method,headers:e.headers,data:e.body,params:e.query,signal:e.config?.signal,timeout:e.config?.timeout});return{status:n.status,headers:b(n.headers)?n.headers:{},data:n.data}}}}async function M(e,t){let n=e;for(let e of t)e.onRequest&&(n=await e.onRequest(n));return n}async function N(e,t,n){let r=e;for(let e=n.length-1;e>=0;e--){let i=n[e];i?.onError&&(r=await i.onError(r,t))}return r}async function P(e,t,n){let r=e;for(let e of n)e.onResponse&&(r=await e.onResponse(r,t));return r}async function F(e,t,n){let r=e;for(let e=n.length-1;e>=0;e--){let i=n[e];if(i?.onError){let e=await i.onError(r,t);if(I(e))return e;r=e}}return r}function I(e){return typeof e==`object`&&!!e&&`success`in e&&typeof e.success==`boolean`}function L(e){let t={code:`UNKNOWN_ERROR`,message:`请求失败`};return e instanceof Error&&(e.message.includes(`timeout`)?(t.code=`TIMEOUT`,t.message=`请求超时`):e.message.includes(`network`)||e.message.includes(`Network`)?(t.code=`NETWORK_ERROR`,t.message=`网络错误`):t.message=e.message),{success:!1,error:t}}async function Re(e,t){try{return await M(e,t)}catch(n){return L(await N(n,e,t))}}async function ze(e,t,n){try{return{response:await t.execute(e)}}catch(t){let r=await F(t,{status:0,headers:{},request:e},n);return I(r)?{error:r}:{error:L(r)}}}function Be(e,t,n){let{status:r,headers:i,data:a}=e,o={status:r,headers:i,request:t},s;return s=I(a)?a:{success:!0,data:a},r===401&&n&&n(),{response:s,context:o}}async function Ve(e,t,n){let r=await Re(e,t.requestInterceptors);if(!(`method`in r))return r;let i=r,a=await ze(i,n,t.responseInterceptors);if(a.error)return a.error;let{response:o,context:s}=Be(a.response,i,t.onUnauthorized);try{return await P(o,s,t.responseInterceptors)}catch(e){let n=await F(e,s,t.responseInterceptors);return I(n)?n:L(n)}}function R(e,t){return{execute:n=>Ve(n,e,t),executeRequestInterceptors:t=>M(t,e.requestInterceptors),executeResponseInterceptors:(t,n)=>P(t,n,e.responseInterceptors),handleRequestError:(t,n)=>N(t,n,e.requestInterceptors),handleResponseError:(t,n)=>F(t,n,e.responseInterceptors)}}function He(e){return{requestInterceptors:e.requestInterceptors??[],responseInterceptors:e.responseInterceptors??[],onUnauthorized:e.onUnauthorized}}function z(e,t){let n=t?.withAuth??!0,r=t?.tokenPrefix??`Bearer`,i=t?.headerName??`Authorization`;return{async onRequest(t){if(!(t.config?.withAuth??n))return t;let a=await e.getToken();return a&&(t.headers[i]=`${r} ${a}`),t}}}function B(e){return{async onRequest(t){switch(e.type){case`bearer`:{let n=await e.tokenProvider.getToken();n&&(t.headers.Authorization=`Bearer ${n}`);break}case`cookie`:t.metadata.credentials=e.credentials??`include`;break;case`custom`:{let n=e.injector({url:t.url,method:t.method,headers:t.headers,params:t.params,query:t.query,body:t.body});n.headers&&Object.assign(t.headers,n.headers);break}case`none`:break}return t}}}function Ue(e){return{type:`bearer`,tokenProvider:e}}function We(e){return{type:`cookie`,credentials:e}}function Ge(e){return{type:`custom`,injector:e}}function Ke(){return{type:`none`}}function V(e,t){let n=t?.headerName??`X-CSRF-Token`,r=t?.injectAll??!1,i=t?.onTokenError??`warn`;return{async onRequest(t){return!(r||(t.route?.csrf??!1))||!(t.config?.withCsrf??!0)?t:qe(t,e,n,i)}}}async function qe(e,t,n,r){try{let r=await t.getToken();r&&(e.headers[n]=r)}catch(e){switch(r){case`warn`:console.warn(`[http-utils] CSRF 令牌获取失败:`,e);break;case`throw`:throw e;case`ignore`:break}}return e}function H(e){return{async onResponse(t,n){try{let n=e(t.data);return{success:n.success,data:n.data,message:n.message,error:n.error,timestamp:n.timestamp}}catch{return{success:!1,error:{code:`TRANSFORM_ERROR`,message:`响应转换失败`}}}}}}const U=[408,429,500,502,503,504];function Je(e){let t=e?.maxRetries??0,n=e?.baseDelay??1e3,r=e?.retryOn??U,i=e?.retryCondition,a=typeof e?.retryDelay==`function`?e.retryDelay:t=>{let r=e?.retryDelay??n*2**t;return typeof r==`number`?r:n*2**t};return{onError(e,n){let o=Number(n.request.metadata.retryCount);return o>=t||!(i?i(e,n):r.includes(n.status))?e:(n.request.metadata.retryCount=o+1,{success:!1,error:{code:`RETRY_PENDING`,message:`请求将在 ${a(o)}ms 后重试 (${o+1}/${t})`},metadata:{retryCount:o+1,retryDelay:a(o)}})}}}function Ye(e,t=1e3){return t*2**e}function W(e){let t=e?.mode??`development`,n=e?.onValidationError??`warn`,r=e?.logger,i=()=>t===!0?!0:t===!1?!1:t===`development`?process.env.NODE_ENV===`development`:!1;return{async onResponse(e,t){if(!i())return e;let a=t.request.route;if(!a||A(a))return e;let o=a.response;return o?Xe(e,o,t,n,r):e}}}function Xe(e,t,n,r,i){if(e.success&&e.data!==void 0){let a=t.safeParse(e.data);if(!a.success){let e=`响应验证失败: ${n.request.url}`;switch(r){case`warn`:i&&i.warn(e,{error:a.error});break;case`throw`:throw Error(`${e}: ${a.error}`,{cause:a.error});case`ignore`:break}}}return e}function G(e,t,n){let r=`[${new Date().toISOString()}] [${e.toUpperCase()}]`;n===void 0?console.log(r,t):console.log(r,t,n)}function K(e){let t=e?.level??`info`,n=e?.logBody??!1,r=e?.logger??G;return{onRequest(e){let i=Date.now();e.metadata.startTime=i;let a={method:e.method,url:e.url};return n&&e.body&&(a.body=e.body),r(t,`请求开始`,a),e},onError(e,t){let n=Date.now()-Number(t.metadata.startTime);return r(`error`,`请求失败`,{method:t.method,url:t.url,duration:`${n}ms`,error:e}),e}}}function q(e){let t=e?.level??`info`,n=e?.logResponse??!1,r=e?.logger??G;return{onResponse(e,i){let a=Date.now()-Number(i.request.metadata.startTime),o={method:i.request.method,url:i.request.url,status:i.status,duration:`${a}ms`,success:e.success};return n&&e.data&&(o.data=e.data),!e.success&&e.error?(o.error=e.error,r(`warn`,`请求完成(失败)`,o)):r(t,`请求完成`,o),e},onError(e,t){let n=Date.now()-Number(t.request.metadata.startTime);return r(`error`,`响应处理失败`,{method:t.request.method,url:t.request.url,status:t.status,duration:`${n}ms`,error:e}),e}}}function Ze(e){return{request:K(e),response:q(e)}}function J(e){let t=[];return e.requestInterceptors&&t.push(...e.requestInterceptors),e.authStrategy?t.push(B(e.authStrategy)):e.tokenProvider&&t.push(z(e.tokenProvider)),e.csrfProvider&&t.push(V(e.csrfProvider,{headerName:e.csrfHeaderName})),t}function Y(e){let t=[];return e.validation!==!1&&t.push(W(e.validation===void 0?void 0:e.validation)),e.responseInterceptors&&t.push(...e.responseInterceptors),e.responseTransformer&&t.push(H(e.responseTransformer)),t}function Qe(e){return e.tokenProvider!==void 0||e.authStrategy!==void 0||e.responseTransformer!==void 0||e.csrfProvider!==void 0}function $e(e){let t=[];e.tokenProvider&&t.push(`tokenProvider (使用 createAuthTokenInterceptor)`),e.authStrategy&&t.push(`authStrategy (使用 createAuthStrategyInterceptor)`),e.responseTransformer&&t.push(`responseTransformer (使用 createResponseTransformerInterceptor)`),e.csrfProvider&&t.push(`csrfProvider (使用 createCsrfInterceptor)`),t.length>0&&console.warn(`[http-utils] 以下配置项已弃用,将在未来版本中移除:
2
2
  `+t.map(e=>` - ${e}`).join(`
3
- `))}function Ze(e,t,n,r,i,a){return{url:`${e}${t}`,method:n,headers:i?.headers??{},body:r,config:i,route:a,metadata:{}}}function Qe(e,t,n){let r=e.path;if(t&&Object.entries(t).forEach(([e,t])=>{r=r.replace(`:${e}`,String(t))}),n){let e=new URLSearchParams;Object.entries(n).forEach(([t,n])=>{n!==void 0&&e.append(t,String(n))});let t=e.toString();t&&(r=`${r}?${t}`)}return r}function $e(e){let{baseUrl:t,timeout:n=3e4,headers:r,onUnauthorized:i}=e;Y(e)&&Xe(e);let a=q(e),o=J(e),s=A({timeout:n}),c=L({requestInterceptors:a,responseInterceptors:o,onUnauthorized:i},s);return{request:async e=>{let{route:n,params:i,query:a,body:o,config:s}=e,l=Ze(t,Qe(n,i,a),n.method,o,{...s,headers:{...r,...s?.headers}},n),u=await c.execute(l);if(b(u))return u;throw Error(`响应类型不匹配`)}}}let X=null;function et(e){X=e}async function tt(e){let t=g.create({baseURL:X?.baseUrl||``,timeout:X?.timeout||3e4,headers:e.headers});return t.interceptors.request.use(async e=>{if(X?.tokenProvider){let t=await X.tokenProvider.getToken();t&&(e.headers.Authorization=`Bearer ${t}`)}return e},e=>Promise.reject(Error(String(e)))),t.interceptors.response.use(e=>e,async e=>(e.response?.status===401&&X?.onUnauthorized&&await X.onUnauthorized(),Promise.reject(e instanceof Error?e:Error(String(e))))),t.request(e)}function nt(e,t){return setTimeout(e,t)}function Z(e){return new Promise(t=>nt(t,e))}function rt(e){return{request:async()=>{if(b(e))return e;throw Error(`模拟响应类型不匹配`)}}}function it(e){return{request:async t=>{let n=`${t.route.method}:${t.route.path}`,r=e.get(n);if(!r){let e={success:!1,error:{code:`MOCK_NOT_FOUND`,message:`未找到模拟响应`}};if(b(e))return e;throw Error(`模拟响应创建失败`)}if(b(r))return r;throw Error(`模拟响应类型不匹配`)}}}function at(e,t){return{request:async()=>{if(await Z(t),b(e))return e;throw Error(`模拟响应类型不匹配`)}}}async function ot(e){throw e}function st(e){return{request:async t=>ot(e)}}function ct(e){return{request:async t=>{let n={route:t.route,params:t.params,query:t.query,body:t.body};for(let r of e){let e=!r.method||t.route.method===r.method,i=!r.path||t.route.path===r.path,a=!r.match||r.match(t.route,t.params,t.query,t.body);if(e&&i&&a){r.delay&&await Z(r.delay);let e=typeof r.response==`function`?r.response(n):r.response;if(b(e))return e;throw Error(`模拟响应类型不匹配`)}}let r={success:!1,error:{code:`MOCK_NOT_FOUND`,message:`未找到路由 ${t.route.method} ${t.route.path} 的模拟响应`}};if(b(r))return r;throw Error(`模拟响应创建失败`)}}}function Q(e,t=``){return e.issues.map(e=>lt(e,t))}function lt(e,t){let n=t+e.path.map(String).join(`.`)||t.slice(0,-1)||`root`;return e.code===`invalid_type`?dt(e,n):{path:n,message:e.message,received:void 0,expected:ft(e.code)}}function ut(e){return typeof e==`object`&&!!e&&`received`in e&&`expected`in e}function dt(e,t){return ut(e)?{path:t,message:e.message,received:e.received,expected:e.expected}:{path:t,message:e.message,received:void 0,expected:`类型不匹配`}}function ft(e){return{invalid_type:`类型不匹配`,invalid_literal:`字面量不匹配`,custom:`自定义验证失败`,invalid_union:`联合类型不匹配`,invalid_union_discriminator:`联合类型判别器无效`,invalid_enum_value:`枚举值无效`,invalid_arguments:`参数无效`,invalid_return_type:`返回类型无效`,invalid_date:`日期无效`,invalid_string:`字符串无效`,too_small:`值过小`,too_big:`值过大`,invalid_intersection_types:`交集类型无效`,not_multiple_of:`不是倍数`,not_finite:`值非有限`}[e]??`验证失败`}function $(e,t,n){if(!e){if(b(t))return{success:!0,data:t};let e={success:!0,data:void 0};if(b(e))return e;throw Error(`Schema 验证结果类型推断失败`)}let r=t??{},i=e.safeParse(r);return i.success?{success:!0,data:i.data}:{success:!1,details:Q(i.error,n)}}function pt(e,t){let n=[],r=$(e.params,t.params,`params.`);r.success||n.push(...r.details);let i=$(e.query,t.query,`query.`);i.success||n.push(...i.details);let a=$(e.body,t.body,`body.`);if(a.success||n.push(...a.details),n.length>0)return{success:!1,error:{code:`VALIDATION_ERROR`,message:`参数验证失败`,details:n}};let o={success:!0,params:r.success?r.data:void 0,query:i.success?i.data:void 0,body:a.success?a.data:void 0};if(b(o))return o;throw Error(`验证结果创建失败`)}function mt(e,t=`参数验证失败`){return{success:!1,error:{code:`VALIDATION_ERROR`,message:t,details:{validationErrors:Q(e)}},message:t}}function ht(e){return{success:!1,error:{code:e.code,message:e.message,details:{validationErrors:e.details}},message:e.message}}export{ie as ApiCompactPaginatedListDataSchema,ge as ApiErrorResponseSchema,_ as ApiErrorSchema,ne as ApiListDataSchema,je as ApiListDataUtil,re as ApiPaginatedListDataSchema,v as ApiResponseSchema,k as ApiResponseUtil,t as CursorPaginationParamsSchema,H as DEFAULT_RETRY_STATUS_CODES,de as DateRangeQuerySchema,C as ERROR_HTTP_STATUS,S as ERROR_MESSAGES,ae as EmptyResponseSchema,x as ErrorCodeSchema,le as FilterQuerySchema,oe as IdParamsSchema,n as OffsetPaginationParamsSchema,i as PaginationParamsSchema,se as PaginationQuerySchema,fe as SearchQuerySchema,ve as buildPath,ye as buildQuery,o as calculateOffset,s as calculateTotalPages,w as concatPath,Ae as createApiClientFactory,z as createAuthStrategyInterceptor,R as createAuthTokenInterceptor,A as createAxiosAdapter,tt as createAxiosInstance,Ve as createBearerAuthStrategy,it as createConfigurableMockHttpClient,He as createCookieAuthStrategy,B as createCsrfInterceptor,Ue as createCustomAuthStrategy,at as createDelayedMockHttpClient,he as createErrorCodeSchema,st as createErrorMockHttpClient,Be as createExecutorConfigFromClientConfig,ue as createFilterQuerySchema,$e as createHttpClient,ce as createHttpPaginationSchema,L as createInterceptorExecutor,Ye as createLoggingInterceptor,G as createLoggingRequestInterceptor,K as createLoggingResponseInterceptor,rt as createMockHttpClient,We as createNoneAuthStrategy,l as createPaginatedResult,q as createRequestInterceptorsFromConfig,J as createResponseInterceptorsFromConfig,V as createResponseTransformerInterceptor,Ke as createRetryInterceptor,ct as createRouteMock,Me as createRouteResponseBuilder,Pe as createTypedEmpty,Ne as createTypedResponse,mt as createValidationErrorResponse,ht as createValidationErrorResponseFromError,U as createValidationInterceptor,W as defaultLogger,_e as defineRoute,we as defineRouteGroup,qe as exponentialBackoff,Q as extractErrorDetails,pe as getErrorMessage,me as getHttpStatus,E as isBlob,T as isFile,O as isFormDataContentType,Y as isLegacyConfig,y as isRecord,b as isType,ee as normalizePagination,D as objectToFormData,et as setHttpClientConfig,Fe as unwrapResult,pt as validateRequest,Xe as warnDeprecatedConfig};
3
+ `))}function et(e,t,n,r,i,a){return{url:`${e}${t}`,method:n,headers:i?.headers??{},body:r,config:i,route:a,metadata:{}}}function tt(e,t,n){let r=e.path;if(t&&Object.entries(t).forEach(([e,t])=>{r=r.replace(`:${e}`,String(t))}),n){let e=new URLSearchParams;Object.entries(n).forEach(([t,n])=>{n!==void 0&&e.append(t,String(n))});let t=e.toString();t&&(r=`${r}?${t}`)}return r}function nt(e){let{baseUrl:t,timeout:n=3e4,headers:r,onUnauthorized:i}=e;Qe(e)&&$e(e);let a=J(e),o=Y(e),s=j({timeout:n}),c=R({requestInterceptors:a,responseInterceptors:o,onUnauthorized:i},s);return{request:async e=>{let{route:n,params:i,query:a,body:o,config:s}=e,l=et(t,tt(n,i,a),n.method,o,{...s,headers:{...r,...s?.headers}},n),u=await c.execute(l);if(b(u))return u;throw Error(`响应类型不匹配`)}}}let X=null;function rt(e){X=e}async function it(e){let t=g.create({baseURL:X?.baseUrl||``,timeout:X?.timeout||3e4,headers:e.headers});return t.interceptors.request.use(async e=>{if(X?.tokenProvider){let t=await X.tokenProvider.getToken();t&&(e.headers.Authorization=`Bearer ${t}`)}return e},e=>Promise.reject(Error(String(e)))),t.interceptors.response.use(e=>e,async e=>(e.response?.status===401&&X?.onUnauthorized&&await X.onUnauthorized(),Promise.reject(e instanceof Error?e:Error(String(e))))),t.request(e)}function at(e,t){return setTimeout(e,t)}function Z(e){return new Promise(t=>at(t,e))}function ot(e){return{request:async()=>{if(b(e))return e;throw Error(`模拟响应类型不匹配`)}}}function st(e){return{request:async t=>{let n=`${t.route.method}:${t.route.path}`,r=e.get(n);if(!r){let e={success:!1,error:{code:`MOCK_NOT_FOUND`,message:`未找到模拟响应`}};if(b(e))return e;throw Error(`模拟响应创建失败`)}if(b(r))return r;throw Error(`模拟响应类型不匹配`)}}}function ct(e,t){return{request:async()=>{if(await Z(t),b(e))return e;throw Error(`模拟响应类型不匹配`)}}}async function lt(e){throw e}function ut(e){return{request:async t=>lt(e)}}function dt(e){return{request:async t=>{let n={route:t.route,params:t.params,query:t.query,body:t.body};for(let r of e){let e=!r.method||t.route.method===r.method,i=!r.path||t.route.path===r.path,a=!r.match||r.match(t.route,t.params,t.query,t.body);if(e&&i&&a){r.delay&&await Z(r.delay);let e=typeof r.response==`function`?r.response(n):r.response;if(b(e))return e;throw Error(`模拟响应类型不匹配`)}}let r={success:!1,error:{code:`MOCK_NOT_FOUND`,message:`未找到路由 ${t.route.method} ${t.route.path} 的模拟响应`}};if(b(r))return r;throw Error(`模拟响应创建失败`)}}}function Q(e,t=``){return e.issues.map(e=>ft(e,t))}function ft(e,t){let n=t+e.path.map(String).join(`.`)||t.slice(0,-1)||`root`;return e.code===`invalid_type`?mt(e,n):{path:n,message:e.message,received:void 0,expected:ht(e.code)}}function pt(e){return typeof e==`object`&&!!e&&`received`in e&&`expected`in e}function mt(e,t){return pt(e)?{path:t,message:e.message,received:e.received,expected:e.expected}:{path:t,message:e.message,received:void 0,expected:`类型不匹配`}}function ht(e){return{invalid_type:`类型不匹配`,invalid_literal:`字面量不匹配`,custom:`自定义验证失败`,invalid_union:`联合类型不匹配`,invalid_union_discriminator:`联合类型判别器无效`,invalid_enum_value:`枚举值无效`,invalid_arguments:`参数无效`,invalid_return_type:`返回类型无效`,invalid_date:`日期无效`,invalid_string:`字符串无效`,too_small:`值过小`,too_big:`值过大`,invalid_intersection_types:`交集类型无效`,not_multiple_of:`不是倍数`,not_finite:`值非有限`}[e]??`验证失败`}function $(e,t,n){if(!e){if(b(t))return{success:!0,data:t};let e={success:!0,data:void 0};if(b(e))return e;throw Error(`Schema 验证结果类型推断失败`)}let r=t??{},i=e.safeParse(r);return i.success?{success:!0,data:i.data}:{success:!1,details:Q(i.error,n)}}function gt(e,t){let n=[],r=$(e.params,t.params,`params.`);r.success||n.push(...r.details);let i=$(e.query,t.query,`query.`);i.success||n.push(...i.details);let a=$(e.body,t.body,`body.`);if(a.success||n.push(...a.details),n.length>0)return{success:!1,error:{code:`VALIDATION_ERROR`,message:`参数验证失败`,details:n}};let o={success:!0,params:r.success?r.data:void 0,query:i.success?i.data:void 0,body:a.success?a.data:void 0};if(b(o))return o;throw Error(`验证结果创建失败`)}function _t(e,t=`参数验证失败`){return{success:!1,error:{code:`VALIDATION_ERROR`,message:t,details:{validationErrors:Q(e)}},message:t}}function vt(e){return{success:!1,error:{code:e.code,message:e.message,details:{validationErrors:e.details}},message:e.message}}export{ie as ApiCompactPaginatedListDataSchema,ge as ApiErrorResponseSchema,_ as ApiErrorSchema,ne as ApiListDataSchema,je as ApiListDataUtil,re as ApiPaginatedListDataSchema,v as ApiResponseSchema,k as ApiResponseUtil,t as CursorPaginationParamsSchema,U as DEFAULT_RETRY_STATUS_CODES,de as DateRangeQuerySchema,C as ERROR_HTTP_STATUS,S as ERROR_MESSAGES,ae as EmptyResponseSchema,x as ErrorCodeSchema,le as FilterQuerySchema,oe as IdParamsSchema,n as OffsetPaginationParamsSchema,i as PaginationParamsSchema,se as PaginationQuerySchema,fe as SearchQuerySchema,ve as buildPath,ye as buildQuery,o as calculateOffset,s as calculateTotalPages,w as concatPath,Ae as createApiClientFactory,B as createAuthStrategyInterceptor,z as createAuthTokenInterceptor,j as createAxiosAdapter,it as createAxiosInstance,Ue as createBearerAuthStrategy,st as createConfigurableMockHttpClient,We as createCookieAuthStrategy,V as createCsrfInterceptor,Ge as createCustomAuthStrategy,ct as createDelayedMockHttpClient,he as createErrorCodeSchema,ut as createErrorMockHttpClient,He as createExecutorConfigFromClientConfig,ue as createFilterQuerySchema,nt as createHttpClient,ce as createHttpPaginationSchema,R as createInterceptorExecutor,Ze as createLoggingInterceptor,K as createLoggingRequestInterceptor,q as createLoggingResponseInterceptor,ot as createMockHttpClient,Ke as createNoneAuthStrategy,l as createPaginatedResult,J as createRequestInterceptorsFromConfig,Y as createResponseInterceptorsFromConfig,H as createResponseTransformerInterceptor,Je as createRetryInterceptor,dt as createRouteMock,Me as createRouteResponseBuilder,Pe as createTypedEmpty,Ne as createTypedResponse,Fe as createTypedStream,_t as createValidationErrorResponse,vt as createValidationErrorResponseFromError,W as createValidationInterceptor,G as defaultLogger,_e as defineRoute,we as defineRouteGroup,Ye as exponentialBackoff,Q as extractErrorDetails,pe as getErrorMessage,me as getHttpStatus,E as isBlob,T as isFile,O as isFormDataContentType,Le as isJsonRoute,Qe as isLegacyConfig,y as isRecord,A as isStreamRoute,b as isType,ee as normalizePagination,D as objectToFormData,rt as setHttpClientConfig,Ie as unwrapResult,gt as validateRequest,$e as warnDeprecatedConfig};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-transport/http-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "keywords": [
5
5
  "api",
6
6
  "contract",