@leaflow/sdk 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,34 @@
1
1
  # leaflow-ts
2
2
 
3
- Leaflow 平台的 TypeScript SDK(`@leaflow/sdk`)
4
- `gen/` 下全是产物,源在 `LeaflowNET/leaflowapis`。
3
+ Leaflow 平台的 TypeScript SDK(`@leaflow/sdk`),由
4
+ [leaflowapis](https://github.com/leaflowapis/leaflowapis) 生成。
5
5
 
6
- ## 为什么和 Go 分开在两个仓库
6
+ ```
7
+ npm i @leaflow/sdk openapi-fetch
8
+ ```
7
9
 
8
- **它们在同一个仓库里会抢同一个 tag 空间。** Go 的子目录模块要 `go/v1.2.3` 这种带前缀的 tag,
9
- npm 要 `v1.2.3`——上一版两者挤在一个仓库里,结果是 Go 那半从来没被正确发布过,而没有任何东西
10
- 会报错(`go get` 只是拿不到)。
10
+ 当前只含类型。请求由 `openapi-fetch` 发出,路径与参数由契约约束。
11
11
 
12
- ## 契约是一个 submodule
12
+ ```ts
13
+ import createClient from 'openapi-fetch';
14
+ import type { compute } from '@leaflow/sdk';
13
15
 
16
+ const api = createClient<compute.paths>({
17
+ baseUrl: 'https://compute.leaflow.cloud',
18
+ headers: { Authorization: `Bearer ${token}` },
19
+ });
20
+
21
+ const { data, error } = await api.GET('/api/v1/instances', {
22
+ params: { query: { limit: 20 } },
23
+ });
14
24
  ```
15
- leaflowapis/ 钉在某一个 commit 上——那个指针就是「这版 SDK 出自哪版契约」的答案
16
- ```
25
+
26
+ 每个操作另有 `<操作>Result` / `<操作>Body` / `<操作>Query` 三个类型别名。
27
+
28
+ ## 重新生成
17
29
 
18
30
  ```
19
- git submodule update --remote leaflowapis # 要跟进新契约时才做
20
31
  npm run generate
21
32
  ```
22
33
 
23
- 产物由人在本地跑完提交,CI 只验证不写回:一个会 commit 回来的流水线,在两次推送挨得近时只能靠
24
- 重试或者强推——前者会打架,后者会丢东西。
34
+ 契约版本记在 `CONTRACTS_REF`。
@@ -1,5 +1,7 @@
1
1
  export type { paths, components, operations, webhooks } from "./schema.js";
2
2
  import type { operations } from "./schema.js";
3
+ /** `GET /account/v1/settings` 成功时的响应体。 */
4
+ export type GetSettingsResult = operations["get-settings"]["responses"][200]["content"]["application/json"];
3
5
  /** `GET /account/v1/agreements` 成功时的响应体。 */
4
6
  export type ListAgreementsResult = operations["list-agreements"]["responses"][200]["content"]["application/json"];
5
7
  /** `GET /account/v1/me/consents` 成功时的响应体。 */
@@ -3,6 +3,30 @@
3
3
  * Do not make direct changes to the file.
4
4
  */
5
5
  export interface paths {
6
+ "/account/v1/settings": {
7
+ parameters: {
8
+ query?: never;
9
+ header?: never;
10
+ path?: never;
11
+ cookie?: never;
12
+ };
13
+ /**
14
+ * 这个平台现在收不收人
15
+ * @description 注册页和「新建项目」按钮用它决定画什么。不需要令牌。
16
+ *
17
+ * `registration_mode` 不是 `OPEN` 时 `POST /account/v1/register` 会答 403:`CLOSED` 是整个关着,`INVITE_ONLY` 是只收手上有项目邀请的邮箱。`project_creation_mode` 同理,`VERIFIED_ONLY` 要先过实名。
18
+ *
19
+ * 两条配额是 0 表示不限。它们只用来提前提示,真正的判定在写入那一刻。
20
+ */
21
+ get: operations["get-settings"];
22
+ put?: never;
23
+ post?: never;
24
+ delete?: never;
25
+ options?: never;
26
+ head?: never;
27
+ patch?: never;
28
+ trace?: never;
29
+ };
6
30
  "/account/v1/agreements": {
7
31
  parameters: {
8
32
  query?: never;
@@ -242,6 +266,28 @@ export interface components {
242
266
  /** Format: int64 */
243
267
  status: number;
244
268
  };
269
+ SettingsResource: {
270
+ /**
271
+ * Format: int64
272
+ * @description 一个项目最多几个成员,0 表示不限
273
+ */
274
+ max_members_per_project: number;
275
+ /**
276
+ * Format: int64
277
+ * @description 你最多能当几个项目的所有者,0 表示不限。已删除的项目不算在内
278
+ */
279
+ max_projects_per_user: number;
280
+ /**
281
+ * @description VERIFIED_ONLY 要求先过实名,审核中不算
282
+ * @enum {string}
283
+ */
284
+ project_creation_mode: "OPEN" | "VERIFIED_ONLY" | "CLOSED";
285
+ /**
286
+ * @description INVITE_ONLY 是只收手上有项目邀请的邮箱
287
+ * @enum {string}
288
+ */
289
+ registration_mode: "OPEN" | "INVITE_ONLY" | "CLOSED";
290
+ };
245
291
  AgreementResource: {
246
292
  /**
247
293
  * Format: date-time
@@ -448,6 +494,35 @@ export interface components {
448
494
  }
449
495
  export type $defs = Record<string, never>;
450
496
  export interface operations {
497
+ "get-settings": {
498
+ parameters: {
499
+ query?: never;
500
+ header?: never;
501
+ path?: never;
502
+ cookie?: never;
503
+ };
504
+ requestBody?: never;
505
+ responses: {
506
+ /** @description OK */
507
+ 200: {
508
+ headers: {
509
+ [name: string]: unknown;
510
+ };
511
+ content: {
512
+ "application/json": components["schemas"]["SettingsResource"];
513
+ };
514
+ };
515
+ /** @description Error */
516
+ default: {
517
+ headers: {
518
+ [name: string]: unknown;
519
+ };
520
+ content: {
521
+ "application/json": components["schemas"]["Error"];
522
+ };
523
+ };
524
+ };
525
+ };
451
526
  "list-agreements": {
452
527
  parameters: {
453
528
  query?: never;
@@ -202,6 +202,10 @@ export type CreateSecurityGroupResult = operations["create-security-group"]["res
202
202
  export type CreateSecurityGroupBody = NonNullable<operations["create-security-group"]["requestBody"]>["content"]["application/json"];
203
203
  /** `GET /api/v1/security-groups/{securityGroupId}` 成功时的响应体。 */
204
204
  export type GetSecurityGroupResult = operations["get-security-group"]["responses"][200]["content"]["application/json"];
205
+ /** `PATCH /api/v1/security-groups/{securityGroupId}` 成功时的响应体。 */
206
+ export type RenameSecurityGroupResult = operations["rename-security-group"]["responses"][200]["content"]["application/json"];
207
+ /** `PATCH /api/v1/security-groups/{securityGroupId}` 的请求体。 */
208
+ export type RenameSecurityGroupBody = NonNullable<operations["rename-security-group"]["requestBody"]>["content"]["application/json"];
205
209
  /** `GET /api/v1/security-groups/{securityGroupId}/rules` 成功时的响应体。 */
206
210
  export type ListSecurityGroupRulesResult = operations["list-security-group-rules"]["responses"][200]["content"]["application/json"];
207
211
  /** `POST /api/v1/security-groups/{securityGroupId}/rules` 成功时的响应体。 */
@@ -1035,7 +1035,11 @@ export interface paths {
1035
1035
  delete: operations["delete-security-group"];
1036
1036
  options?: never;
1037
1037
  head?: never;
1038
- patch?: never;
1038
+ /**
1039
+ * 重命名安全组
1040
+ * @description 仅可修改名称,规则请用规则接口。
1041
+ */
1042
+ patch: operations["rename-security-group"];
1039
1043
  trace?: never;
1040
1044
  };
1041
1045
  "/api/v1/security-groups/{securityGroupId}/rules": {
@@ -1795,6 +1799,9 @@ export interface components {
1795
1799
  disk_id: string;
1796
1800
  name: string;
1797
1801
  };
1802
+ RenameSecurityGroupRequestBody: {
1803
+ name: string;
1804
+ };
1798
1805
  RenameSnapshotRequestBody: {
1799
1806
  name: string;
1800
1807
  };
@@ -4183,6 +4190,41 @@ export interface operations {
4183
4190
  };
4184
4191
  };
4185
4192
  };
4193
+ "rename-security-group": {
4194
+ parameters: {
4195
+ query?: never;
4196
+ header?: never;
4197
+ path: {
4198
+ securityGroupId: string;
4199
+ };
4200
+ cookie?: never;
4201
+ };
4202
+ requestBody: {
4203
+ content: {
4204
+ "application/json": components["schemas"]["RenameSecurityGroupRequestBody"];
4205
+ };
4206
+ };
4207
+ responses: {
4208
+ /** @description OK */
4209
+ 200: {
4210
+ headers: {
4211
+ [name: string]: unknown;
4212
+ };
4213
+ content: {
4214
+ "application/json": components["schemas"]["SecurityGroupResource"];
4215
+ };
4216
+ };
4217
+ /** @description Error */
4218
+ default: {
4219
+ headers: {
4220
+ [name: string]: unknown;
4221
+ };
4222
+ content: {
4223
+ "application/json": components["schemas"]["Error"];
4224
+ };
4225
+ };
4226
+ };
4227
+ };
4186
4228
  "list-security-group-rules": {
4187
4229
  parameters: {
4188
4230
  query?: never;
@@ -1,38 +1,16 @@
1
1
  export type { paths, components, operations, webhooks } from "./schema.js";
2
2
  import type { operations } from "./schema.js";
3
- /** `GET /api/v1/operation-logs` 成功时的响应体。 */
4
- export type ListTunnelOperationLogsResult = operations["list-tunnel-operation-logs"]["responses"][200]["content"]["application/json"];
5
- /** `GET /api/v1/operation-logs` 的查询参数。 */
6
- export type ListTunnelOperationLogsQuery = operations["list-tunnel-operation-logs"]["parameters"]["query"];
7
- /** `GET /api/v1/plans` 成功时的响应体。 */
8
- export type ListTunnelPlansResult = operations["list-tunnel-plans"]["responses"][200]["content"]["application/json"];
9
- /** `DELETE /api/v1/tunnel` 成功时的响应体。 */
10
- export type CloseTunnelResult = operations["close-tunnel"]["responses"][200]["content"]["application/json"];
11
- /** `GET /api/v1/tunnel` 成功时的响应体。 */
12
- export type GetTunnelResult = operations["get-tunnel"]["responses"][200]["content"]["application/json"];
13
- /** `PATCH /api/v1/tunnel` 成功时的响应体。 */
14
- export type UpdateTunnelProfileResult = operations["update-tunnel-profile"]["responses"][200]["content"]["application/json"];
15
- /** `PATCH /api/v1/tunnel` 的请求体。 */
16
- export type UpdateTunnelProfileBody = NonNullable<operations["update-tunnel-profile"]["requestBody"]>["content"]["application/json"];
17
- /** `POST /api/v1/tunnel` 成功时的响应体。 */
18
- export type OpenTunnelResult = operations["open-tunnel"]["responses"][201]["content"]["application/json"];
19
- /** `POST /api/v1/tunnel` 的请求体。 */
20
- export type OpenTunnelBody = NonNullable<operations["open-tunnel"]["requestBody"]>["content"]["application/json"];
21
- /** `POST /api/v1/tunnel/actions` 成功时的响应体。 */
22
- export type ActOnTunnelResult = operations["act-on-tunnel"]["responses"][200]["content"]["application/json"];
23
- /** `POST /api/v1/tunnel/actions` 的请求体。 */
24
- export type ActOnTunnelBody = NonNullable<operations["act-on-tunnel"]["requestBody"]>["content"]["application/json"];
25
- /** `PUT /api/v1/tunnel/plan` 成功时的响应体。 */
26
- export type ChangeTunnelPlanResult = operations["change-tunnel-plan"]["responses"][200]["content"]["application/json"];
27
- /** `PUT /api/v1/tunnel/plan` 的请求体。 */
28
- export type ChangeTunnelPlanBody = NonNullable<operations["change-tunnel-plan"]["requestBody"]>["content"]["application/json"];
29
- /** `GET /api/v1/tunnel/subscription` 成功时的响应体。 */
30
- export type GetTunnelSubscriptionResult = operations["get-tunnel-subscription"]["responses"][200]["content"]["application/json"];
31
- /** `POST /api/v1/tunnel/subscription/rotate` 成功时的响应体。 */
32
- export type RotateTunnelSubscriptionResult = operations["rotate-tunnel-subscription"]["responses"][200]["content"]["application/json"];
33
- /** `GET /api/v1/tunnel/usage` 成功时的响应体。 */
34
- export type GetTunnelUsageResult = operations["get-tunnel-usage"]["responses"][200]["content"]["application/json"];
35
- /** `GET /api/v1/tunnel/usage/series` 成功时的响应体。 */
36
- export type ListTunnelUsageSeriesResult = operations["list-tunnel-usage-series"]["responses"][200]["content"]["application/json"];
37
- /** `GET /api/v1/tunnel/usage/series` 的查询参数。 */
38
- export type ListTunnelUsageSeriesQuery = operations["list-tunnel-usage-series"]["parameters"]["query"];
3
+ /** `GET /api/v1/tunnel/l4` 成功时的响应体。 */
4
+ export type GetL4TunnelResult = operations["get-l4-tunnel"]["responses"][200]["content"]["application/json"];
5
+ /** `POST /api/v1/tunnel/l4` 成功时的响应体。 */
6
+ export type GenerateL4TunnelResult = operations["generate-l4-tunnel"]["responses"][200]["content"]["application/json"];
7
+ /** `GET /api/v1/tunnel/l4/subscription` 成功时的响应体。 */
8
+ export type GetL4TunnelSubscriptionResult = operations["get-l4-tunnel-subscription"]["responses"][200]["content"]["application/json"];
9
+ /** `POST /api/v1/tunnel/l4/subscription/rotate` 成功时的响应体。 */
10
+ export type RotateL4TunnelSubscriptionResult = operations["rotate-l4-tunnel-subscription"]["responses"][200]["content"]["application/json"];
11
+ /** `GET /api/v1/tunnel/l4/usage` 成功时的响应体。 */
12
+ export type GetL4TunnelUsageResult = operations["get-l4-tunnel-usage"]["responses"][200]["content"]["application/json"];
13
+ /** `GET /api/v1/tunnel/l4/usage/series` 成功时的响应体。 */
14
+ export type ListL4TunnelUsageSeriesResult = operations["list-l4-tunnel-usage-series"]["responses"][200]["content"]["application/json"];
15
+ /** `GET /api/v1/tunnel/l4/usage/series` 的查询参数。 */
16
+ export type ListL4TunnelUsageSeriesQuery = operations["list-l4-tunnel-usage-series"]["parameters"]["query"];
@@ -3,7 +3,7 @@
3
3
  * Do not make direct changes to the file.
4
4
  */
5
5
  export interface paths {
6
- "/api/v1/operation-logs": {
6
+ "/api/v1/tunnel/l4": {
7
7
  parameters: {
8
8
  query?: never;
9
9
  header?: never;
@@ -11,135 +11,27 @@ export interface paths {
11
11
  cookie?: never;
12
12
  };
13
13
  /**
14
- * 查看本项目的操作日志
15
- * @description 记录每一次**写**操作:谁、什么时候、做了什么、成功还是失败。读操作不记录。
14
+ * 查看本项目的四层隧道
15
+ * @description 还没生成过时返回 `TUNNEL_NOT_FOUND`——首屏据此决定画「生成订阅链接」那个按钮还是画结果。
16
16
  *
17
- * `actor` 为 null 表示该操作由平台执行(例如自动重试删除、项目停服)——平台做了什么是看得到的,但具体是哪位运营人员不会展示。
18
- *
19
- * `payload` 只包含路径参数与查询串,且其中像凭据的字段已被替换为占位符。
20
- */
21
- get: operations["list-tunnel-operation-logs"];
22
- put?: never;
23
- post?: never;
24
- delete?: never;
25
- options?: never;
26
- head?: never;
27
- patch?: never;
28
- trace?: never;
29
- };
30
- "/api/v1/plans": {
31
- parameters: {
32
- query?: never;
33
- header?: never;
34
- path?: never;
35
- cookie?: never;
36
- };
37
- /**
38
- * 列出可开通的套餐
39
- * @description 只返回在售的套餐,按 `sort` 升序。已下架的不在其中——但正在用它的隧道仍然正常,下架只是不再接新单。
40
- *
41
- * `quota_bytes` 是套餐**标称**的额度,仅供比较;实际额度由上游按线路分组决定,以隧道用量接口返回的 `quota_bytes` 为准。
42
- */
43
- get: operations["list-tunnel-plans"];
44
- put?: never;
45
- post?: never;
46
- delete?: never;
47
- options?: never;
48
- head?: never;
49
- patch?: never;
50
- trace?: never;
51
- };
52
- "/api/v1/tunnel": {
53
- parameters: {
54
- query?: never;
55
- header?: never;
56
- path?: never;
57
- cookie?: never;
58
- };
59
- /**
60
- * 查看本项目的隧道
61
- * @description 每个项目最多一条隧道。尚未开通时返回 404(`TUNNEL_NOT_FOUND`)。
62
- *
63
- * 响应里的 `usage` 是**缓存**的用量,`usage.synced_at` 说明它是什么时候采集的;为 null 表示尚未采集过,而不是用量为零。需要当前值请调用量接口。
64
- *
65
- * **订阅地址不在这里**,它是一条长期有效的凭据,只由订阅接口单独返回。
66
- */
67
- get: operations["get-tunnel"];
68
- put?: never;
69
- /**
70
- * 开通隧道
71
- * @description 为当前项目开通一条隧道,返回时订阅通常处于 `preparing`——节点仍在下发,但**订阅地址此时已经可用**,内容会在拉取那一刻按当时的状态重新派生。
72
- *
73
- * 一个项目只能有一条。已经有了返回 `TUNNEL_ALREADY_OPEN`;上一条还在退订中返回 `TUNNEL_CLOSING`,稍后重试即可。
74
- *
75
- * 套餐必须处于在售状态,已下架的返回 `TUNNEL_PLAN_RETIRED`。若返回 `TUNNEL_PLAN_GROUPS_MISSING`,说明该套餐在上游对应的线路分组不存在——这是一个配置问题,请联系运营,换一款套餐或稍后重试都不会有帮助。
76
- */
77
- post: operations["open-tunnel"];
78
- /**
79
- * 退订隧道
80
- * @description **不可逆。** 上游账户会被删除,订阅地址立刻失效,重新开通得到的是一条全新的隧道和一条全新的订阅地址。
81
- *
82
- * 删除是异步的:返回时 `status` 可能仍是 `deleting`,表示上游还没删干净(通常是某台服务器暂时连不上)。平台会自动重试,期间这条隧道仍然出现在查询接口里。退订完成前无法重新开通。
83
- *
84
- * 只是暂时不用的话请用停用,它保留端口和订阅地址。
85
- */
86
- delete: operations["close-tunnel"];
87
- options?: never;
88
- head?: never;
89
- /**
90
- * 修改隧道的显示信息
91
- * @description 改显示名和联系邮箱,**不影响订阅、用量或线路**。
92
- *
93
- * `email` 不传表示不改动,传空字符串表示清空。它会被转发给上游面板——上游拿它做什么由面板决定,平台不使用它。
17
+ * 订阅地址、用量、配额各有自己的接口,这里不重复返回。
94
18
  */
95
- patch: operations["update-tunnel-profile"];
96
- trace?: never;
97
- };
98
- "/api/v1/tunnel/actions": {
99
- parameters: {
100
- query?: never;
101
- header?: never;
102
- path?: never;
103
- cookie?: never;
104
- };
105
- get?: never;
19
+ get: operations["get-l4-tunnel"];
106
20
  put?: never;
107
21
  /**
108
- * 启用或停用隧道
109
- * @description **停用不是退订。** 停用会把这条隧道的实例从上游调度器撤下,但端口保留,重新启用后原样回来,订阅地址也不变。适合「这段时间不用」。
110
- *
111
- * 被平台停用的隧道(`suspended` 为 true)无法自行启用,会返回 `TUNNEL_SUSPENDED`——那通常是欠费或违规,需要先处理对应的问题。
112
- */
113
- post: operations["act-on-tunnel"];
114
- delete?: never;
115
- options?: never;
116
- head?: never;
117
- patch?: never;
118
- trace?: never;
119
- };
120
- "/api/v1/tunnel/plan": {
121
- parameters: {
122
- query?: never;
123
- header?: never;
124
- path?: never;
125
- cookie?: never;
126
- };
127
- get?: never;
128
- /**
129
- * 更换套餐
130
- * @description 换套餐会立刻重判线路资格:多出来的线路马上可用,**少掉的那些进入删除队列——宽限期内照常可用,到期才真正释放**。所以换套餐不是一次瞬时切换,订阅内容会在接下来一段时间内变化。
22
+ * 生成四层隧道
23
+ * @description **幂等**:已经有了再调一次返回同一条,不报错。按钮被点两次是安全的。
131
24
  *
132
- * 换完之后建议重新拉取一次订阅。
25
+ * 生成之后请调订阅接口取地址,本接口不返回它。
133
26
  */
134
- put: operations["change-tunnel-plan"];
135
- post?: never;
27
+ post: operations["generate-l4-tunnel"];
136
28
  delete?: never;
137
29
  options?: never;
138
30
  head?: never;
139
31
  patch?: never;
140
32
  trace?: never;
141
33
  };
142
- "/api/v1/tunnel/subscription": {
34
+ "/api/v1/tunnel/l4/subscription": {
143
35
  parameters: {
144
36
  query?: never;
145
37
  header?: never;
@@ -148,15 +40,13 @@ export interface paths {
148
40
  };
149
41
  /**
150
42
  * 获取订阅地址
151
- * @description **返回的是一条长期有效的凭据,等同于密码。** 拿到它就能取得本项目全部节点与密码,请勿转发、截图或提交到工单。
152
- *
153
- * 它不会出现在隧道详情或任何列表里,只由这个接口返回。
43
+ * @description **这条 URL 是凭据,等同于密码。** 拿着它就能取到这个项目的全部节点和密码,所以它只在这一个接口里出现,一次一条——不进任何列表,也不在隧道详情里。
154
44
  *
155
- * `status` 为 `preparing` 时链接**照样可用**,内容会在拉取那一刻按当时的状态重新派生。
45
+ * 客户端不应在用户主动请求之前调用它:这个接口的每一次调用都会被记进操作日志。
156
46
  *
157
- * 怀疑泄露时请调用重置接口。
47
+ * `status` 为 `preparing` 时链接**照样有效**,内容会在拉取那一刻重新派生。它只该影响页面上说什么。
158
48
  */
159
- get: operations["get-tunnel-subscription"];
49
+ get: operations["get-l4-tunnel-subscription"];
160
50
  put?: never;
161
51
  post?: never;
162
52
  delete?: never;
@@ -165,7 +55,7 @@ export interface paths {
165
55
  patch?: never;
166
56
  trace?: never;
167
57
  };
168
- "/api/v1/tunnel/subscription/rotate": {
58
+ "/api/v1/tunnel/l4/subscription/rotate": {
169
59
  parameters: {
170
60
  query?: never;
171
61
  header?: never;
@@ -180,16 +70,18 @@ export interface paths {
180
70
  *
181
71
  * 订阅 token 和节点密码同时更换,所有客户端都必须重新拉取一次订阅才能继续使用。调用前请确认这确实是想要的结果。
182
72
  *
183
- * 重置后再调订阅接口取新地址。
73
+ * 隧道被平台停用时无法重置(`TUNNEL_DISABLED_FOR_ROTATE`),需要先处理停用的原因。
74
+ *
75
+ * 重置后请调订阅接口取新地址,**本接口不返回它**。
184
76
  */
185
- post: operations["rotate-tunnel-subscription"];
77
+ post: operations["rotate-l4-tunnel-subscription"];
186
78
  delete?: never;
187
79
  options?: never;
188
80
  head?: never;
189
81
  patch?: never;
190
82
  trace?: never;
191
83
  };
192
- "/api/v1/tunnel/usage": {
84
+ "/api/v1/tunnel/l4/usage": {
193
85
  parameters: {
194
86
  query?: never;
195
87
  header?: never;
@@ -198,13 +90,11 @@ export interface paths {
198
90
  };
199
91
  /**
200
92
  * 查看本期用量
201
- * @description 现场向上游查询,比隧道详情里那份缓存新。
202
- *
203
- * **判断是否超额只看 `billed_bytes`**:线路可以设置倍率(如 1.5× 或 0×),`raw_bytes` 是实际传输量,两者不一定相等。`over_quota` 已经算好。
93
+ * @description 实时查询,不经过缓存。
204
94
  *
205
- * 用量由上游定期采集,**最多滞后一个采集周期**,适合用量管控,不适合作为计费结算依据。
95
+ * 判断是否超额只看 `billed_bytes`:线路可以设置倍率(如 1.5× 或 0×),`raw_bytes` 是实际传输量,两者不一定相等。`quota_bytes` 为 0 表示不限量。
206
96
  */
207
- get: operations["get-tunnel-usage"];
97
+ get: operations["get-l4-tunnel-usage"];
208
98
  put?: never;
209
99
  post?: never;
210
100
  delete?: never;
@@ -213,7 +103,7 @@ export interface paths {
213
103
  patch?: never;
214
104
  trace?: never;
215
105
  };
216
- "/api/v1/tunnel/usage/series": {
106
+ "/api/v1/tunnel/l4/usage/series": {
217
107
  parameters: {
218
108
  query?: never;
219
109
  header?: never;
@@ -222,13 +112,11 @@ export interface paths {
222
112
  };
223
113
  /**
224
114
  * 查看按天用量
225
- * @description 按**自然日**切分,用于画趋势图。
226
- *
227
- * **没有流量的日子不会出现在结果里**(不补零),画图前需要自行补齐日期轴,否则空档会被连成一条斜线。
115
+ * @description 按自然日切分。没有流量的日子不会出现在结果里(不补零),画图那一侧要自己补齐日期轴——否则一段没人用的日子会被画成一条直接连过去的线,看起来像那几天一直在匀速跑流量。
228
116
  *
229
- * **把这里的天加起来不等于本期用量**,这是有意的:本期用量按计费周期切,而且「重置本期用量」只作用于本期,日汇总一行都不删。两者回答的是不同的问题。
117
+ * 把这里的天加起来**不等于**本期用量,这是有意的:本期按计费周期切,而且「重置本期用量」只作用于本期,日汇总一行都不删。
230
118
  */
231
- get: operations["list-tunnel-usage-series"];
119
+ get: operations["list-l4-tunnel-usage-series"];
232
120
  put?: never;
233
121
  post?: never;
234
122
  delete?: never;
@@ -250,152 +138,6 @@ export interface components {
250
138
  /** Format: int64 */
251
139
  status: number;
252
140
  };
253
- OperationLogResource: {
254
- action: string;
255
- /** @description 操作者的用户 id;null 表示由平台执行 */
256
- actor: string | null;
257
- /** Format: date-time */
258
- created_at: string;
259
- failure: string;
260
- /** Format: uuid */
261
- id: string;
262
- payload: {
263
- [key: string]: unknown;
264
- };
265
- subject_id: string;
266
- subject_type: string;
267
- succeeded: boolean;
268
- };
269
- LengthAwarePageOperationLogResource: {
270
- /** @description 这一页的内容 */
271
- items: components["schemas"]["OperationLogResource"][];
272
- /**
273
- * Format: int64
274
- * @description 这一页最多几条,回显请求里的值
275
- */
276
- limit: number;
277
- /**
278
- * Format: int64
279
- * @description 跳过了多少条,回显请求里的值
280
- */
281
- offset: number;
282
- /**
283
- * Format: int64
284
- * @description 命中的总条数,不只是这一页
285
- */
286
- total: number;
287
- };
288
- TunnelPlanResource: {
289
- description: string;
290
- /** Format: uuid */
291
- id: string;
292
- name: string;
293
- /**
294
- * Format: int64
295
- * @description 套餐标称的流量额度,仅供比较。实际额度以隧道用量接口返回的 quota_bytes 为准
296
- */
297
- quota_bytes: number;
298
- /**
299
- * Format: int64
300
- * @description 货架上的排列顺序,越小越靠前
301
- */
302
- sort: number;
303
- };
304
- TunnelPlanListResponseBody: {
305
- items: components["schemas"]["TunnelPlanResource"][];
306
- };
307
- TunnelUsageSnapshot: {
308
- /**
309
- * Format: int64
310
- * @description 按线路倍率折算后的用量,配额比对以此为准
311
- */
312
- billed_bytes: number;
313
- /** @description billed_bytes 是否已超过 quota_bytes;配额为 0 时恒为 false */
314
- over_quota: boolean;
315
- /**
316
- * Format: int64
317
- * @description 上游给出的真实配额,0 表示不限量
318
- */
319
- quota_bytes: number;
320
- /**
321
- * Format: int64
322
- * @description 实际传输的字节,不用于配额比对
323
- */
324
- raw_bytes: number;
325
- /**
326
- * Format: date-time
327
- * @description 这份用量是什么时候采集的;null 表示尚未采集
328
- */
329
- synced_at: string | null;
330
- /** Format: int64 */
331
- upload_bytes: number;
332
- };
333
- TunnelResource: {
334
- /** Format: date-time */
335
- created_at: string;
336
- display_name: string;
337
- /** @description 转发给上游面板的联系邮箱;平台不使用它 */
338
- email: string | null;
339
- /** @description 用户自己的开关。停用会把实例从调度器撤下,但端口保留,启用后原样回来 */
340
- enabled: boolean;
341
- /** @description 最近一次上游拒绝的说明,仅在存在时非空 */
342
- failure: string | null;
343
- /** Format: uuid */
344
- id: string;
345
- /** Format: uuid */
346
- plan_id: string;
347
- plan_name: string;
348
- /**
349
- * @description deleting 表示已退订但上游尚未删除完成
350
- * @enum {string}
351
- */
352
- status: "active" | "deleting";
353
- /**
354
- * @description preparing 表示节点仍在下发;订阅链接此时照样可用
355
- * @enum {string}
356
- */
357
- subscription_status: "preparing" | "ready";
358
- /**
359
- * Format: int64
360
- * @description 每次重置订阅后递增
361
- */
362
- subscription_version: number;
363
- /** @description 被平台停用(欠费、违规或项目停服)。为 true 时无法自行启用 */
364
- suspended: boolean;
365
- /**
366
- * Format: date-time
367
- * @description 被平台停用的时刻
368
- */
369
- suspended_at: string | null;
370
- usage: components["schemas"]["TunnelUsageSnapshot"];
371
- };
372
- OpenTunnelRequestBody: {
373
- /** @description 这条隧道的名字,只影响显示 */
374
- display_name: string;
375
- /**
376
- * Format: email
377
- * @description 转发给上游面板的联系邮箱,可留空
378
- */
379
- email?: string;
380
- /**
381
- * Format: uuid
382
- * @description 套餐 id,取自 GET /plans
383
- */
384
- plan_id: string;
385
- };
386
- UpdateTunnelProfileRequestBody: {
387
- display_name: string;
388
- /** @description 联系邮箱。不传表示不改动,传空字符串表示清空 */
389
- email?: string | null;
390
- };
391
- ActOnTunnelRequestBody: {
392
- /** @enum {string} */
393
- action: "enable" | "disable";
394
- };
395
- ChangeTunnelPlanRequestBody: {
396
- /** Format: uuid */
397
- plan_id: string;
398
- };
399
141
  SubscriptionResource: {
400
142
  /**
401
143
  * @description ready 表示节点已全部下发;preparing 表示仍在下发——此时链接照样可用
@@ -409,6 +151,23 @@ export interface components {
409
151
  /** Format: int64 */
410
152
  version: number;
411
153
  };
154
+ /** @description 当前项目那条四层隧道。它只回答一个问题:生成过没有。 */
155
+ TunnelResource: {
156
+ /** Format: date-time */
157
+ created_at: string;
158
+ /** @description 隧道当前是否可用。为 false 表示被平台停用(欠费、违规或项目停服),需要先处理停用的原因 */
159
+ enabled: boolean;
160
+ /** Format: uuid */
161
+ id: string;
162
+ };
163
+ UsageDayResource: {
164
+ /** Format: int64 */
165
+ billed_bytes: number;
166
+ /** @description YYYY-MM-DD */
167
+ day: string;
168
+ /** Format: int64 */
169
+ raw_bytes: number;
170
+ };
412
171
  UsageResource: {
413
172
  /**
414
173
  * Format: int64
@@ -443,14 +202,6 @@ export interface components {
443
202
  */
444
203
  usage_percent: number;
445
204
  };
446
- UsageDayResource: {
447
- /** Format: int64 */
448
- billed_bytes: number;
449
- /** @description YYYY-MM-DD */
450
- day: string;
451
- /** Format: int64 */
452
- raw_bytes: number;
453
- };
454
205
  UsageSeriesResource: {
455
206
  /**
456
207
  * Format: int64
@@ -468,72 +219,7 @@ export interface components {
468
219
  }
469
220
  export type $defs = Record<string, never>;
470
221
  export interface operations {
471
- "list-tunnel-operation-logs": {
472
- parameters: {
473
- query?: {
474
- /** @description 这一页最多返回多少条 */
475
- limit?: number;
476
- /** @description 跳过多少条。要翻得更深请改用游标翻页的接口 */
477
- offset?: number;
478
- /** @description 只看某一种操作,取值是接口的 operation id,比如 open-tunnel */
479
- action?: string;
480
- };
481
- header?: never;
482
- path?: never;
483
- cookie?: never;
484
- };
485
- requestBody?: never;
486
- responses: {
487
- /** @description OK */
488
- 200: {
489
- headers: {
490
- [name: string]: unknown;
491
- };
492
- content: {
493
- "application/json": components["schemas"]["LengthAwarePageOperationLogResource"];
494
- };
495
- };
496
- /** @description Error */
497
- default: {
498
- headers: {
499
- [name: string]: unknown;
500
- };
501
- content: {
502
- "application/json": components["schemas"]["Error"];
503
- };
504
- };
505
- };
506
- };
507
- "list-tunnel-plans": {
508
- parameters: {
509
- query?: never;
510
- header?: never;
511
- path?: never;
512
- cookie?: never;
513
- };
514
- requestBody?: never;
515
- responses: {
516
- /** @description OK */
517
- 200: {
518
- headers: {
519
- [name: string]: unknown;
520
- };
521
- content: {
522
- "application/json": components["schemas"]["TunnelPlanListResponseBody"];
523
- };
524
- };
525
- /** @description Error */
526
- default: {
527
- headers: {
528
- [name: string]: unknown;
529
- };
530
- content: {
531
- "application/json": components["schemas"]["Error"];
532
- };
533
- };
534
- };
535
- };
536
- "get-tunnel": {
222
+ "get-l4-tunnel": {
537
223
  parameters: {
538
224
  query?: never;
539
225
  header?: never;
@@ -562,40 +248,7 @@ export interface operations {
562
248
  };
563
249
  };
564
250
  };
565
- "open-tunnel": {
566
- parameters: {
567
- query?: never;
568
- header?: never;
569
- path?: never;
570
- cookie?: never;
571
- };
572
- requestBody: {
573
- content: {
574
- "application/json": components["schemas"]["OpenTunnelRequestBody"];
575
- };
576
- };
577
- responses: {
578
- /** @description Created */
579
- 201: {
580
- headers: {
581
- [name: string]: unknown;
582
- };
583
- content: {
584
- "application/json": components["schemas"]["TunnelResource"];
585
- };
586
- };
587
- /** @description Error */
588
- default: {
589
- headers: {
590
- [name: string]: unknown;
591
- };
592
- content: {
593
- "application/json": components["schemas"]["Error"];
594
- };
595
- };
596
- };
597
- };
598
- "close-tunnel": {
251
+ "generate-l4-tunnel": {
599
252
  parameters: {
600
253
  query?: never;
601
254
  header?: never;
@@ -624,106 +277,7 @@ export interface operations {
624
277
  };
625
278
  };
626
279
  };
627
- "update-tunnel-profile": {
628
- parameters: {
629
- query?: never;
630
- header?: never;
631
- path?: never;
632
- cookie?: never;
633
- };
634
- requestBody: {
635
- content: {
636
- "application/json": components["schemas"]["UpdateTunnelProfileRequestBody"];
637
- };
638
- };
639
- responses: {
640
- /** @description OK */
641
- 200: {
642
- headers: {
643
- [name: string]: unknown;
644
- };
645
- content: {
646
- "application/json": components["schemas"]["TunnelResource"];
647
- };
648
- };
649
- /** @description Error */
650
- default: {
651
- headers: {
652
- [name: string]: unknown;
653
- };
654
- content: {
655
- "application/json": components["schemas"]["Error"];
656
- };
657
- };
658
- };
659
- };
660
- "act-on-tunnel": {
661
- parameters: {
662
- query?: never;
663
- header?: never;
664
- path?: never;
665
- cookie?: never;
666
- };
667
- requestBody: {
668
- content: {
669
- "application/json": components["schemas"]["ActOnTunnelRequestBody"];
670
- };
671
- };
672
- responses: {
673
- /** @description OK */
674
- 200: {
675
- headers: {
676
- [name: string]: unknown;
677
- };
678
- content: {
679
- "application/json": components["schemas"]["TunnelResource"];
680
- };
681
- };
682
- /** @description Error */
683
- default: {
684
- headers: {
685
- [name: string]: unknown;
686
- };
687
- content: {
688
- "application/json": components["schemas"]["Error"];
689
- };
690
- };
691
- };
692
- };
693
- "change-tunnel-plan": {
694
- parameters: {
695
- query?: never;
696
- header?: never;
697
- path?: never;
698
- cookie?: never;
699
- };
700
- requestBody: {
701
- content: {
702
- "application/json": components["schemas"]["ChangeTunnelPlanRequestBody"];
703
- };
704
- };
705
- responses: {
706
- /** @description OK */
707
- 200: {
708
- headers: {
709
- [name: string]: unknown;
710
- };
711
- content: {
712
- "application/json": components["schemas"]["TunnelResource"];
713
- };
714
- };
715
- /** @description Error */
716
- default: {
717
- headers: {
718
- [name: string]: unknown;
719
- };
720
- content: {
721
- "application/json": components["schemas"]["Error"];
722
- };
723
- };
724
- };
725
- };
726
- "get-tunnel-subscription": {
280
+ "get-l4-tunnel-subscription": {
727
281
  parameters: {
728
282
  query?: never;
729
283
  header?: never;
@@ -752,7 +306,7 @@ export interface operations {
752
306
  };
753
307
  };
754
308
  };
755
- "rotate-tunnel-subscription": {
309
+ "rotate-l4-tunnel-subscription": {
756
310
  parameters: {
757
311
  query?: never;
758
312
  header?: never;
@@ -781,7 +335,7 @@ export interface operations {
781
335
  };
782
336
  };
783
337
  };
784
- "get-tunnel-usage": {
338
+ "get-l4-tunnel-usage": {
785
339
  parameters: {
786
340
  query?: never;
787
341
  header?: never;
@@ -810,10 +364,10 @@ export interface operations {
810
364
  };
811
365
  };
812
366
  };
813
- "list-tunnel-usage-series": {
367
+ "list-l4-tunnel-usage-series": {
814
368
  parameters: {
815
369
  query?: {
816
- /** @description 取最近多少天,0 表示用上游的默认值(30)。上游只接受 1–365,超出会被它夹住 */
370
+ /** @description 取最近多少天。0 表示用上游的默认值(30)——上游只接受 1–365,超出会被它夹住 */
817
371
  days?: number;
818
372
  };
819
373
  header?: never;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@leaflow/sdk",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Leaflow 平台 API 的 TypeScript SDK",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/LeaflowNET/leaflow-ts.git"
8
+ "url": "git+https://github.com/leaflowapis/leaflow-ts.git"
9
9
  },
10
10
  "type": "module",
11
11
  "main": "./dist/index.js",