UNPKG

gplayapi-ts

Version:
1 lines 9.53 kB
{"version":3,"sources":["../../src/api/client.ts"],"sourcesContent":["/**\n * Main Google Play API client\n */\n\nimport { promises as fs } from \"fs\";\nimport type { AuthData } from \"../models/auth\";\nimport type { DeviceInfo } from \"../models/device\";\nimport { Pixel3a } from \"../devices/factory\";\nimport { GPTokenExpiredError, GPNetworkError } from \"../errors\";\nimport { doRequest, createDefaultHeaders } from \"../utils/network\";\nimport { unmarshalResponseWrapper } from \"../utils/parser\";\nimport { AuthEndpoint } from \"./endpoints/auth\";\nimport { AppsEndpoint } from \"./endpoints/apps\";\nimport { LibraryEndpoint } from \"./endpoints/library\";\nimport { HttpStatusCode } from \"../models/common\";\nimport type { Payload } from \"../gen_proto/googleplay_pb\";\n\nexport class GooglePlayClient {\n public authData: AuthData;\n public deviceInfo: DeviceInfo;\n public sessionFile?: string;\n\n public readonly auth: AuthEndpoint;\n public readonly apps: AppsEndpoint;\n public readonly library: LibraryEndpoint;\n\n constructor(authData: AuthData, deviceInfo: DeviceInfo = Pixel3a) {\n this.authData = authData;\n this.deviceInfo = deviceInfo;\n\n // Initialize endpoints\n this.auth = new AuthEndpoint(\n this.authData,\n this.deviceInfo,\n () => this.getAuthHeaders(),\n (url, options) => this.doAuthedReq(url, options)\n );\n \n this.apps = new AppsEndpoint(\n (url, options) => this.doAuthedReq(url, options)\n );\n\n this.library = new LibraryEndpoint(\n (url, options) => this.doAuthedReq(url, options),\n (packageName) => this.getAppDetails(packageName)\n );\n }\n\n static async newClient(email: string, aasToken: string): Promise<GooglePlayClient> {\n return GooglePlayClient.newClientWithDeviceInfo(email, aasToken, Pixel3a);\n }\n\n static async newClientWithDeviceInfo(\n email: string,\n aasToken: string,\n deviceInfo: DeviceInfo,\n ): Promise<GooglePlayClient> {\n const authData: AuthData = {\n email,\n aasToken,\n locale: \"en_GB\",\n };\n\n const client = new GooglePlayClient(authData, deviceInfo);\n\n await client.auth.generateGsfId();\n\n const deviceConfigRes = await client.auth.uploadDeviceConfig();\n authData.deviceConfigToken = deviceConfigRes.uploadDeviceConfigToken;\n\n const token = await client.auth.generateGPToken();\n authData.authToken = token;\n\n await client.auth.toc();\n\n return client;\n }\n\n async saveSession(file: string): Promise<void> {\n await fs.writeFile(file, JSON.stringify(this.authData, null, 2));\n }\n\n static async loadSession(file: string): Promise<GooglePlayClient> {\n return GooglePlayClient.loadSessionWithDeviceInfo(file, Pixel3a);\n }\n\n static async loadSessionWithDeviceInfo(file: string, deviceInfo: DeviceInfo): Promise<GooglePlayClient> {\n const data = await fs.readFile(file, \"utf-8\");\n const authData: AuthData = JSON.parse(data);\n const client = new GooglePlayClient(authData, deviceInfo);\n return client;\n }\n\n private async _doAuthedReq(url: string, options: RequestInit = {}): Promise<Payload | null> {\n const { data, status } = await doRequest(url, {\n ...(options as Omit<RequestInit, \"headers\">),\n headers: {\n ...this.getDefaultHeaders(),\n ...((options.headers as Record<string, string>) || {}),\n },\n });\n\n if (status === HttpStatusCode.UNAUTHORIZED) {\n throw new GPTokenExpiredError();\n }\n\n if (status >= 400) {\n throw new GPNetworkError(`Request failed with status ${status}`, status);\n }\n\n const resp = await unmarshalResponseWrapper(data);\n return resp.payload || null;\n }\n\n async doAuthedReq(url: string, options: RequestInit = {}): Promise<Payload | null> {\n try {\n return await this._doAuthedReq(url, options);\n } catch (error) {\n if (error instanceof GPTokenExpiredError) {\n await this.auth.regenerateGPToken();\n if (this.sessionFile) {\n await this.saveSession(this.sessionFile);\n }\n return await this._doAuthedReq(url, options);\n }\n throw error;\n }\n }\n\n private getAuthHeaders(): Record<string, string> {\n return {\n App: \"com.google.android.gms\",\n \"User-Agent\": this.deviceInfo.authUserAgent,\n ...(this.authData.gsfId && { Device: this.authData.gsfId }),\n };\n }\n\n private getDefaultHeaders(): Record<string, string> {\n const data = this.authData;\n const headers = createDefaultHeaders(\n this.deviceInfo.userAgent,\n data.gsfId!,\n data.authToken\n );\n\n if (data.deviceCheckInConsistencyToken) {\n headers[\"X-Dfe-Device-Checkin-Consistency-Token\"] = data.deviceCheckInConsistencyToken;\n }\n\n if (data.deviceConfigToken) {\n headers[\"X-Dfe-Device-Config-Token\"] = data.deviceConfigToken;\n }\n\n if (data.dfeCookie) {\n headers[\"X-Dfe-Cookie\"] = data.dfeCookie;\n }\n\n if (this.deviceInfo.simOperator) {\n headers[\"X-Dfe-Mccmnc\"] = this.deviceInfo.simOperator;\n }\n\n return headers;\n }\n\n // Convenience methods\n async getAppDetails(packageName: string) {\n return this.apps.getAppDetails(packageName);\n }\n\n async getBuyResponse(packageName: string, version: number) {\n return this.library.getBuyResponse(packageName, version);\n }\n\n async getDeliveryResponse(packageName: string, version: number) {\n return this.library.getDeliveryResponse(packageName, version);\n }\n\n async purchase(packageName: string, version?: number) {\n return this.library.purchase(packageName, version);\n }\n\n async generateGsfId(): Promise<string> {\n return this.auth.generateGsfId();\n }\n\n async regenerateGPToken(): Promise<void> {\n return this.auth.regenerateGPToken();\n }\n}"],"mappings":"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","names":[]}