@leaflow/sdk 0.0.0-dev.125.ged02bc4 → 0.0.0-dev.129.g409f04f

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.
@@ -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 建的人就是所有者。项目会连带预置 OWNER、ADMIN 两个内置角色和一个空权限的 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;
@@ -311,6 +313,12 @@ export interface components {
311
313
  code?: string;
312
314
  message: string;
313
315
  meta?: {
316
+ /**
317
+ * @description Present on every response whose `code` is `VALIDATION_FAILED`, and on no
318
+ * other response.
319
+ */
320
+ violations?: components["schemas"]["Violation"][];
321
+ } & {
314
322
  [key: string]: unknown;
315
323
  };
316
324
  /** Format: int64 */
@@ -319,21 +327,21 @@ export interface components {
319
327
  SettingsResource: {
320
328
  /**
321
329
  * Format: int64
322
- * @description 一个项目最多几个成员,0 表示不限
330
+ * @description Maximum number of members a project may hold; 0 means unlimited
323
331
  */
324
332
  max_members_per_project: number;
325
333
  /**
326
334
  * Format: int64
327
- * @description 你最多能当几个项目的所有者,0 表示不限。已删除的项目不算在内
335
+ * @description Maximum number of projects an account may own; 0 means unlimited. Deleted projects do not count
328
336
  */
329
337
  max_projects_per_user: number;
330
338
  /**
331
- * @description VERIFIED_ONLY 要求先过实名,审核中不算
339
+ * @description VERIFIED_ONLY requires identity verification to have completed; a submission under review does not qualify
332
340
  * @enum {string}
333
341
  */
334
342
  project_creation_mode: "OPEN" | "VERIFIED_ONLY" | "CLOSED";
335
343
  /**
336
- * @description INVITE_ONLY 是只收手上有项目邀请的邮箱
344
+ * @description INVITE_ONLY accepts only an email address holding a project invitation
337
345
  * @enum {string}
338
346
  */
339
347
  registration_mode: "OPEN" | "INVITE_ONLY" | "CLOSED";
@@ -341,14 +349,14 @@ export interface components {
341
349
  AgreementResource: {
342
350
  /**
343
351
  * Format: date-time
344
- * @description 从这一刻起注册必须同意这一版
352
+ * @description From this moment on, registration requires this version
345
353
  */
346
354
  effective_at: string;
347
355
  /** @enum {string} */
348
356
  type: "TERMS" | "PRIVACY" | "DPA";
349
- /** @description 正文发布在哪 */
357
+ /** @description Where the text is published */
350
358
  url: string;
351
- /** @description 同意时原样回传这个值 */
359
+ /** @description Send this value back unchanged when consenting */
352
360
  version: string;
353
361
  };
354
362
  AgreementListResponseBody: {
@@ -358,7 +366,7 @@ export interface components {
358
366
  /** Format: date-time */
359
367
  consented_at: string;
360
368
  /**
361
- * @description OFFLINE 是线下签的,由运营录入
369
+ * @description OFFLINE is a consent given off the platform and recorded by an operator
362
370
  * @enum {string}
363
371
  */
364
372
  method: "CLICKWRAP" | "OFFLINE";
@@ -383,24 +391,24 @@ export interface components {
383
391
  email: string;
384
392
  /** Format: date-time */
385
393
  email_verified_at: string | null;
386
- /** @description 来自登录信息,可能为空 */
394
+ /** @description Taken from the sign-in claims; may be empty */
387
395
  first_name: string;
388
- /** @description 身份提供方签发的 subject */
396
+ /** @description The subject issued by the identity provider */
389
397
  id: string;
390
- /** @description 来自登录信息,可能为空 */
398
+ /** @description Taken from the sign-in claims; may be empty */
391
399
  last_name: string;
392
- /** @description ISO 3166-1 alpha-2。这两个字段是后加的,注册时才开始要求填——已经注册过的人这里 是空串,让他们在设置里补,补之前一切照常。 */
400
+ /** @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
401
  country?: string;
394
- /** @description 为空表示没设过,那时按请求头(Accept-Language)走,两者都没有才用平台默认 */
402
+ /** @description Empty while never set, in which case `Accept-Language` applies, and the platform default when that is absent as well */
395
403
  locale?: string;
396
404
  pending_agreements: components["schemas"]["AgreementResource"][] | null;
397
405
  /** @enum {string} */
398
406
  status: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING";
399
407
  };
400
408
  RegisterRequestBody: {
401
- /** @description 当前生效的必签文件全部要在里面,版本号要和 GET /api/v1/agreements 给的一致 */
409
+ /** @description Must cover every agreement currently in force, at the versions returned by GET /account/v1/agreements */
402
410
  consents: components["schemas"]["ConsentBody"][] | null;
403
- /** @description ISO 3166-1 alpha-2(CN、HK、US)。必须是现实世界里真实存在的国家或地区——EU、ZZ 这类在标准里有位置但不是国家的代码会被拒。存代码不存名字:名字是本地化的,存下来 的那份只会是某一种语言的。 */
411
+ /** @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
412
  country: string;
405
413
  locale: components["schemas"]["Locale"];
406
414
  };
@@ -409,31 +417,31 @@ export interface components {
409
417
  languages: components["schemas"]["LanguageOption"][];
410
418
  };
411
419
  CountryOption: {
412
- /** @description ISO 3166-1 alpha-2,注册时原样回传 */
420
+ /** @description ISO 3166-1 alpha-2, sent back unchanged at registration */
413
421
  code: string;
414
- /** @description 按 Accept-Language 渲染的名字 */
422
+ /** @description The name rendered according to `Accept-Language` */
415
423
  name: string;
416
424
  };
417
425
  LanguageOption: {
418
426
  code: components["schemas"]["Locale"];
419
- /** @description 这种语言的自称,用它自己写(「简体中文」「繁體中文(香港)」「English」)。不跟着 Accept-Language 变——一个只看得懂繁体的人,在一个全简体的列表里找不到自己那一项。 */
427
+ /** @description The endonym of the language, written in that language itself. It does not follow `Accept-Language` */
420
428
  name: string;
421
429
  };
422
430
  /**
423
- * @description 界面和邮件用哪种语言。它和 country 是两件事,不能互相推——一个在香港的人可能读简体, 一个在美国的人可能读繁体。
431
+ * @description The language used for the interface and for email. It is independent of `country`, and neither can be inferred from the other
424
432
  * @enum {string}
425
433
  */
426
434
  Locale: "zh-Hans" | "zh-Hant-HK" | "en";
427
- /** @description 两个字段都是「不传就不动」。设置页上它们是两个独立的控件,用户可能只改其中一个;做成 整体替换的话,一次只想改语言的提交会把国家清掉,而那种丢失不报错。 */
435
+ /** @description Both fields are optional, and an omitted field is left unchanged */
428
436
  UpdateAccountRequestBody: {
429
- /** @description 同注册时那个 country */
437
+ /** @description As at registration */
430
438
  country?: string;
431
439
  locale?: components["schemas"]["Locale"];
432
440
  };
433
441
  IdentityVerificationResource: {
434
442
  reject_reason: string;
435
443
  /**
436
- * @description PERSONAL 和 ENTERPRISE 是两类主体而不是两个等级,别拿它们比大小
444
+ * @description PERSONAL and ENTERPRISE are two kinds of subject rather than two levels, and are not ordered
437
445
  * @enum {string}
438
446
  */
439
447
  status: "UNVERIFIED" | "PENDING" | "PERSONAL" | "ENTERPRISE" | "REJECTED";
@@ -443,24 +451,21 @@ export interface components {
443
451
  verified_at: string | null;
444
452
  };
445
453
  SubmitIdentityVerificationRequestBody: {
446
- /** @description 证件号码。同上,而且同一个号码不能挂在两个账号上 */
454
+ /** @description The document number. It is returned by no endpoint, and one number cannot be attached to two accounts */
447
455
  id_number: string;
448
- /** @description 真实姓名。敏感个人信息,加密入库,任何接口都不会再把它读出来 */
456
+ /** @description The legal name. It is returned by no endpoint */
449
457
  real_name: string;
450
458
  };
451
- /**
452
- * @description 一封邀请在被接受之前能给出的全部信息。
453
- * 它比 InvitationResource 少两样:要约 id 和完整的收件地址。id 不给是因为持有令牌不等于 这封要约列在你名下——真正列在你名下的那些走 list-my-invitations,那条是认过身份的。
454
- */
459
+ /** @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
460
  InvitationPreviewResource: {
456
- /** @description 打过码的收件地址,只够收件人认出「这是发给我的」 */
461
+ /** @description The masked recipient address, enough for the recipient to recognise it */
457
462
  email_masked: string;
458
463
  /** Format: date-time */
459
464
  expires_at: string;
460
- /** @description 邀请人的显示名,姓名都空时是他的邮箱 */
465
+ /** @description The display name of the sender, or their email address when no name is set */
461
466
  invited_by_name: string;
462
467
  project_name: string;
463
- /** @description 接受之后会拿到的角色,显示名 */
468
+ /** @description The display names of the roles granted on acceptance */
464
469
  role_names: string[] | null;
465
470
  };
466
471
  InvitationResource: {
@@ -471,42 +476,40 @@ export interface components {
471
476
  expires_at: string;
472
477
  /** Format: uuid */
473
478
  id: string;
474
- /** @description 发出这份要约的账号 id */
479
+ /** @description The id of the account that issued the invitation */
475
480
  invited_by: string;
476
- /** @description 发出这份要约的人的显示名,姓名都空时是他的邮箱。它是读取那一刻的事实,不是发信时的快照 */
481
+ /** @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
482
  invited_by_name: string;
478
483
  /** Format: uuid */
479
484
  project_id: string;
480
- /**
481
- * @description 目标项目的名字。
482
- * 它在这里,而这一度是刻意不给的——理由是「没接受就不是成员,而名字只有成员能读」。 那条克制在这个场景下站不住:邀请邮件正文里就写着项目名,收件人早就知道了,而一个 只显示 uuid 的邀请列表让人没法判断该不该接受。
483
- */
485
+ /** @description The name of the target project */
484
486
  project_name: string;
485
- /** @description 兑现时会授予的角色编码 */
487
+ /** @description The role codes granted on acceptance */
486
488
  roles: string[] | null;
487
- /** @description 上面那些编码的显示名,按同样的顺序。读者看的是「管理员」,不是 ADMIN */
489
+ /** @description The display names of those codes, in the same order */
488
490
  role_names: string[] | null;
489
491
  };
490
492
  LengthAwarePageInvitationResource: {
491
- /** @description 这一页的内容 */
493
+ /** @description The items in this page */
492
494
  items: components["schemas"]["InvitationResource"][];
493
495
  /**
494
496
  * Format: int64
495
- * @description 这一页最多几条,回显请求里的值
497
+ * @description Maximum number of items in this page, echoing the request
496
498
  */
497
499
  limit: number;
498
500
  /**
499
501
  * Format: int64
500
- * @description 跳过了多少条,回显请求里的值
502
+ * @description Number of items skipped, echoing the request
501
503
  */
502
504
  offset: number;
503
505
  /**
504
506
  * Format: int64
505
- * @description 命中的总条数,不只是这一页
507
+ * @description Total number of matches, not only this page
506
508
  */
507
509
  total: number;
508
510
  };
509
511
  AcceptInvitationByTokenRequestBody: {
512
+ /** @description The token carried by the invitation link */
510
513
  token: string;
511
514
  };
512
515
  ProjectResource: {
@@ -516,7 +519,7 @@ export interface components {
516
519
  created_by: string;
517
520
  /**
518
521
  * Format: date-time
519
- * @description 盖上墓碑的那一刻
522
+ * @description When the project was deleted
520
523
  */
521
524
  deleted_at: string | null;
522
525
  description: string;
@@ -525,7 +528,7 @@ export interface components {
525
528
  name: string;
526
529
  /** @enum {string} */
527
530
  status: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING" | "DELETED";
528
- /** @description 给人看的,不参与任何查询 */
531
+ /** @description Written for a reader; it takes part in no query */
529
532
  status_reason: string;
530
533
  /** Format: date-time */
531
534
  updated_at: string;
@@ -536,23 +539,23 @@ export interface components {
536
539
  GrantResource: {
537
540
  admin: boolean;
538
541
  owner: boolean;
539
- /** @description 持有的角色编码,只用于展示 */
542
+ /** @description The role codes held, for display only */
540
543
  roles: string[] | null;
541
- /** @description 他全部策略编译出来的规则。**不要自己遍历它做判定**——拿它配上自己那份权限目录交给 pkg/rbac:那里面的顺序(所有者不可被 deny、deny 优先于管理员、带资源范围的规则不 参与项目级判定)每一条都对着一种会静默放行的写法。 */
544
+ /** @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
545
  rules: components["schemas"]["RuleResource"][] | null;
543
546
  };
544
547
  ResourceRefResource: {
545
- /** @description 是字符串而不是 uuid:dns 的 zone 标识是一个域名,而且它根本不在 IAM 的库里。匹配 语义是 glob,所以 *.example.com 能表达一批子域名;uuid 和域名都不含 glob 元字符, 对它们来说这就是精确相等。 */
548
+ /** @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
549
  id: string;
547
- /** @description 形如 compute:instance、dns:zone,和权限名同一个命名空间 */
550
+ /** @description Of the form compute:instance or dns:zone, in the same namespace as permission names */
548
551
  type: string;
549
552
  };
550
553
  RuleResource: {
551
554
  /** @enum {string} */
552
555
  effect: "allow" | "deny";
553
- /** @description 支持尾部通配(compute:instance.*),通配必须带服务前缀 */
556
+ /** @description A trailing wildcard is supported (compute:instance.*), and must carry the service prefix */
554
557
  permissions: string[] | null;
555
- /** @description 为空表示这条规则在整个项目范围内成立;非空则表示它只在这些资源上成立,而那意味着 它回答不了项目级的问题。 */
558
+ /** @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
559
  resources: components["schemas"]["ResourceRefResource"][] | null;
557
560
  };
558
561
  ProjectAccessResource: {
@@ -560,21 +563,21 @@ export interface components {
560
563
  project: components["schemas"]["ProjectResource"];
561
564
  };
562
565
  LengthAwarePageProjectAccessResource: {
563
- /** @description 这一页的内容 */
566
+ /** @description The items in this page */
564
567
  items: components["schemas"]["ProjectAccessResource"][];
565
568
  /**
566
569
  * Format: int64
567
- * @description 这一页最多几条,回显请求里的值
570
+ * @description Maximum number of items in this page, echoing the request
568
571
  */
569
572
  limit: number;
570
573
  /**
571
574
  * Format: int64
572
- * @description 跳过了多少条,回显请求里的值
575
+ * @description Number of items skipped, echoing the request
573
576
  */
574
577
  offset: number;
575
578
  /**
576
579
  * Format: int64
577
- * @description 命中的总条数,不只是这一页
580
+ * @description Total number of matches, not only this page
578
581
  */
579
582
  total: number;
580
583
  };
@@ -582,26 +585,49 @@ export interface components {
582
585
  description?: string;
583
586
  name: string;
584
587
  };
585
- ProjectTokenResponseBody: {
588
+ ScopedTokenResponseBody: {
586
589
  /**
587
590
  * Format: date-time
588
- * @description 过期时刻。到点之前拿用户身份再换一张,别等第一个 401
591
+ * @description When the token expires. Exchange for a new one before then rather than waiting for the first 401
589
592
  */
590
593
  expires_at: string;
591
594
  /**
592
595
  * Format: int64
593
- * @description 还能活多少秒
596
+ * @description Seconds remaining before expiry
594
597
  */
595
598
  expires_in: number;
596
- /** @description **这一份是此刻的快照,不在令牌里,也不要缓存它。** 它只用来决定界面上画什么;真正的判定每次都要重新问 */
599
+ /** @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
600
  grant: components["schemas"]["GrantResource"];
598
- /** @description 顺带带上项目本身,省掉换完之后立刻再查一次 */
601
+ /** @description The project itself, so that no further lookup is needed after the exchange */
599
602
  project: components["schemas"]["ProjectResource"];
600
- /** @description 项目令牌,放进 Authorization: Bearer 里用 */
603
+ /** @description The scoped token, to be sent as `Authorization: Bearer` */
601
604
  token: string;
602
- /** @description 固定是 Bearer */
605
+ /** @description Always `Bearer` */
603
606
  token_type: string;
604
607
  };
608
+ /**
609
+ * @description A single mismatch between the request and the contract.
610
+ *
611
+ * Use `field` to locate the input, `rule` to decide what to tell the user, and
612
+ * `reason` only for diagnostics.
613
+ */
614
+ Violation: {
615
+ /**
616
+ * @description Dot-separated path to the field, such as `name` or
617
+ * `schedule.0.start_time_seconds`.
618
+ */
619
+ field: string;
620
+ /**
621
+ * @description The JSON Schema keyword that failed, such as `minLength`, `minimum` or
622
+ * `pattern`.
623
+ */
624
+ rule: string;
625
+ /**
626
+ * @description The validator's own wording, in English. Intended for diagnostics; do not
627
+ * display it to end users.
628
+ */
629
+ reason?: string;
630
+ };
605
631
  };
606
632
  responses: never;
607
633
  parameters: never;
@@ -920,9 +946,9 @@ export interface operations {
920
946
  "list-my-invitations": {
921
947
  parameters: {
922
948
  query?: {
923
- /** @description 这一页最多返回多少条 */
949
+ /** @description Maximum number of items in this page */
924
950
  limit?: number;
925
- /** @description 跳过多少条。要翻得更深请改用游标翻页的接口 */
951
+ /** @description Number of items to skip. Use the cursor-paged endpoint to page deeper */
926
952
  offset?: number;
927
953
  };
928
954
  header?: never;
@@ -954,7 +980,7 @@ export interface operations {
954
980
  "preview-invitation-by-token": {
955
981
  parameters: {
956
982
  query: {
957
- /** @description 邀请链接里那串令牌 */
983
+ /** @description The token carried by the invitation link */
958
984
  token: string;
959
985
  };
960
986
  header?: never;
@@ -1050,13 +1076,13 @@ export interface operations {
1050
1076
  "list-projects": {
1051
1077
  parameters: {
1052
1078
  query?: {
1053
- /** @description 这一页最多返回多少条 */
1079
+ /** @description Maximum number of items in this page */
1054
1080
  limit?: number;
1055
- /** @description 跳过多少条。要翻得更深请改用游标翻页的接口 */
1081
+ /** @description Number of items to skip. Use the cursor-paged endpoint to page deeper */
1056
1082
  offset?: number;
1057
- /** @description 按名称或描述模糊匹配 */
1083
+ /** @description Matches against name or description */
1058
1084
  keyword?: string;
1059
- /** @description 按对外状态过滤。不传时不返回已删除的项目 */
1085
+ /** @description Filters by external status. Deleted projects are excluded while this is absent */
1060
1086
  status?: "ACTIVE" | "SUSPENDED" | "BANNED" | "DELETING" | "DELETED";
1061
1087
  };
1062
1088
  header?: never;
@@ -1118,7 +1144,7 @@ export interface operations {
1118
1144
  };
1119
1145
  };
1120
1146
  };
1121
- "exchange-project-token": {
1147
+ "create-scoped-token": {
1122
1148
  parameters: {
1123
1149
  query?: never;
1124
1150
  header?: never;
@@ -1135,7 +1161,7 @@ export interface operations {
1135
1161
  [name: string]: unknown;
1136
1162
  };
1137
1163
  content: {
1138
- "application/json": components["schemas"]["ProjectTokenResponseBody"];
1164
+ "application/json": components["schemas"]["ScopedTokenResponseBody"];
1139
1165
  };
1140
1166
  };
1141
1167
  /** @description Error */