@snack-kit/lib 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,355 @@
1
+ import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
+
3
+ /**
4
+ * HTTP 请求配置,扩展自 AxiosRequestConfig
5
+ */
6
+ interface HttpRequestConfig<D = unknown> extends AxiosRequestConfig<D> {
7
+ /** Context key,自动从 HttpContext 获取 baseURL */
8
+ ctx?: string;
9
+ /** 自定义请求 ID,用于主动取消 */
10
+ cancelId?: string;
11
+ /** 回调接收生成的 cancelId */
12
+ onCancelId?: (id: string) => void;
13
+ /**
14
+ * 是否添加时间戳防缓存,默认 false(添加防缓存时间戳)
15
+ * 设为 true 时不添加时间戳
16
+ */
17
+ cache?: boolean;
18
+ }
19
+ /**
20
+ * HTTP 请求结果,扩展自 AxiosResponse
21
+ */
22
+ interface HttpResult<T = unknown> extends Partial<AxiosResponse<T>> {
23
+ /** 有 error 则请求失败,无 error 则成功 */
24
+ error?: HttpError;
25
+ }
26
+ /**
27
+ * HTTP 错误信息
28
+ */
29
+ interface HttpError {
30
+ /** HTTP 状态码 */
31
+ status?: number;
32
+ /** 错误描述 */
33
+ message: string;
34
+ /** 服务端返回的原始错误体 */
35
+ data?: unknown;
36
+ }
37
+ /**
38
+ * 网关 `/ngw/context` 接口返回的元数据(`$info` 字段)
39
+ */
40
+ interface ContextInfo {
41
+ /** 网关版本号,例如 `"4.6.2-r10"` */
42
+ version: string;
43
+ /** 网关域名,例如 `"http://172.16.32.155:20000"` */
44
+ domain: string;
45
+ /** 客户端标识 */
46
+ client: string;
47
+ /** 当前语言 */
48
+ lang: string;
49
+ }
50
+ /**
51
+ * 网关 `/web-debug/host/list` 接口返回的服务列表项
52
+ */
53
+ interface ServerItem {
54
+ /** 服务唯一标识 */
55
+ key: string;
56
+ /** 服务名称 */
57
+ name: string;
58
+ /** 服务类型分组,可为空字符串 */
59
+ type: string;
60
+ /** 服务地址,用于 `context.load()` 切换路由映射 */
61
+ origin: string;
62
+ /** 代理配置(由网关管理,前端只读) */
63
+ proxyInfo: Record<string, unknown>;
64
+ }
65
+
66
+ /**
67
+ * 管理服务地址映射的上下文单例
68
+ *
69
+ * 支持两种加载方式:
70
+ * - **远程加载**:传入网关 URL,自动请求 `GET /ngw/context` 获取映射表
71
+ * - **本地注入**:直接传入键值对象
72
+ *
73
+ * @example 远程加载
74
+ * ```ts
75
+ * import { Context } from '@snack-kit/lib/http'
76
+ *
77
+ * await Context.load('http://172.16.32.155:20000')
78
+ * Context.get('ngw') // 'http://172.16.32.155:20000/ngw'
79
+ * Context.info // { version: '4.6.2-r10', domain: '...', ... }
80
+ * ```
81
+ *
82
+ * @example 本地注入
83
+ * ```ts
84
+ * await Context.load({
85
+ * 'user-svc': 'http://user.api.com',
86
+ * 'order-svc': 'http://order.api.com',
87
+ * })
88
+ * ```
89
+ */
90
+ declare class HttpContext {
91
+ private _store;
92
+ private _loaded;
93
+ private _info;
94
+ /**
95
+ * 加载服务地址映射
96
+ *
97
+ * 远程加载时,响应中的 `$info` 元数据字段会被单独存储,不计入路由映射表。
98
+ *
99
+ * @param source 远程加载传入网关 URL;本地注入传入键值对象
100
+ * @param timeout 远程加载超时(ms),默认 5000
101
+ *
102
+ * @example 远程加载
103
+ * ```ts
104
+ * await Context.load('http://172.16.32.155:20000', 3000)
105
+ * ```
106
+ *
107
+ * @example 本地注入
108
+ * ```ts
109
+ * await Context.load({ 'user-svc': 'http://user.api.com' })
110
+ * ```
111
+ */
112
+ load(source: string | Record<string, string>, timeout?: number): Promise<void>;
113
+ /**
114
+ * 获取指定 ctx key 对应的服务地址
115
+ * @param key ctx key,例如 `'ngw'`、`'osc'`
116
+ * @returns 服务地址,未找到时返回空字符串
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * await Context.load('http://172.16.32.155:20000')
121
+ * Context.get('osc') // 'http://172.16.32.155:20000/osc'
122
+ * Context.get('none') // ''
123
+ * ```
124
+ */
125
+ get(key: string): string;
126
+ /**
127
+ * 网关元数据(仅远程加载后可用)
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * await Context.load('http://172.16.32.155:20000')
132
+ * Context.info?.version // '4.6.2-r10'
133
+ * Context.info?.domain // 'http://172.16.32.155:20000'
134
+ * ```
135
+ */
136
+ get info(): ContextInfo | undefined;
137
+ /**
138
+ * Context 是否已加载
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * Context.loaded // false
143
+ * await Context.load({ 'user-svc': 'http://user.api.com' })
144
+ * Context.loaded // true
145
+ * ```
146
+ */
147
+ get loaded(): boolean;
148
+ /**
149
+ * 清空所有映射并重置加载状态
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * Context.clear()
154
+ * Context.loaded // false
155
+ * ```
156
+ */
157
+ clear(): void;
158
+ }
159
+ /**
160
+ * HttpContext 全局单例
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { Context } from '@snack-kit/lib/http'
165
+ *
166
+ * await Context.load('http://172.16.32.155:20000')
167
+ * Context.get('osc') // 'http://172.16.32.155:20000/osc'
168
+ * ```
169
+ */
170
+ declare const Context: HttpContext;
171
+ /**
172
+ * 当前页面的 origin(`protocol + host`)
173
+ *
174
+ * 在非浏览器环境(如 SSR/Node)返回空字符串。
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * import { Origin } from '@snack-kit/lib/http'
179
+ * // 浏览器中:'https://app.example.com'
180
+ * // Node 环境:''
181
+ * ```
182
+ */
183
+ declare const Origin: string;
184
+ /**
185
+ * 当前页面路径的首段,可直接用作 `ctx` 参数
186
+ *
187
+ * 例如 `/osc/employee` → `'osc'`,在非浏览器环境返回空字符串。
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * import { Ctx, Get } from '@snack-kit/lib/http'
192
+ *
193
+ * // 当前路径为 /osc/... 时,Ctx === 'osc'
194
+ * const result = await Get('/employee', { ctx: Ctx })
195
+ * ```
196
+ */
197
+ declare const Ctx: string;
198
+
199
+ /**
200
+ * 取消指定 id 的请求并从注册表移除
201
+ *
202
+ * @param id 请求唯一标识
203
+ * @returns 是否找到并取消了请求
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * import { Get, Cancel } from '@snack-kit/lib/http'
208
+ *
209
+ * let cancelId = ''
210
+ * Get('/api/data', { onCancelId: (id) => { cancelId = id } })
211
+ *
212
+ * // 需要时取消
213
+ * Cancel(cancelId)
214
+ * ```
215
+ */
216
+ declare function Cancel(id: string): boolean;
217
+ /**
218
+ * 取消所有已注册的请求并清空注册表
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * import { CancelAll } from '@snack-kit/lib/http'
223
+ *
224
+ * // 页面卸载时取消所有进行中的请求
225
+ * window.addEventListener('beforeunload', () => CancelAll())
226
+ * ```
227
+ */
228
+ declare function CancelAll(): void;
229
+
230
+ /**
231
+ * 核心请求函数,所有快捷方法基于此实现
232
+ *
233
+ * 自动处理:
234
+ * - `ctx` → 从 HttpContext 查询 baseURL 并注入
235
+ * - `cache: false`(默认)→ URL 附加 `?_=timestamp` 防缓存
236
+ * - 请求取消 → 自动注册 AbortController,完成后自动清理
237
+ * - 错误捕获 → 统一返回 `{ error }` 而非 throw
238
+ *
239
+ * @param config 请求配置
240
+ * @returns 请求结果
241
+ *
242
+ * @example 基础用法
243
+ * ```ts
244
+ * import { Request } from '@snack-kit/lib/http'
245
+ *
246
+ * const result = await Request<{ id: number }>({ url: '/api/user', method: 'GET' })
247
+ * if (result.error) {
248
+ * console.error(result.error.message)
249
+ * } else {
250
+ * console.log(result.data)
251
+ * }
252
+ * ```
253
+ *
254
+ * @example 使用 ctx 自动注入 baseURL
255
+ * ```ts
256
+ * import { context, Request } from '@snack-kit/lib/http'
257
+ *
258
+ * await context.load({ 'user-svc': 'http://user.api.com' })
259
+ * const result = await Request({ url: '/profile', method: 'GET', ctx: 'user-svc' })
260
+ * // 实际请求:GET http://user.api.com/profile
261
+ * ```
262
+ */
263
+ declare function Request<T>(config: HttpRequestConfig): Promise<HttpResult<T>>;
264
+ /**
265
+ * 发起 GET 请求
266
+ *
267
+ * @param url 请求地址
268
+ * @param config 请求配置
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * import { Get } from '@snack-kit/lib/http'
273
+ *
274
+ * const { data, error } = await Get<{ name: string }>('/api/user/1')
275
+ * if (!error) console.log(data?.name)
276
+ * ```
277
+ *
278
+ * @example 使用 ctx 自动路由
279
+ * ```ts
280
+ * const { data } = await Get('/profile', { ctx: 'user-svc' })
281
+ * ```
282
+ *
283
+ * @example 获取 cancelId 以便主动取消
284
+ * ```ts
285
+ * let cancelId = ''
286
+ * Get('/api/list', { onCancelId: (id) => { cancelId = id } })
287
+ * Cancel(cancelId) // 取消请求
288
+ * ```
289
+ */
290
+ declare function Get<T>(url: string, config?: HttpRequestConfig): Promise<HttpResult<T>>;
291
+ /**
292
+ * 发起 POST 请求
293
+ *
294
+ * @param url 请求地址
295
+ * @param data 请求体数据
296
+ * @param config 请求配置
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * import { Post } from '@snack-kit/lib/http'
301
+ *
302
+ * const { data, error } = await Post<{ token: string }>('/api/login', {
303
+ * username: 'admin',
304
+ * password: '123456',
305
+ * })
306
+ * if (!error) console.log(data?.token)
307
+ * ```
308
+ */
309
+ declare function Post<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<HttpResult<T>>;
310
+ /**
311
+ * 发起 PUT 请求
312
+ *
313
+ * @param url 请求地址
314
+ * @param data 请求体数据
315
+ * @param config 请求配置
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * import { Put } from '@snack-kit/lib/http'
320
+ *
321
+ * await Put('/api/user/1', { name: 'Alice' })
322
+ * ```
323
+ */
324
+ declare function Put<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<HttpResult<T>>;
325
+ /**
326
+ * 发起 PATCH 请求
327
+ *
328
+ * @param url 请求地址
329
+ * @param data 请求体数据
330
+ * @param config 请求配置
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * import { Patch } from '@snack-kit/lib/http'
335
+ *
336
+ * await Patch('/api/user/1', { avatar: 'https://...' })
337
+ * ```
338
+ */
339
+ declare function Patch<T>(url: string, data?: unknown, config?: HttpRequestConfig): Promise<HttpResult<T>>;
340
+ /**
341
+ * 发起 DELETE 请求
342
+ *
343
+ * @param url 请求地址
344
+ * @param config 请求配置
345
+ *
346
+ * @example
347
+ * ```ts
348
+ * import { Del } from '@snack-kit/lib/http'
349
+ *
350
+ * await Del('/api/user/1')
351
+ * ```
352
+ */
353
+ declare function Del<T>(url: string, config?: HttpRequestConfig): Promise<HttpResult<T>>;
354
+
355
+ export { Cancel, CancelAll, Context, type ContextInfo, Ctx, Del, Get, HttpContext, type HttpError, type HttpRequestConfig, type HttpResult, Origin, Patch, Post, Put, Request, type ServerItem };
@@ -0,0 +1,7 @@
1
+ export { Cancel, CancelAll, Context, ContextInfo, Ctx, Del, Get, HttpContext, HttpError, HttpRequestConfig, HttpResult, Origin, Patch, Post, Put, Request, ServerItem } from './http.js';
2
+ export { Debugger, DebuggerOptions } from './debugger.js';
3
+ import 'axios';
4
+
5
+ var version = "0.1.0";
6
+
7
+ export { version as VERSION };