@leaflow/sdk 0.54.3 → 0.55.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.
@@ -50,5 +50,5 @@ export type ListProjectsQuery = operations["list-projects"]["parameters"]["query
50
50
  export type CreateProjectResult = operations["create-project"]["responses"][201]["content"]["application/json"];
51
51
  /** `POST /account/v1/projects` 的请求体。 */
52
52
  export type CreateProjectBody = NonNullable<operations["create-project"]["requestBody"]>["content"]["application/json"];
53
- /** `POST /account/v1/projects/{projectId}/token` 成功时的响应体。 */
54
- export type ExchangeProjectTokenResult = operations["exchange-project-token"]["responses"][201]["content"]["application/json"];
53
+ /** `POST /account/v1/projects/{projectId}/scoped-tokens` 成功时的响应体。 */
54
+ export type CreateScopedTokenResult = operations["create-scoped-token"]["responses"][201]["content"]["application/json"];
@@ -11,12 +11,12 @@ export interface paths {
11
11
  cookie?: never;
12
12
  };
13
13
  /**
14
- * 这个平台现在收不收人
15
- * @description 注册页和「新建项目」按钮用它决定画什么。不需要令牌。
14
+ * Get registration and project creation settings
15
+ * @description No token required.
16
16
  *
17
- * `registration_mode` 不是 `OPEN` `POST /account/v1/register` 会答 403:`CLOSED` 是整个关着,`INVITE_ONLY` 是只收手上有项目邀请的邮箱。`project_creation_mode` 同理,`VERIFIED_ONLY` 要先过实名。
17
+ * While `registration_mode` is not `OPEN`, `POST /account/v1/register` answers 403: `CLOSED` refuses everyone, and `INVITE_ONLY` accepts only an email address holding a project invitation. `project_creation_mode` behaves the same way, and `VERIFIED_ONLY` requires identity verification to have completed.
18
18
  *
19
- * 两条配额是 0 表示不限。它们只用来提前提示,真正的判定在写入那一刻。
19
+ * Both quotas are `0` when unlimited. The decision itself is made at the moment of writing.
20
20
  */
21
21
  get: operations["get-settings"];
22
22
  put?: never;
@@ -35,10 +35,12 @@ export interface paths {
35
35
  cookie?: never;
36
36
  };
37
37
  /**
38
- * 注册页要用的国家/地区和语言清单
39
- * @description 免认证:注册页在还没有账号的时候就要画出这两个下拉框。
40
- * 国家名和排序都跟着 `Accept-Language` 走——一个英文用户看到的是 China 而不是「中国」, 而顺序按那种语言自己的规则(中文按拼音,英文按字母),不是按码点。头缺失时用简体中文。
41
- * 清单来自 CLDR,不是我们自己维护的一份:ISO 3166 每年都改,而抄下来的那份不会跟着改。 已经退役的代码(苏联、南斯拉夫)和不是地方的代码(欧盟、联合国)都不在里面。
38
+ * List countries and languages for registration
39
+ * @description No token required: the registration page renders both lists before an account exists.
40
+ *
41
+ * Country names and their order follow `Accept-Language`. A name is rendered in the requested language and the list is ordered by the rules of that language rather than by code point. Simplified Chinese applies when the header is absent.
42
+ *
43
+ * Retired codes such as the Soviet Union and Yugoslavia, and codes that denote no country such as the European Union, are not listed.
42
44
  */
43
45
  get: operations["list-locales"];
44
46
  put?: never;
@@ -57,10 +59,10 @@ export interface paths {
57
59
  cookie?: never;
58
60
  };
59
61
  /**
60
- * 列出注册必须同意的文件
61
- * @description 注册页显示它,用户同意之后把每一项的 `type` `version` 原样回传给 `POST /api/v1/register`。
62
+ * List the agreements registration requires
63
+ * @description No token required. Send the `type` and `version` of each one back unchanged to `POST /account/v1/register`.
62
64
  *
63
- * 不需要令牌。还没有任何文件生效时返回空数组,那时注册不需要提交 `consents`。
65
+ * The array is empty while no agreement is in force, and registration then takes no `consents`.
64
66
  */
65
67
  get: operations["list-agreements"];
66
68
  put?: never;
@@ -79,16 +81,16 @@ export interface paths {
79
81
  cookie?: never;
80
82
  };
81
83
  /**
82
- * 列出我同意过的文件
83
- * @description 全部记录,最新的在前,包括已经不是当前版本的那些。
84
+ * List the agreements the caller has consented to
85
+ * @description Every record, most recent first, including versions that are no longer current.
84
86
  */
85
87
  get: operations["list-consents"];
86
88
  put?: never;
87
89
  /**
88
- * 同意条款
89
- * @description 条款改版之后用它重新同意,`GET /api/v1/me` `pending_agreements` 非空时就该调。
90
+ * Consent to the current agreements
91
+ * @description Call this once a new version is published, which is whenever `pending_agreements` on `GET /account/v1/me` is not empty.
90
92
  *
91
- * 只收当前生效的版本,签旧版答 409。重复提交同一版不报错,第一次那条记录会留着。
93
+ * Only the version currently in force is accepted; consenting to an earlier one answers 409. Submitting the same version twice is not an error and leaves the first record in place.
92
94
  */
93
95
  post: operations["accept-agreements"];
94
96
  delete?: never;
@@ -107,10 +109,10 @@ export interface paths {
107
109
  get?: never;
108
110
  put?: never;
109
111
  /**
110
- * 注册账号
111
- * @description auth.leaflow.net 登录之后调它,带上账号令牌。姓名和邮箱取自登录信息,不从请求体收。
112
+ * Register an account
113
+ * @description Call this after signing in at auth.leaflow.net, carrying the access token. The name and email address are taken from the sign-in claims and are not read from the request body.
112
114
  *
113
- * `consents` 要覆盖 `GET /api/v1/agreements` 返回的每一份,版本号也要一致;漏一份答 400,版本对不上答 409(多半是页面开着的时候条款改版了,重新拉一次清单即可)。已经注册过的答 409
115
+ * `consents` must cover every agreement returned by `GET /account/v1/agreements`, at the same versions. A missing agreement answers 400 and a stale version answers 409, in which case fetch the list again. An account that already exists answers 409.
114
116
  */
115
117
  post: operations["register"];
116
118
  delete?: never;
@@ -127,8 +129,8 @@ export interface paths {
127
129
  cookie?: never;
128
130
  };
129
131
  /**
130
- * 查看当前账号
131
- * @description `pending_agreements` 是还没同意的文件,非空就要先引导用户同意,再调 `POST /api/v1/me/consents`。
132
+ * Get the current account
133
+ * @description `pending_agreements` holds the agreements not yet consented to. While it is not empty, obtain consent and call `POST /account/v1/me/consents`.
132
134
  */
133
135
  get: operations["get-account"];
134
136
  put?: never;
@@ -137,8 +139,8 @@ export interface paths {
137
139
  options?: never;
138
140
  head?: never;
139
141
  /**
140
- * 改当前账号的国家/地区和语言
141
- * @description 姓名和邮箱不在这里改:它们来自身份提供方,改了会在下一次登录同步时被覆盖回去。
142
+ * Update the country and language of the current account
143
+ * @description The name and email address cannot be changed here. They come from the identity provider, and a change would be overwritten at the next sign-in.
142
144
  */
143
145
  patch: operations["update-account"];
144
146
  trace?: never;
@@ -151,14 +153,14 @@ export interface paths {
151
153
  cookie?: never;
152
154
  };
153
155
  /**
154
- * 查看实名核验状态
155
- * @description 没交过材料时答 UNVERIFIED,不是 404。姓名和证件号不会出现在任何响应里。
156
+ * Get identity verification status
157
+ * @description The status is `UNVERIFIED` rather than 404 when nothing has been submitted. The legal name and the document number appear in no response.
156
158
  */
157
159
  get: operations["get-identity-verification"];
158
160
  put?: never;
159
161
  /**
160
- * 提交实名核验材料
161
- * @description 已经在等人审的和已经核过的都会被拒。被驳回之后可以改了再交。
162
+ * Submit identity verification
163
+ * @description A submission awaiting review, and an account already verified, are both refused. A rejected submission may be corrected and sent again.
162
164
  */
163
165
  post: operations["submit-identity-verification"];
164
166
  delete?: never;
@@ -175,8 +177,8 @@ export interface paths {
175
177
  cookie?: never;
176
178
  };
177
179
  /**
178
- * 列出寄给我的要约
179
- * @description 按当前账号的邮箱查,因为要约是寄给一个地址的——被邀请的人当时可能还没注册。
180
+ * List invitations addressed to the caller
181
+ * @description Matched against the email address of the current account.
180
182
  */
181
183
  get: operations["list-my-invitations"];
182
184
  put?: never;
@@ -195,12 +197,12 @@ export interface paths {
195
197
  cookie?: never;
196
198
  };
197
199
  /**
198
- * 看一眼这封邀请是谁发的、加入哪儿、什么角色
199
- * @description 免认证,而且是有意的:点邮件里那条链接的人多半还没登录,甚至还没有账号。要他先注册再 告诉他这是谁发来的、加入哪个项目,等于让他在不知道要加入什么的情况下决定要不要注册。
200
- * 它不多泄露任何东西。 这三样——项目名、邀请人、角色——邮件正文里已经写着了,而读得到 这个令牌的人就是收得到那封邮件的人。同一个令牌本来就能把持有者加进项目(见 `accept-invitation-by-token`),读一个项目名比那件事轻得多。
201
- * 收件地址打了码(`t***@example.com`)。 不打码的话,这个接口就成了「拿一个令牌反查它 当初寄给了哪个地址」——而那是邮件正文里没有、持有者也未必知道的一件事。
202
- * 令牌不存在、已经用过、被撤回、过期,四种情况同一个 404 和同一句话。分开报会把它变成 一个可以拿来试令牌的探针,而这个接口免认证,任何人都试得起。
203
- * 它不在 `/me` 下面,隔壁那两条接受要约的在。 `/me` 的意思是「按这次请求的身份认出来 的、属于我的那些」,而这条路上没有身份——持有令牌的人未必是收件人本人。挂在 `/me` 下面会让读的人以为它认过身份,而那正是这条路唯一不做的事。
200
+ * Preview an invitation by its token
201
+ * @description No token required: whoever follows the link in an invitation email has usually not signed in, and may hold no account at all.
202
+ *
203
+ * The recipient address is masked (`t***@example.com`).
204
+ *
205
+ * A token that does not exist, one already redeemed, one revoked and one expired all answer the same 404.
204
206
  */
205
207
  get: operations["preview-invitation-by-token"];
206
208
  put?: never;
@@ -221,8 +223,8 @@ export interface paths {
221
223
  get?: never;
222
224
  put?: never;
223
225
  /**
224
- * 顺着邀请链接接受
225
- * @description token 对不上和这份要约已经不作数了是同一个回答:持有者对这两种情况能做的事完全一样,分开报会把这个接口变成一个可以拿来试 token 的探针。
226
+ * Accept an invitation by its token
227
+ * @description A token that does not match, and an invitation that no longer stands, answer the same way.
226
228
  */
227
229
  post: operations["accept-invitation-by-token"];
228
230
  delete?: never;
@@ -241,8 +243,8 @@ export interface paths {
241
243
  get?: never;
242
244
  put?: never;
243
245
  /**
244
- * 接受一份列在我名下的要约
245
- * @description 不需要 token:token 证明的是「你就是这份要约寄给的那个人」,而当前账号的邮箱对得上这份要约,证明的是同一件事。
246
+ * Accept an invitation listed against the caller
247
+ * @description No token is required; the invitation is addressed to the email address of the current account.
246
248
  */
247
249
  post: operations["accept-invitation"];
248
250
  delete?: never;
@@ -259,14 +261,14 @@ export interface paths {
259
261
  cookie?: never;
260
262
  };
261
263
  /**
262
- * 列出我参与的项目
263
- * @description 默认不含已删除的项目——那些是已经不存在了的东西,要看必须明确用 status=DELETED 点名。
264
+ * List the projects the caller belongs to
265
+ * @description Deleted projects are excluded unless `status=DELETED` asks for them by name.
264
266
  */
265
267
  get: operations["list-projects"];
266
268
  put?: never;
267
269
  /**
268
- * 建一个项目
269
- * @description 建的人就是所有者。项目会连带预置 OWNERADMIN 两个内置角色和一个空权限的 member 角色。
270
+ * Create a project
271
+ * @description The caller becomes its owner. The project is created with the built-in `OWNER` and `ADMIN` roles and a `member` role carrying no permissions.
270
272
  */
271
273
  post: operations["create-project"];
272
274
  delete?: never;
@@ -275,7 +277,7 @@ export interface paths {
275
277
  patch?: never;
276
278
  trace?: never;
277
279
  };
278
- "/account/v1/projects/{projectId}/token": {
280
+ "/account/v1/projects/{projectId}/scoped-tokens": {
279
281
  parameters: {
280
282
  query?: never;
281
283
  header?: never;
@@ -285,18 +287,18 @@ export interface paths {
285
287
  get?: never;
286
288
  put?: never;
287
289
  /**
288
- * 换一张项目令牌
289
- * @description 选定一个项目后,用账号令牌换取该项目的令牌。
290
+ * Exchange the access token for a scoped token
291
+ * @description Once a project has been chosen, exchange the access token for a scoped token for that project.
290
292
  *
291
- * **只接受 auth.leaflow.net 签发的账号令牌,不接受项目令牌。** 项目令牌过期后,先在 auth.leaflow.net 续期账号令牌,再重新调用这个接口。
293
+ * **Only an access token issued by auth.leaflow.net is accepted; a scoped token is not.** Once a scoped token has expired, obtain a fresh access token at auth.leaflow.net and call this endpoint again.
292
294
  *
293
- * 换取时会确认账号可用、项目存在,且**调用者是该项目的成员**。非成员无法换取。
295
+ * The exchange confirms that the account is usable, that the project exists, and that the caller is a member of it. A caller who is not a member obtains no token.
294
296
  *
295
- * 令牌只表明身份(用户与项目),**不包含权限**:权限在每次请求时实时判定,所以角色调整立即生效,不必等待令牌过期。
297
+ * A scoped token states identity only — the user and the project — and **carries no permissions**. Permissions are evaluated on every request, so a change of role takes effect immediately rather than at the next expiry.
296
298
  *
297
- * 项目处于停用、封禁或删除中时**仍可换取令牌**:这些状态限制的是写入,不影响查看项目当前状况。
299
+ * A project that is suspended, banned or being deleted still issues tokens; those states restrict writes, and the project remains readable.
298
300
  */
299
- post: operations["exchange-project-token"];
301
+ post: operations["create-scoped-token"];
300
302
  delete?: never;
301
303
  options?: never;
302
304
  head?: never;
@@ -310,6 +312,10 @@ export interface components {
310
312
  Error: {
311
313
  code?: string;
312
314
  message: string;
315
+ /**
316
+ * @description What a given `code` carries alongside the message. The keys depend on the code,
317
+ * and a client that does not recognise one ignores it.
318
+ */
313
319
  meta?: {
314
320
  [key: string]: unknown;
315
321
  };
@@ -319,21 +325,21 @@ export interface components {
319
325
  SettingsResource: {
320
326
  /**
321
327
  * Format: int64
322
- * @description 一个项目最多几个成员,0 表示不限
328
+ * @description Maximum number of members a project may hold; 0 means unlimited
323
329
  */
324
330
  max_members_per_project: number;
325
331
  /**
326
332
  * Format: int64
327
- * @description 你最多能当几个项目的所有者,0 表示不限。已删除的项目不算在内
333
+ * @description Maximum number of projects an account may own; 0 means unlimited. Deleted projects do not count
328
334
  */
329
335
  max_projects_per_user: number;
330
336
  /**
331
- * @description VERIFIED_ONLY 要求先过实名,审核中不算
337
+ * @description VERIFIED_ONLY requires identity verification to have completed; a submission under review does not qualify
332
338
  * @enum {string}
333
339
  */
334
340
  project_creation_mode: "OPEN" | "VERIFIED_ONLY" | "CLOSED";
335
341
  /**
336
- * @description INVITE_ONLY 是只收手上有项目邀请的邮箱
342
+ * @description INVITE_ONLY accepts only an email address holding a project invitation
337
343
  * @enum {string}
338
344
  */
339
345
  registration_mode: "OPEN" | "INVITE_ONLY" | "CLOSED";
@@ -341,14 +347,14 @@ export interface components {
341
347
  AgreementResource: {
342
348
  /**
343
349
  * Format: date-time
344
- * @description 从这一刻起注册必须同意这一版
350
+ * @description From this moment on, registration requires this version
345
351
  */
346
352
  effective_at: string;
347
353
  /** @enum {string} */
348
354
  type: "TERMS" | "PRIVACY" | "DPA";
349
- /** @description 正文发布在哪 */
355
+ /** @description Where the text is published */
350
356
  url: string;
351
- /** @description 同意时原样回传这个值 */
357
+ /** @description Send this value back unchanged when consenting */
352
358
  version: string;
353
359
  };
354
360
  AgreementListResponseBody: {
@@ -358,7 +364,7 @@ export interface components {
358
364
  /** Format: date-time */
359
365
  consented_at: string;
360
366
  /**
361
- * @description OFFLINE 是线下签的,由运营录入
367
+ * @description OFFLINE is a consent given off the platform and recorded by an operator
362
368
  * @enum {string}
363
369
  */
364
370
  method: "CLICKWRAP" | "OFFLINE";
@@ -383,24 +389,24 @@ export interface components {
383
389
  email: string;
384
390
  /** Format: date-time */
385
391
  email_verified_at: string | null;
386
- /** @description 来自登录信息,可能为空 */
392
+ /** @description Taken from the sign-in claims; may be empty */
387
393
  first_name: string;
388
- /** @description 身份提供方签发的 subject */
394
+ /** @description The subject issued by the identity provider */
389
395
  id: string;
390
- /** @description 来自登录信息,可能为空 */
396
+ /** @description Taken from the sign-in claims; may be empty */
391
397
  last_name: string;
392
- /** @description ISO 3166-1 alpha-2。这两个字段是后加的,注册时才开始要求填——已经注册过的人这里 是空串,让他们在设置里补,补之前一切照常。 */
398
+ /** @description ISO 3166-1 alpha-2. Empty on an account that registered before this was required; such an account continues to work and can set it from the settings page */
393
399
  country?: string;
394
- /** @description 为空表示没设过,那时按请求头(Accept-Language)走,两者都没有才用平台默认 */
400
+ /** @description Empty while never set, in which case `Accept-Language` applies, and the platform default when that is absent as well */
395
401
  locale?: string;
396
402
  pending_agreements: components["schemas"]["AgreementResource"][] | null;
397
403
  /** @enum {string} */
398
404
  status: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING";
399
405
  };
400
406
  RegisterRequestBody: {
401
- /** @description 当前生效的必签文件全部要在里面,版本号要和 GET /api/v1/agreements 给的一致 */
407
+ /** @description Must cover every agreement currently in force, at the versions returned by GET /account/v1/agreements */
402
408
  consents: components["schemas"]["ConsentBody"][] | null;
403
- /** @description ISO 3166-1 alpha-2CNHKUS)。必须是现实世界里真实存在的国家或地区——EUZZ 这类在标准里有位置但不是国家的代码会被拒。存代码不存名字:名字是本地化的,存下来 的那份只会是某一种语言的。 */
409
+ /** @description ISO 3166-1 alpha-2 (CN, HK, US). Must denote a country or territory that exists; codes such as EU and ZZ hold a place in the standard without denoting one and are refused */
404
410
  country: string;
405
411
  locale: components["schemas"]["Locale"];
406
412
  };
@@ -409,31 +415,31 @@ export interface components {
409
415
  languages: components["schemas"]["LanguageOption"][];
410
416
  };
411
417
  CountryOption: {
412
- /** @description ISO 3166-1 alpha-2,注册时原样回传 */
418
+ /** @description ISO 3166-1 alpha-2, sent back unchanged at registration */
413
419
  code: string;
414
- /** @description Accept-Language 渲染的名字 */
420
+ /** @description The name rendered according to `Accept-Language` */
415
421
  name: string;
416
422
  };
417
423
  LanguageOption: {
418
424
  code: components["schemas"]["Locale"];
419
- /** @description 这种语言的自称,用它自己写(「简体中文」「繁體中文(香港)」「English」)。不跟着 Accept-Language 变——一个只看得懂繁体的人,在一个全简体的列表里找不到自己那一项。 */
425
+ /** @description The endonym of the language, written in that language itself. It does not follow `Accept-Language` */
420
426
  name: string;
421
427
  };
422
428
  /**
423
- * @description 界面和邮件用哪种语言。它和 country 是两件事,不能互相推——一个在香港的人可能读简体, 一个在美国的人可能读繁体。
429
+ * @description The language used for the interface and for email. It is independent of `country`, and neither can be inferred from the other
424
430
  * @enum {string}
425
431
  */
426
432
  Locale: "zh-Hans" | "zh-Hant-HK" | "en";
427
- /** @description 两个字段都是「不传就不动」。设置页上它们是两个独立的控件,用户可能只改其中一个;做成 整体替换的话,一次只想改语言的提交会把国家清掉,而那种丢失不报错。 */
433
+ /** @description Both fields are optional, and an omitted field is left unchanged */
428
434
  UpdateAccountRequestBody: {
429
- /** @description 同注册时那个 country */
435
+ /** @description As at registration */
430
436
  country?: string;
431
437
  locale?: components["schemas"]["Locale"];
432
438
  };
433
439
  IdentityVerificationResource: {
434
440
  reject_reason: string;
435
441
  /**
436
- * @description PERSONAL ENTERPRISE 是两类主体而不是两个等级,别拿它们比大小
442
+ * @description PERSONAL and ENTERPRISE are two kinds of subject rather than two levels, and are not ordered
437
443
  * @enum {string}
438
444
  */
439
445
  status: "UNVERIFIED" | "PENDING" | "PERSONAL" | "ENTERPRISE" | "REJECTED";
@@ -443,24 +449,21 @@ export interface components {
443
449
  verified_at: string | null;
444
450
  };
445
451
  SubmitIdentityVerificationRequestBody: {
446
- /** @description 证件号码。同上,而且同一个号码不能挂在两个账号上 */
452
+ /** @description The document number. It is returned by no endpoint, and one number cannot be attached to two accounts */
447
453
  id_number: string;
448
- /** @description 真实姓名。敏感个人信息,加密入库,任何接口都不会再把它读出来 */
454
+ /** @description The legal name. It is returned by no endpoint */
449
455
  real_name: string;
450
456
  };
451
- /**
452
- * @description 一封邀请在被接受之前能给出的全部信息。
453
- * 它比 InvitationResource 少两样:要约 id 和完整的收件地址。id 不给是因为持有令牌不等于 这封要约列在你名下——真正列在你名下的那些走 list-my-invitations,那条是认过身份的。
454
- */
457
+ /** @description What an invitation states before it is accepted. It carries neither the invitation id nor the full recipient address; the invitations listed against the current account are returned by `list-my-invitations` */
455
458
  InvitationPreviewResource: {
456
- /** @description 打过码的收件地址,只够收件人认出「这是发给我的」 */
459
+ /** @description The masked recipient address, enough for the recipient to recognise it */
457
460
  email_masked: string;
458
461
  /** Format: date-time */
459
462
  expires_at: string;
460
- /** @description 邀请人的显示名,姓名都空时是他的邮箱 */
463
+ /** @description The display name of the sender, or their email address when no name is set */
461
464
  invited_by_name: string;
462
465
  project_name: string;
463
- /** @description 接受之后会拿到的角色,显示名 */
466
+ /** @description The display names of the roles granted on acceptance */
464
467
  role_names: string[] | null;
465
468
  };
466
469
  InvitationResource: {
@@ -471,42 +474,40 @@ export interface components {
471
474
  expires_at: string;
472
475
  /** Format: uuid */
473
476
  id: string;
474
- /** @description 发出这份要约的账号 id */
477
+ /** @description The id of the account that issued the invitation */
475
478
  invited_by: string;
476
- /** @description 发出这份要约的人的显示名,姓名都空时是他的邮箱。它是读取那一刻的事实,不是发信时的快照 */
479
+ /** @description The display name of that account, or its email address when no name is set. It reflects the value at the time of reading rather than at the time the invitation was sent */
477
480
  invited_by_name: string;
478
481
  /** Format: uuid */
479
482
  project_id: string;
480
- /**
481
- * @description 目标项目的名字。
482
- * 它在这里,而这一度是刻意不给的——理由是「没接受就不是成员,而名字只有成员能读」。 那条克制在这个场景下站不住:邀请邮件正文里就写着项目名,收件人早就知道了,而一个 只显示 uuid 的邀请列表让人没法判断该不该接受。
483
- */
483
+ /** @description The name of the target project */
484
484
  project_name: string;
485
- /** @description 兑现时会授予的角色编码 */
485
+ /** @description The role codes granted on acceptance */
486
486
  roles: string[] | null;
487
- /** @description 上面那些编码的显示名,按同样的顺序。读者看的是「管理员」,不是 ADMIN */
487
+ /** @description The display names of those codes, in the same order */
488
488
  role_names: string[] | null;
489
489
  };
490
490
  LengthAwarePageInvitationResource: {
491
- /** @description 这一页的内容 */
491
+ /** @description The items in this page */
492
492
  items: components["schemas"]["InvitationResource"][];
493
493
  /**
494
494
  * Format: int64
495
- * @description 这一页最多几条,回显请求里的值
495
+ * @description Maximum number of items in this page, echoing the request
496
496
  */
497
497
  limit: number;
498
498
  /**
499
499
  * Format: int64
500
- * @description 跳过了多少条,回显请求里的值
500
+ * @description Number of items skipped, echoing the request
501
501
  */
502
502
  offset: number;
503
503
  /**
504
504
  * Format: int64
505
- * @description 命中的总条数,不只是这一页
505
+ * @description Total number of matches, not only this page
506
506
  */
507
507
  total: number;
508
508
  };
509
509
  AcceptInvitationByTokenRequestBody: {
510
+ /** @description The token carried by the invitation link */
510
511
  token: string;
511
512
  };
512
513
  ProjectResource: {
@@ -516,7 +517,7 @@ export interface components {
516
517
  created_by: string;
517
518
  /**
518
519
  * Format: date-time
519
- * @description 盖上墓碑的那一刻
520
+ * @description When the project was deleted
520
521
  */
521
522
  deleted_at: string | null;
522
523
  description: string;
@@ -525,7 +526,7 @@ export interface components {
525
526
  name: string;
526
527
  /** @enum {string} */
527
528
  status: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING" | "DELETED";
528
- /** @description 给人看的,不参与任何查询 */
529
+ /** @description Written for a reader; it takes part in no query */
529
530
  status_reason: string;
530
531
  /** Format: date-time */
531
532
  updated_at: string;
@@ -536,23 +537,23 @@ export interface components {
536
537
  GrantResource: {
537
538
  admin: boolean;
538
539
  owner: boolean;
539
- /** @description 持有的角色编码,只用于展示 */
540
+ /** @description The role codes held, for display only */
540
541
  roles: string[] | null;
541
- /** @description 他全部策略编译出来的规则。**不要自己遍历它做判定**——拿它配上自己那份权限目录交给 pkg/rbac:那里面的顺序(所有者不可被 deny、deny 优先于管理员、带资源范围的规则不 参与项目级判定)每一条都对着一种会静默放行的写法。 */
542
+ /** @description **Do not walk these rules to reach a decision.** They are compiled from every policy that applies to the caller, and serve to render what a user may do. Each request is decided by the service handling it */
542
543
  rules: components["schemas"]["RuleResource"][] | null;
543
544
  };
544
545
  ResourceRefResource: {
545
- /** @description 是字符串而不是 uuid:dns zone 标识是一个域名,而且它根本不在 IAM 的库里。匹配 语义是 glob,所以 *.example.com 能表达一批子域名;uuid 和域名都不含 glob 元字符, 对它们来说这就是精确相等。 */
546
+ /** @description A string rather than a UUID; a DNS zone, for one, is named by its domain. Matching is glob, so `*.example.com` covers a set of subdomains, while a value carrying no glob metacharacter matches exactly */
546
547
  id: string;
547
- /** @description 形如 compute:instancedns:zone,和权限名同一个命名空间 */
548
+ /** @description Of the form compute:instance or dns:zone, in the same namespace as permission names */
548
549
  type: string;
549
550
  };
550
551
  RuleResource: {
551
552
  /** @enum {string} */
552
553
  effect: "allow" | "deny";
553
- /** @description 支持尾部通配(compute:instance.*),通配必须带服务前缀 */
554
+ /** @description A trailing wildcard is supported (compute:instance.*), and must carry the service prefix */
554
555
  permissions: string[] | null;
555
- /** @description 为空表示这条规则在整个项目范围内成立;非空则表示它只在这些资源上成立,而那意味着 它回答不了项目级的问题。 */
556
+ /** @description Empty means the rule holds across the whole project. While it is not empty the rule holds only on those resources, and therefore answers no project-level question */
556
557
  resources: components["schemas"]["ResourceRefResource"][] | null;
557
558
  };
558
559
  ProjectAccessResource: {
@@ -560,21 +561,21 @@ export interface components {
560
561
  project: components["schemas"]["ProjectResource"];
561
562
  };
562
563
  LengthAwarePageProjectAccessResource: {
563
- /** @description 这一页的内容 */
564
+ /** @description The items in this page */
564
565
  items: components["schemas"]["ProjectAccessResource"][];
565
566
  /**
566
567
  * Format: int64
567
- * @description 这一页最多几条,回显请求里的值
568
+ * @description Maximum number of items in this page, echoing the request
568
569
  */
569
570
  limit: number;
570
571
  /**
571
572
  * Format: int64
572
- * @description 跳过了多少条,回显请求里的值
573
+ * @description Number of items skipped, echoing the request
573
574
  */
574
575
  offset: number;
575
576
  /**
576
577
  * Format: int64
577
- * @description 命中的总条数,不只是这一页
578
+ * @description Total number of matches, not only this page
578
579
  */
579
580
  total: number;
580
581
  };
@@ -582,24 +583,24 @@ export interface components {
582
583
  description?: string;
583
584
  name: string;
584
585
  };
585
- ProjectTokenResponseBody: {
586
+ ScopedTokenResponseBody: {
586
587
  /**
587
588
  * Format: date-time
588
- * @description 过期时刻。到点之前拿用户身份再换一张,别等第一个 401
589
+ * @description When the token expires. Exchange for a new one before then rather than waiting for the first 401
589
590
  */
590
591
  expires_at: string;
591
592
  /**
592
593
  * Format: int64
593
- * @description 还能活多少秒
594
+ * @description Seconds remaining before expiry
594
595
  */
595
596
  expires_in: number;
596
- /** @description **这一份是此刻的快照,不在令牌里,也不要缓存它。** 它只用来决定界面上画什么;真正的判定每次都要重新问 */
597
+ /** @description **A snapshot taken at the moment of the exchange. It is not carried in the token, and must not be cached.** It serves to render what a user may do; each request is decided again */
597
598
  grant: components["schemas"]["GrantResource"];
598
- /** @description 顺带带上项目本身,省掉换完之后立刻再查一次 */
599
+ /** @description The project itself, so that no further lookup is needed after the exchange */
599
600
  project: components["schemas"]["ProjectResource"];
600
- /** @description 项目令牌,放进 Authorization: Bearer 里用 */
601
+ /** @description The scoped token, to be sent as `Authorization: Bearer` */
601
602
  token: string;
602
- /** @description 固定是 Bearer */
603
+ /** @description Always `Bearer` */
603
604
  token_type: string;
604
605
  };
605
606
  };
@@ -920,9 +921,9 @@ export interface operations {
920
921
  "list-my-invitations": {
921
922
  parameters: {
922
923
  query?: {
923
- /** @description 这一页最多返回多少条 */
924
+ /** @description Maximum number of items in this page */
924
925
  limit?: number;
925
- /** @description 跳过多少条。要翻得更深请改用游标翻页的接口 */
926
+ /** @description Number of items to skip. Use the cursor-paged endpoint to page deeper */
926
927
  offset?: number;
927
928
  };
928
929
  header?: never;
@@ -954,7 +955,7 @@ export interface operations {
954
955
  "preview-invitation-by-token": {
955
956
  parameters: {
956
957
  query: {
957
- /** @description 邀请链接里那串令牌 */
958
+ /** @description The token carried by the invitation link */
958
959
  token: string;
959
960
  };
960
961
  header?: never;
@@ -1050,13 +1051,13 @@ export interface operations {
1050
1051
  "list-projects": {
1051
1052
  parameters: {
1052
1053
  query?: {
1053
- /** @description 这一页最多返回多少条 */
1054
+ /** @description Maximum number of items in this page */
1054
1055
  limit?: number;
1055
- /** @description 跳过多少条。要翻得更深请改用游标翻页的接口 */
1056
+ /** @description Number of items to skip. Use the cursor-paged endpoint to page deeper */
1056
1057
  offset?: number;
1057
- /** @description 按名称或描述模糊匹配 */
1058
+ /** @description Matches against name or description */
1058
1059
  keyword?: string;
1059
- /** @description 按对外状态过滤。不传时不返回已删除的项目 */
1060
+ /** @description Filters by external status. Deleted projects are excluded while this is absent */
1060
1061
  status?: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING" | "DELETED";
1061
1062
  };
1062
1063
  header?: never;
@@ -1118,7 +1119,7 @@ export interface operations {
1118
1119
  };
1119
1120
  };
1120
1121
  };
1121
- "exchange-project-token": {
1122
+ "create-scoped-token": {
1122
1123
  parameters: {
1123
1124
  query?: never;
1124
1125
  header?: never;
@@ -1135,7 +1136,7 @@ export interface operations {
1135
1136
  [name: string]: unknown;
1136
1137
  };
1137
1138
  content: {
1138
- "application/json": components["schemas"]["ProjectTokenResponseBody"];
1139
+ "application/json": components["schemas"]["ScopedTokenResponseBody"];
1139
1140
  };
1140
1141
  };
1141
1142
  /** @description Error */
@@ -679,6 +679,10 @@ export interface components {
679
679
  Error: {
680
680
  code?: string;
681
681
  message: string;
682
+ /**
683
+ * @description What a given `code` carries alongside the message. The keys depend on the code,
684
+ * and a client that does not recognise one ignores it.
685
+ */
682
686
  meta?: {
683
687
  [key: string]: unknown;
684
688
  };