All files / src/entities/members schema-readonly.ts

100% Statements 13/13
100% Branches 0/0
100% Functions 1/1
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 12719x 19x 19x                       19x     35x                             19x                       19x                       19x                         19x                         19x                             19x                               19x                       19x  
import { z } from "zod";
import { requiredId } from "../utils";
import { PaginationOptionsSchema } from "../shared";
 
/**
 * Access levels for GitLab members
 * - 0: No access
 * - 5: Minimal access
 * - 10: Guest (view only)
 * - 20: Reporter (view + comment)
 * - 30: Developer (push code)
 * - 40: Maintainer (manage settings)
 * - 50: Owner (full control)
 */
const AccessLevelSchema = z
  .number()
  .int()
  .refine(val => [0, 5, 10, 20, 30, 40, 50].includes(val), {
    message:
      "Access level must be 0 (No access), 5 (Minimal), 10 (Guest), 20 (Reporter), 30 (Developer), 40 (Maintainer), or 50 (Owner)",
  })
  .describe(
    "Access level: 0=No access, 5=Minimal, 10=Guest, 20=Reporter, 30=Developer, 40=Maintainer, 50=Owner"
  );
 
// =============================================================================
// Browse Members Actions (Query)
// =============================================================================
 
/**
 * List project members
 */
const ListProjectMembersSchema = z
  .object({
    action: z.literal("list_project").describe("List all members of a project"),
    project_id: requiredId.describe("Project ID or URL-encoded path"),
    query: z.string().optional().describe("Search members by name or username"),
    user_ids: z.array(z.coerce.string()).optional().describe("Filter to specific user IDs"),
  })
  .merge(PaginationOptionsSchema);
 
/**
 * List group members
 */
const ListGroupMembersSchema = z
  .object({
    action: z.literal("list_group").describe("List all members of a group"),
    group_id: requiredId.describe("Group ID or URL-encoded path"),
    query: z.string().optional().describe("Search members by name or username"),
    user_ids: z.array(z.coerce.string()).optional().describe("Filter to specific user IDs"),
  })
  .merge(PaginationOptionsSchema);
 
/**
 * Get specific member from project
 */
const GetProjectMemberSchema = z.object({
  action: z.literal("get_project").describe("Get a specific member of a project"),
  project_id: requiredId.describe("Project ID or URL-encoded path"),
  user_id: requiredId.describe("User ID of the member"),
  include_inherited: z
    .boolean()
    .optional()
    .describe("Include members inherited from parent groups"),
});
 
/**
 * Get specific member from group
 */
const GetGroupMemberSchema = z.object({
  action: z.literal("get_group").describe("Get a specific member of a group"),
  group_id: requiredId.describe("Group ID or URL-encoded path"),
  user_id: requiredId.describe("User ID of the member"),
  include_inherited: z
    .boolean()
    .optional()
    .describe("Include members inherited from parent groups"),
});
 
/**
 * List all members including inherited (project)
 */
const ListAllProjectMembersSchema = z
  .object({
    action: z
      .literal("list_all_project")
      .describe("List all project members including inherited from parent groups"),
    project_id: requiredId.describe("Project ID or URL-encoded path"),
    query: z.string().optional().describe("Search members by name or username"),
    user_ids: z.array(z.coerce.string()).optional().describe("Filter to specific user IDs"),
    state: z.enum(["active", "awaiting", "blocked"]).optional().describe("Filter by member state"),
  })
  .merge(PaginationOptionsSchema);
 
/**
 * List all members including inherited (group)
 */
const ListAllGroupMembersSchema = z
  .object({
    action: z
      .literal("list_all_group")
      .describe("List all group members including inherited from parent groups"),
    group_id: requiredId.describe("Group ID or URL-encoded path"),
    query: z.string().optional().describe("Search members by name or username"),
    user_ids: z.array(z.coerce.string()).optional().describe("Filter to specific user IDs"),
    state: z.enum(["active", "awaiting", "blocked"]).optional().describe("Filter by member state"),
  })
  .merge(PaginationOptionsSchema);
 
// =============================================================================
// BrowseMembersSchema - Discriminated Union
// =============================================================================
 
export const BrowseMembersSchema = z.discriminatedUnion("action", [
  ListProjectMembersSchema,
  ListGroupMembersSchema,
  GetProjectMemberSchema,
  GetGroupMemberSchema,
  ListAllProjectMembersSchema,
  ListAllGroupMembersSchema,
]);
 
export type BrowseMembersOptions = z.infer<typeof BrowseMembersSchema>;
 
// Export AccessLevelSchema for reuse in manage schema
export { AccessLevelSchema };