{"version":3,"file":"server-fyv6VaLE.mjs","names":["roleToSet: string[]","member","finalUpdates: Record<string, any>","where: Where[]","updateData: Record<string, unknown>"],"sources":["../src/error-codes.ts","../src/server.ts"],"sourcesContent":["import { defineErrorCodes } from \"better-auth\";\n\nexport const ORGANIZATION_MEMBER_ERROR_CODES = defineErrorCodes({\n  INVALID_FILTER_JSON_PARAMETER: \"Invalid 'filterJson' parameter. Must be a valid JSON array.\",\n  CANNOT_REMOVE_YOURSELF: \"You are not allowed to remove yourself\",\n});\n","/** @format */\n\nimport {\n  APIError,\n  BASE_ERROR_CODES,\n  defineErrorCodes,\n  type AuthContext,\n  type BetterAuthOptions,\n  type BetterAuthPlugin,\n  type GenericEndpointContext,\n  type Session,\n  type User,\n} from \"better-auth\";\nimport {\n  createAuthEndpoint,\n  createAuthMiddleware,\n  sessionMiddleware,\n} from \"better-auth/api\";\nimport { clientSideHasPermission } from \"better-auth/client/plugins\";\nimport type { InferAdditionalFieldsFromPluginOptions } from \"better-auth/db\";\nimport { toZodSchema } from \"better-auth/db\";\nimport {\n  getOrgAdapter,\n  InferInvitation,\n  type InferMember,\n  type InferOrganization,\n  type Member,\n  type OrganizationOptions,\n  type OrganizationPlugin,\n  type Role,\n} from \"better-auth/plugins\";\nimport { defaultRoles } from \"better-auth/plugins/organization/access\";\nimport type { Where } from \"better-auth/types\";\nimport z from \"zod\";\nimport { ORGANIZATION_MEMBER_ERROR_CODES } from \"./error-codes\";\nimport { oauthProvider } from \"@better-auth/oauth-provider\";\n\nconst ORGANIZATION_ERROR_CODES = defineErrorCodes({\n  NO_ACTIVE_ORGANIZATION: \"No active organization\",\n  MEMBER_NOT_FOUND: \"Member not found\",\n  ORGANIZATION_NOT_FOUND: \"Organization not found\",\n  YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER:\n    \"You are not allowed to update this member\",\n  YOU_CANNOT_LEAVE_THE_ORGANIZATION_WITHOUT_AN_OWNER:\n    \"You cannot leave the organization without an owner\",\n  INVITATION_NOT_FOUND: \"Invitation not found\",\n  YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_INVITATION:\n    \"You are not allowed to update this invitation\",\n  ONLY_PENDING_INVITATIONS_CAN_BE_UPDATED:\n    \"Only pending invitations can be updated\",\n  YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION:\n    \"You are not a member of this organization\",\n});\n\nconst getOauthProviderPlugin = <\n  Options extends BetterAuthOptions = BetterAuthOptions,\n>(\n  ctx: AuthContext<Options>,\n) => {\n  return ctx.options.plugins?.find(\n    (plugin) => plugin.id === \"oauth-provider\",\n  ) as ReturnType<typeof oauthProvider>;\n};\n\nconst getOrganizationPlugin = <\n  Options extends BetterAuthOptions = BetterAuthOptions,\n>(\n  ctx: AuthContext<Options>\n) => {\n  return ctx.options.plugins?.find(\n    (plugin) => plugin.id === \"organization\"\n  ) as OrganizationPlugin<OrganizationOptions>;\n};\n\nexport interface OrganizationMemberOptions {\n  schema?: OrganizationOptions[\"schema\"];\n  /**\n   * Hooks for the organization member plugin\n   */\n  organizationMemberHooks?: {\n    /**\n     * A callback that runs before a member's info is updated\n     *\n     * You can return a `data` object to override the default data.\n     */\n    beforeUpdateMember?: (data: {\n      member: InferMember<OrganizationOptions, false>;\n      updates: {\n        role?: string | string[];\n      } & InferAdditionalFieldsFromPluginOptions<\"member\", OrganizationOptions>;\n      user: User;\n      organization: InferOrganization<OrganizationOptions, false>;\n    }) => Promise<void | {\n      data: {\n        role?: string | string[];\n      } & InferAdditionalFieldsFromPluginOptions<\"member\", OrganizationOptions>;\n    }>;\n\n    /**\n     * A callback that runs after a member's info is updated\n     */\n    afterUpdateMember?: (data: {\n      member: InferMember<OrganizationOptions, false>;\n      user: User;\n      organization: InferOrganization<OrganizationOptions, false>;\n    }) => Promise<void>;\n\n    /**\n     * A callback that runs before an invitation is updated\n     *\n     * You can return a `data` object to override the default data.\n     */\n    beforeUpdateInvitation?: (data: {\n      invitation: InferInvitation<OrganizationOptions, false>;\n      updates: {\n        role?: string | string[];\n      } & InferAdditionalFieldsFromPluginOptions<\n        \"invitation\",\n        OrganizationOptions\n      >;\n      inviter: User;\n      organization: InferOrganization<OrganizationOptions, false>;\n    }) => Promise<void | {\n      data: {\n        role?: string | string[];\n      } & InferAdditionalFieldsFromPluginOptions<\n        \"invitation\",\n        OrganizationOptions\n      >;\n    }>;\n\n    /**\n     * A callback that runs after an invitation is updated\n     */\n    afterUpdateInvitation?: (data: {\n      invitation: InferInvitation<OrganizationOptions, false>;\n      inviter: User;\n      organization: InferOrganization<OrganizationOptions, false>;\n    }) => Promise<void>;\n  };\n}\n\nexport const orgMiddleware = createAuthMiddleware(async () => {\n  return {} as {\n    orgOptions: OrganizationOptions;\n    roles: typeof defaultRoles & {\n      [key: string]: Role<{}>;\n    };\n    getSession: (context: GenericEndpointContext) => Promise<{\n      session: Session & {\n        activeTeamId?: string | undefined;\n        activeOrganizationId?: string | undefined;\n      };\n      user: User;\n    }>;\n  };\n});\n\n/**\n * The middleware forces the endpoint to require a valid session by utilizing the `sessionMiddleware`.\n * It also appends additional types to the session type regarding organizations.\n */\nexport const orgSessionMiddleware = createAuthMiddleware(\n  {\n    use: [sessionMiddleware],\n  },\n  async (ctx) => {\n    const session = ctx.context.session as {\n      session: Session & {\n        activeTeamId?: string | undefined;\n        activeOrganizationId?: string | undefined;\n      };\n      user: User;\n    };\n    return {\n      session,\n    };\n  }\n);\n\n/**\n * Organization Member Plugin\n *\n * Extends the organization plugin with:\n * - updateMember endpoint to update member fields (not just role)\n * - Automatically adds afterAcceptInvitation hook to transfer invitation data to member\n *\n * @requires organization plugin\n */\n\nconst createUpdateMemberEndpoint = (options?: OrganizationMemberOptions) => {\n  const additionalFieldsSchema = toZodSchema({\n    fields: options?.schema?.member?.additionalFields || {},\n    isClientSide: true,\n  });\n\n  return createAuthEndpoint(\n    \"/organization/update-member\",\n    {\n      method: \"POST\",\n      body: z.object({\n        memberId: z.string().meta({\n          description: 'The member id to apply the update to. Eg: \"member-id\"',\n        }),\n        organizationId: z\n          .string()\n          .meta({\n            description:\n              'An optional organization ID which the member is a part of. If not provided, you must provide session headers to get the active organization. Eg: \"organization-id\"',\n          })\n          .optional(),\n        data: z\n          .object({\n            role: z\n              .union([z.string(), z.array(z.string())])\n              .optional()\n              .meta({\n                description:\n                  'The new role to be applied. This can be a string or array of strings representing the roles. Eg: [\"admin\", \"sale\"]',\n              }),\n            ...additionalFieldsSchema.shape,\n          })\n          .partial(),\n      }),\n      use: [orgMiddleware, orgSessionMiddleware],\n      requireHeaders: true,\n      metadata: {\n        $Infer: {\n          body: {} as {\n            memberId: string;\n            organizationId?: string;\n            data: {\n              role?: string | string[];\n              firstName?: string;\n              lastName?: string;\n              avatar?: string;\n            } & Partial<\n              InferAdditionalFieldsFromPluginOptions<\n                \"member\",\n                OrganizationOptions\n              >\n            >;\n          },\n        },\n        openapi: {\n          operationId: \"updateOrganizationMember\",\n          description: \"Update a member in an organization\",\n          responses: {\n            \"200\": {\n              description: \"Success\",\n              content: {\n                \"application/json\": {\n                  schema: {\n                    type: \"object\",\n                    properties: {\n                      id: {\n                        type: \"string\",\n                      },\n                      userId: {\n                        type: \"string\",\n                      },\n                      organizationId: {\n                        type: \"string\",\n                      },\n                      firstName: {\n                        type: \"string\",\n                      },\n                      lastName: {\n                        type: \"string\",\n                      },\n                      avatar: {\n                        type: \"string\",\n                      },\n                    },\n                    required: [\"id\", \"userId\", \"organizationId\", \"role\"],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    },\n    async (ctx) => {\n      const session = ctx.context.session;\n\n      const organizationPlugin = getOrganizationPlugin(ctx.context);\n      if (!organizationPlugin) {\n        throw new Error(\n          \"organization-member plugin requires the organization plugin\"\n        );\n      }\n\n      const organizationId =\n        ctx.body.organizationId || session.session.activeOrganizationId;\n\n      if (!organizationId) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION\n        );\n      }\n\n      const adapter = getOrgAdapter(ctx.context, organizationPlugin.options);\n      const roleToSet: string[] = ctx.body.data?.role\n        ? Array.isArray(ctx.body.data.role)\n          ? ctx.body.data.role\n          : [ctx.body.data.role]\n        : [];\n\n      const member = await adapter.findMemberByOrgId({\n        userId: session.user.id,\n        organizationId: organizationId,\n      });\n\n      if (!member) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.MEMBER_NOT_FOUND\n        );\n      }\n\n      const toBeUpdatedMember =\n        member.id !== ctx.body.memberId\n          ? await adapter.findMemberById(ctx.body.memberId)\n          : member;\n\n      if (!toBeUpdatedMember) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.MEMBER_NOT_FOUND\n        );\n      }\n\n      const memberBelongsToOrganization =\n        toBeUpdatedMember.organizationId === organizationId;\n\n      if (!memberBelongsToOrganization) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER\n        );\n      }\n\n      const creatorRole = organizationPlugin.options?.creatorRole || \"owner\";\n\n      const updatingMemberRoles = member.role.split(\",\");\n      const toBeUpdatedMemberRoles = toBeUpdatedMember.role.split(\",\");\n\n      const isUpdatingCreator = toBeUpdatedMemberRoles.includes(creatorRole);\n      const updaterIsCreator = updatingMemberRoles.includes(creatorRole);\n\n      const isSettingCreatorRole = roleToSet.includes(creatorRole);\n\n      const memberIsUpdatingThemselves = member.id === toBeUpdatedMember.id;\n\n      if (\n        (isUpdatingCreator && !updaterIsCreator) ||\n        (isSettingCreatorRole && !updaterIsCreator)\n      ) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER\n        );\n      }\n\n      if (updaterIsCreator && memberIsUpdatingThemselves) {\n        const members = await ctx.context.adapter.findMany<\n          InferMember<OrganizationOptions, false>\n        >({\n          model: \"member\",\n          where: [\n            {\n              field: \"organizationId\",\n              value: organizationId,\n            },\n          ],\n        });\n        const owners = members.filter((member: Member) => {\n          const roles = member.role.split(\",\");\n          return roles.includes(creatorRole);\n        });\n        if (owners.length <= 1 && !isSettingCreatorRole) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_ERROR_CODES.YOU_CANNOT_LEAVE_THE_ORGANIZATION_WITHOUT_AN_OWNER\n          );\n        }\n      }\n\n      // currently use clientSideHasPermission instead of hasPermission\n      // this does not support dynamic access control yet\n      // TODO: improve me\n      const canUpdateMember = clientSideHasPermission({\n        role: member.role,\n        options: organizationPlugin.options,\n        permissions: {\n          member: [\"update\"],\n        },\n        allowCreatorAllPermissions: true,\n      });\n\n      if (!canUpdateMember) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER\n        );\n      }\n\n      // Get organization\n      const organization = await adapter.findOrganizationById(organizationId);\n\n      if (!organization) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND\n        );\n      }\n\n      const userBeingUpdated = await ctx.context.internalAdapter.findUserById(\n        toBeUpdatedMember.userId\n      );\n\n      if (!userBeingUpdated) {\n        throw APIError.from(\"BAD_REQUEST\", BASE_ERROR_CODES.USER_NOT_FOUND);\n      }\n\n      // Extract updates from data object\n      const updates = ctx.body.data || {};\n      let finalUpdates: Record<string, any> = updates;\n\n      // Run beforeUpdateMember hook (if provided via options parameter)\n      if (options?.organizationMemberHooks?.beforeUpdateMember) {\n        const response =\n          await options.organizationMemberHooks.beforeUpdateMember({\n            member: toBeUpdatedMember,\n            updates,\n            user: userBeingUpdated,\n            organization: organization as InferOrganization<\n              OrganizationOptions,\n              false\n            >,\n          });\n        if (response && typeof response === \"object\" && \"data\" in response) {\n          finalUpdates = response.data;\n        }\n      }\n\n      // Update the member - NOTE: this is different from updateMemberRole\n      // which only updates the role field. We update any additional fields.\n      const updatedMember = await ctx.context.adapter.update<\n        InferMember<OrganizationOptions, false>\n      >({\n        model: \"member\",\n        where: [{ field: \"id\", value: ctx.body.memberId }],\n        update: finalUpdates,\n      });\n\n      if (!updatedMember) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.MEMBER_NOT_FOUND\n        );\n      }\n\n      // Run afterUpdateMember hook (if provided via options parameter)\n      if (options?.organizationMemberHooks?.afterUpdateMember) {\n        await options.organizationMemberHooks.afterUpdateMember({\n          member: updatedMember,\n          user: userBeingUpdated,\n          organization: organization as InferOrganization<\n            OrganizationOptions,\n            false\n          >,\n        });\n      }\n\n      return ctx.json(updatedMember);\n    }\n  );\n};\n\nconst createUpdateInvitationEndpoint = (\n  options?: OrganizationMemberOptions\n) => {\n  const baseInvitationSchema = z.object({\n    invitationId: z.string().meta({\n      description: 'The invitation id to update. Eg: \"invitation-id\"',\n    }),\n    organizationId: z\n      .string()\n      .meta({\n        description:\n          'An optional organization ID which the invitation belongs to. If not provided, you must provide session headers to get the active organization. Eg: \"organization-id\"',\n      })\n      .optional(),\n  });\n\n  const additionalFieldsSchema = toZodSchema({\n    fields: options?.schema?.invitation?.additionalFields || {},\n    isClientSide: true,\n  });\n\n  return createAuthEndpoint(\n    \"/organization/update-invitation\",\n    {\n      method: \"POST\",\n      body: z.object({\n        invitationId: z.string().meta({\n          description: 'The invitation id to update. Eg: \"invitation-id\"',\n        }),\n        organizationId: z\n          .string()\n          .meta({\n            description:\n              'An optional organization ID which the invitation belongs to. If not provided, you must provide session headers to get the active organization. Eg: \"organization-id\"',\n          })\n          .optional(),\n        data: z\n          .object({\n            role: z\n              .union([z.string(), z.array(z.string())])\n              .optional()\n              .meta({\n                description:\n                  'The new role to be applied. This can be a string or array of strings representing the roles. Eg: [\"admin\", \"sale\"]',\n              }),\n            ...additionalFieldsSchema.shape,\n          })\n          .partial(),\n      }),\n      use: [orgMiddleware, orgSessionMiddleware],\n      requireHeaders: true,\n      metadata: {\n        $Infer: {\n          body: {} as {\n            invitationId: string;\n            organizationId?: string;\n            data: {\n              role?: string | string[];\n            } & Partial<\n              InferAdditionalFieldsFromPluginOptions<\n                \"invitation\",\n                OrganizationOptions\n              >\n            >;\n          },\n        },\n        openapi: {\n          operationId: \"updateOrganizationInvitation\",\n          description: \"Update a pending invitation in an organization\",\n          responses: {\n            \"200\": {\n              description: \"Success\",\n              content: {\n                \"application/json\": {\n                  schema: {\n                    type: \"object\",\n                    properties: {\n                      id: {\n                        type: \"string\",\n                      },\n                      organizationId: {\n                        type: \"string\",\n                      },\n                      email: {\n                        type: \"string\",\n                      },\n                      role: {\n                        type: \"string\",\n                      },\n                      createdAt: {\n                        type: \"string\",\n                        format: \"date-time\",\n                        description: \"Timestamp when the team was created\",\n                      },\n                      updatedAt: {\n                        type: \"string\",\n                        format: \"date-time\",\n                        description: \"Timestamp when the team was last updated\",\n                      },\n                    },\n                    required: [\"id\", \"organizationId\", \"email\", \"role\"],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    },\n    async (ctx) => {\n      const session = ctx.context.session;\n\n      const organizationPlugin = getOrganizationPlugin(ctx.context);\n      if (!organizationPlugin) {\n        throw new Error(\n          \"organization-member plugin requires the organization plugin\"\n        );\n      }\n\n      const organizationId =\n        ctx.body.organizationId || session.session.activeOrganizationId;\n\n      if (!organizationId) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION\n        );\n      }\n\n      const adapter = getOrgAdapter(ctx.context, organizationPlugin.options);\n\n      // Get the current user's member record\n      const member = await adapter.findMemberByOrgId({\n        userId: session.user.id,\n        organizationId: organizationId,\n      });\n\n      if (!member) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.MEMBER_NOT_FOUND\n        );\n      }\n\n      // Check permissions - user must have permission to manage invitations\n      const canManageInvitations = clientSideHasPermission({\n        role: member.role,\n        options: organizationPlugin.options,\n        permissions: {\n          invitation: [\"create\"],\n        },\n        allowCreatorAllPermissions: true,\n      });\n\n      if (!canManageInvitations) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_INVITATION\n        );\n      }\n\n      // Get the invitation\n      const invitation = await adapter.findInvitationById(\n        ctx.body.invitationId\n      );\n\n      if (!invitation) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.INVITATION_NOT_FOUND\n        );\n      }\n\n      // Verify invitation belongs to the organization\n      if (invitation.organizationId !== organizationId) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_INVITATION\n        );\n      }\n\n      // Only allow updating pending invitations\n      if (invitation.status !== \"pending\") {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.ONLY_PENDING_INVITATIONS_CAN_BE_UPDATED\n        );\n      }\n\n      // Get organization\n      const organization = await adapter.findOrganizationById(organizationId);\n\n      if (!organization) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND\n        );\n      }\n\n      // Extract updates from data object\n      const updates = ctx.body.data || {};\n      let finalUpdates: Record<string, any> = updates;\n\n      // Run beforeUpdateInvitation hook (if provided via options parameter)\n      if (options?.organizationMemberHooks?.beforeUpdateInvitation) {\n        const response =\n          await options.organizationMemberHooks.beforeUpdateInvitation({\n            invitation,\n            updates,\n            inviter: session.user,\n            organization,\n          });\n        if (response && typeof response === \"object\" && \"data\" in response) {\n          finalUpdates = response.data;\n        }\n      }\n\n      // Update the invitation\n      const updatedInvitation = await ctx.context.adapter.update<\n        InferInvitation<OrganizationOptions, false>\n      >({\n        model: \"invitation\",\n        where: [{ field: \"id\", value: ctx.body.invitationId }],\n        update: finalUpdates,\n      });\n\n      if (!updatedInvitation) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.INVITATION_NOT_FOUND\n        );\n      }\n\n      // Run afterUpdateInvitation hook (if provided via options parameter)\n      if (options?.organizationMemberHooks?.afterUpdateInvitation) {\n        await options.organizationMemberHooks.afterUpdateInvitation({\n          invitation: updatedInvitation,\n          inviter: session.user,\n          organization,\n        });\n      }\n\n      return ctx.json(updatedInvitation);\n    }\n  );\n};\n\nconst createListInvitationsEndpoint = (options?: OrganizationMemberOptions) => {\n  return createAuthEndpoint(\n    \"/organization/list-invitations\",\n    {\n      method: \"GET\",\n      query: z\n        .object({\n          limit: z\n            .string()\n            .meta({\n              description: \"The number of invitations to return\",\n            })\n            .or(z.number())\n            .optional(),\n          offset: z\n            .string()\n            .meta({\n              description: \"The offset to start from\",\n            })\n            .or(z.number())\n            .optional(),\n          sortBy: z\n            .string()\n            .meta({\n              description: \"The field to sort by\",\n            })\n            .optional(),\n          sortDirection: z\n            .enum([\"asc\", \"desc\"])\n            .meta({\n              description: \"The direction to sort by\",\n            })\n            .optional(),\n          filterJson: z\n            .string()\n            .meta({\n              description:\n                'JSON string array of Where filters. Example: \\'[{\"field\":\"status\",\"value\":\"pending\",\"operator\":\"eq\"}]\\'',\n            })\n            .optional(),\n          // Legacy single filter support (for backward compatibility)\n          filterField: z\n            .string()\n            .meta({\n              description:\n                \"The field to filter by (legacy, use 'where' for multiple filters)\",\n            })\n            .optional(),\n          filterValue: z\n            .string()\n            .meta({\n              description:\n                \"The value to filter by (legacy, use 'where' for multiple filters)\",\n            })\n            .or(z.number())\n            .or(z.boolean())\n            .optional(),\n          filterOperator: z\n            .enum([\"eq\", \"ne\", \"lt\", \"lte\", \"gt\", \"gte\", \"contains\"])\n            .meta({\n              description:\n                \"The operator to use for the filter (legacy, use 'where' for multiple filters)\",\n            })\n            .optional(),\n          organizationId: z\n            .string()\n            .meta({\n              description:\n                'The organization ID to list invitations for. If not provided, will default to the user\\'s active organization. Eg: \"organization-id\"',\n            })\n            .optional(),\n          organizationSlug: z\n            .string()\n            .meta({\n              description:\n                'The organization slug to list invitations for. If not provided, will default to the user\\'s active organization. Eg: \"organization-slug\"',\n            })\n            .optional(),\n        })\n        .optional(),\n      requireHeaders: true,\n      use: [orgMiddleware, orgSessionMiddleware],\n      metadata: {\n        $Infer: {\n          query: {} as {\n            limit?: number;\n            offset?: number;\n            sortBy?: string;\n            sortDirection?: \"asc\" | \"desc\";\n            filterJson?: string; // JSON string of Where[]\n            filterField?: string;\n            filterValue?: string | number | boolean;\n            filterOperator?:\n              | \"eq\"\n              | \"ne\"\n              | \"lt\"\n              | \"lte\"\n              | \"gt\"\n              | \"gte\"\n              | \"contains\";\n            organizationId?: string;\n            organizationSlug?: string;\n          },\n        },\n        openapi: {\n          operationId: \"listOrganizationInvitations\",\n          description:\n            \"List invitations in an organization with filtering and sorting\",\n          responses: {\n            \"200\": {\n              description: \"Success\",\n              content: {\n                \"application/json\": {\n                  schema: {\n                    type: \"object\",\n                    properties: {\n                      invitations: {\n                        type: \"array\",\n                        items: {\n                          type: \"object\",\n                        },\n                      },\n                      total: {\n                        type: \"number\",\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    },\n    async (ctx) => {\n      const session = ctx.context.session;\n      let organizationId =\n        ctx.query?.organizationId || session.session.activeOrganizationId;\n\n      const organizationPlugin = getOrganizationPlugin(ctx.context);\n      if (!organizationPlugin) {\n        throw new Error(\n          \"organization-member plugin requires the organization plugin\"\n        );\n      }\n\n      const adapter = getOrgAdapter(ctx.context, organizationPlugin.options);\n\n      if (ctx.query?.organizationSlug) {\n        const organization = await adapter.findOrganizationBySlug(\n          ctx.query.organizationSlug\n        );\n        if (!organization) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND\n          );\n        }\n        organizationId = organization.id;\n      }\n\n      if (!organizationId) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION\n        );\n      }\n\n      const isMember = await adapter.findMemberByOrgId({\n        userId: session.user.id,\n        organizationId,\n      });\n\n      if (!isMember) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION\n        );\n      }\n\n      // Build where clause\n      const where: Where[] = [\n        { field: \"organizationId\", value: organizationId },\n      ];\n\n      // Parse where array from query if provided\n      if (ctx.query?.filterJson) {\n        try {\n          const parsedWhere = JSON.parse(ctx.query.filterJson) as Where[];\n          if (Array.isArray(parsedWhere)) {\n            where.push(...parsedWhere);\n          }\n        } catch (error) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_MEMBER_ERROR_CODES.INVALID_FILTER_JSON_PARAMETER\n          );\n        }\n      }\n\n      // Legacy single filter support (for backward compatibility)\n      if (ctx.query?.filterField) {\n        where.push({\n          field: ctx.query.filterField,\n          value: ctx.query.filterValue,\n          ...(ctx.query.filterOperator\n            ? { operator: ctx.query.filterOperator }\n            : {}),\n        } as Where);\n      }\n\n      // Get invitations with pagination and sorting\n      const [invitations, total] = await Promise.all([\n        ctx.context.adapter.findMany<\n          InferInvitation<OrganizationOptions, false>\n        >({\n          model: \"invitation\",\n          where,\n          limit: ctx.query?.limit ? Number(ctx.query.limit) : 100,\n          offset: ctx.query?.offset ? Number(ctx.query.offset) : 0,\n          sortBy: ctx.query?.sortBy\n            ? {\n                field: ctx.query.sortBy,\n                direction: ctx.query.sortDirection || \"asc\",\n              }\n            : undefined,\n        }),\n        ctx.context.adapter.count({\n          model: \"invitation\",\n          where,\n        }),\n      ]);\n\n      return ctx.json({\n        invitations,\n        total,\n      });\n    }\n  );\n};\n\nconst createListMembersEndpoint = (options?: OrganizationMemberOptions) => {\n  return createAuthEndpoint(\n    \"/organization/list-members\",\n    {\n      method: \"GET\",\n      query: z\n        .object({\n          limit: z\n            .string()\n            .meta({\n              description: \"The number of members to return\",\n            })\n            .or(z.number())\n            .optional(),\n          offset: z\n            .string()\n            .meta({\n              description: \"The offset to start from\",\n            })\n            .or(z.number())\n            .optional(),\n          sortBy: z\n            .string()\n            .meta({\n              description: \"The field to sort by\",\n            })\n            .optional(),\n          sortDirection: z\n            .enum([\"asc\", \"desc\"])\n            .meta({\n              description: \"The direction to sort by\",\n            })\n            .optional(),\n          filterJson: z\n            .string()\n            .meta({\n              description:\n                'JSON string array of Where filters. Example: \\'[{\"field\":\"role\",\"value\":\"admin\",\"operator\":\"eq\"}]\\'',\n            })\n            .optional(),\n          // Legacy single filter support (for backward compatibility)\n          filterField: z\n            .string()\n            .meta({\n              description:\n                \"The field to filter by (legacy, use 'filterJson' for multiple filters)\",\n            })\n            .optional(),\n          filterValue: z\n            .string()\n            .meta({\n              description:\n                \"The value to filter by (legacy, use 'filterJson' for multiple filters)\",\n            })\n            .or(z.number())\n            .or(z.boolean())\n            .optional(),\n          filterOperator: z\n            .enum([\"eq\", \"ne\", \"lt\", \"lte\", \"gt\", \"gte\", \"contains\"])\n            .meta({\n              description:\n                \"The operator to use for the filter (legacy, use 'filterJson' for multiple filters)\",\n            })\n            .optional(),\n          organizationId: z\n            .string()\n            .meta({\n              description:\n                'The organization ID to list members for. If not provided, will default to the user\\'s active organization. Eg: \"organization-id\"',\n            })\n            .optional(),\n          organizationSlug: z\n            .string()\n            .meta({\n              description:\n                'The organization slug to list members for. If not provided, will default to the user\\'s active organization. Eg: \"organization-slug\"',\n            })\n            .optional(),\n        })\n        .optional(),\n      requireHeaders: true,\n      use: [orgMiddleware, orgSessionMiddleware],\n      metadata: {\n        $Infer: {\n          query: {} as {\n            limit?: number;\n            offset?: number;\n            sortBy?: string;\n            sortDirection?: \"asc\" | \"desc\";\n            filterJson?: string; // JSON string of Where[]\n            filterField?: string;\n            filterValue?: string | number | boolean;\n            filterOperator?:\n              | \"eq\"\n              | \"ne\"\n              | \"lt\"\n              | \"lte\"\n              | \"gt\"\n              | \"gte\"\n              | \"contains\";\n            organizationId?: string;\n            organizationSlug?: string;\n          },\n        },\n        openapi: {\n          operationId: \"listOrganizationMembers\",\n          description:\n            \"List members in an organization with filtering and sorting\",\n          responses: {\n            \"200\": {\n              description: \"Success\",\n              content: {\n                \"application/json\": {\n                  schema: {\n                    type: \"object\",\n                    properties: {\n                      members: {\n                        type: \"array\",\n                        items: {\n                          type: \"object\",\n                        },\n                      },\n                      total: {\n                        type: \"number\",\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    },\n    async (ctx) => {\n      const session = ctx.context.session;\n      let organizationId =\n        ctx.query?.organizationId || session.session.activeOrganizationId;\n\n      const organizationPlugin = getOrganizationPlugin(ctx.context);\n      if (!organizationPlugin) {\n        throw new Error(\n          \"organization-member plugin requires the organization plugin\"\n        );\n      }\n\n      const adapter = getOrgAdapter(ctx.context, organizationPlugin.options);\n\n      if (ctx.query?.organizationSlug) {\n        const organization = await adapter.findOrganizationBySlug(\n          ctx.query.organizationSlug\n        );\n        if (!organization) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND\n          );\n        }\n        organizationId = organization.id;\n      }\n\n      if (!organizationId) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION\n        );\n      }\n\n      const isMember = await adapter.findMemberByOrgId({\n        userId: session.user.id,\n        organizationId,\n      });\n\n      if (!isMember) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION\n        );\n      }\n\n      // Build where clause\n      const where: Where[] = [\n        { field: \"organizationId\", value: organizationId },\n      ];\n\n      // Parse where array from query if provided\n      if (ctx.query?.filterJson) {\n        try {\n          const parsedWhere = JSON.parse(ctx.query.filterJson) as Where[];\n          if (Array.isArray(parsedWhere)) {\n            where.push(...parsedWhere);\n          }\n        } catch (error) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_MEMBER_ERROR_CODES.INVALID_FILTER_JSON_PARAMETER\n          );\n        }\n      }\n\n      // Legacy single filter support (for backward compatibility)\n      if (ctx.query?.filterField) {\n        where.push({\n          field: ctx.query.filterField,\n          value: ctx.query.filterValue,\n          ...(ctx.query.filterOperator\n            ? { operator: ctx.query.filterOperator }\n            : {}),\n        } as Where);\n      }\n\n      // Get members with pagination and sorting\n      const [members, total] = await Promise.all([\n        ctx.context.adapter.findMany<InferMember<OrganizationOptions, false>>({\n          model: \"member\",\n          where,\n          limit: ctx.query?.limit ? Number(ctx.query.limit) : 100,\n          offset: ctx.query?.offset ? Number(ctx.query.offset) : 0,\n          sortBy: ctx.query?.sortBy\n            ? {\n                field: ctx.query.sortBy,\n                direction: ctx.query.sortDirection || \"asc\",\n              }\n            : undefined,\n        }),\n        ctx.context.adapter.count({\n          model: \"member\",\n          where,\n        }),\n      ]);\n\n      // Fetch user data for each member\n      const membersWithUsers = await Promise.all(\n        members.map(async (member) => {\n          const user = await ctx.context.adapter.findOne<User>({\n            model: \"user\",\n            where: [{ field: \"id\", value: member.userId }],\n          });\n\n          return {\n            ...member,\n            user: user\n              ? {\n                  id: user.id,\n                  email: user.email,\n                  name: user.name,\n                  image: user.image,\n                }\n              : null,\n          };\n        })\n      );\n\n      return ctx.json({\n        members: membersWithUsers,\n        total,\n      });\n    }\n  );\n};\n\nconst createCountInvitationsEndpoint = (\n  options?: OrganizationMemberOptions\n) => {\n  return createAuthEndpoint(\n    \"/organization/count-invitations\",\n    {\n      method: \"GET\",\n      query: z\n        .object({\n          filterJson: z\n            .string()\n            .meta({\n              description:\n                'JSON string array of Where filters. Example: \\'[{\"field\":\"status\",\"value\":\"pending\",\"operator\":\"eq\"}]\\'',\n            })\n            .optional(),\n          // Legacy single filter support (for backward compatibility)\n          filterField: z\n            .string()\n            .meta({\n              description:\n                \"The field to filter by (legacy, use 'where' for multiple filters)\",\n            })\n            .optional(),\n          filterValue: z\n            .string()\n            .meta({\n              description:\n                \"The value to filter by (legacy, use 'where' for multiple filters)\",\n            })\n            .or(z.number())\n            .or(z.boolean())\n            .optional(),\n          filterOperator: z\n            .enum([\"eq\", \"ne\", \"lt\", \"lte\", \"gt\", \"gte\", \"contains\"])\n            .meta({\n              description:\n                \"The operator to use for the filter (legacy, use 'where' for multiple filters)\",\n            })\n            .optional(),\n          organizationId: z\n            .string()\n            .meta({\n              description:\n                'The organization ID to list invitations for. If not provided, will default to the user\\'s active organization. Eg: \"organization-id\"',\n            })\n            .optional(),\n          organizationSlug: z\n            .string()\n            .meta({\n              description:\n                'The organization slug to list invitations for. If not provided, will default to the user\\'s active organization. Eg: \"organization-slug\"',\n            })\n            .optional(),\n        })\n        .optional(),\n      requireHeaders: true,\n      use: [orgMiddleware, orgSessionMiddleware],\n      metadata: {\n        $Infer: {\n          query: {} as {\n            filterJson?: string; // JSON string of Where[]\n            filterField?: string;\n            filterValue?: string | number | boolean;\n            filterOperator?:\n              | \"eq\"\n              | \"ne\"\n              | \"lt\"\n              | \"lte\"\n              | \"gt\"\n              | \"gte\"\n              | \"contains\";\n            organizationId?: string;\n            organizationSlug?: string;\n          },\n        },\n        openapi: {\n          operationId: \"countOrganizationInvitations\",\n          description: \"Count invitations in an organization with filtering\",\n          responses: {\n            \"200\": {\n              description: \"Success\",\n              content: {\n                \"application/json\": {\n                  schema: {\n                    type: \"object\",\n                    properties: {\n                      count: {\n                        type: \"number\",\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    },\n    async (ctx) => {\n      const session = ctx.context.session;\n      let organizationId =\n        ctx.query?.organizationId || session.session.activeOrganizationId;\n\n      const organizationPlugin = getOrganizationPlugin(ctx.context);\n      if (!organizationPlugin) {\n        throw new Error(\n          \"organization-member plugin requires the organization plugin\"\n        );\n      }\n\n      const adapter = getOrgAdapter(ctx.context, organizationPlugin.options);\n\n      if (ctx.query?.organizationSlug) {\n        const organization = await adapter.findOrganizationBySlug(\n          ctx.query.organizationSlug\n        );\n        if (!organization) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND\n          );\n        }\n        organizationId = organization.id;\n      }\n\n      if (!organizationId) {\n        throw APIError.from(\n          \"BAD_REQUEST\",\n          ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION\n        );\n      }\n\n      const isMember = await adapter.findMemberByOrgId({\n        userId: session.user.id,\n        organizationId,\n      });\n\n      if (!isMember) {\n        throw APIError.from(\n          \"FORBIDDEN\",\n          ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION\n        );\n      }\n\n      // Build where clause\n      const where: Where[] = [\n        { field: \"organizationId\", value: organizationId },\n      ];\n\n      // Parse where array from query if provided\n      if (ctx.query?.filterJson) {\n        try {\n          const parsedWhere = JSON.parse(ctx.query.filterJson) as Where[];\n          if (Array.isArray(parsedWhere)) {\n            where.push(...parsedWhere);\n          }\n        } catch (error) {\n          throw APIError.from(\n            \"BAD_REQUEST\",\n            ORGANIZATION_MEMBER_ERROR_CODES.INVALID_FILTER_JSON_PARAMETER\n          );\n        }\n      }\n\n      // Legacy single filter support (for backward compatibility)\n      if (ctx.query?.filterField) {\n        where.push({\n          field: ctx.query.filterField,\n          value: ctx.query.filterValue,\n          ...(ctx.query.filterOperator\n            ? { operator: ctx.query.filterOperator }\n            : {}),\n        } as Where);\n      }\n\n      const total = await ctx.context.adapter.count({\n        model: \"invitation\",\n        where,\n      });\n\n      return ctx.json({ count: total });\n    }\n  );\n};\n\nexport const organizationMember = (\n  userConfig?: OrganizationMemberOptions\n): BetterAuthPlugin => {\n  const config = {\n    ...userConfig,\n  } satisfies OrganizationMemberOptions;\n\n  return {\n    id: \"organization-member\",\n    init(ctx) {\n      const organizationPlugin = getOrganizationPlugin(ctx);\n      if (!organizationPlugin) {\n        throw new Error(\n          \"organization-member plugin requires the organization plugin\"\n        );\n      }\n\n      // Get or create organizationHooks\n      if (!organizationPlugin.options.organizationHooks) {\n        organizationPlugin.options.organizationHooks = {};\n      }\n\n      // after accepting invitation, transfer additional fields to member\n      const existingAfterAcceptInvitation =\n        organizationPlugin.options.organizationHooks?.afterAcceptInvitation;\n      organizationPlugin.options.organizationHooks.afterAcceptInvitation =\n        async (data) => {\n          await existingAfterAcceptInvitation?.(data);\n\n          try {\n            const { invitation, member } = data;\n            const updateData: Record<string, unknown> = {};\n\n            // TODO improve me\n            for (const field of Object.keys(\n              organizationPlugin.options?.schema?.invitation\n                ?.additionalFields ?? {}\n            )) {\n              const fieldName =\n                organizationPlugin.options?.schema?.invitation\n                  ?.additionalFields?.[field]?.fieldName || field;\n              updateData[fieldName] = invitation[fieldName];\n            }\n\n            // Only update if there are fields to transfer\n            if (Object.keys(updateData).length > 0) {\n              await ctx.adapter.update({\n                model: \"member\",\n                where: [{ field: \"id\", value: member.id }],\n                update: updateData,\n              });\n\n              ctx.logger?.info(\"Member fields updated from invitation:\", {\n                memberId: member.id,\n                fields: Object.keys(updateData),\n              });\n            }\n          } catch (error) {\n            ctx.logger?.error(\n              \"Failed to update member fields from invitation:\",\n              error\n            );\n            // Don't throw - let the invitation acceptance succeed\n          }\n        };\n\n      // before removing member, dont allow removing yourself\n      const existingBeforeRemoveMember =\n        organizationPlugin.options.organizationHooks?.beforeRemoveMember;\n      organizationPlugin.options.organizationHooks.beforeRemoveMember =\n        async (data) => {\n          await existingBeforeRemoveMember?.(data);\n          \n          try {\n            const { member } = data;\n            if (member.userId === ctx.session?.user.id) {\n              throw APIError.from('FORBIDDEN', ORGANIZATION_MEMBER_ERROR_CODES.CANNOT_REMOVE_YOURSELF);\n            }\n          }\n          catch(error) {\n            ctx.logger?.error(\n              \"Before remove member hook failed:\",\n              error\n            );\n          }\n        };\n\n      // when oauth provider is used\n      // after removing member, revoke refresh token / access token immediately\n      const oauthProviderPlugin = getOauthProviderPlugin(ctx);\n\n      const existingAfterRemoveMember =\n        organizationPlugin.options.organizationHooks?.afterRemoveMember;\n      organizationPlugin.options.organizationHooks.afterRemoveMember =\n        async (data) => {\n          await existingAfterRemoveMember?.(data);\n          \n          try {\n            // if oauth provider is not used, return\n            if (!oauthProviderPlugin) {\n              return;\n            }\n\n            const { member } = data;\n            const activeOrganizationId = member.organizationId ?? ctx.session?.session.activeOrganizationId;\n            if (!activeOrganizationId) {\n              return;\n            }\n\n            const sessions = await ctx.internalAdapter.listSessions(member.userId);\n            const activeOrgSessions = sessions.filter((s: any) => s.activeOrganizationId === activeOrganizationId);\n            if (activeOrgSessions.length === 0) {\n              return;\n            }\n\n            await Promise.all([\n              // Revoke refresh tokens\n              Promise.all(\n                activeOrgSessions.map(s =>\n                  ctx.adapter.deleteMany({\n                    model: \"oauthRefreshToken\",\n                    where: [{ field: \"sessionId\", value: s.id }],\n                  }),\n                ),\n              ),\n              // Revoke access tokens\n              Promise.all(\n                activeOrgSessions.map(s =>\n                  ctx.adapter.deleteMany({\n                    model: \"oauthAccessToken\",\n                    where: [{ field: \"sessionId\", value: s.id }],\n                  }),\n                ),\n              ),\n              // Delete sessions\n              Promise.all(\n                activeOrgSessions.map(s =>\n                  ctx.internalAdapter.deleteSessions(s.token),\n                ),\n              ),\n            ]);\n\n          }\n          catch(error) {\n            ctx.logger?.error(\n              \"After remove member hook failed:\",\n              error\n            );\n          }\n        };\n    },\n    endpoints: {\n      updateMember: createUpdateMemberEndpoint(userConfig),\n      updateInvitation: createUpdateInvitationEndpoint(userConfig),\n      listMembers: createListMembersEndpoint(userConfig),\n      listInvitations: createListInvitationsEndpoint(userConfig),\n      countInvitations: createCountInvitationsEndpoint(userConfig),\n    },\n    options: userConfig as NoInfer<OrganizationMemberOptions>,\n    $ERROR_CODES: ORGANIZATION_ERROR_CODES,\n  } satisfies BetterAuthPlugin;\n};\n"],"mappings":"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"}