@leaflow/sdk 0.0.0-dev.481.g3bd94d5 → 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 (36) hide show
  1. package/dist/iam/v1/generated/functions.d.ts +46 -103
  2. package/dist/iam/v1/generated/functions.js +29 -114
  3. package/dist/iam/v1/generated/models.d.ts +53 -118
  4. package/dist/iam/v1/generated/models.js +2 -6
  5. package/dist/iam/v1/generated/schemas.zod.d.ts +31 -62
  6. package/dist/iam/v1/generated/schemas.zod.js +35 -53
  7. package/dist/iam/v1/generated/validators/{updatePolicyRequestBody.zod.d.ts → createMemberPermissionRequestBody.zod.d.ts} +9 -11
  8. package/dist/iam/v1/generated/validators/createMemberPermissionRequestBody.zod.js +36 -0
  9. package/dist/iam/v1/generated/validators/grantResource.zod.js +1 -1
  10. package/dist/iam/v1/generated/validators/lengthAwarePageMemberResource.zod.d.ts +12 -0
  11. package/dist/iam/v1/generated/validators/{listProjectInvitationsParams.zod.d.ts → listInvitationsParams.zod.d.ts} +8 -8
  12. package/dist/iam/v1/generated/validators/{listProjectInvitationsParams.zod.js → listInvitationsParams.zod.js} +11 -11
  13. package/dist/iam/v1/generated/validators/{policyListResponseBody.zod.d.ts → memberPermissionListResponseBody.zod.d.ts} +8 -14
  14. package/dist/iam/v1/generated/validators/{catalogListResponseBody.zod.js → memberPermissionListResponseBody.zod.js} +3 -3
  15. package/dist/iam/v1/generated/validators/{policyResource.zod.d.ts → memberPermissionResource.zod.d.ts} +11 -14
  16. package/dist/iam/v1/generated/validators/memberPermissionResource.zod.js +38 -0
  17. package/dist/iam/v1/generated/validators/memberResource.zod.d.ts +12 -0
  18. package/dist/iam/v1/generated/validators/memberResource.zod.js +5 -0
  19. package/dist/iam/v1/generated/validators/ownershipTransferResponseBody.zod.d.ts +24 -0
  20. package/dist/iam/v1/generated/validators/{catalogResource.zod.d.ts → permissionListResponseBody.zod.d.ts} +4 -8
  21. package/dist/iam/v1/generated/validators/{policyListResponseBody.zod.js → permissionListResponseBody.zod.js} +3 -3
  22. package/dist/routes.d.ts +7 -31
  23. package/dist/routes.js +7 -34
  24. package/package.json +1 -1
  25. package/dist/iam/v1/generated/validators/attachPolicyRequestBody.zod.d.ts +0 -33
  26. package/dist/iam/v1/generated/validators/attachPolicyRequestBody.zod.js +0 -43
  27. package/dist/iam/v1/generated/validators/catalogListResponseBody.zod.d.ts +0 -30
  28. package/dist/iam/v1/generated/validators/catalogResource.zod.js +0 -25
  29. package/dist/iam/v1/generated/validators/listPoliciesParams.zod.d.ts +0 -21
  30. package/dist/iam/v1/generated/validators/listPoliciesParams.zod.js +0 -23
  31. package/dist/iam/v1/generated/validators/policyResource.zod.js +0 -33
  32. package/dist/iam/v1/generated/validators/resourceTypeResource.zod.d.ts +0 -20
  33. package/dist/iam/v1/generated/validators/resourceTypeResource.zod.js +0 -20
  34. package/dist/iam/v1/generated/validators/setMemberPermissionsRequestBody.zod.d.ts +0 -20
  35. package/dist/iam/v1/generated/validators/setMemberPermissionsRequestBody.zod.js +0 -21
  36. package/dist/iam/v1/generated/validators/updatePolicyRequestBody.zod.js +0 -39
@@ -12,7 +12,7 @@
12
12
  * project. It does not state whether a given operation is allowed; each service declares which permission its own operations require.
13
13
  * OpenAPI spec version: 1.0.0
14
14
  */
15
- import type { ApplicationResource, AttachPolicyRequestBody, BatchGetMembersRequestBody, BatchGetMembersResponseBody, CatalogListResponseBody, CreateApplicationRequestBody, CreateApplicationResponseBody, CreateRoleRequestBody, CreateSSHKeyRequestBody, Error, IssueInvitationRequestBody, IssuedInvitationResponseBody, LengthAwarePageApplicationResource, LengthAwarePageInvitationResource, LengthAwarePageMemberResource, LengthAwarePageSSHKeyResource, ListApplicationsParams, ListMembersParams, ListPoliciesParams, ListProjectInvitationsParams, ListSshKeysParams, MemberResource, MembershipResource, OwnershipTransferResponseBody, PolicyListResponseBody, PolicyResource, ProjectAccessResource, QuotaListResponseBody, RenameSSHKeyRequestBody, RoleListResponseBody, RoleResource, RotateApplicationSecretResponseBody, SSHKeyResource, SetMemberPermissionsRequestBody, SetMemberRolesRequestBody, SetProjectSlugRequestBody, TransferOwnershipRequestBody, UpdateApplicationRequestBody, UpdatePolicyRequestBody, UpdateProjectRequestBody, UpdateRoleRequestBody } from "./models.js";
15
+ import type { ApplicationResource, BatchGetMembersRequestBody, BatchGetMembersResponseBody, CreateApplicationRequestBody, CreateApplicationResponseBody, CreateMemberPermissionRequestBody, CreateRoleRequestBody, CreateSSHKeyRequestBody, Error, IssueInvitationRequestBody, IssuedInvitationResponseBody, LengthAwarePageApplicationResource, LengthAwarePageInvitationResource, LengthAwarePageMemberResource, LengthAwarePageSSHKeyResource, ListApplicationsParams, ListInvitationsParams, ListMembersParams, ListSshKeysParams, MemberPermissionListResponseBody, MemberPermissionResource, MemberResource, MembershipResource, OwnershipTransferResponseBody, PermissionListResponseBody, ProjectAccessResource, QuotaListResponseBody, RenameSSHKeyRequestBody, RoleListResponseBody, RoleResource, RotateApplicationSecretResponseBody, SSHKeyResource, SetMemberRolesRequestBody, SetProjectSlugRequestBody, TransferOwnershipRequestBody, UpdateApplicationRequestBody, UpdateProjectRequestBody, UpdateRoleRequestBody } from "./models.js";
16
16
  export type HTTPStatusCode1xx = 100 | 101 | 102 | 103;
17
17
  export type HTTPStatusCode2xx = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207;
18
18
  export type HTTPStatusCode3xx = 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308;
@@ -20,7 +20,7 @@ export type HTTPStatusCode4xx = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 |
20
20
  export type HTTPStatusCode5xx = 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511;
21
21
  export type HTTPStatusCodes = HTTPStatusCode1xx | HTTPStatusCode2xx | HTTPStatusCode3xx | HTTPStatusCode4xx | HTTPStatusCode5xx;
22
22
  export type listPermissionsResponse200 = {
23
- data: CatalogListResponseBody;
23
+ data: PermissionListResponseBody;
24
24
  status: 200;
25
25
  };
26
26
  export type listPermissionsResponseDefault = {
@@ -36,7 +36,7 @@ export type listPermissionsResponseError = listPermissionsResponseDefault & {
36
36
  export type listPermissionsResponse = listPermissionsResponseSuccess | listPermissionsResponseError;
37
37
  export declare const getListPermissionsUrl: () => string;
38
38
  /**
39
- * 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.
39
+ * 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.
40
40
  * @summary List every permission the platform can grant
41
41
  */
42
42
  export declare const listPermissions: (options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<listPermissionsResponse>;
@@ -150,7 +150,7 @@ export type getProjectMembershipResponseError = getProjectMembershipResponseDefa
150
150
  export type getProjectMembershipResponse = getProjectMembershipResponseSuccess | getProjectMembershipResponseError;
151
151
  export declare const getGetProjectMembershipUrl: () => string;
152
152
  /**
153
- * 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.
153
+ * 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.
154
154
  * @summary Get the caller's standing in this project
155
155
  */
156
156
  export declare const getProjectMembership: (options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<getProjectMembershipResponse>;
@@ -175,27 +175,27 @@ export declare const getListQuotasUrl: () => string;
175
175
  * @summary List this project's quotas
176
176
  */
177
177
  export declare const listQuotas: (options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<listQuotasResponse>;
178
- export type listProjectInvitationsResponse200 = {
178
+ export type listInvitationsResponse200 = {
179
179
  data: LengthAwarePageInvitationResource;
180
180
  status: 200;
181
181
  };
182
- export type listProjectInvitationsResponseDefault = {
182
+ export type listInvitationsResponseDefault = {
183
183
  data: Error;
184
184
  status: Exclude<HTTPStatusCodes, 200>;
185
185
  };
186
- export type listProjectInvitationsResponseSuccess = listProjectInvitationsResponse200 & {
186
+ export type listInvitationsResponseSuccess = listInvitationsResponse200 & {
187
187
  headers: Headers;
188
188
  };
189
- export type listProjectInvitationsResponseError = listProjectInvitationsResponseDefault & {
189
+ export type listInvitationsResponseError = listInvitationsResponseDefault & {
190
190
  headers: Headers;
191
191
  };
192
- export type listProjectInvitationsResponse = listProjectInvitationsResponseSuccess | listProjectInvitationsResponseError;
193
- export declare const getListProjectInvitationsUrl: (params?: ListProjectInvitationsParams) => string;
192
+ export type listInvitationsResponse = listInvitationsResponseSuccess | listInvitationsResponseError;
193
+ export declare const getListInvitationsUrl: (params?: ListInvitationsParams) => string;
194
194
  /**
195
195
  * Visible to any member, on the same rule as the member list. Who has been invited is part of who is in the project.
196
196
  * @summary List the invitations this project is still waiting on
197
197
  */
198
- export declare const listProjectInvitations: (params?: ListProjectInvitationsParams, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<listProjectInvitationsResponse>;
198
+ export declare const listInvitations: (params?: ListInvitationsParams, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<listInvitationsResponse>;
199
199
  export type issueInvitationResponse201 = {
200
200
  data: IssuedInvitationResponseBody;
201
201
  status: 201;
@@ -324,132 +324,75 @@ export declare const getSetMemberRolesUrl: (userId: string) => string;
324
324
  * @summary Set the roles a member holds
325
325
  */
326
326
  export declare const setMemberRoles: (userId: string, setMemberRolesRequestBody: SetMemberRolesRequestBody, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<setMemberRolesResponse>;
327
- export type setMemberPermissionsResponse200 = {
328
- data: PolicyResource;
327
+ export type listMemberPermissionsResponse200 = {
328
+ data: MemberPermissionListResponseBody;
329
329
  status: 200;
330
330
  };
331
- export type setMemberPermissionsResponseDefault = {
331
+ export type listMemberPermissionsResponseDefault = {
332
332
  data: Error;
333
333
  status: Exclude<HTTPStatusCodes, 200>;
334
334
  };
335
- export type setMemberPermissionsResponseSuccess = setMemberPermissionsResponse200 & {
335
+ export type listMemberPermissionsResponseSuccess = listMemberPermissionsResponse200 & {
336
336
  headers: Headers;
337
337
  };
338
- export type setMemberPermissionsResponseError = setMemberPermissionsResponseDefault & {
338
+ export type listMemberPermissionsResponseError = listMemberPermissionsResponseDefault & {
339
339
  headers: Headers;
340
340
  };
341
- export type setMemberPermissionsResponse = setMemberPermissionsResponseSuccess | setMemberPermissionsResponseError;
342
- export declare const getSetMemberPermissionsUrl: (userId: string) => string;
341
+ export type listMemberPermissionsResponse = listMemberPermissionsResponseSuccess | listMemberPermissionsResponseError;
342
+ export declare const getListMemberPermissionsUrl: (userId: string) => string;
343
343
  /**
344
- * 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`.
345
- * @summary Set the permissions attached directly to a member
346
- */
347
- export declare const setMemberPermissions: (userId: string, setMemberPermissionsRequestBody: SetMemberPermissionsRequestBody, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<setMemberPermissionsResponse>;
348
- export type listPoliciesResponse200 = {
349
- data: PolicyListResponseBody;
350
- status: 200;
351
- };
352
- export type listPoliciesResponseDefault = {
353
- data: Error;
354
- status: Exclude<HTTPStatusCodes, 200>;
355
- };
356
- export type listPoliciesResponseSuccess = listPoliciesResponse200 & {
357
- headers: Headers;
358
- };
359
- export type listPoliciesResponseError = listPoliciesResponseDefault & {
360
- headers: Headers;
361
- };
362
- export type listPoliciesResponse = listPoliciesResponseSuccess | listPoliciesResponseError;
363
- export declare const getListPoliciesUrl: (params?: ListPoliciesParams) => string;
364
- /**
365
- * 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.
366
- * @summary List the policies in this project
344
+ * 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.
345
+ *
346
+ * Visible to any member, on the same rule as the member list.
347
+ * @summary List the permissions granted directly to a member
367
348
  */
368
- export declare const listPolicies: (params?: ListPoliciesParams, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<listPoliciesResponse>;
369
- export type attachPolicyResponse201 = {
370
- data: PolicyResource;
349
+ export declare const listMemberPermissions: (userId: string, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<listMemberPermissionsResponse>;
350
+ export type createMemberPermissionResponse201 = {
351
+ data: MemberPermissionResource;
371
352
  status: 201;
372
353
  };
373
- export type attachPolicyResponseDefault = {
354
+ export type createMemberPermissionResponseDefault = {
374
355
  data: Error;
375
356
  status: Exclude<HTTPStatusCodes, 201>;
376
357
  };
377
- export type attachPolicyResponseSuccess = attachPolicyResponse201 & {
378
- headers: Headers;
379
- };
380
- export type attachPolicyResponseError = attachPolicyResponseDefault & {
381
- headers: Headers;
382
- };
383
- export type attachPolicyResponse = attachPolicyResponseSuccess | attachPolicyResponseError;
384
- export declare const getAttachPolicyUrl: () => string;
385
- /**
386
- * 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`.
387
- * @summary Attach a policy
388
- */
389
- export declare const attachPolicy: (attachPolicyRequestBody: AttachPolicyRequestBody, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<attachPolicyResponse>;
390
- export type getPolicyResponse200 = {
391
- data: PolicyResource;
392
- status: 200;
393
- };
394
- export type getPolicyResponseDefault = {
395
- data: Error;
396
- status: Exclude<HTTPStatusCodes, 200>;
397
- };
398
- export type getPolicyResponseSuccess = getPolicyResponse200 & {
399
- headers: Headers;
400
- };
401
- export type getPolicyResponseError = getPolicyResponseDefault & {
402
- headers: Headers;
403
- };
404
- export type getPolicyResponse = getPolicyResponseSuccess | getPolicyResponseError;
405
- export declare const getGetPolicyUrl: (policyId: string) => string;
406
- /**
407
- * Visible to any member, on the same rule as list-policies; no further permission is required.
408
- * @summary Get a policy
409
- */
410
- export declare const getPolicy: (policyId: string, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<getPolicyResponse>;
411
- export type updatePolicyResponse200 = {
412
- data: PolicyResource;
413
- status: 200;
414
- };
415
- export type updatePolicyResponseDefault = {
416
- data: Error;
417
- status: Exclude<HTTPStatusCodes, 200>;
418
- };
419
- export type updatePolicyResponseSuccess = updatePolicyResponse200 & {
358
+ export type createMemberPermissionResponseSuccess = createMemberPermissionResponse201 & {
420
359
  headers: Headers;
421
360
  };
422
- export type updatePolicyResponseError = updatePolicyResponseDefault & {
361
+ export type createMemberPermissionResponseError = createMemberPermissionResponseDefault & {
423
362
  headers: Headers;
424
363
  };
425
- export type updatePolicyResponse = updatePolicyResponseSuccess | updatePolicyResponseError;
426
- export declare const getUpdatePolicyUrl: (policyId: string) => string;
364
+ export type createMemberPermissionResponse = createMemberPermissionResponseSuccess | createMemberPermissionResponseError;
365
+ export declare const getCreateMemberPermissionUrl: (userId: string) => string;
427
366
  /**
428
- * 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`.
429
- * @summary Update a policy
367
+ * 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.
368
+ *
369
+ * `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.
370
+ *
371
+ * Requires `iam:members.manage`.
372
+ * @summary Grant a permission to a member
430
373
  */
431
- export declare const updatePolicy: (policyId: string, updatePolicyRequestBody: UpdatePolicyRequestBody, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<updatePolicyResponse>;
432
- export type detachPolicyResponse204 = {
374
+ export declare const createMemberPermission: (userId: string, createMemberPermissionRequestBody: CreateMemberPermissionRequestBody, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<createMemberPermissionResponse>;
375
+ export type deleteMemberPermissionResponse204 = {
433
376
  data: void;
434
377
  status: 204;
435
378
  };
436
- export type detachPolicyResponseDefault = {
379
+ export type deleteMemberPermissionResponseDefault = {
437
380
  data: Error;
438
381
  status: Exclude<HTTPStatusCodes, 204>;
439
382
  };
440
- export type detachPolicyResponseSuccess = detachPolicyResponse204 & {
383
+ export type deleteMemberPermissionResponseSuccess = deleteMemberPermissionResponse204 & {
441
384
  headers: Headers;
442
385
  };
443
- export type detachPolicyResponseError = detachPolicyResponseDefault & {
386
+ export type deleteMemberPermissionResponseError = deleteMemberPermissionResponseDefault & {
444
387
  headers: Headers;
445
388
  };
446
- export type detachPolicyResponse = detachPolicyResponseSuccess | detachPolicyResponseError;
447
- export declare const getDetachPolicyUrl: (policyId: string) => string;
389
+ export type deleteMemberPermissionResponse = deleteMemberPermissionResponseSuccess | deleteMemberPermissionResponseError;
390
+ export declare const getDeleteMemberPermissionUrl: (userId: string, permissionId: string) => string;
448
391
  /**
449
- * 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`.
450
- * @summary Detach a policy
392
+ * Removes that one row. Requires `iam:members.manage`.
393
+ * @summary Revoke a permission granted directly to a member
451
394
  */
452
- export declare const detachPolicy: (policyId: string, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<detachPolicyResponse>;
395
+ export declare const deleteMemberPermission: (userId: string, permissionId: string, options?: RequestInit, fetchFn?: typeof globalThis.fetch) => Promise<deleteMemberPermissionResponse>;
453
396
  export type transferProjectOwnershipResponse200 = {
454
397
  data: OwnershipTransferResponseBody;
455
398
  status: 200;
@@ -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
  });