@leaflow/sdk 0.0.0-dev.9.gd1c7e65 → 0.0.0-dev.93.ga14702b

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,9 @@
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"];
5
+ /** `GET /account/v1/locales` 成功时的响应体。 */
6
+ export type ListLocalesResult = operations["list-locales"]["responses"][200]["content"]["application/json"];
3
7
  /** `GET /account/v1/agreements` 成功时的响应体。 */
4
8
  export type ListAgreementsResult = operations["list-agreements"]["responses"][200]["content"]["application/json"];
5
9
  /** `GET /account/v1/me/consents` 成功时的响应体。 */
@@ -14,6 +18,10 @@ export type RegisterResult = operations["register"]["responses"][201]["content"]
14
18
  export type RegisterBody = NonNullable<operations["register"]["requestBody"]>["content"]["application/json"];
15
19
  /** `GET /account/v1/me` 成功时的响应体。 */
16
20
  export type GetAccountResult = operations["get-account"]["responses"][200]["content"]["application/json"];
21
+ /** `PATCH /account/v1/me` 成功时的响应体。 */
22
+ export type UpdateAccountResult = operations["update-account"]["responses"][200]["content"]["application/json"];
23
+ /** `PATCH /account/v1/me` 的请求体。 */
24
+ export type UpdateAccountBody = NonNullable<operations["update-account"]["requestBody"]>["content"]["application/json"];
17
25
  /** `GET /account/v1/me/identity-verification` 成功时的响应体。 */
18
26
  export type GetIdentityVerificationResult = operations["get-identity-verification"]["responses"][200]["content"]["application/json"];
19
27
  /** `POST /account/v1/me/identity-verification` 成功时的响应体。 */
@@ -22,6 +30,8 @@ export type SubmitIdentityVerificationResult = operations["submit-identity-verif
22
30
  export type SubmitIdentityVerificationBody = NonNullable<operations["submit-identity-verification"]["requestBody"]>["content"]["application/json"];
23
31
  /** `GET /account/v1/me/invitations` 成功时的响应体。 */
24
32
  export type ListMyInvitationsResult = operations["list-my-invitations"]["responses"][200]["content"]["application/json"];
33
+ /** `GET /account/v1/me/invitations` 的查询参数。 */
34
+ export type ListMyInvitationsQuery = operations["list-my-invitations"]["parameters"]["query"];
25
35
  /** `POST /account/v1/me/invitations/accept` 成功时的响应体。 */
26
36
  export type AcceptInvitationByTokenResult = operations["accept-invitation-by-token"]["responses"][200]["content"]["application/json"];
27
37
  /** `POST /account/v1/me/invitations/accept` 的请求体。 */
@@ -30,6 +40,8 @@ export type AcceptInvitationByTokenBody = NonNullable<operations["accept-invitat
30
40
  export type AcceptInvitationResult = operations["accept-invitation"]["responses"][200]["content"]["application/json"];
31
41
  /** `GET /account/v1/projects` 成功时的响应体。 */
32
42
  export type ListProjectsResult = operations["list-projects"]["responses"][200]["content"]["application/json"];
43
+ /** `GET /account/v1/projects` 的查询参数。 */
44
+ export type ListProjectsQuery = operations["list-projects"]["parameters"]["query"];
33
45
  /** `POST /account/v1/projects` 成功时的响应体。 */
34
46
  export type CreateProjectResult = operations["create-project"]["responses"][201]["content"]["application/json"];
35
47
  /** `POST /account/v1/projects` 的请求体。 */
@@ -3,6 +3,52 @@
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
+ };
30
+ "/account/v1/locales": {
31
+ parameters: {
32
+ query?: never;
33
+ header?: never;
34
+ path?: never;
35
+ cookie?: never;
36
+ };
37
+ /**
38
+ * 注册页要用的国家/地区和语言清单
39
+ * @description 免认证:注册页在还没有账号的时候就要画出这两个下拉框。
40
+ * 国家名和排序都跟着 `Accept-Language` 走——一个英文用户看到的是 China 而不是「中国」, 而顺序按那种语言自己的规则(中文按拼音,英文按字母),不是按码点。头缺失时用简体中文。
41
+ * 清单来自 CLDR,不是我们自己维护的一份:ISO 3166 每年都改,而抄下来的那份不会跟着改。 已经退役的代码(苏联、南斯拉夫)和不是地方的代码(欧盟、联合国)都不在里面。
42
+ */
43
+ get: operations["list-locales"];
44
+ put?: never;
45
+ post?: never;
46
+ delete?: never;
47
+ options?: never;
48
+ head?: never;
49
+ patch?: never;
50
+ trace?: never;
51
+ };
6
52
  "/account/v1/agreements": {
7
53
  parameters: {
8
54
  query?: never;
@@ -90,7 +136,11 @@ export interface paths {
90
136
  delete?: never;
91
137
  options?: never;
92
138
  head?: never;
93
- patch?: never;
139
+ /**
140
+ * 改当前账号的国家/地区和语言
141
+ * @description 姓名和邮箱不在这里改:它们来自身份提供方,改了会在下一次登录同步时被覆盖回去。
142
+ */
143
+ patch: operations["update-account"];
94
144
  trace?: never;
95
145
  };
96
146
  "/account/v1/me/identity-verification": {
@@ -242,6 +292,28 @@ export interface components {
242
292
  /** Format: int64 */
243
293
  status: number;
244
294
  };
295
+ SettingsResource: {
296
+ /**
297
+ * Format: int64
298
+ * @description 一个项目最多几个成员,0 表示不限
299
+ */
300
+ max_members_per_project: number;
301
+ /**
302
+ * Format: int64
303
+ * @description 你最多能当几个项目的所有者,0 表示不限。已删除的项目不算在内
304
+ */
305
+ max_projects_per_user: number;
306
+ /**
307
+ * @description VERIFIED_ONLY 要求先过实名,审核中不算
308
+ * @enum {string}
309
+ */
310
+ project_creation_mode: "OPEN" | "VERIFIED_ONLY" | "CLOSED";
311
+ /**
312
+ * @description INVITE_ONLY 是只收手上有项目邀请的邮箱
313
+ * @enum {string}
314
+ */
315
+ registration_mode: "OPEN" | "INVITE_ONLY" | "CLOSED";
316
+ };
245
317
  AgreementResource: {
246
318
  /**
247
319
  * Format: date-time
@@ -293,6 +365,10 @@ export interface components {
293
365
  id: string;
294
366
  /** @description 来自登录信息,可能为空 */
295
367
  last_name: string;
368
+ /** @description ISO 3166-1 alpha-2。这两个字段是后加的,注册时才开始要求填——已经注册过的人这里 是空串,让他们在设置里补,补之前一切照常。 */
369
+ country?: string;
370
+ /** @description 为空表示没设过,那时按请求头(Accept-Language)走,两者都没有才用平台默认 */
371
+ locale?: string;
296
372
  pending_agreements: components["schemas"]["AgreementResource"][] | null;
297
373
  /** @enum {string} */
298
374
  status: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING";
@@ -300,6 +376,35 @@ export interface components {
300
376
  RegisterRequestBody: {
301
377
  /** @description 当前生效的必签文件全部要在里面,版本号要和 GET /api/v1/agreements 给的一致 */
302
378
  consents: components["schemas"]["ConsentBody"][] | null;
379
+ /** @description ISO 3166-1 alpha-2(CN、HK、US)。必须是现实世界里真实存在的国家或地区——EU、ZZ 这类在标准里有位置但不是国家的代码会被拒。存代码不存名字:名字是本地化的,存下来 的那份只会是某一种语言的。 */
380
+ country: string;
381
+ locale: components["schemas"]["Locale"];
382
+ };
383
+ LocaleOptionsResource: {
384
+ countries: components["schemas"]["CountryOption"][];
385
+ languages: components["schemas"]["LanguageOption"][];
386
+ };
387
+ CountryOption: {
388
+ /** @description ISO 3166-1 alpha-2,注册时原样回传 */
389
+ code: string;
390
+ /** @description 按 Accept-Language 渲染的名字 */
391
+ name: string;
392
+ };
393
+ LanguageOption: {
394
+ code: components["schemas"]["Locale"];
395
+ /** @description 这种语言的自称,用它自己写(「简体中文」「繁體中文(香港)」「English」)。不跟着 Accept-Language 变——一个只看得懂繁体的人,在一个全简体的列表里找不到自己那一项。 */
396
+ name: string;
397
+ };
398
+ /**
399
+ * @description 界面和邮件用哪种语言。它和 country 是两件事,不能互相推——一个在香港的人可能读简体, 一个在美国的人可能读繁体。
400
+ * @enum {string}
401
+ */
402
+ Locale: "zh-Hans" | "zh-Hant-HK" | "en";
403
+ /** @description 两个字段都是「不传就不动」。设置页上它们是两个独立的控件,用户可能只改其中一个;做成 整体替换的话,一次只想改语言的提交会把国家清掉,而那种丢失不报错。 */
404
+ UpdateAccountRequestBody: {
405
+ /** @description 同注册时那个 country */
406
+ country?: string;
407
+ locale?: components["schemas"]["Locale"];
303
408
  };
304
409
  IdentityVerificationResource: {
305
410
  reject_reason: string;
@@ -387,10 +492,24 @@ export interface components {
387
492
  GrantResource: {
388
493
  admin: boolean;
389
494
  owner: boolean;
390
- /** @description 持有的全部自定义角色的权限并集,已去重排序 */
391
- permissions: string[] | null;
392
495
  /** @description 持有的角色编码,只用于展示 */
393
496
  roles: string[] | null;
497
+ /** @description 他全部策略编译出来的规则。**不要自己遍历它做判定**——拿它配上自己那份权限目录交给 pkg/rbac:那里面的顺序(所有者不可被 deny、deny 优先于管理员、带资源范围的规则不 参与项目级判定)每一条都对着一种会静默放行的写法。 */
498
+ rules: components["schemas"]["RuleResource"][] | null;
499
+ };
500
+ ResourceRefResource: {
501
+ /** @description 是字符串而不是 uuid:dns 的 zone 标识是一个域名,而且它根本不在 IAM 的库里。匹配 语义是 glob,所以 *.example.com 能表达一批子域名;uuid 和域名都不含 glob 元字符, 对它们来说这就是精确相等。 */
502
+ id: string;
503
+ /** @description 形如 compute:instance、dns:zone,和权限名同一个命名空间 */
504
+ type: string;
505
+ };
506
+ RuleResource: {
507
+ /** @enum {string} */
508
+ effect: "allow" | "deny";
509
+ /** @description 支持尾部通配(compute:instance.*),通配必须带服务前缀 */
510
+ permissions: string[] | null;
511
+ /** @description 为空表示这条规则在整个项目范围内成立;非空则表示它只在这些资源上成立,而那意味着 它回答不了项目级的问题。 */
512
+ resources: components["schemas"]["ResourceRefResource"][] | null;
394
513
  };
395
514
  ProjectAccessResource: {
396
515
  grant: components["schemas"]["GrantResource"];
@@ -448,6 +567,64 @@ export interface components {
448
567
  }
449
568
  export type $defs = Record<string, never>;
450
569
  export interface operations {
570
+ "get-settings": {
571
+ parameters: {
572
+ query?: never;
573
+ header?: never;
574
+ path?: never;
575
+ cookie?: never;
576
+ };
577
+ requestBody?: never;
578
+ responses: {
579
+ /** @description OK */
580
+ 200: {
581
+ headers: {
582
+ [name: string]: unknown;
583
+ };
584
+ content: {
585
+ "application/json": components["schemas"]["SettingsResource"];
586
+ };
587
+ };
588
+ /** @description Error */
589
+ default: {
590
+ headers: {
591
+ [name: string]: unknown;
592
+ };
593
+ content: {
594
+ "application/json": components["schemas"]["Error"];
595
+ };
596
+ };
597
+ };
598
+ };
599
+ "list-locales": {
600
+ parameters: {
601
+ query?: never;
602
+ header?: never;
603
+ path?: never;
604
+ cookie?: never;
605
+ };
606
+ requestBody?: never;
607
+ responses: {
608
+ /** @description OK */
609
+ 200: {
610
+ headers: {
611
+ [name: string]: unknown;
612
+ };
613
+ content: {
614
+ "application/json": components["schemas"]["LocaleOptionsResource"];
615
+ };
616
+ };
617
+ /** @description Error */
618
+ default: {
619
+ headers: {
620
+ [name: string]: unknown;
621
+ };
622
+ content: {
623
+ "application/json": components["schemas"]["Error"];
624
+ };
625
+ };
626
+ };
627
+ };
451
628
  "list-agreements": {
452
629
  parameters: {
453
630
  query?: never;
@@ -601,6 +778,39 @@ export interface operations {
601
778
  };
602
779
  };
603
780
  };
781
+ "update-account": {
782
+ parameters: {
783
+ query?: never;
784
+ header?: never;
785
+ path?: never;
786
+ cookie?: never;
787
+ };
788
+ requestBody: {
789
+ content: {
790
+ "application/json": components["schemas"]["UpdateAccountRequestBody"];
791
+ };
792
+ };
793
+ responses: {
794
+ /** @description OK */
795
+ 200: {
796
+ headers: {
797
+ [name: string]: unknown;
798
+ };
799
+ content: {
800
+ "application/json": components["schemas"]["AccountResource"];
801
+ };
802
+ };
803
+ /** @description Error */
804
+ default: {
805
+ headers: {
806
+ [name: string]: unknown;
807
+ };
808
+ content: {
809
+ "application/json": components["schemas"]["Error"];
810
+ };
811
+ };
812
+ };
813
+ };
604
814
  "get-identity-verification": {
605
815
  parameters: {
606
816
  query?: never;
@@ -2,12 +2,18 @@ export type { paths, components, operations, webhooks } from "./schema.js";
2
2
  import type { operations } from "./schema.js";
3
3
  /** `POST /api/v1/attachments` 成功时的响应体。 */
4
4
  export type UploadAttachmentResult = operations["upload-attachment"]["responses"][201]["content"]["application/json"];
5
+ /** `POST /api/v1/attachments` 的查询参数。 */
6
+ export type UploadAttachmentQuery = operations["upload-attachment"]["parameters"]["query"];
5
7
  /** `GET /api/v1/bindings` 成功时的响应体。 */
6
8
  export type ListBindingsResult = operations["list-bindings"]["responses"][200]["content"]["application/json"];
9
+ /** `GET /api/v1/bindings` 的查询参数。 */
10
+ export type ListBindingsQuery = operations["list-bindings"]["parameters"]["query"];
7
11
  /** `GET /api/v1/bindings/{binding}` 成功时的响应体。 */
8
12
  export type GetBindingResult = operations["get-binding"]["responses"][200]["content"]["application/json"];
9
13
  /** `GET /api/v1/channels` 成功时的响应体。 */
10
14
  export type ListChannelsResult = operations["list-channels"]["responses"][200]["content"]["application/json"];
15
+ /** `GET /api/v1/channels` 的查询参数。 */
16
+ export type ListChannelsQuery = operations["list-channels"]["parameters"]["query"];
11
17
  /** `POST /api/v1/channels` 成功时的响应体。 */
12
18
  export type CreateChannelResult = operations["create-channel"]["responses"][201]["content"]["application/json"];
13
19
  /** `POST /api/v1/channels` 的请求体。 */
@@ -22,12 +28,16 @@ export type UpdateChannelBody = NonNullable<operations["update-channel"]["reques
22
28
  export type CreateBindingCodeResult = operations["create-binding-code"]["responses"][201]["content"]["application/json"];
23
29
  /** `GET /api/v1/channels/{channel}/rejections` 成功时的响应体。 */
24
30
  export type ListChannelRejectionsResult = operations["list-channel-rejections"]["responses"][200]["content"]["application/json"];
31
+ /** `GET /api/v1/channels/{channel}/rejections` 的查询参数。 */
32
+ export type ListChannelRejectionsQuery = operations["list-channel-rejections"]["parameters"]["query"];
25
33
  /** `POST /api/v1/channels/{channel}/secret` 成功时的响应体。 */
26
34
  export type RotateChannelSecretResult = operations["rotate-channel-secret"]["responses"][200]["content"]["application/json"];
27
35
  /** `POST /api/v1/channels/{channel}/secret` 的请求体。 */
28
36
  export type RotateChannelSecretBody = NonNullable<operations["rotate-channel-secret"]["requestBody"]>["content"]["application/json"];
29
37
  /** `GET /api/v1/channels/{channel}/sender-check` 成功时的响应体。 */
30
38
  export type CheckSenderResult = operations["check-sender"]["responses"][200]["content"]["application/json"];
39
+ /** `GET /api/v1/channels/{channel}/sender-check` 的查询参数。 */
40
+ export type CheckSenderQuery = operations["check-sender"]["parameters"]["query"];
31
41
  /** `POST /api/v1/channels/{channel}/weixin-logins` 成功时的响应体。 */
32
42
  export type BeginWeixinLoginResult = operations["begin-weixin-login"]["responses"][201]["content"]["application/json"];
33
43
  /** `GET /api/v1/platforms` 成功时的响应体。 */
@@ -38,10 +48,26 @@ export type GetWeixinLoginResult = operations["get-weixin-login"]["responses"][2
38
48
  export type SubmitWeixinVerifyCodeResult = operations["submit-weixin-verify-code"]["responses"][200]["content"]["application/json"];
39
49
  /** `POST /api/v1/weixin-logins/{login}/verify-code` 的请求体。 */
40
50
  export type SubmitWeixinVerifyCodeBody = NonNullable<operations["submit-weixin-verify-code"]["requestBody"]>["content"]["application/json"];
41
- /** `GET /api/v1/models` 成功时的响应体。 */
42
- export type ListModelsResult = operations["list-models"]["responses"][200]["content"]["application/json"];
51
+ /** `POST /api/v1/dynamic-calls/{call}/result` 的请求体。 */
52
+ export type SubmitDynamicCallResultBody = NonNullable<operations["submit-dynamic-call-result"]["requestBody"]>["content"]["application/json"];
53
+ /** `GET /api/v1/memories` 成功时的响应体。 */
54
+ export type ListMemoriesResult = operations["list-memories"]["responses"][200]["content"]["application/json"];
55
+ /** `GET /api/v1/skills` 成功时的响应体。 */
56
+ export type ListSkillsResult = operations["list-skills"]["responses"][200]["content"]["application/json"];
57
+ /** `POST /api/v1/skills` 成功时的响应体。 */
58
+ export type PutSkillResult = operations["put-skill"]["responses"][200]["content"]["application/json"];
59
+ /** `POST /api/v1/skills` 的请求体。 */
60
+ export type PutSkillBody = NonNullable<operations["put-skill"]["requestBody"]>["content"]["application/json"];
61
+ /** `GET /api/v1/skills/{skill}` 成功时的响应体。 */
62
+ export type GetSkillResult = operations["get-skill"]["responses"][200]["content"]["application/json"];
63
+ /** `PATCH /api/v1/skills/{skill}` 成功时的响应体。 */
64
+ export type SetSkillEnabledResult = operations["set-skill-enabled"]["responses"][200]["content"]["application/json"];
65
+ /** `PATCH /api/v1/skills/{skill}` 的请求体。 */
66
+ export type SetSkillEnabledBody = NonNullable<operations["set-skill-enabled"]["requestBody"]>["content"]["application/json"];
43
67
  /** `GET /api/v1/threads` 成功时的响应体。 */
44
68
  export type ListThreadsResult = operations["list-threads"]["responses"][200]["content"]["application/json"];
69
+ /** `GET /api/v1/threads` 的查询参数。 */
70
+ export type ListThreadsQuery = operations["list-threads"]["parameters"]["query"];
45
71
  /** `POST /api/v1/threads` 成功时的响应体。 */
46
72
  export type CreateThreadResult = operations["create-thread"]["responses"][201]["content"]["application/json"];
47
73
  /** `POST /api/v1/threads` 的请求体。 */
@@ -56,6 +82,8 @@ export type UpdateThreadBody = NonNullable<operations["update-thread"]["requestB
56
82
  export type DecideApprovalBody = NonNullable<operations["decide-approval"]["requestBody"]>["content"]["application/json"];
57
83
  /** `GET /api/v1/threads/{thread}/earlier` 成功时的响应体。 */
58
84
  export type ListEarlierItemsResult = operations["list-earlier-items"]["responses"][200]["content"]["application/json"];
85
+ /** `GET /api/v1/threads/{thread}/earlier` 的查询参数。 */
86
+ export type ListEarlierItemsQuery = operations["list-earlier-items"]["parameters"]["query"];
59
87
  /** `POST /api/v1/threads/{thread}/messages` 成功时的响应体。 */
60
88
  export type SendMessageResult = operations["send-message"]["responses"][202]["content"]["application/json"];
61
89
  /** `POST /api/v1/threads/{thread}/messages` 的请求体。 */