{"version":3,"sources":["../src/groups.ts"],"sourcesContent":["import { FirebaseAppDistribution } from \".\";\r\nimport {\r\n  APP_DISTRIBUTION_ENDPOINT,\r\n  ENDPOINT_VERSION,\r\n  makeRequest,\r\n} from \"./utils\";\r\n\r\nexport interface Group {\r\n  name: string;\r\n  displayName: string;\r\n  testerCount?: number;\r\n  releaseCount?: number;\r\n  inviteLinkCount?: number;\r\n  id: string; // custom added field\r\n}\r\n\r\ninterface GroupListResponse {\r\n  groups: Group[];\r\n  nextPageToken: string;\r\n}\r\n\r\ntype ValidGroupId = Lowercase<string>;\r\n\r\ninterface GroupListArgs {\r\n  pageSize?: number;\r\n  maxPages?: number;\r\n}\r\n\r\ninterface GroupUpdateArgs {\r\n  displayName?: string;\r\n}\r\n\r\nfunction getGroupIdFromName(groupName: string) {\r\n  return groupName.split(\"/\").pop()!;\r\n}\r\n\r\nexport class Groups {\r\n  private parent: FirebaseAppDistribution;\r\n  constructor(parent: FirebaseAppDistribution) {\r\n    this.parent = parent;\r\n  }\r\n\r\n  async create(displayName: string, groupId?: string): Promise<Group> {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups`,\r\n    );\r\n    if (groupId) {\r\n      url.searchParams.set(\"groupId\", groupId);\r\n    }\r\n\r\n    const requestBody = JSON.stringify({\r\n      displayName,\r\n    });\r\n\r\n    const response = await makeRequest<Group>(url, {\r\n      headers: {\r\n        authorization: `Bearer ${accessToken}`,\r\n      },\r\n      body: requestBody,\r\n      method: \"POST\",\r\n    });\r\n\r\n    return { ...response, id: getGroupIdFromName(response.name) };\r\n  }\r\n\r\n  async delete(groupId: ValidGroupId): Promise<{}> {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups/${groupId}`,\r\n    );\r\n    // This response body is an empty object if successfull.\r\n    // See: https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.groups/delete#response-body\r\n    const response = await makeRequest<{}>(url, {\r\n      headers: {\r\n        authorization: `Bearer ${accessToken}`,\r\n      },\r\n      body: null,\r\n      method: \"DELETE\",\r\n    });\r\n    return response;\r\n  }\r\n\r\n  async get(groupId: ValidGroupId): Promise<Group | null> {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups/${groupId}`,\r\n    );\r\n    const response = await makeRequest<Group>(url, {\r\n      headers: {\r\n        authorization: `Bearer ${accessToken}`,\r\n      },\r\n      body: null,\r\n      method: \"GET\",\r\n    });\r\n\r\n    if (response.name === undefined) {\r\n      return null;\r\n    }\r\n\r\n    return { ...response, id: getGroupIdFromName(response.name) };\r\n  }\r\n\r\n  async list({ pageSize = 25, maxPages = 10 }: GroupListArgs = {}): Promise<\r\n    Group[]\r\n  > {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const groupList: Group[] = [];\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups`,\r\n    );\r\n    url.searchParams.set(\"pageSize\", pageSize.toString());\r\n\r\n    let nextPageToken = \"\";\r\n    for (let page = 0; page < maxPages; page++) {\r\n      if (nextPageToken) {\r\n        url.searchParams.set(\"pageToken\", nextPageToken);\r\n      } else {\r\n        url.searchParams.delete(\"pageToken\");\r\n      }\r\n      const response = await makeRequest<GroupListResponse>(url, {\r\n        headers: {\r\n          authorization: `Bearer ${accessToken}`,\r\n        },\r\n        body: null,\r\n        method: \"GET\",\r\n      });\r\n\r\n      if (response.groups === undefined) {\r\n        break;\r\n      }\r\n\r\n      for (let group of response.groups) {\r\n        groupList.push({\r\n          ...group,\r\n          id: getGroupIdFromName(group.name),\r\n        });\r\n      }\r\n      if (response.nextPageToken !== undefined) {\r\n        nextPageToken = response.nextPageToken;\r\n      } else {\r\n        break;\r\n      }\r\n    }\r\n    return groupList;\r\n  }\r\n\r\n  async update(\r\n    groupId: ValidGroupId,\r\n    { displayName }: GroupUpdateArgs,\r\n  ): Promise<Group> {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups/${groupId}`,\r\n    );\r\n\r\n    if (displayName) {\r\n      url.searchParams.set(\"updateMask\", \"displayName\");\r\n    }\r\n\r\n    const requestBody = JSON.stringify({\r\n      displayName,\r\n    });\r\n\r\n    const response = await makeRequest<Group>(url, {\r\n      headers: {\r\n        authorization: `Bearer ${accessToken}`,\r\n      },\r\n      body: requestBody,\r\n      method: \"PATCH\",\r\n    });\r\n\r\n    return { ...response, id: getGroupIdFromName(response.name) };\r\n  }\r\n\r\n  async removeTesters(groupId: string, emails: string[]): Promise<{}> {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups/${groupId}:batchLeave`,\r\n    );\r\n    const reuqestBody = JSON.stringify({\r\n      emails,\r\n    });\r\n    // This response body is an empty object if successfull.\r\n    // See: https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.groups/batchLeave#response-body\r\n    const response = await makeRequest<{}>(url, {\r\n      headers: {\r\n        authorization: `Bearer ${accessToken}`,\r\n      },\r\n      body: reuqestBody,\r\n      method: \"POST\",\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  async addTesters(groupId: string, emails: string[]): Promise<{}> {\r\n    const accessToken = await this.parent.getAccessToken();\r\n    const projectNumber = await this.parent.getProjectNumber();\r\n\r\n    const url = new URL(\r\n      `${APP_DISTRIBUTION_ENDPOINT}/${ENDPOINT_VERSION}/projects/${projectNumber}/groups/${groupId}:batchJoin`,\r\n    );\r\n    const reuqestBody = JSON.stringify({\r\n      emails,\r\n      createMissingTesters: true,\r\n    });\r\n    // This response body is an empty object if successfull.\r\n    // See: https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.groups/batchJoin#response-body\r\n    const response = await makeRequest<{}>(url, {\r\n      headers: {\r\n        authorization: `Bearer ${accessToken}`,\r\n      },\r\n      body: reuqestBody,\r\n      method: \"POST\",\r\n    });\r\n\r\n    return response;\r\n  }\r\n}\r\n"],"mappings":";;;;;;;;;;AAgCA,SAAS,mBAAmB,WAAmB;AAC7C,SAAO,UAAU,MAAM,GAAG,EAAE,IAAI;AAClC;AAEO,IAAM,SAAN,MAAa;AAAA,EAElB,YAAY,QAAiC;AAC3C,SAAK,SAAS;AAAA,EAChB;AAAA,EAEM,OAAO,aAAqB,SAAkC;AAAA;AAClE,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa;AAAA,MAC5E;AACA,UAAI,SAAS;AACX,YAAI,aAAa,IAAI,WAAW,OAAO;AAAA,MACzC;AAEA,YAAM,cAAc,KAAK,UAAU;AAAA,QACjC;AAAA,MACF,CAAC;AAED,YAAM,WAAW,MAAM,YAAmB,KAAK;AAAA,QAC7C,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,aAAO,iCAAK,WAAL,EAAe,IAAI,mBAAmB,SAAS,IAAI,EAAE;AAAA,IAC9D;AAAA;AAAA,EAEM,OAAO,SAAoC;AAAA;AAC/C,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa,WAAW,OAAO;AAAA,MAC9F;AAGA,YAAM,WAAW,MAAM,YAAgB,KAAK;AAAA,QAC1C,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AACD,aAAO;AAAA,IACT;AAAA;AAAA,EAEM,IAAI,SAA8C;AAAA;AACtD,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa,WAAW,OAAO;AAAA,MAC9F;AACA,YAAM,WAAW,MAAM,YAAmB,KAAK;AAAA,QAC7C,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,UAAI,SAAS,SAAS,QAAW;AAC/B,eAAO;AAAA,MACT;AAEA,aAAO,iCAAK,WAAL,EAAe,IAAI,mBAAmB,SAAS,IAAI,EAAE;AAAA,IAC9D;AAAA;AAAA,EAEM,OAEJ;AAAA,+CAFS,EAAE,WAAW,IAAI,WAAW,GAAG,IAAmB,CAAC,GAE5D;AACA,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,YAAqB,CAAC;AAE5B,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa;AAAA,MAC5E;AACA,UAAI,aAAa,IAAI,YAAY,SAAS,SAAS,CAAC;AAEpD,UAAI,gBAAgB;AACpB,eAAS,OAAO,GAAG,OAAO,UAAU,QAAQ;AAC1C,YAAI,eAAe;AACjB,cAAI,aAAa,IAAI,aAAa,aAAa;AAAA,QACjD,OAAO;AACL,cAAI,aAAa,OAAO,WAAW;AAAA,QACrC;AACA,cAAM,WAAW,MAAM,YAA+B,KAAK;AAAA,UACzD,SAAS;AAAA,YACP,eAAe,UAAU,WAAW;AAAA,UACtC;AAAA,UACA,MAAM;AAAA,UACN,QAAQ;AAAA,QACV,CAAC;AAED,YAAI,SAAS,WAAW,QAAW;AACjC;AAAA,QACF;AAEA,iBAAS,SAAS,SAAS,QAAQ;AACjC,oBAAU,KAAK,iCACV,QADU;AAAA,YAEb,IAAI,mBAAmB,MAAM,IAAI;AAAA,UACnC,EAAC;AAAA,QACH;AACA,YAAI,SAAS,kBAAkB,QAAW;AACxC,0BAAgB,SAAS;AAAA,QAC3B,OAAO;AACL;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA;AAAA,EAEM,OACJ,IACA,IACgB;AAAA,+CAFhB,SACA,EAAE,YAAY,GACE;AAChB,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa,WAAW,OAAO;AAAA,MAC9F;AAEA,UAAI,aAAa;AACf,YAAI,aAAa,IAAI,cAAc,aAAa;AAAA,MAClD;AAEA,YAAM,cAAc,KAAK,UAAU;AAAA,QACjC;AAAA,MACF,CAAC;AAED,YAAM,WAAW,MAAM,YAAmB,KAAK;AAAA,QAC7C,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,aAAO,iCAAK,WAAL,EAAe,IAAI,mBAAmB,SAAS,IAAI,EAAE;AAAA,IAC9D;AAAA;AAAA,EAEM,cAAc,SAAiB,QAA+B;AAAA;AAClE,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa,WAAW,OAAO;AAAA,MAC9F;AACA,YAAM,cAAc,KAAK,UAAU;AAAA,QACjC;AAAA,MACF,CAAC;AAGD,YAAM,WAAW,MAAM,YAAgB,KAAK;AAAA,QAC1C,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,aAAO;AAAA,IACT;AAAA;AAAA,EAEM,WAAW,SAAiB,QAA+B;AAAA;AAC/D,YAAM,cAAc,MAAM,KAAK,OAAO,eAAe;AACrD,YAAM,gBAAgB,MAAM,KAAK,OAAO,iBAAiB;AAEzD,YAAM,MAAM,IAAI;AAAA,QACd,GAAG,yBAAyB,IAAI,gBAAgB,aAAa,aAAa,WAAW,OAAO;AAAA,MAC9F;AACA,YAAM,cAAc,KAAK,UAAU;AAAA,QACjC;AAAA,QACA,sBAAsB;AAAA,MACxB,CAAC;AAGD,YAAM,WAAW,MAAM,YAAgB,KAAK;AAAA,QAC1C,SAAS;AAAA,UACP,eAAe,UAAU,WAAW;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAED,aAAO;AAAA,IACT;AAAA;AACF;","names":[]}