@leaflow/sdk 0.0.0-dev.478.g138087b → 0.0.0-dev.482.g339e5e7

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.
Files changed (47) hide show
  1. package/dist/billing/v1/generated/functions.d.ts +1 -1
  2. package/dist/billing/v1/generated/functions.js +1 -1
  3. package/dist/billing/v1/generated/models.d.ts +15 -6
  4. package/dist/billing/v1/generated/models.js +5 -5
  5. package/dist/billing/v1/generated/schemas.zod.d.ts +7 -1
  6. package/dist/billing/v1/generated/schemas.zod.js +9 -1
  7. package/dist/billing/v1/generated/validators/billingAccount.zod.js +2 -1
  8. package/dist/billing/v1/generated/validators/billingAccountStatus.zod.d.ts +15 -0
  9. package/dist/billing/v1/generated/validators/billingAccountStatus.zod.js +11 -0
  10. package/dist/billing/v1/generated/validators/listBillingAccountsParams.zod.d.ts +6 -0
  11. package/dist/billing/v1/generated/validators/listBillingAccountsParams.zod.js +3 -0
  12. package/dist/iam/v1/generated/functions.d.ts +46 -103
  13. package/dist/iam/v1/generated/functions.js +29 -114
  14. package/dist/iam/v1/generated/models.d.ts +53 -118
  15. package/dist/iam/v1/generated/models.js +2 -6
  16. package/dist/iam/v1/generated/schemas.zod.d.ts +31 -62
  17. package/dist/iam/v1/generated/schemas.zod.js +35 -53
  18. package/dist/iam/v1/generated/validators/{updatePolicyRequestBody.zod.d.ts → createMemberPermissionRequestBody.zod.d.ts} +9 -11
  19. package/dist/iam/v1/generated/validators/createMemberPermissionRequestBody.zod.js +36 -0
  20. package/dist/iam/v1/generated/validators/grantResource.zod.js +1 -1
  21. package/dist/iam/v1/generated/validators/lengthAwarePageMemberResource.zod.d.ts +12 -0
  22. package/dist/iam/v1/generated/validators/{listProjectInvitationsParams.zod.d.ts → listInvitationsParams.zod.d.ts} +8 -8
  23. package/dist/iam/v1/generated/validators/{listProjectInvitationsParams.zod.js → listInvitationsParams.zod.js} +11 -11
  24. package/dist/iam/v1/generated/validators/{policyListResponseBody.zod.d.ts → memberPermissionListResponseBody.zod.d.ts} +8 -14
  25. package/dist/iam/v1/generated/validators/{catalogListResponseBody.zod.js → memberPermissionListResponseBody.zod.js} +3 -3
  26. package/dist/iam/v1/generated/validators/{policyResource.zod.d.ts → memberPermissionResource.zod.d.ts} +11 -14
  27. package/dist/iam/v1/generated/validators/memberPermissionResource.zod.js +38 -0
  28. package/dist/iam/v1/generated/validators/memberResource.zod.d.ts +12 -0
  29. package/dist/iam/v1/generated/validators/memberResource.zod.js +5 -0
  30. package/dist/iam/v1/generated/validators/ownershipTransferResponseBody.zod.d.ts +24 -0
  31. package/dist/iam/v1/generated/validators/{catalogResource.zod.d.ts → permissionListResponseBody.zod.d.ts} +4 -8
  32. package/dist/iam/v1/generated/validators/{policyListResponseBody.zod.js → permissionListResponseBody.zod.js} +3 -3
  33. package/dist/routes.d.ts +7 -31
  34. package/dist/routes.js +7 -34
  35. package/package.json +1 -1
  36. package/dist/iam/v1/generated/validators/attachPolicyRequestBody.zod.d.ts +0 -33
  37. package/dist/iam/v1/generated/validators/attachPolicyRequestBody.zod.js +0 -43
  38. package/dist/iam/v1/generated/validators/catalogListResponseBody.zod.d.ts +0 -30
  39. package/dist/iam/v1/generated/validators/catalogResource.zod.js +0 -25
  40. package/dist/iam/v1/generated/validators/listPoliciesParams.zod.d.ts +0 -21
  41. package/dist/iam/v1/generated/validators/listPoliciesParams.zod.js +0 -23
  42. package/dist/iam/v1/generated/validators/policyResource.zod.js +0 -33
  43. package/dist/iam/v1/generated/validators/resourceTypeResource.zod.d.ts +0 -20
  44. package/dist/iam/v1/generated/validators/resourceTypeResource.zod.js +0 -20
  45. package/dist/iam/v1/generated/validators/setMemberPermissionsRequestBody.zod.d.ts +0 -20
  46. package/dist/iam/v1/generated/validators/setMemberPermissionsRequestBody.zod.js +0 -21
  47. package/dist/iam/v1/generated/validators/updatePolicyRequestBody.zod.js +0 -39
@@ -2,7 +2,7 @@ export const getListPermissionsUrl = () => {
2
2
  return `https://iam.leaflow.cloud/api/v1/permissions`;
3
3
  };
4
4
  /**
5
- * Each service registers its own catalogue with IAM at start-up, so this is the platform-wide list rather than the permissions of IAM alone. **IAM does not decide anything with it** — each service decides using the caller's grant together with its own catalogue, and this list only serves to render the choices. A service that has never started does not appear here.
5
+ * Each service registers the permissions it enforces with IAM at start-up, so this is the platform-wide list rather than the permissions of IAM alone. **IAM does not decide anything with it** — each service decides using the caller's grant together with the permissions compiled into its own binary, and this list only serves to render the choices. A service that has never started does not appear here.
6
6
  * @summary List every permission the platform can grant
7
7
  */
8
8
  export const listPermissions = async (options, fetchFn) => {
@@ -125,7 +125,7 @@ export const getGetProjectMembershipUrl = () => {
125
125
  return `https://iam.leaflow.cloud/api/v1/membership`;
126
126
  };
127
127
  /**
128
- * Facts rather than a conclusion. There is no `allowed` field here, because each service holds the catalogue mapping its operations to permissions and decides on its own.
128
+ * Facts rather than a conclusion. There is no `allowed` field here, because each service holds the permissions its operations need and decides on its own.
129
129
  * @summary Get the caller's standing in this project
130
130
  */
131
131
  export const getProjectMembership = async (options, fetchFn) => {
@@ -153,7 +153,7 @@ export const listQuotas = async (options, fetchFn) => {
153
153
  const data = body ? JSON.parse(body) : {};
154
154
  return { data, status: res.status, headers: res.headers };
155
155
  };
156
- export const getListProjectInvitationsUrl = (params) => {
156
+ export const getListInvitationsUrl = (params) => {
157
157
  const normalizedParams = new URLSearchParams();
158
158
  Object.entries(params || {}).forEach(([key, value]) => {
159
159
  if (value !== undefined) {
@@ -169,8 +169,8 @@ export const getListProjectInvitationsUrl = (params) => {
169
169
  * Visible to any member, on the same rule as the member list. Who has been invited is part of who is in the project.
170
170
  * @summary List the invitations this project is still waiting on
171
171
  */
172
- export const listProjectInvitations = async (params, options, fetchFn) => {
173
- const res = await (fetchFn ?? fetch)(getListProjectInvitationsUrl(params), {
172
+ export const listInvitations = async (params, options, fetchFn) => {
173
+ const res = await (fetchFn ?? fetch)(getListInvitationsUrl(params), {
174
174
  ...options,
175
175
  method: "GET",
176
176
  });
@@ -336,57 +336,17 @@ export const setMemberRoles = async (userId, setMemberRolesRequestBody, options,
336
336
  const data = body ? JSON.parse(body) : {};
337
337
  return { data, status: res.status, headers: res.headers };
338
338
  };
339
- export const getSetMemberPermissionsUrl = (userId) => {
339
+ export const getListMemberPermissionsUrl = (userId) => {
340
340
  return `https://iam.leaflow.cloud/api/v1/members/${encodeURIComponent(String(userId))}/permissions`;
341
341
  };
342
342
  /**
343
- * Replaces, in full, the permissions attached directly to the base policy. A direct permission grants one person something without creating a role only they hold, and it does not follow later changes to any role. Requires `iam:members.manage`.
344
- * @summary Set the permissions attached directly to a member
345
- */
346
- export const setMemberPermissions = async (userId, setMemberPermissionsRequestBody, options, fetchFn) => {
347
- const getHeaders = (h) => {
348
- if (!h)
349
- return {};
350
- if (h instanceof Headers)
351
- return Object.fromEntries(h.entries());
352
- if (Symbol.iterator in h) {
353
- return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
354
- }
355
- const headers = {};
356
- for (const [name, value] of Object.entries(h)) {
357
- if (value !== undefined)
358
- headers[name] = value;
359
- }
360
- return headers;
361
- };
362
- const res = await (fetchFn ?? fetch)(getSetMemberPermissionsUrl(userId), {
363
- ...options,
364
- method: "PUT",
365
- headers: { "Content-Type": "application/json", ...getHeaders(options?.headers) },
366
- body: JSON.stringify(setMemberPermissionsRequestBody),
367
- });
368
- const body = [204, 205, 304].includes(res.status) ? null : await res.text();
369
- const data = body ? JSON.parse(body) : {};
370
- return { data, status: res.status, headers: res.headers };
371
- };
372
- export const getListPoliciesUrl = (params) => {
373
- const normalizedParams = new URLSearchParams();
374
- Object.entries(params || {}).forEach(([key, value]) => {
375
- if (value !== undefined) {
376
- normalizedParams.append(key, value === null ? "null" : String(value));
377
- }
378
- });
379
- const stringifiedParams = normalizedParams.toString();
380
- return stringifiedParams.length > 0
381
- ? `https://iam.leaflow.cloud/api/v1/policies?${stringifiedParams}`
382
- : `https://iam.leaflow.cloud/api/v1/policies`;
383
- };
384
- /**
385
- * Visible to any member, on the same rule as the member list. What has been granted to whom is part of who is in the project.
386
- * @summary List the policies in this project
343
+ * Every row states one permission this person holds apart from their roles: project-wide when `resource_type` and `resource_id` are null, otherwise only on that resource. What a role grants is not listed here; the member's grant carries the roles and their compiled rules.
344
+ *
345
+ * Visible to any member, on the same rule as the member list.
346
+ * @summary List the permissions granted directly to a member
387
347
  */
388
- export const listPolicies = async (params, options, fetchFn) => {
389
- const res = await (fetchFn ?? fetch)(getListPoliciesUrl(params), {
348
+ export const listMemberPermissions = async (userId, options, fetchFn) => {
349
+ const res = await (fetchFn ?? fetch)(getListMemberPermissionsUrl(userId), {
390
350
  ...options,
391
351
  method: "GET",
392
352
  });
@@ -394,14 +354,18 @@ export const listPolicies = async (params, options, fetchFn) => {
394
354
  const data = body ? JSON.parse(body) : {};
395
355
  return { data, status: res.status, headers: res.headers };
396
356
  };
397
- export const getAttachPolicyUrl = () => {
398
- return `https://iam.leaflow.cloud/api/v1/policies`;
357
+ export const getCreateMemberPermissionUrl = (userId) => {
358
+ return `https://iam.leaflow.cloud/api/v1/members/${encodeURIComponent(String(userId))}/permissions`;
399
359
  };
400
360
  /**
401
- * This creates an **additional** policy, which either carries a resource scope or has `deny` as its effect. An `allow` covering every resource is a base policy, of which each member holds exactly one, and it is changed with set-member-roles and set-member-permissions. `roles` cannot contain `OWNER` or `ADMIN`. Requires `iam:members.manage`.
402
- * @summary Attach a policy
361
+ * Creates one permission row. The same row twice answers 409; changing a grant means revoking the row and creating another, so that each row records when it was granted.
362
+ *
363
+ * `OWNER` and `ADMIN` cannot be granted here, being facts on the membership. A permission that carries no resource dimension cannot be scoped: IAM refuses the row at grant time rather than storing a scope that would never hold.
364
+ *
365
+ * Requires `iam:members.manage`.
366
+ * @summary Grant a permission to a member
403
367
  */
404
- export const attachPolicy = async (attachPolicyRequestBody, options, fetchFn) => {
368
+ export const createMemberPermission = async (userId, createMemberPermissionRequestBody, options, fetchFn) => {
405
369
  const getHeaders = (h) => {
406
370
  if (!h)
407
371
  return {};
@@ -417,74 +381,25 @@ export const attachPolicy = async (attachPolicyRequestBody, options, fetchFn) =>
417
381
  }
418
382
  return headers;
419
383
  };
420
- const res = await (fetchFn ?? fetch)(getAttachPolicyUrl(), {
384
+ const res = await (fetchFn ?? fetch)(getCreateMemberPermissionUrl(userId), {
421
385
  ...options,
422
386
  method: "POST",
423
387
  headers: { "Content-Type": "application/json", ...getHeaders(options?.headers) },
424
- body: JSON.stringify(attachPolicyRequestBody),
425
- });
426
- const body = [204, 205, 304].includes(res.status) ? null : await res.text();
427
- const data = body ? JSON.parse(body) : {};
428
- return { data, status: res.status, headers: res.headers };
429
- };
430
- export const getGetPolicyUrl = (policyId) => {
431
- return `https://iam.leaflow.cloud/api/v1/policies/${encodeURIComponent(String(policyId))}`;
432
- };
433
- /**
434
- * Visible to any member, on the same rule as list-policies; no further permission is required.
435
- * @summary Get a policy
436
- */
437
- export const getPolicy = async (policyId, options, fetchFn) => {
438
- const res = await (fetchFn ?? fetch)(getGetPolicyUrl(policyId), {
439
- ...options,
440
- method: "GET",
441
- });
442
- const body = [204, 205, 304].includes(res.status) ? null : await res.text();
443
- const data = body ? JSON.parse(body) : {};
444
- return { data, status: res.status, headers: res.headers };
445
- };
446
- export const getUpdatePolicyUrl = (policyId) => {
447
- return `https://iam.leaflow.cloud/api/v1/policies/${encodeURIComponent(String(policyId))}`;
448
- };
449
- /**
450
- * Replaced in full rather than field by field — `resources`, `roles` and `permissions` are each overwritten, and an omitted one becomes empty. The **kind** of a policy cannot change — a base policy (an `allow` covering every resource) cannot take a resource scope, and a scoped policy cannot have its scope cleared. Delete and recreate to change the kind. Requires `iam:members.manage`.
451
- * @summary Update a policy
452
- */
453
- export const updatePolicy = async (policyId, updatePolicyRequestBody, options, fetchFn) => {
454
- const getHeaders = (h) => {
455
- if (!h)
456
- return {};
457
- if (h instanceof Headers)
458
- return Object.fromEntries(h.entries());
459
- if (Symbol.iterator in h) {
460
- return Object.fromEntries(Array.from(h, (entry) => Array.from(entry)));
461
- }
462
- const headers = {};
463
- for (const [name, value] of Object.entries(h)) {
464
- if (value !== undefined)
465
- headers[name] = value;
466
- }
467
- return headers;
468
- };
469
- const res = await (fetchFn ?? fetch)(getUpdatePolicyUrl(policyId), {
470
- ...options,
471
- method: "PUT",
472
- headers: { "Content-Type": "application/json", ...getHeaders(options?.headers) },
473
- body: JSON.stringify(updatePolicyRequestBody),
388
+ body: JSON.stringify(createMemberPermissionRequestBody),
474
389
  });
475
390
  const body = [204, 205, 304].includes(res.status) ? null : await res.text();
476
391
  const data = body ? JSON.parse(body) : {};
477
392
  return { data, status: res.status, headers: res.headers };
478
393
  };
479
- export const getDetachPolicyUrl = (policyId) => {
480
- return `https://iam.leaflow.cloud/api/v1/policies/${encodeURIComponent(String(policyId))}`;
394
+ export const getDeleteMemberPermissionUrl = (userId, permissionId) => {
395
+ return `https://iam.leaflow.cloud/api/v1/members/${encodeURIComponent(String(userId))}/permissions/${encodeURIComponent(String(permissionId))}`;
481
396
  };
482
397
  /**
483
- * A base policy cannot be detached; it is where a member's roles sit. Use remove-member to take someone out of the project. Requires `iam:members.manage`.
484
- * @summary Detach a policy
398
+ * Removes that one row. Requires `iam:members.manage`.
399
+ * @summary Revoke a permission granted directly to a member
485
400
  */
486
- export const detachPolicy = async (policyId, options, fetchFn) => {
487
- const res = await (fetchFn ?? fetch)(getDetachPolicyUrl(policyId), {
401
+ export const deleteMemberPermission = async (userId, permissionId, options, fetchFn) => {
402
+ const res = await (fetchFn ?? fetch)(getDeleteMemberPermissionUrl(userId, permissionId), {
488
403
  ...options,
489
404
  method: "DELETE",
490
405
  });
@@ -79,23 +79,9 @@ export interface PermissionResource {
79
79
  /** The kind of resource this permission is decided against; empty means it is decided at project level. **It need not be the object being operated on** — a compute route carries no project_id and is isolated through its parent network, so compute:route.create is decided against compute:private_network. A non-empty value also means the permission can be scoped to particular instances; create and list are always empty */
80
80
  resource_type: string;
81
81
  }
82
- export interface ResourceTypeResource {
83
- /** The code of the resource type, such as dns:zone. There is no display name here either; what it reads as is decided by the layer rendering it */
84
- name: string;
85
- }
86
- export interface CatalogResource {
87
- /** @nullable */
88
- permissions: PermissionResource[] | null;
89
- /**
90
- * The resource types this service declares. A scoped rule can only land on one of them
91
- * @nullable
92
- */
93
- resource_types: ResourceTypeResource[] | null;
94
- service: string;
95
- }
96
- export interface CatalogListResponseBody {
82
+ export interface PermissionListResponseBody {
97
83
  /** @nullable */
98
- items: CatalogResource[] | null;
84
+ items: PermissionResource[] | null;
99
85
  }
100
86
  export interface ResourceRefResource {
101
87
  /** A string rather than a UUID; a DNS zone is named by its domain, which IAM does not hold. Matching is glob, so `*.example.com` covers a set of subdomains, while a value carrying no glob metacharacter matches exactly */
@@ -130,7 +116,7 @@ export interface GrantResource {
130
116
  */
131
117
  roles: string[] | null;
132
118
  /**
133
- * **The rules compiled from every policy that applies. Do not walk them to reach a decision.** They are here to render what a user may do; each request is decided by the service handling it
119
+ * **The rules compiled from the roles and grants that apply. Do not walk them to reach a decision.** They are here to render what a user may do; each request is decided by the service handling it
134
120
  * @nullable
135
121
  */
136
122
  rules: RuleResource[] | null;
@@ -281,6 +267,35 @@ export interface BatchGetMembersResponseBody {
281
267
  /** The people that resolved. Ids that never belonged to this project are absent, as are ids that do not resolve at all. */
282
268
  items: ResolvedMemberResource[];
283
269
  }
270
+ export type MemberPermissionResourceEffect = (typeof MemberPermissionResourceEffect)[keyof typeof MemberPermissionResourceEffect];
271
+ export declare const MemberPermissionResourceEffect: {
272
+ readonly allow: "allow";
273
+ readonly deny: "deny";
274
+ };
275
+ export interface MemberPermissionResource {
276
+ /** The id of this grant, used to revoke it */
277
+ id: string;
278
+ /**
279
+ * The code of the permission, such as compute:instance.delete
280
+ * @maxLength 128
281
+ */
282
+ permission: string;
283
+ effect: MemberPermissionResourceEffect;
284
+ /**
285
+ * The kind of resource this grant holds on, such as fleet:machine. Null with `resource_id` means it holds project-wide
286
+ * @maxLength 128
287
+ * @nullable
288
+ */
289
+ resource_type: string | null;
290
+ /**
291
+ * The resource identifier, which may carry a glob. Null with `resource_type` means the grant holds project-wide
292
+ * @maxLength 255
293
+ * @nullable
294
+ */
295
+ resource_id: string | null;
296
+ created_at: string;
297
+ updated_at: string;
298
+ }
284
299
  export interface MemberResource {
285
300
  /** MD5 hash of the lowercased, trimmed email address, for use with Gravatar-compatible avatar services. Empty if the account has no email address. */
286
301
  avatar_hash: string;
@@ -290,6 +305,11 @@ export interface MemberResource {
290
305
  first_name: string;
291
306
  grant: GrantResource;
292
307
  last_name: string;
308
+ /**
309
+ * The permissions granted to this person directly, apart from their roles
310
+ * @nullable
311
+ */
312
+ permissions: MemberPermissionResource[] | null;
293
313
  user_id: string;
294
314
  }
295
315
  export interface LengthAwarePageMemberResource {
@@ -309,113 +329,35 @@ export interface SetMemberRolesRequestBody {
309
329
  */
310
330
  roles: string[] | null;
311
331
  }
312
- export interface SetMemberPermissionsRequestBody {
313
- /**
314
- * **Every** permission name to be attached directly to this person, replaced in full. The permissions a role grants are neither listed here nor touched by this write
315
- * @nullable
316
- */
317
- permissions: string[] | null;
318
- }
319
- export type PolicyResourceEffect = (typeof PolicyResourceEffect)[keyof typeof PolicyResourceEffect];
320
- export declare const PolicyResourceEffect: {
321
- readonly allow: "allow";
322
- readonly deny: "deny";
323
- };
324
- export interface PolicyResource {
325
- /** The base policy is the one whose effect is `allow` and which covers every resource. Each member holds exactly one, and it carries their ordinary roles. Change it with PUT /members/{userId}/roles and PUT /members/{userId}/permissions */
326
- base: boolean;
327
- created_at: string;
328
- /** Why it was granted, written for a reader */
329
- description: string;
330
- effect: PolicyResourceEffect;
331
- id: string;
332
- /**
333
- * Permission names attached directly to this person, without passing through a role
334
- * @nullable
335
- */
336
- permissions: string[] | null;
337
- /**
338
- * Empty means the whole project
339
- * @nullable
340
- */
341
- resources: ResourceRefResource[] | null;
342
- /**
343
- * The role codes this policy carries
344
- * @nullable
345
- */
346
- roles: string[] | null;
347
- updated_at: string;
348
- user_id: string;
349
- }
350
- export interface PolicyListResponseBody {
332
+ export interface MemberPermissionListResponseBody {
351
333
  /** @nullable */
352
- items: PolicyResource[] | null;
334
+ items: MemberPermissionResource[] | null;
353
335
  }
354
- export type AttachPolicyRequestBodyEffect = (typeof AttachPolicyRequestBodyEffect)[keyof typeof AttachPolicyRequestBodyEffect];
355
- export declare const AttachPolicyRequestBodyEffect: {
336
+ export type CreateMemberPermissionRequestBodyEffect = (typeof CreateMemberPermissionRequestBodyEffect)[keyof typeof CreateMemberPermissionRequestBodyEffect];
337
+ export declare const CreateMemberPermissionRequestBodyEffect: {
356
338
  readonly allow: "allow";
357
339
  readonly deny: "deny";
358
340
  };
359
- export interface AttachPolicyRequestBody {
360
- /**
361
- * Why it was granted, written for a reader
362
- * @maxLength 255
363
- */
364
- description?: string;
365
- effect: AttachPolicyRequestBodyEffect;
366
- /**
367
- * Permission names attached directly, which avoids creating a role only one person holds
368
- * @nullable
369
- */
370
- permissions?: string[] | null;
371
- /**
372
- * The policy holds only on these resources. Leaving it empty makes sense only together with `deny`, since an `allow` covering every resource is the base policy, which already exists
373
- * @nullable
374
- */
375
- resources?: ResourceRefResource[] | null;
376
- /**
377
- * Each must be a role already defined in this project. `OWNER` and `ADMIN` are not accepted, being rules rather than sets of permissions
378
- * @nullable
379
- */
380
- roles?: string[] | null;
341
+ export interface CreateMemberPermissionRequestBody {
381
342
  /**
382
- * Must already be a member of this project
343
+ * The code of the permission to grant
383
344
  * @minLength 1
384
- * @maxLength 255
385
- */
386
- user_id: string;
387
- }
388
- /**
389
- * Must match the current effect of the policy. The effect itself cannot be changed; delete the policy and create another instead. It is still required in the request because the write replaces the policy in full, and omitting it would let a caller believe an effect had been changed while the field was ignored. A mismatch answers PROJECT_POLICY_EFFECT_IMMUTABLE
390
- */
391
- export type UpdatePolicyRequestBodyEffect = (typeof UpdatePolicyRequestBodyEffect)[keyof typeof UpdatePolicyRequestBodyEffect];
392
- export declare const UpdatePolicyRequestBodyEffect: {
393
- readonly allow: "allow";
394
- readonly deny: "deny";
395
- };
396
- export interface UpdatePolicyRequestBody {
397
- /**
398
- * Why it was granted, written for a reader. It is replaced together with the change, so that what remains does not explain an earlier version
399
- * @maxLength 255
400
- */
401
- description?: string;
402
- /** Must match the current effect of the policy. The effect itself cannot be changed; delete the policy and create another instead. It is still required in the request because the write replaces the policy in full, and omitting it would let a caller believe an effect had been changed while the field was ignored. A mismatch answers PROJECT_POLICY_EFFECT_IMMUTABLE */
403
- effect: UpdatePolicyRequestBodyEffect;
404
- /**
405
- * Permission names attached directly, replaced in full. Anything not listed is withdrawn rather than kept
406
- * @nullable
345
+ * @maxLength 128
407
346
  */
408
- permissions?: string[] | null;
347
+ permission: string;
348
+ effect: CreateMemberPermissionRequestBodyEffect;
409
349
  /**
410
- * The resource scope of this policy, replaced in full. What the scope contains can change; whether the policy has one cannot. A base policy cannot take a scope, and a scoped policy cannot have its scope cleared
350
+ * The kind of resource to hold on; give it together with `resource_id`. Both null grant the permission project-wide
351
+ * @maxLength 128
411
352
  * @nullable
412
353
  */
413
- resources?: ResourceRefResource[] | null;
354
+ resource_type: string | null;
414
355
  /**
415
- * Each must be a role already defined in this project, replaced in full. As when attaching, `OWNER` and `ADMIN` are not accepted
356
+ * The resource identifier to hold on, which may carry a glob. Give it together with `resource_type`
357
+ * @maxLength 255
416
358
  * @nullable
417
359
  */
418
- roles?: string[] | null;
360
+ resource_id: string | null;
419
361
  }
420
362
  export interface TransferOwnershipRequestBody {
421
363
  /**
@@ -637,7 +579,7 @@ export interface CursorPagination {
637
579
  /** @nullable */
638
580
  next_cursor?: string | null;
639
581
  }
640
- export type ListProjectInvitationsParams = {
582
+ export type ListInvitationsParams = {
641
583
  /**
642
584
  * Items returned in this page. Defaults to 50; at most 200.
643
585
  * @minimum 1
@@ -670,13 +612,6 @@ export type ListMembersParams = {
670
612
  */
671
613
  keyword?: string;
672
614
  };
673
- export type ListPoliciesParams = {
674
- /**
675
- * Restricts the result to one person. Omitting it covers the whole project
676
- * @maxLength 255
677
- */
678
- userId?: string;
679
- };
680
615
  export type ListSshKeysParams = {
681
616
  /**
682
617
  * Items returned in this page. Defaults to 50; at most 200.
@@ -11,15 +11,11 @@ export const ProjectResourceStatus = {
11
11
  deleting: "deleting",
12
12
  deleted: "deleted",
13
13
  };
14
- export const PolicyResourceEffect = {
14
+ export const MemberPermissionResourceEffect = {
15
15
  allow: "allow",
16
16
  deny: "deny",
17
17
  };
18
- export const AttachPolicyRequestBodyEffect = {
19
- allow: "allow",
20
- deny: "deny",
21
- };
22
- export const UpdatePolicyRequestBodyEffect = {
18
+ export const CreateMemberPermissionRequestBodyEffect = {
23
19
  allow: "allow",
24
20
  deny: "deny",
25
21
  };
@@ -41,12 +41,12 @@ export declare const SetProjectSlugBody: zod.ZodObject<{
41
41
  * Visible to any member, on the same rule as the member list. Who has been invited is part of who is in the project.
42
42
  * @summary List the invitations this project is still waiting on
43
43
  */
44
- export declare const listProjectInvitationsQueryLimitDefault = 50;
45
- export declare const listProjectInvitationsQueryLimitMax = 200;
46
- export declare const listProjectInvitationsQueryOffsetDefault = 0;
47
- export declare const listProjectInvitationsQueryOffsetMin = 0;
48
- export declare const listProjectInvitationsQueryOffsetMax = 10000;
49
- export declare const ListProjectInvitationsQueryParams: zod.ZodObject<{
44
+ export declare const listInvitationsQueryLimitDefault = 50;
45
+ export declare const listInvitationsQueryLimitMax = 200;
46
+ export declare const listInvitationsQueryOffsetDefault = 0;
47
+ export declare const listInvitationsQueryOffsetMin = 0;
48
+ export declare const listInvitationsQueryOffsetMax = 10000;
49
+ export declare const ListInvitationsQueryParams: zod.ZodObject<{
50
50
  limit: zod.ZodDefault<zod.ZodInt>;
51
51
  offset: zod.ZodDefault<zod.ZodInt>;
52
52
  }, zod.z.core.$strict>;
@@ -109,75 +109,44 @@ export declare const SetMemberRolesBody: zod.ZodObject<{
109
109
  roles: zod.ZodNullable<zod.ZodArray<zod.ZodString>>;
110
110
  }, zod.z.core.$strict>;
111
111
  /**
112
- * Replaces, in full, the permissions attached directly to the base policy. A direct permission grants one person something without creating a role only they hold, and it does not follow later changes to any role. Requires `iam:members.manage`.
113
- * @summary Set the permissions attached directly to a member
112
+ * Every row states one permission this person holds apart from their roles: project-wide when `resource_type` and `resource_id` are null, otherwise only on that resource. What a role grants is not listed here; the member's grant carries the roles and their compiled rules.
113
+ *
114
+ * Visible to any member, on the same rule as the member list.
115
+ * @summary List the permissions granted directly to a member
114
116
  */
115
- export declare const setMemberPermissionsPathUserIdMax = 255;
116
- export declare const SetMemberPermissionsParams: zod.ZodObject<{
117
+ export declare const listMemberPermissionsPathUserIdMax = 255;
118
+ export declare const ListMemberPermissionsParams: zod.ZodObject<{
117
119
  userId: zod.ZodString;
118
120
  }, zod.z.core.$strict>;
119
- export declare const SetMemberPermissionsBody: zod.ZodObject<{
120
- permissions: zod.ZodNullable<zod.ZodArray<zod.ZodString>>;
121
- }, zod.z.core.$strict>;
122
- /**
123
- * Visible to any member, on the same rule as the member list. What has been granted to whom is part of who is in the project.
124
- * @summary List the policies in this project
125
- */
126
- export declare const listPoliciesQueryUserIdMax = 255;
127
- export declare const ListPoliciesQueryParams: zod.ZodObject<{
128
- userId: zod.ZodOptional<zod.ZodString>;
129
- }, zod.z.core.$strict>;
130
121
  /**
131
- * This creates an **additional** policy, which either carries a resource scope or has `deny` as its effect. An `allow` covering every resource is a base policy, of which each member holds exactly one, and it is changed with set-member-roles and set-member-permissions. `roles` cannot contain `OWNER` or `ADMIN`. Requires `iam:members.manage`.
132
- * @summary Attach a policy
133
- */
134
- export declare const AttachPolicyBody: zod.ZodObject<{
135
- description: zod.ZodOptional<zod.ZodString>;
136
- effect: zod.ZodEnum<{
137
- allow: "allow";
138
- deny: "deny";
139
- }>;
140
- permissions: zod.ZodOptional<zod.ZodNullable<zod.ZodArray<zod.ZodString>>>;
141
- resources: zod.ZodOptional<zod.ZodNullable<zod.ZodArray<zod.ZodObject<{
142
- id: zod.ZodString;
143
- type: zod.ZodString;
144
- }, zod.z.core.$strict>>>>;
145
- roles: zod.ZodOptional<zod.ZodNullable<zod.ZodArray<zod.ZodString>>>;
146
- user_id: zod.ZodString;
147
- }, zod.z.core.$strict>;
148
- /**
149
- * Visible to any member, on the same rule as list-policies; no further permission is required.
150
- * @summary Get a policy
151
- */
152
- export declare const GetPolicyParams: zod.ZodObject<{
153
- policyId: zod.ZodUUID;
154
- }, zod.z.core.$strict>;
155
- /**
156
- * Replaced in full rather than field by field — `resources`, `roles` and `permissions` are each overwritten, and an omitted one becomes empty. The **kind** of a policy cannot change — a base policy (an `allow` covering every resource) cannot take a resource scope, and a scoped policy cannot have its scope cleared. Delete and recreate to change the kind. Requires `iam:members.manage`.
157
- * @summary Update a policy
122
+ * Creates one permission row. The same row twice answers 409; changing a grant means revoking the row and creating another, so that each row records when it was granted.
123
+ *
124
+ * `OWNER` and `ADMIN` cannot be granted here, being facts on the membership. A permission that carries no resource dimension cannot be scoped: IAM refuses the row at grant time rather than storing a scope that would never hold.
125
+ *
126
+ * Requires `iam:members.manage`.
127
+ * @summary Grant a permission to a member
158
128
  */
159
- export declare const UpdatePolicyParams: zod.ZodObject<{
160
- policyId: zod.ZodUUID;
129
+ export declare const createMemberPermissionPathUserIdMax = 255;
130
+ export declare const CreateMemberPermissionParams: zod.ZodObject<{
131
+ userId: zod.ZodString;
161
132
  }, zod.z.core.$strict>;
162
- export declare const UpdatePolicyBody: zod.ZodObject<{
163
- description: zod.ZodOptional<zod.ZodString>;
133
+ export declare const CreateMemberPermissionBody: zod.ZodObject<{
134
+ permission: zod.ZodString;
164
135
  effect: zod.ZodEnum<{
165
136
  allow: "allow";
166
137
  deny: "deny";
167
138
  }>;
168
- permissions: zod.ZodOptional<zod.ZodNullable<zod.ZodArray<zod.ZodString>>>;
169
- resources: zod.ZodOptional<zod.ZodNullable<zod.ZodArray<zod.ZodObject<{
170
- id: zod.ZodString;
171
- type: zod.ZodString;
172
- }, zod.z.core.$strict>>>>;
173
- roles: zod.ZodOptional<zod.ZodNullable<zod.ZodArray<zod.ZodString>>>;
139
+ resource_type: zod.ZodNullable<zod.ZodString>;
140
+ resource_id: zod.ZodNullable<zod.ZodString>;
174
141
  }, zod.z.core.$strict>;
175
142
  /**
176
- * A base policy cannot be detached; it is where a member's roles sit. Use remove-member to take someone out of the project. Requires `iam:members.manage`.
177
- * @summary Detach a policy
143
+ * Removes that one row. Requires `iam:members.manage`.
144
+ * @summary Revoke a permission granted directly to a member
178
145
  */
179
- export declare const DetachPolicyParams: zod.ZodObject<{
180
- policyId: zod.ZodUUID;
146
+ export declare const deleteMemberPermissionPathUserIdMax = 255;
147
+ export declare const DeleteMemberPermissionParams: zod.ZodObject<{
148
+ userId: zod.ZodString;
149
+ permissionId: zod.ZodUUID;
181
150
  }, zod.z.core.$strict>;
182
151
  /**
183
152
  * The only way `OWNER` moves, and only the owner can initiate it.