├── .eslintignore ├── .eslintrc ├── .gitignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── docs ├── README.md └── enums │ ├── categories.md │ ├── countries.md │ └── languages.md ├── package.json ├── src ├── common │ ├── assert.ts │ ├── consts.ts │ ├── data-format.ts │ └── requests.ts ├── endpoints │ ├── app-details.ts │ ├── data-safety.ts │ ├── search.ts │ └── top-charts.ts └── index.ts ├── tsconfig.json ├── typedoc.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint"], 5 | "extends": [ 6 | "eslint:recommended", 7 | "plugin:@typescript-eslint/recommended", 8 | "plugin:import/errors", 9 | "plugin:import/warnings", 10 | "plugin:import/typescript", 11 | "plugin:eslint-comments/recommended", 12 | "prettier" 13 | ], 14 | "rules": { 15 | "no-undef": "off", 16 | "no-unused-vars": ["warn", { "args": "none", "caughtErrors": "none" }], 17 | "no-empty": ["error", { "allowEmptyCatch": true }], 18 | "@typescript-eslint/no-non-null-assertion": "off", 19 | "@typescript-eslint/no-explicit-any": "off" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | *.tmp 3 | tmp.* 4 | *.tmp.* 5 | 6 | dist/ 7 | 8 | # Created by https://www.toptal.com/developers/gitignore/api/linux,macos,windows,visualstudiocode,jetbrains+all,sublimetext,node 9 | # Edit at https://www.toptal.com/developers/gitignore?templates=linux,macos,windows,visualstudiocode,jetbrains+all,sublimetext,node 10 | 11 | ### JetBrains+all ### 12 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 13 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 14 | 15 | # User-specific stuff 16 | .idea/**/workspace.xml 17 | .idea/**/tasks.xml 18 | .idea/**/usage.statistics.xml 19 | .idea/**/dictionaries 20 | .idea/**/shelf 21 | 22 | # Generated files 23 | .idea/**/contentModel.xml 24 | 25 | # Sensitive or high-churn files 26 | .idea/**/dataSources/ 27 | .idea/**/dataSources.ids 28 | .idea/**/dataSources.local.xml 29 | .idea/**/sqlDataSources.xml 30 | .idea/**/dynamic.xml 31 | .idea/**/uiDesigner.xml 32 | .idea/**/dbnavigator.xml 33 | 34 | # Gradle 35 | .idea/**/gradle.xml 36 | .idea/**/libraries 37 | 38 | # Gradle and Maven with auto-import 39 | # When using Gradle or Maven with auto-import, you should exclude module files, 40 | # since they will be recreated, and may cause churn. Uncomment if using 41 | # auto-import. 42 | # .idea/artifacts 43 | # .idea/compiler.xml 44 | # .idea/jarRepositories.xml 45 | # .idea/modules.xml 46 | # .idea/*.iml 47 | # .idea/modules 48 | # *.iml 49 | # *.ipr 50 | 51 | # CMake 52 | cmake-build-*/ 53 | 54 | # Mongo Explorer plugin 55 | .idea/**/mongoSettings.xml 56 | 57 | # File-based project format 58 | *.iws 59 | 60 | # IntelliJ 61 | out/ 62 | 63 | # mpeltonen/sbt-idea plugin 64 | .idea_modules/ 65 | 66 | # JIRA plugin 67 | atlassian-ide-plugin.xml 68 | 69 | # Cursive Clojure plugin 70 | .idea/replstate.xml 71 | 72 | # Crashlytics plugin (for Android Studio and IntelliJ) 73 | com_crashlytics_export_strings.xml 74 | crashlytics.properties 75 | crashlytics-build.properties 76 | fabric.properties 77 | 78 | # Editor-based Rest Client 79 | .idea/httpRequests 80 | 81 | # Android studio 3.1+ serialized cache file 82 | .idea/caches/build_file_checksums.ser 83 | 84 | ### JetBrains+all Patch ### 85 | # Ignores the whole .idea folder and all .iml files 86 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 87 | 88 | .idea/ 89 | 90 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 91 | 92 | *.iml 93 | modules.xml 94 | .idea/misc.xml 95 | *.ipr 96 | 97 | # Sonarlint plugin 98 | .idea/sonarlint 99 | 100 | ### Linux ### 101 | *~ 102 | 103 | # temporary files which can be created if a process still has a handle open of a deleted file 104 | .fuse_hidden* 105 | 106 | # KDE directory preferences 107 | .directory 108 | 109 | # Linux trash folder which might appear on any partition or disk 110 | .Trash-* 111 | 112 | # .nfs files are created when an open file is removed but is still being accessed 113 | .nfs* 114 | 115 | ### macOS ### 116 | # General 117 | .DS_Store 118 | .AppleDouble 119 | .LSOverride 120 | 121 | # Icon must end with two \r 122 | Icon 123 | 124 | 125 | # Thumbnails 126 | ._* 127 | 128 | # Files that might appear in the root of a volume 129 | .DocumentRevisions-V100 130 | .fseventsd 131 | .Spotlight-V100 132 | .TemporaryItems 133 | .Trashes 134 | .VolumeIcon.icns 135 | .com.apple.timemachine.donotpresent 136 | 137 | # Directories potentially created on remote AFP share 138 | .AppleDB 139 | .AppleDesktop 140 | Network Trash Folder 141 | Temporary Items 142 | .apdisk 143 | 144 | ### Node ### 145 | # Logs 146 | logs 147 | *.log 148 | npm-debug.log* 149 | yarn-debug.log* 150 | yarn-error.log* 151 | lerna-debug.log* 152 | 153 | # Diagnostic reports (https://nodejs.org/api/report.html) 154 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 155 | 156 | # Runtime data 157 | pids 158 | *.pid 159 | *.seed 160 | *.pid.lock 161 | 162 | # Directory for instrumented libs generated by jscoverage/JSCover 163 | lib-cov 164 | 165 | # Coverage directory used by tools like istanbul 166 | coverage 167 | *.lcov 168 | 169 | # nyc test coverage 170 | .nyc_output 171 | 172 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 173 | .grunt 174 | 175 | # Bower dependency directory (https://bower.io/) 176 | bower_components 177 | 178 | # node-waf configuration 179 | .lock-wscript 180 | 181 | # Compiled binary addons (https://nodejs.org/api/addons.html) 182 | build/Release 183 | 184 | # Dependency directories 185 | node_modules/ 186 | jspm_packages/ 187 | 188 | # TypeScript v1 declaration files 189 | typings/ 190 | 191 | # TypeScript cache 192 | *.tsbuildinfo 193 | 194 | # Optional npm cache directory 195 | .npm 196 | 197 | # Optional eslint cache 198 | .eslintcache 199 | 200 | # Microbundle cache 201 | .rpt2_cache/ 202 | .rts2_cache_cjs/ 203 | .rts2_cache_es/ 204 | .rts2_cache_umd/ 205 | 206 | # Optional REPL history 207 | .node_repl_history 208 | 209 | # Output of 'npm pack' 210 | *.tgz 211 | 212 | # Yarn Integrity file 213 | .yarn-integrity 214 | 215 | # dotenv environment variables file 216 | .env 217 | .env.test 218 | .env*.local 219 | 220 | # parcel-bundler cache (https://parceljs.org/) 221 | .cache 222 | .parcel-cache 223 | 224 | # Next.js build output 225 | .next 226 | 227 | # Nuxt.js build / generate output 228 | .nuxt 229 | dist 230 | 231 | # Gatsby files 232 | .cache/ 233 | # Comment in the public line in if your project uses Gatsby and not Next.js 234 | # https://nextjs.org/blog/next-9-1#public-directory-support 235 | # public 236 | 237 | # vuepress build output 238 | .vuepress/dist 239 | 240 | # Serverless directories 241 | .serverless/ 242 | 243 | # FuseBox cache 244 | .fusebox/ 245 | 246 | # DynamoDB Local files 247 | .dynamodb/ 248 | 249 | # TernJS port file 250 | .tern-port 251 | 252 | # Stores VSCode versions used for testing VSCode extensions 253 | .vscode-test 254 | 255 | ### SublimeText ### 256 | # Cache files for Sublime Text 257 | *.tmlanguage.cache 258 | *.tmPreferences.cache 259 | *.stTheme.cache 260 | 261 | # Workspace files are user-specific 262 | *.sublime-workspace 263 | 264 | # Project files should be checked into the repository, unless a significant 265 | # proportion of contributors will probably not be using Sublime Text 266 | # *.sublime-project 267 | 268 | # SFTP configuration file 269 | sftp-config.json 270 | 271 | # Package control specific files 272 | Package Control.last-run 273 | Package Control.ca-list 274 | Package Control.ca-bundle 275 | Package Control.system-ca-bundle 276 | Package Control.cache/ 277 | Package Control.ca-certs/ 278 | Package Control.merged-ca-bundle 279 | Package Control.user-ca-bundle 280 | oscrypto-ca-bundle.crt 281 | bh_unicode_properties.cache 282 | 283 | # Sublime-github package stores a github token in this file 284 | # https://packagecontrol.io/packages/sublime-github 285 | GitHub.sublime-settings 286 | 287 | ### VisualStudioCode ### 288 | .vscode/* 289 | !.vscode/tasks.json 290 | !.vscode/launch.json 291 | *.code-workspace 292 | 293 | ### VisualStudioCode Patch ### 294 | # Ignore all local history of files 295 | .history 296 | .ionide 297 | 298 | ### Windows ### 299 | # Windows thumbnail cache files 300 | Thumbs.db 301 | Thumbs.db:encryptable 302 | ehthumbs.db 303 | ehthumbs_vista.db 304 | 305 | # Dump file 306 | *.stackdump 307 | 308 | # Folder config file 309 | [Dd]esktop.ini 310 | 311 | # Recycle Bin used on file shares 312 | $RECYCLE.BIN/ 313 | 314 | # Windows Installer files 315 | *.cab 316 | *.msi 317 | *.msix 318 | *.msm 319 | *.msp 320 | 321 | # Windows shortcuts 322 | *.lnk 323 | 324 | # End of 325 | # https://www.toptal.com/developers/gitignore/api/linux,macos,windows,visualstudiocode,jetbrains+all,sublimetext,node 326 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "jsxBracketSameLine": true, 5 | "tabWidth": 4 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright 2022 Benjamin Altpeter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # parse-play 2 | 3 | > Library for fetching and parsing select data on Android apps from the Google Play Store via undocumented internal APIs. 4 | 5 | This library is able to fetch and parse data from undocumented internal API endpoints of the Google Play Store. Currently, it has the following features: 6 | 7 | * Fetch the **charts of the most popular apps**, including filtering by category and chart. 8 | * Fetch an app's **metadata** including **data safety labels**. 9 | * **Search** for apps. 10 | 11 | I'll extend the supported API endpoints over time, as per what I need for my projects. The focus will likely be on functions useful for research into mobile privacy and data protection. 12 | 13 | As all the used endpoints are undocumented, I had to resort to reverse-engineering the Play Store website, which involved some amount of guessing as to which values mean what. It is possible that I have misinterpreted some of them. It is also entirely possible that some or all of the endpoints will stop working out of the blue at some point, or change their request and/or response formats. 14 | 15 | ## Installation 16 | 17 | You can install parse-play using yarn or npm: 18 | 19 | ```sh 20 | yarn add parse-play 21 | # or `npm i parse-play` 22 | ``` 23 | 24 | ## API reference 25 | 26 | A full API reference can be found in the [`docs` folder](/docs/README.md). 27 | 28 | ## Usage examples 29 | 30 | ### Fetch app top charts 31 | 32 | The following example fetches the current top 100 free apps across all categories for Germany: 33 | 34 | ```ts 35 | import { fetchTopCharts } from 'parse-play'; 36 | 37 | (async () => { 38 | const topChart = await fetchTopCharts( 39 | { category: 'APPLICATION', chart: 'topselling_free', count: 100 }, 40 | { country: 'DE', language: 'EN' } 41 | ); 42 | 43 | console.log(topChart?.length); // 100 44 | console.log(topChart?.[0]?.app_id, topChart?.[0]?.name); // com.amazon.mShop.android.shopping Amazon Shopping 45 | })(); 46 | ``` 47 | 48 | You can also request multiple top charts at once. These will all be fetched in a single API request. Note that country and language apply to _all_ requests in a batch. 49 | 50 | This example fetches the top 5 free education apps, as well as the top 1000 paid adventure game apps, both for the UK: 51 | 52 | ```ts 53 | const topCharts = await fetchTopCharts( 54 | [ 55 | { category: 'EDUCATION', chart: 'topselling_free', count: 5 }, 56 | { category: 'GAME_ADVENTURE', chart: 'topselling_paid', count: 1000 }, 57 | ], 58 | { country: 'GB', language: 'EN' } 59 | ); 60 | 61 | console.log(topCharts[0]?.length); // 5 62 | console.log(topCharts[0]?.[0]?.app_id, topCharts?.[0]?.[0]?.name); // cn.danatech.xingseus PictureThis - Plant Identifier 63 | console.log(topCharts[1]?.length); // 660 64 | console.log(topCharts[1]?.[0]?.app_id, topCharts?.[1]?.[0]?.name); // com.MOBGames.PoppyMobileChap1 Poppy Playtime Chapter 1 65 | ``` 66 | 67 | Note that despite us trying to fetch 1000 apps for the second chart, only 660 apps were returned. This is a server-side limit. 68 | 69 | ### Fetch app details 70 | 71 | The following example fetches the metadata of the Facebook app: 72 | 73 | ```ts 74 | import { fetchAppDetails } from 'parse-play'; 75 | 76 | (async () => { 77 | const appDetails = await fetchAppDetails({ appId: 'com.facebook.katana' }, { language: 'EN', country: 'DE' }); 78 | console.log(appDetails.name, 'costs', appDetails.price, 'and was last updated on', appDetails.updated_on); 79 | // Facebook costs €0.00 and was last updated on 2024-06-13T04:58:13.000Z 80 | })(); 81 | ``` 82 | 83 | Through this endpoint, you can also fetch an app's data safety labels: 84 | 85 | ```ts 86 | const appDetails = await fetchAppDetails({ appId: 'com.facebook.katana' }, { language: 'EN', country: 'DE' }); 87 | 88 | console.log('Data shared:', appDetails.data_shared); 89 | console.log('Data collected:', appDetails.data_collected); 90 | console.log('Security practices:', appDetails.security_practices); 91 | console.log('Privacy policy URL:', appDetails.privacy_policy_url); 92 | ``` 93 | 94 |
95 | Data safety label response 96 | The result looks like this: 97 | 98 | ``` 99 | Data shared: [ 100 | { 101 | category: 'Personal info', 102 | type: 'Name', 103 | purposes: [ 'Fraud prevention, security, and compliance' ], 104 | optional: false 105 | }, 106 | // … 107 | ] 108 | Data collected: [ 109 | { 110 | category: 'Personal info', 111 | type: 'Name', 112 | purposes: [ 113 | 'App functionality', 114 | 'Analytics', 115 | 'Developer communications', 116 | 'Advertising or marketing', 117 | 'Fraud prevention, security, and compliance', 118 | 'Personalization', 119 | 'Account management' 120 | ], 121 | optional: false 122 | }, 123 | // … 124 | ] 125 | Security practices: { 126 | data_encrypted_in_transit: true, 127 | can_request_data_deletion: true, 128 | committed_to_play_families_policy: undefined, 129 | independent_security_review: undefined 130 | } 131 | Privacy policy URL: https://www.facebook.com/about/privacy/ 132 | ``` 133 |
134 | 135 | ### Search for apps 136 | 137 | The following example searches for the term "education": 138 | 139 | ```ts 140 | import { searchApps } from 'parse-play'; 141 | 142 | (async () => { 143 | const searchResult = await searchApps({ searchTerm: 'education' }, { language: 'EN', country: 'DE' }); 144 | console.dir(searchResult, { depth: null }); 145 | })(); 146 | ``` 147 | 148 |
149 | Search apps response 150 | The response looks like this: 151 | 152 | ```ts 153 | [ 154 | { 155 | position: 1, 156 | app_id: 'de.easysoft.app.education', 157 | icon_url: 'https://play-lh.googleusercontent.com/KZ19KJw8vrNy6gpRtyzLAGichfxShCU9L2kZdJbnKs6mrKblKqcWBvM5v9QdgEW-SGFR', 158 | screenshot_urls: [ 159 | 'https://play-lh.googleusercontent.com/Bh0sDOl-oOcOtmjKTIXL4eE_vIcDqntnrwqvoi9qylQjptmPnMtZyMkUxUh4JnC0hQ', 160 | 'https://play-lh.googleusercontent.com/vlOZjzYHjRZEwBTWYVWxkWvXMEjtJGJ2tbJQJuNuB89wgXA-MVLM5MwaJOhRMdY7vA', 161 | 'https://play-lh.googleusercontent.com/zEiBcIIuY6LP_BbNZQ5PxxilZMmkf6dOn2XsYCNET5GumPOktuhZPo438QiasoVv5g4l', 162 | 'https://play-lh.googleusercontent.com/XP02HcK1hsyCUdrt9abKiy-KdF0ATB3W5jVVW5StHkxsmrlz22DFXfPbovZhyYjLiqI', 163 | 'https://play-lh.googleusercontent.com/c3pmHB-DkHZ6j3g3LfmgWgdHlIK18jOt-2oFGkh9GTtQwY2aay7C9VO70XnZPX3qJas', 164 | 'https://play-lh.googleusercontent.com/8Pj29QXYfhFlmPrMhNvgXdWeCj4X2n3vubIxoHGgd_w4h4MsE04TftKskB53BHp01XU', 165 | 'https://play-lh.googleusercontent.com/mnyR06BYAQQ66ONQrYMluqALsdpKIV1_M2pKEIYurLlpEdRsE0Yu-AMsOmuPNYk-a8jP' 166 | ], 167 | name: 'easySoft App Education', 168 | rating: 2.739726, 169 | category: 'Business', 170 | price: '€0.00', 171 | buy_url: 'https://play.google.com/store/apps/details?id=de.easysoft.app.education&rdid=de.easysoft.app.education&feature=md&offerId', 172 | store_path: '/store/apps/details?id=de.easysoft.app.education', 173 | trailer_url: undefined, 174 | description: 'With the easySoft App Education, […]', 175 | developer: 'easySoft. GmbH', 176 | downloads: '10,000+', 177 | cover_image_url: 'https://play-lh.googleusercontent.com/mnyR06BYAQQ66ONQrYMluqALsdpKIV1_M2pKEIYurLlpEdRsE0Yu-AMsOmuPNYk-a8jP' 178 | }, 179 | // … 180 | ] 181 | ``` 182 |
183 | 184 | ### Fetch an app's data safety labels 185 | 186 | > [!WARNING] 187 | > The separate function for fetching data safety labels is deprecated and will be removed in a future release. Instead, you can use [fetch an app's metadata](#fetch-app-details), which includes the data safety label. 188 | 189 | The following example fetches the data safety labels for TikTok in English: 190 | 191 | ```ts 192 | import { fetchDataSafetyLabels } from 'parse-play'; 193 | 194 | (async () => { 195 | const labels = await fetchDataSafetyLabels([{ app_id: 'com.zhiliaoapp.musically' }], { language: 'EN', }); 196 | console.dir(labels, { depth: null }); 197 | })(); 198 | ``` 199 | 200 |
201 | Data safety label response 202 | The response looks like this: 203 | 204 | ```ts 205 | { 206 | name: 'TikTok', 207 | app_id: 'com.zhiliaoapp.musically', 208 | developer: { 209 | name: 'TikTok Pte. Ltd.', 210 | path: '/store/apps/developer?id=TikTok+Pte.+Ltd.', 211 | website_url: 'https://www.tiktok.com/', 212 | email: 'feedback@tiktok.com', 213 | address: '201 Henderson Road,\n#06-22 Apex@Henderson,\nSingapore 159545 Singapore' 214 | }, 215 | icon_url: 'https://play-lh.googleusercontent.com/iBYjvYuNq8BB7EEEHktPG1fpX9NiY7Jcyg1iRtQxO442r9CZ8H-X9cLkTjpbORwWDG9d', 216 | privacy_policy_url: 'https://www.tiktok.com/legal/privacy-policy', 217 | data_shared: [], 218 | data_collected: [ 219 | { 220 | category: 'Location', 221 | type: 'Approximate location', 222 | purposes: [ 223 | 'App functionality', 224 | 'Analytics', 225 | 'Advertising or marketing', 226 | 'Personalization' 227 | ] 228 | }, 229 | // … 230 | ], 231 | security_practices: { 232 | data_encrypted_in_transit: true, 233 | can_request_data_deletion: true, 234 | committed_to_play_families_policy: undefined, 235 | independent_security_review: undefined 236 | } 237 | } 238 | ``` 239 |
240 | 241 | You can also request the labels for multiple apps at once by adding corresponding objects to the first parameter, they will all be fetched in a single API request. 242 | 243 | 244 | ## License 245 | 246 | parse-play is licensed under the MIT license, see the [`LICENSE`](/LICENSE) file for details. 247 | 248 | Issues and pull requests are welcome! 249 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | parse-play - v3.1.0 2 | 3 | # parse-play - v3.1.0 4 | 5 | ## Table of contents 6 | 7 | ### Enumerations 8 | 9 | - [categories](enums/categories.md) 10 | - [countries](enums/countries.md) 11 | - [languages](enums/languages.md) 12 | 13 | ### Type Aliases 14 | 15 | - [AppDetailsOptions](README.md#appdetailsoptions) 16 | - [AppDetailsRequest](README.md#appdetailsrequest) 17 | - [AppDetailsResult](README.md#appdetailsresult) 18 | - [AppMetadata](README.md#appmetadata) 19 | - [AppMetadataFull](README.md#appmetadatafull) 20 | - [AppMetadataProperty](README.md#appmetadataproperty) 21 | - [AppMetadataPropertyFetchAppDetails](README.md#appmetadatapropertyfetchappdetails) 22 | - [AppMetadataPropertySearch](README.md#appmetadatapropertysearch) 23 | - [AppMetadataPropertyTopCharts](README.md#appmetadatapropertytopcharts) 24 | - [CategoryId](README.md#categoryid) 25 | - [CountryCode](README.md#countrycode) 26 | - [DataSafetyLabel](README.md#datasafetylabel) 27 | - [DataSafetyLabelDataCategory](README.md#datasafetylabeldatacategory) 28 | - [DataSafetyLabelDataType](README.md#datasafetylabeldatatype) 29 | - [DataSafetyLabelPurpose](README.md#datasafetylabelpurpose) 30 | - [DataSafetyLabelRequest](README.md#datasafetylabelrequest) 31 | - [DataSafetyLabelSecurityPracticesDeclarations](README.md#datasafetylabelsecuritypracticesdeclarations) 32 | - [DataSafetyLabelsOptions](README.md#datasafetylabelsoptions) 33 | - [DataTypeDeclaration](README.md#datatypedeclaration) 34 | - [LanguageCode](README.md#languagecode) 35 | - [PermissionGroup](README.md#permissiongroup) 36 | - [SearchAppsOptions](README.md#searchappsoptions) 37 | - [SearchAppsRequest](README.md#searchappsrequest) 38 | - [SearchAppsResults](README.md#searchappsresults) 39 | - [TopChartsEntry](README.md#topchartsentry) 40 | - [TopChartsOptions](README.md#topchartsoptions) 41 | - [TopChartsRequest](README.md#topchartsrequest) 42 | - [TopChartsResult](README.md#topchartsresult) 43 | 44 | ### Variables 45 | 46 | - [dataSafetyLabelDataCategories](README.md#datasafetylabeldatacategories) 47 | - [dataSafetyLabelDataTypes](README.md#datasafetylabeldatatypes) 48 | - [dataSafetyLabelPurposes](README.md#datasafetylabelpurposes) 49 | - [fetchAppDetailsMetadataProperties](README.md#fetchappdetailsmetadataproperties) 50 | - [searchAppMetadataProperties](README.md#searchappmetadataproperties) 51 | - [topChartsAppMetadataProperties](README.md#topchartsappmetadataproperties) 52 | 53 | ### Functions 54 | 55 | - [fetchAppDetails](README.md#fetchappdetails) 56 | - [fetchDataSafetyLabels](README.md#fetchdatasafetylabels) 57 | - [fetchTopCharts](README.md#fetchtopcharts) 58 | - [parseAppEntry](README.md#parseappentry) 59 | - [searchApps](README.md#searchapps) 60 | 61 | ## Type Aliases 62 | 63 | ### AppDetailsOptions 64 | 65 | Ƭ **AppDetailsOptions**: `Object` 66 | 67 | Parameters for all fetch app details requests in a [fetchAppDetails](README.md#fetchappdetails) call. 68 | 69 | #### Type declaration 70 | 71 | | Name | Type | Description | 72 | | :------ | :------ | :------ | 73 | | `country` | [`CountryCode`](README.md#countrycode) | The country version of the Play Store to fetch from. | 74 | | `language` | [`LanguageCode`](README.md#languagecode) | The language for descriptions, etc. | 75 | 76 | #### Defined in 77 | 78 | [endpoints/app-details.ts:13](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L13) 79 | 80 | ___ 81 | 82 | ### AppDetailsRequest 83 | 84 | Ƭ **AppDetailsRequest**: `Object` 85 | 86 | Parameters for a fetch app details request. 87 | 88 | #### Type declaration 89 | 90 | | Name | Type | Description | 91 | | :------ | :------ | :------ | 92 | | `appId` | `string` | The app ID. | 93 | 94 | #### Defined in 95 | 96 | [endpoints/app-details.ts:8](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L8) 97 | 98 | ___ 99 | 100 | ### AppDetailsResult 101 | 102 | Ƭ **AppDetailsResult**: [`AppMetadata`](README.md#appmetadata)<[`AppMetadataPropertyFetchAppDetails`](README.md#appmetadatapropertyfetchappdetails)\> 103 | 104 | The result of a fetch app details request. 105 | 106 | #### Defined in 107 | 108 | [endpoints/app-details.ts:59](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L59) 109 | 110 | ___ 111 | 112 | ### AppMetadata 113 | 114 | Ƭ **AppMetadata**<`P`\>: `Pick`<[`AppMetadataFull`](README.md#appmetadatafull), `P`\> 115 | 116 | The metadata for a single app. The available properties depend on which endpoint this was fetched from. 117 | 118 | #### Type parameters 119 | 120 | | Name | Type | 121 | | :------ | :------ | 122 | | `P` | extends [`AppMetadataProperty`](README.md#appmetadataproperty) | 123 | 124 | #### Defined in 125 | 126 | [common/data-format.ts:127](https://github.com/baltpeter/parse-play/blob/main/src/common/data-format.ts#L127) 127 | 128 | ___ 129 | 130 | ### AppMetadataFull 131 | 132 | Ƭ **AppMetadataFull**: `Object` 133 | 134 | The full metadata that can theoretically be fetched for an app. The individual endpoints will only return a subset of 135 | this, see [AppMetadata](README.md#appmetadata). 136 | 137 | #### Type declaration 138 | 139 | | Name | Type | Description | 140 | | :------ | :------ | :------ | 141 | | `app_id` | `string` | The app's bundle ID. | 142 | | `buy_url` | `string` \| `undefined` | A URL to the Play Store website to buy the app. | 143 | | `category` | `string` | The app's main category. | 144 | | `content_rating?` | { `icon_url`: `string` ; `interactive_elements?`: `string` ; `label`: `string` } | The app's content rating. | 145 | | `content_rating.icon_url` | `string` | The URL to an icon for the content rating. | 146 | | `content_rating.interactive_elements?` | `string` | A description of interactive elements in the app. | 147 | | `content_rating.label` | `string` | The label for the content rating. | 148 | | `cover_image_url` | `string` \| `undefined` | A URL to the app's cover image. | 149 | | `data_collected` | [`DataTypeDeclaration`](README.md#datatypedeclaration)[] \| `undefined` | An overview of the data the app may collect. | 150 | | `data_shared` | [`DataTypeDeclaration`](README.md#datatypedeclaration)[] \| `undefined` | An overview of the data that the app may share with other companies or organizations. | 151 | | `description` | `string` | The app's description. | 152 | | `developer` | `string` | The app's developer. | 153 | | `developer_address` | `string` \| `undefined` | The developer's address. | 154 | | `developer_email` | `string` | The developer's email address. | 155 | | `developer_path` | `string` | The relative path of the developer's page on the Play Store website. | 156 | | `developer_website_url` | `string` \| `undefined` | The URL to the developer's website. | 157 | | `downloads` | `string` | The approximate download count of the app as a string, as displayed on the Play Store website. | 158 | | `downloads_exact` | `number` | The exact download count of the app. | 159 | | `icon_url` | `string` | A URL to the app's icon. | 160 | | `in_app_purchases?` | `string` | The cost of in-app purchases for the app. | 161 | | `name` | `string` | The app's name. | 162 | | `offered_by` | `string` | The company distributing the app on the Play Store. | 163 | | `permissions` | [`PermissionGroup`](README.md#permissiongroup)[] | The app's permissions, grouped by category. | 164 | | `position` | `number` | The app's position in a list (top chart, search results). | 165 | | `price` | `string` \| `undefined` | The app's price. Can be undefined for pre-release apps. | 166 | | `privacy_policy_url` | `string` \| `undefined` | The URL to the app's privacy policy. | 167 | | `rating` | `number` \| `undefined` | The app's review rating. | 168 | | `rating_counts` | { `1`: `number` ; `2`: `number` ; `3`: `number` ; `4`: `number` ; `5`: `number` ; `total`: `number` } | The number of each rating the app has received. | 169 | | `rating_counts.1` | `number` | The number of 1-star ratings. | 170 | | `rating_counts.2` | `number` | The number of 2-star ratings. | 171 | | `rating_counts.3` | `number` | The number of 3-star ratings. | 172 | | `rating_counts.4` | `number` | The number of 4-star ratings. | 173 | | `rating_counts.5` | `number` | The number of 5-star ratings. | 174 | | `rating_counts.total` | `number` | The total number of ratings. | 175 | | `released_on?` | `Date` | The date when the app was first published. | 176 | | `requires_android?` | {} | The app's required version of Android. | 177 | | `screenshot_urls` | `string`[] | URLs to screenshots of the app. | 178 | | `security_practices` | [`DataSafetyLabelSecurityPracticesDeclarations`](README.md#datasafetylabelsecuritypracticesdeclarations) \| `undefined` | An overview of the app's security practices. | 179 | | `store_path` | `string` | The relative path of the app on the Play Store website. | 180 | | `tags?` | { `id?`: `string` ; `name`: `string` ; `path`: `string` } | A list of the app's categories and related search terms. | 181 | | `tags.id?` | `string` | A machine-readable ID for the tag. | 182 | | `tags.name` | `string` | The name/label of the tag. | 183 | | `tags.path` | `string` | The relative path of the category/search page on the Play Store website. | 184 | | `top_chart_placement?` | { `label`: `string` ; `placement`: `string` } | The app's placement on a top chart. | 185 | | `top_chart_placement.label` | `string` | The label for the placement. | 186 | | `top_chart_placement.placement` | `string` | The app's position in the top chart. | 187 | | `trailer_url` | `string` \| `undefined` | A URL to a video trailer for the app. | 188 | | `updated_on` | `Date` | The date when the app was last updated. | 189 | | `version?` | `string` | The app's version. | 190 | 191 | #### Defined in 192 | 193 | [common/data-format.ts:20](https://github.com/baltpeter/parse-play/blob/main/src/common/data-format.ts#L20) 194 | 195 | ___ 196 | 197 | ### AppMetadataProperty 198 | 199 | Ƭ **AppMetadataProperty**: keyof [`AppMetadataFull`](README.md#appmetadatafull) 200 | 201 | A property that can be present in the metadata of an app. 202 | 203 | #### Defined in 204 | 205 | [common/data-format.ts:125](https://github.com/baltpeter/parse-play/blob/main/src/common/data-format.ts#L125) 206 | 207 | ___ 208 | 209 | ### AppMetadataPropertyFetchAppDetails 210 | 211 | Ƭ **AppMetadataPropertyFetchAppDetails**: typeof [`fetchAppDetailsMetadataProperties`](README.md#fetchappdetailsmetadataproperties)[`number`] 212 | 213 | A property present when fetching app details. 214 | 215 | #### Defined in 216 | 217 | [endpoints/app-details.ts:57](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L57) 218 | 219 | ___ 220 | 221 | ### AppMetadataPropertySearch 222 | 223 | Ƭ **AppMetadataPropertySearch**: typeof [`searchAppMetadataProperties`](README.md#searchappmetadataproperties)[`number`] 224 | 225 | A property present in the metadata of each app in the search results. 226 | 227 | #### Defined in 228 | 229 | [endpoints/search.ts:42](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L42) 230 | 231 | ___ 232 | 233 | ### AppMetadataPropertyTopCharts 234 | 235 | Ƭ **AppMetadataPropertyTopCharts**: typeof [`topChartsAppMetadataProperties`](README.md#topchartsappmetadataproperties)[`number`] 236 | 237 | A property present in the metadata of each app in the top chart. 238 | 239 | #### Defined in 240 | 241 | [endpoints/top-charts.ts:49](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L49) 242 | 243 | ___ 244 | 245 | ### CategoryId 246 | 247 | Ƭ **CategoryId**: keyof typeof [`categories`](enums/categories.md) 248 | 249 | The ID of a category on the Play Store. 250 | 251 | #### Defined in 252 | 253 | [common/consts.ts:74](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L74) 254 | 255 | ___ 256 | 257 | ### CountryCode 258 | 259 | Ƭ **CountryCode**: keyof typeof [`countries`](enums/countries.md) 260 | 261 | The country code of a country supported on the Play Store. 262 | 263 | #### Defined in 264 | 265 | [common/consts.ts:140](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L140) 266 | 267 | ___ 268 | 269 | ### DataSafetyLabel 270 | 271 | Ƭ **DataSafetyLabel**: `Object` 272 | 273 | An app's data safety label. 274 | 275 | **`deprecated`** The separate function for fetching data safety labels is deprecated and will be removed in a future 276 | release. Instead, you can use the [fetchAppDetails](README.md#fetchappdetails) function to fetch an app's metadata, which includes the 277 | data safety label. 278 | 279 | #### Type declaration 280 | 281 | | Name | Type | Description | 282 | | :------ | :------ | :------ | 283 | | `app_id` | `string` | The app's bundle ID. | 284 | | `data_collected` | [`DataTypeDeclaration`](README.md#datatypedeclaration)[] \| `undefined` | An overview of the data the app may collect. | 285 | | `data_shared` | [`DataTypeDeclaration`](README.md#datatypedeclaration)[] \| `undefined` | An overview of the data that the app may share with other companies or organizations. | 286 | | `developer` | { `address`: `string` \| `undefined` ; `email`: `string` ; `name`: `string` ; `path`: `string` ; `website_url`: `string` \| `undefined` } | Data about the app's developer. | 287 | | `developer.address` | `string` \| `undefined` | The developer's address. | 288 | | `developer.email` | `string` | The developer's email address. | 289 | | `developer.name` | `string` | The developer's name | 290 | | `developer.path` | `string` | The relative path of the developer's page on the Play Store website. | 291 | | `developer.website_url` | `string` \| `undefined` | The URL to the developer's website. | 292 | | `icon_url` | `string` | The URL to the app's icon. | 293 | | `name` | `string` | The app's name. | 294 | | `privacy_policy_url` | `string` \| `undefined` | The URL to the app's privacy policy. | 295 | | `security_practices` | [`DataSafetyLabelSecurityPracticesDeclarations`](README.md#datasafetylabelsecuritypracticesdeclarations) \| `undefined` | An overview of the app's security practices. | 296 | 297 | #### Defined in 298 | 299 | [endpoints/data-safety.ts:69](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L69) 300 | 301 | ___ 302 | 303 | ### DataSafetyLabelDataCategory 304 | 305 | Ƭ **DataSafetyLabelDataCategory**: typeof [`dataSafetyLabelDataCategories`](README.md#datasafetylabeldatacategories)[`number`] 306 | 307 | A category that groups multiple related data types in a data safety label. 308 | 309 | #### Defined in 310 | 311 | [common/consts.ts:270](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L270) 312 | 313 | ___ 314 | 315 | ### DataSafetyLabelDataType 316 | 317 | Ƭ **DataSafetyLabelDataType**: typeof [`dataSafetyLabelDataTypes`](README.md#datasafetylabeldatatypes)[`number`] 318 | 319 | A type of data that can be declared in a data safety label. 320 | 321 | #### Defined in 322 | 323 | [common/consts.ts:319](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L319) 324 | 325 | ___ 326 | 327 | ### DataSafetyLabelPurpose 328 | 329 | Ƭ **DataSafetyLabelPurpose**: typeof [`dataSafetyLabelPurposes`](README.md#datasafetylabelpurposes)[`number`] 330 | 331 | A purpose for which data collection or sharing can be declared in a data safety label. 332 | 333 | #### Defined in 334 | 335 | [common/consts.ts:337](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L337) 336 | 337 | ___ 338 | 339 | ### DataSafetyLabelRequest 340 | 341 | Ƭ **DataSafetyLabelRequest**: `Object` 342 | 343 | Parameters for a single data safety label request. 344 | 345 | **`deprecated`** The separate function for fetching data safety labels is deprecated and will be removed in a future 346 | release. Instead, you can use the [fetchAppDetails](README.md#fetchappdetails) function to fetch an app's metadata, which includes the 347 | data safety label. 348 | 349 | #### Type declaration 350 | 351 | | Name | Type | Description | 352 | | :------ | :------ | :------ | 353 | | `app_id` | `string` | The app's bundle ID. | 354 | 355 | #### Defined in 356 | 357 | [endpoints/data-safety.ts:18](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L18) 358 | 359 | ___ 360 | 361 | ### DataSafetyLabelSecurityPracticesDeclarations 362 | 363 | Ƭ **DataSafetyLabelSecurityPracticesDeclarations**: `Object` 364 | 365 | An app's declared security practices in a data safety label. 366 | 367 | #### Type declaration 368 | 369 | | Name | Type | Description | 370 | | :------ | :------ | :------ | 371 | | `can_request_data_deletion` | `boolean` \| `undefined` | Whether the app provides a way for users to request deletion of their data. | 372 | | `committed_to_play_families_policy` | `boolean` \| `undefined` | Whether the developer has reviewed the app's compliance with Google Play's [Families policy requirements](https://support.google.com/googleplay/android-developer/answer/9893335) (only for applicable apps). | 373 | | `data_encrypted_in_transit` | `boolean` \| `undefined` | Whether data collected or shared by the app uses encryption in transit. | 374 | | `independent_security_review` | `boolean` \| `undefined` | Whether the app has been independently validated against a global security standard. | 375 | 376 | #### Defined in 377 | 378 | [endpoints/data-safety.ts:48](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L48) 379 | 380 | ___ 381 | 382 | ### DataSafetyLabelsOptions 383 | 384 | Ƭ **DataSafetyLabelsOptions**: `Object` 385 | 386 | Parameters for all data safety label requests in a [fetchDataSafetyLabels](README.md#fetchdatasafetylabels) call. 387 | 388 | #### Type declaration 389 | 390 | | Name | Type | Description | 391 | | :------ | :------ | :------ | 392 | | `language` | [`LanguageCode`](README.md#languagecode) | The language for descriptions, etc. | 393 | 394 | #### Defined in 395 | 396 | [endpoints/data-safety.ts:27](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L27) 397 | 398 | ___ 399 | 400 | ### DataTypeDeclaration 401 | 402 | Ƭ **DataTypeDeclaration**: `Object` 403 | 404 | An app's declaration for a single data type in a data safety label. 405 | 406 | #### Type declaration 407 | 408 | | Name | Type | Description | 409 | | :------ | :------ | :------ | 410 | | `category` | [`DataSafetyLabelDataCategory`](README.md#datasafetylabeldatacategory) | The category the data type fits into. | 411 | | `optional` | `boolean` | Whether the data type is marked as optional. | 412 | | `purposes` | [`DataSafetyLabelPurpose`](README.md#datasafetylabelpurpose)[] | The purposes for which the data type is collected or shared. | 413 | | `type` | [`DataSafetyLabelDataType`](README.md#datasafetylabeldatatype) | The data type. | 414 | 415 | #### Defined in 416 | 417 | [endpoints/data-safety.ts:35](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L35) 418 | 419 | ___ 420 | 421 | ### LanguageCode 422 | 423 | Ƭ **LanguageCode**: keyof typeof [`languages`](enums/languages.md) 424 | 425 | The language code of a language supported on the Play Store. 426 | 427 | #### Defined in 428 | 429 | [common/consts.ts:240](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L240) 430 | 431 | ___ 432 | 433 | ### PermissionGroup 434 | 435 | Ƭ **PermissionGroup**: `Object` 436 | 437 | A group of related permissions the app has access to. 438 | 439 | #### Type declaration 440 | 441 | | Name | Type | Description | 442 | | :------ | :------ | :------ | 443 | | `icon_url?` | `string` | The URL to the group's icon. | 444 | | `id?` | `string` | A machine-readable ID for the group. | 445 | | `name?` | `string` | The name/label of the group. | 446 | | `permissions` | `string`[] | The detailed permissions in this group the app has access to. | 447 | 448 | #### Defined in 449 | 450 | [common/data-format.ts:5](https://github.com/baltpeter/parse-play/blob/main/src/common/data-format.ts#L5) 451 | 452 | ___ 453 | 454 | ### SearchAppsOptions 455 | 456 | Ƭ **SearchAppsOptions**: `Object` 457 | 458 | Parameters for all search apps requests in a [searchApps](README.md#searchapps) call. 459 | 460 | #### Type declaration 461 | 462 | | Name | Type | Description | 463 | | :------ | :------ | :------ | 464 | | `country` | [`CountryCode`](README.md#countrycode) | The country version of the Play Store to search in. | 465 | | `language` | [`LanguageCode`](README.md#languagecode) | The language for descriptions, etc. | 466 | 467 | #### Defined in 468 | 469 | [endpoints/search.ts:16](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L16) 470 | 471 | ___ 472 | 473 | ### SearchAppsRequest 474 | 475 | Ƭ **SearchAppsRequest**: `Object` 476 | 477 | Parameters for a search apps request. 478 | 479 | #### Type declaration 480 | 481 | | Name | Type | Description | 482 | | :------ | :------ | :------ | 483 | | `searchTerm` | `string` | The term to search for. | 484 | 485 | #### Defined in 486 | 487 | [endpoints/search.ts:9](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L9) 488 | 489 | ___ 490 | 491 | ### SearchAppsResults 492 | 493 | Ƭ **SearchAppsResults**: [`AppMetadata`](README.md#appmetadata)<[`AppMetadataPropertySearch`](README.md#appmetadatapropertysearch)\>[] 494 | 495 | A list of the search results. 496 | 497 | #### Defined in 498 | 499 | [endpoints/search.ts:46](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L46) 500 | 501 | ___ 502 | 503 | ### TopChartsEntry 504 | 505 | Ƭ **TopChartsEntry**: [`AppMetadata`](README.md#appmetadata)<[`AppMetadataPropertyTopCharts`](README.md#appmetadatapropertytopcharts)\> 506 | 507 | A single app and its associated metadata on a top chart. 508 | 509 | #### Defined in 510 | 511 | [endpoints/top-charts.ts:54](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L54) 512 | 513 | ___ 514 | 515 | ### TopChartsOptions 516 | 517 | Ƭ **TopChartsOptions**: `Object` 518 | 519 | Parameters for all top charts requests in a [fetchTopCharts](README.md#fetchtopcharts) call. 520 | 521 | #### Type declaration 522 | 523 | | Name | Type | Description | 524 | | :------ | :------ | :------ | 525 | | `country` | [`CountryCode`](README.md#countrycode) | The country for which to fetch the top chart(s). | 526 | | `language` | [`LanguageCode`](README.md#languagecode) | The language for descriptions, etc. | 527 | 528 | #### Defined in 529 | 530 | [endpoints/top-charts.ts:23](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L23) 531 | 532 | ___ 533 | 534 | ### TopChartsRequest 535 | 536 | Ƭ **TopChartsRequest**: `Object` 537 | 538 | Parameters for a single top charts request. 539 | 540 | #### Type declaration 541 | 542 | | Name | Type | Description | 543 | | :------ | :------ | :------ | 544 | | `category` | [`CategoryId`](README.md#categoryid) | The category to use. Use `APPLICATION` for all apps, or `GAME` for all games, or one of the subcategory. | 545 | | `chart` | ``"topselling_free"`` \| ``"topgrossing"`` \| ``"topselling_paid"`` | The chart to use, where `topselling_free`: Top free (or Top for €0, Top for $0, depending on the country); `topgrossing`: Top grossing; `topselling_paid`: Top selling. | 546 | | `count` | `number` | The number of apps to include in the top list. This seems to be limited to 660 apps. | 547 | 548 | #### Defined in 549 | 550 | [endpoints/top-charts.ts:9](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L9) 551 | 552 | ___ 553 | 554 | ### TopChartsResult 555 | 556 | Ƭ **TopChartsResult**: [`TopChartsEntry`](README.md#topchartsentry)[] 557 | 558 | A list of the entries on the respective top chart. 559 | 560 | #### Defined in 561 | 562 | [endpoints/top-charts.ts:58](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L58) 563 | 564 | ## Variables 565 | 566 | ### dataSafetyLabelDataCategories 567 | 568 | • `Const` **dataSafetyLabelDataCategories**: readonly [``"App activity"``, ``"App info and performance"``, ``"Audio files"``, ``"Calendar"``, ``"Contacts"``, ``"Device or other IDs"``, ``"Files and docs"``, ``"Financial info"``, ``"Health and fitness"``, ``"Location"``, ``"Messages"``, ``"Personal info"``, ``"Photos and videos"``, ``"Web browsing"``] 569 | 570 | The categories that group multiple related data types in a data safety label. 571 | 572 | Taken from the official documentation: 573 | 574 | #### Defined in 575 | 576 | [common/consts.ts:251](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L251) 577 | 578 | ___ 579 | 580 | ### dataSafetyLabelDataTypes 581 | 582 | • `Const` **dataSafetyLabelDataTypes**: readonly [``"Approximate location"``, ``"Precise location"``, ``"Name"``, ``"Email address"``, ``"User IDs"``, ``"Address"``, ``"Phone number"``, ``"Race and ethnicity"``, ``"Political or religious beliefs"``, ``"Sexual orientation"``, ``"Other info"``, ``"User payment info"``, ``"Purchase history"``, ``"Credit score"``, ``"Other financial info"``, ``"Health info"``, ``"Fitness info"``, ``"Emails"``, ``"SMS or MMS"``, ``"Other in-app messages"``, ``"Photos"``, ``"Videos"``, ``"Voice or sound recordings"``, ``"Music files"``, ``"Other audio files"``, ``"Files and docs"``, ``"Calendar events"``, ``"Contacts"``, ``"App interactions"``, ``"In-app search history"``, ``"Installed apps"``, ``"Other user-generated content"``, ``"Other actions"``, ``"Web browsing history"``, ``"Crash logs"``, ``"Diagnostics"``, ``"Other app performance data"``, ``"Device or other IDs"``] 583 | 584 | The types of data that can be declared in a data safety label. 585 | 586 | Taken from the official documentation: 587 | 588 | #### Defined in 589 | 590 | [common/consts.ts:276](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L276) 591 | 592 | ___ 593 | 594 | ### dataSafetyLabelPurposes 595 | 596 | • `Const` **dataSafetyLabelPurposes**: readonly [``"App functionality"``, ``"Analytics"``, ``"Developer communications"``, ``"Advertising or marketing"``, ``"Fraud prevention, security, and compliance"``, ``"Personalization"``, ``"Account management"``] 597 | 598 | The purposes for which data collection or sharing can be declared in a data safety label. 599 | 600 | Taken from the official documentation: 601 | 602 | #### Defined in 603 | 604 | [common/consts.ts:325](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L325) 605 | 606 | ___ 607 | 608 | ### fetchAppDetailsMetadataProperties 609 | 610 | • `Const` **fetchAppDetailsMetadataProperties**: readonly [``"app_id"``, ``"name"``, ``"content_rating"``, ``"released_on"``, ``"downloads"``, ``"downloads_exact"``, ``"in_app_purchases"``, ``"offered_by"``, ``"rating"``, ``"rating_counts"``, ``"price"``, ``"buy_url"``, ``"top_chart_placement"``, ``"developer"``, ``"developer_path"``, ``"developer_website_url"``, ``"developer_email"``, ``"developer_address"``, ``"description"``, ``"permissions"``, ``"screenshot_urls"``, ``"category"``, ``"icon_url"``, ``"cover_image_url"``, ``"privacy_policy_url"``, ``"trailer_url"``, ``"tags"``, ``"data_shared"``, ``"data_collected"``, ``"security_practices"``, ``"version"``, ``"requires_android"``, ``"updated_on"``] 611 | 612 | The properties present when fetching app details. 613 | 614 | #### Defined in 615 | 616 | [endpoints/app-details.ts:21](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L21) 617 | 618 | ___ 619 | 620 | ### searchAppMetadataProperties 621 | 622 | • `Const` **searchAppMetadataProperties**: readonly [``"position"``, ``"app_id"``, ``"icon_url"``, ``"screenshot_urls"``, ``"name"``, ``"rating"``, ``"category"``, ``"price"``, ``"buy_url"``, ``"store_path"``, ``"trailer_url"``, ``"description"``, ``"developer"``, ``"downloads"``, ``"cover_image_url"``] 623 | 624 | The properties present in the metadata of each app in the search results. 625 | 626 | #### Defined in 627 | 628 | [endpoints/search.ts:24](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L24) 629 | 630 | ___ 631 | 632 | ### topChartsAppMetadataProperties 633 | 634 | • `Const` **topChartsAppMetadataProperties**: readonly [``"position"``, ``"app_id"``, ``"icon_url"``, ``"screenshot_urls"``, ``"name"``, ``"rating"``, ``"category"``, ``"price"``, ``"buy_url"``, ``"store_path"``, ``"trailer_url"``, ``"description"``, ``"developer"``, ``"downloads"``, ``"cover_image_url"``] 635 | 636 | The properties present in the metadata of each app in the top chart. 637 | 638 | #### Defined in 639 | 640 | [endpoints/top-charts.ts:31](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L31) 641 | 642 | ## Functions 643 | 644 | ### fetchAppDetails 645 | 646 | ▸ **fetchAppDetails**(`request`, `options`): `Promise`<[`AppDetailsResult`](README.md#appdetailsresult)\> 647 | 648 | Fetch the details/metadata of an app on the Google Play Store. 649 | 650 | This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `Ws7gDc`. 651 | 652 | #### Parameters 653 | 654 | | Name | Type | Description | 655 | | :------ | :------ | :------ | 656 | | `request` | [`AppDetailsRequest`](README.md#appdetailsrequest) \| [[`AppDetailsRequest`](README.md#appdetailsrequest)] | The parameters of which app to fetch the details of. | 657 | | `options` | [`AppDetailsOptions`](README.md#appdetailsoptions) | Language and country options. | 658 | 659 | #### Returns 660 | 661 | `Promise`<[`AppDetailsResult`](README.md#appdetailsresult)\> 662 | 663 | The app details. 664 | 665 | #### Defined in 666 | 667 | [endpoints/app-details.ts:252](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L252) 668 | 669 | ▸ **fetchAppDetails**(`requests`, `options`): `Promise`<[`AppDetailsResult`](README.md#appdetailsresult)[]\> 670 | 671 | Same as [fetchAppDetails](README.md#fetchappdetails) but for fetching the details of multiple apps at once. The details are all fetched in 672 | a single API request. 673 | 674 | **`see`** [fetchAppDetails](README.md#fetchappdetails) 675 | 676 | #### Parameters 677 | 678 | | Name | Type | Description | 679 | | :------ | :------ | :------ | 680 | | `requests` | [`AppDetailsRequest`](README.md#appdetailsrequest)[] | An array of fetch app details requests. | 681 | | `options` | [`AppDetailsOptions`](README.md#appdetailsoptions) | The options for _all_ requests. | 682 | 683 | #### Returns 684 | 685 | `Promise`<[`AppDetailsResult`](README.md#appdetailsresult)[]\> 686 | 687 | An array of the app details, in the same order as the requests. 688 | 689 | #### Defined in 690 | 691 | [endpoints/app-details.ts:266](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/app-details.ts#L266) 692 | 693 | ___ 694 | 695 | ### fetchDataSafetyLabels 696 | 697 | ▸ **fetchDataSafetyLabels**(`request`, `options`): `Promise`<[`DataSafetyLabel`](README.md#datasafetylabel) \| `undefined`\> 698 | 699 | Fetch and parse the given app's data safety label from the Google Play Store. 700 | 701 | This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `Ws7gDc`. 702 | 703 | **`deprecated`** The separate function for fetching data safety labels is deprecated and will be removed in a future 704 | release. Instead, you can use the [fetchAppDetails](README.md#fetchappdetails) function to fetch an app's metadata, which includes the 705 | data safety label. 706 | 707 | #### Parameters 708 | 709 | | Name | Type | Description | 710 | | :------ | :------ | :------ | 711 | | `request` | [`DataSafetyLabelRequest`](README.md#datasafetylabelrequest) \| [[`DataSafetyLabelRequest`](README.md#datasafetylabelrequest)] | The parameters for which app to fetch. | 712 | | `options` | [`DataSafetyLabelsOptions`](README.md#datasafetylabelsoptions) | Language options. | 713 | 714 | #### Returns 715 | 716 | `Promise`<[`DataSafetyLabel`](README.md#datasafetylabel) \| `undefined`\> 717 | 718 | The data safety label. 719 | 720 | #### Defined in 721 | 722 | [endpoints/data-safety.ts:198](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L198) 723 | 724 | ▸ **fetchDataSafetyLabels**(`requests`, `options`): `Promise`<([`DataSafetyLabel`](README.md#datasafetylabel) \| `undefined`)[]\> 725 | 726 | Same as [fetchDataSafetyLabels](README.md#fetchdatasafetylabels) but for fetching multiple data safety labels at once. The data safety labels 727 | are fetched in a single API request. 728 | 729 | **`deprecated`** The separate function for fetching data safety labels is deprecated and will be removed in a future 730 | release. Instead, you can use the [fetchAppDetails](README.md#fetchappdetails) function to fetch an app's metadata, which includes the 731 | data safety label. 732 | 733 | **`see`** [fetchDataSafetyLabels](README.md#fetchdatasafetylabels) 734 | 735 | #### Parameters 736 | 737 | | Name | Type | Description | 738 | | :------ | :------ | :------ | 739 | | `requests` | [`DataSafetyLabelRequest`](README.md#datasafetylabelrequest)[] | An array of data safety label requests. | 740 | | `options` | [`DataSafetyLabelsOptions`](README.md#datasafetylabelsoptions) | The options for _all_ requests. | 741 | 742 | #### Returns 743 | 744 | `Promise`<([`DataSafetyLabel`](README.md#datasafetylabel) \| `undefined`)[]\> 745 | 746 | An array of the data safety labels, in the same order as the requests. 747 | 748 | #### Defined in 749 | 750 | [endpoints/data-safety.ts:216](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/data-safety.ts#L216) 751 | 752 | ___ 753 | 754 | ### fetchTopCharts 755 | 756 | ▸ **fetchTopCharts**(`request`, `options`): `Promise`<[`TopChartsResult`](README.md#topchartsresult) \| `undefined`\> 757 | 758 | Fetch and parse the current top chart rankings from the Play Store for the given criteria. 759 | 760 | This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `vyAe2`. 761 | 762 | #### Parameters 763 | 764 | | Name | Type | Description | 765 | | :------ | :------ | :------ | 766 | | `request` | [`TopChartsRequest`](README.md#topchartsrequest) \| [[`TopChartsRequest`](README.md#topchartsrequest)] | The parameters for which top chart to fetch. | 767 | | `options` | [`TopChartsOptions`](README.md#topchartsoptions) | Language and country options. | 768 | 769 | #### Returns 770 | 771 | `Promise`<[`TopChartsResult`](README.md#topchartsresult) \| `undefined`\> 772 | 773 | The top chart. 774 | 775 | #### Defined in 776 | 777 | [endpoints/top-charts.ts:117](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L117) 778 | 779 | ▸ **fetchTopCharts**(`requests`, `options`): `Promise`<([`TopChartsResult`](README.md#topchartsresult) \| `undefined`)[]\> 780 | 781 | Same as [fetchTopCharts](README.md#fetchtopcharts) but for fetching multiple top charts at once. The top charts are fetched in a single 782 | API request. 783 | 784 | **`see`** [fetchTopCharts](README.md#fetchtopcharts) 785 | 786 | #### Parameters 787 | 788 | | Name | Type | Description | 789 | | :------ | :------ | :------ | 790 | | `requests` | [`TopChartsRequest`](README.md#topchartsrequest)[] | An array of top chart requests. | 791 | | `options` | [`TopChartsOptions`](README.md#topchartsoptions) | The options for _all_ requests. | 792 | 793 | #### Returns 794 | 795 | `Promise`<([`TopChartsResult`](README.md#topchartsresult) \| `undefined`)[]\> 796 | 797 | An array of the top charts, in the same order as the requests. 798 | 799 | #### Defined in 800 | 801 | [endpoints/top-charts.ts:131](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/top-charts.ts#L131) 802 | 803 | ___ 804 | 805 | ### parseAppEntry 806 | 807 | ▸ **parseAppEntry**<`P`\>(`entry`, `properties`, `options`): [`AppMetadata`](README.md#appmetadata)<`P`\> 808 | 809 | Parse an app entry in a search or top chart response. 810 | 811 | #### Type parameters 812 | 813 | | Name | Type | 814 | | :------ | :------ | 815 | | `P` | extends keyof [`AppMetadataFull`](README.md#appmetadatafull) | 816 | 817 | #### Parameters 818 | 819 | | Name | Type | 820 | | :------ | :------ | 821 | | `entry` | `any` | 822 | | `properties` | `P`[] \| readonly `P`[] | 823 | | `options` | `Object` | 824 | 825 | #### Returns 826 | 827 | [`AppMetadata`](README.md#appmetadata)<`P`\> 828 | 829 | #### Defined in 830 | 831 | [common/data-format.ts:154](https://github.com/baltpeter/parse-play/blob/main/src/common/data-format.ts#L154) 832 | 833 | ___ 834 | 835 | ### searchApps 836 | 837 | ▸ **searchApps**(`request`, `options`): `Promise`<[`SearchAppsResults`](README.md#searchappsresults) \| `undefined`\> 838 | 839 | Search for apps on the Google Play Stroe. 840 | 841 | This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `lGYRle`. 842 | 843 | #### Parameters 844 | 845 | | Name | Type | Description | 846 | | :------ | :------ | :------ | 847 | | `request` | [`SearchAppsRequest`](README.md#searchappsrequest) \| [[`SearchAppsRequest`](README.md#searchappsrequest)] | The parameters for what to search for. | 848 | | `options` | [`SearchAppsOptions`](README.md#searchappsoptions) | Language options. | 849 | 850 | #### Returns 851 | 852 | `Promise`<[`SearchAppsResults`](README.md#searchappsresults) \| `undefined`\> 853 | 854 | The search results. 855 | 856 | #### Defined in 857 | 858 | [endpoints/search.ts:151](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L151) 859 | 860 | ▸ **searchApps**(`requests`, `options`): `Promise`<([`SearchAppsResults`](README.md#searchappsresults) \| `undefined`)[]\> 861 | 862 | Same as [searchApps](README.md#searchapps) but for doing multiple searches at once. The search results are fetched in a single API 863 | request. 864 | 865 | **`see`** [searchApps](README.md#searchapps) 866 | 867 | #### Parameters 868 | 869 | | Name | Type | Description | 870 | | :------ | :------ | :------ | 871 | | `requests` | [`SearchAppsRequest`](README.md#searchappsrequest)[] | An array of search apps requests. | 872 | | `options` | [`SearchAppsOptions`](README.md#searchappsoptions) | The options for _all_ requests. | 873 | 874 | #### Returns 875 | 876 | `Promise`<([`SearchAppsResults`](README.md#searchappsresults) \| `undefined`)[]\> 877 | 878 | An array of the search results, in the same order as the requests. 879 | 880 | #### Defined in 881 | 882 | [endpoints/search.ts:165](https://github.com/baltpeter/parse-play/blob/main/src/endpoints/search.ts#L165) 883 | -------------------------------------------------------------------------------- /docs/enums/categories.md: -------------------------------------------------------------------------------- 1 | [parse-play - v3.1.0](../README.md) / categories 2 | 3 | # Enumeration: categories 4 | 5 | A category on the Play Store. 6 | 7 | ## Table of contents 8 | 9 | ### Enumeration Members 10 | 11 | - [ANDROID\_WEAR](categories.md#android_wear) 12 | - [APPLICATION](categories.md#application) 13 | - [ART\_AND\_DESIGN](categories.md#art_and_design) 14 | - [AUTO\_AND\_VEHICLES](categories.md#auto_and_vehicles) 15 | - [BEAUTY](categories.md#beauty) 16 | - [BOOKS\_AND\_REFERENCE](categories.md#books_and_reference) 17 | - [BUSINESS](categories.md#business) 18 | - [COMICS](categories.md#comics) 19 | - [COMMUNICATION](categories.md#communication) 20 | - [DATING](categories.md#dating) 21 | - [EDUCATION](categories.md#education) 22 | - [ENTERTAINMENT](categories.md#entertainment) 23 | - [EVENTS](categories.md#events) 24 | - [FAMILY](categories.md#family) 25 | - [FINANCE](categories.md#finance) 26 | - [FOOD\_AND\_DRINK](categories.md#food_and_drink) 27 | - [GAME](categories.md#game) 28 | - [GAME\_ACTION](categories.md#game_action) 29 | - [GAME\_ADVENTURE](categories.md#game_adventure) 30 | - [GAME\_ARCADE](categories.md#game_arcade) 31 | - [GAME\_BOARD](categories.md#game_board) 32 | - [GAME\_CARD](categories.md#game_card) 33 | - [GAME\_CASINO](categories.md#game_casino) 34 | - [GAME\_CASUAL](categories.md#game_casual) 35 | - [GAME\_EDUCATIONAL](categories.md#game_educational) 36 | - [GAME\_MUSIC](categories.md#game_music) 37 | - [GAME\_PUZZLE](categories.md#game_puzzle) 38 | - [GAME\_RACING](categories.md#game_racing) 39 | - [GAME\_ROLE\_PLAYING](categories.md#game_role_playing) 40 | - [GAME\_SIMULATION](categories.md#game_simulation) 41 | - [GAME\_SPORTS](categories.md#game_sports) 42 | - [GAME\_STRATEGY](categories.md#game_strategy) 43 | - [GAME\_TRIVIA](categories.md#game_trivia) 44 | - [GAME\_WORD](categories.md#game_word) 45 | - [HEALTH\_AND\_FITNESS](categories.md#health_and_fitness) 46 | - [HOUSE\_AND\_HOME](categories.md#house_and_home) 47 | - [LIBRARIES\_AND\_DEMO](categories.md#libraries_and_demo) 48 | - [LIFESTYLE](categories.md#lifestyle) 49 | - [MAPS\_AND\_NAVIGATION](categories.md#maps_and_navigation) 50 | - [MEDICAL](categories.md#medical) 51 | - [MUSIC\_AND\_AUDIO](categories.md#music_and_audio) 52 | - [NEWS\_AND\_MAGAZINES](categories.md#news_and_magazines) 53 | - [PARENTING](categories.md#parenting) 54 | - [PERSONALIZATION](categories.md#personalization) 55 | - [PHOTOGRAPHY](categories.md#photography) 56 | - [PRODUCTIVITY](categories.md#productivity) 57 | - [SHOPPING](categories.md#shopping) 58 | - [SOCIAL](categories.md#social) 59 | - [SPORTS](categories.md#sports) 60 | - [TOOLS](categories.md#tools) 61 | - [TRAVEL\_AND\_LOCAL](categories.md#travel_and_local) 62 | - [VIDEO\_PLAYERS](categories.md#video_players) 63 | - [WATCH\_FACE](categories.md#watch_face) 64 | - [WEATHER](categories.md#weather) 65 | 66 | ## Enumeration Members 67 | 68 | ### ANDROID\_WEAR 69 | 70 | • **ANDROID\_WEAR** 71 | 72 | #### Defined in 73 | 74 | [common/consts.ts:49](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L49) 75 | 76 | ___ 77 | 78 | ### APPLICATION 79 | 80 | • **APPLICATION** 81 | 82 | #### Defined in 83 | 84 | [common/consts.ts:16](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L16) 85 | 86 | ___ 87 | 88 | ### ART\_AND\_DESIGN 89 | 90 | • **ART\_AND\_DESIGN** 91 | 92 | #### Defined in 93 | 94 | [common/consts.ts:18](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L18) 95 | 96 | ___ 97 | 98 | ### AUTO\_AND\_VEHICLES 99 | 100 | • **AUTO\_AND\_VEHICLES** 101 | 102 | #### Defined in 103 | 104 | [common/consts.ts:19](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L19) 105 | 106 | ___ 107 | 108 | ### BEAUTY 109 | 110 | • **BEAUTY** 111 | 112 | #### Defined in 113 | 114 | [common/consts.ts:20](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L20) 115 | 116 | ___ 117 | 118 | ### BOOKS\_AND\_REFERENCE 119 | 120 | • **BOOKS\_AND\_REFERENCE** 121 | 122 | #### Defined in 123 | 124 | [common/consts.ts:21](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L21) 125 | 126 | ___ 127 | 128 | ### BUSINESS 129 | 130 | • **BUSINESS** 131 | 132 | #### Defined in 133 | 134 | [common/consts.ts:22](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L22) 135 | 136 | ___ 137 | 138 | ### COMICS 139 | 140 | • **COMICS** 141 | 142 | #### Defined in 143 | 144 | [common/consts.ts:23](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L23) 145 | 146 | ___ 147 | 148 | ### COMMUNICATION 149 | 150 | • **COMMUNICATION** 151 | 152 | #### Defined in 153 | 154 | [common/consts.ts:24](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L24) 155 | 156 | ___ 157 | 158 | ### DATING 159 | 160 | • **DATING** 161 | 162 | #### Defined in 163 | 164 | [common/consts.ts:25](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L25) 165 | 166 | ___ 167 | 168 | ### EDUCATION 169 | 170 | • **EDUCATION** 171 | 172 | #### Defined in 173 | 174 | [common/consts.ts:26](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L26) 175 | 176 | ___ 177 | 178 | ### ENTERTAINMENT 179 | 180 | • **ENTERTAINMENT** 181 | 182 | #### Defined in 183 | 184 | [common/consts.ts:27](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L27) 185 | 186 | ___ 187 | 188 | ### EVENTS 189 | 190 | • **EVENTS** 191 | 192 | #### Defined in 193 | 194 | [common/consts.ts:28](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L28) 195 | 196 | ___ 197 | 198 | ### FAMILY 199 | 200 | • **FAMILY** 201 | 202 | #### Defined in 203 | 204 | [common/consts.ts:69](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L69) 205 | 206 | ___ 207 | 208 | ### FINANCE 209 | 210 | • **FINANCE** 211 | 212 | #### Defined in 213 | 214 | [common/consts.ts:29](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L29) 215 | 216 | ___ 217 | 218 | ### FOOD\_AND\_DRINK 219 | 220 | • **FOOD\_AND\_DRINK** 221 | 222 | #### Defined in 223 | 224 | [common/consts.ts:30](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L30) 225 | 226 | ___ 227 | 228 | ### GAME 229 | 230 | • **GAME** 231 | 232 | #### Defined in 233 | 234 | [common/consts.ts:17](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L17) 235 | 236 | ___ 237 | 238 | ### GAME\_ACTION 239 | 240 | • **GAME\_ACTION** 241 | 242 | #### Defined in 243 | 244 | [common/consts.ts:52](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L52) 245 | 246 | ___ 247 | 248 | ### GAME\_ADVENTURE 249 | 250 | • **GAME\_ADVENTURE** 251 | 252 | #### Defined in 253 | 254 | [common/consts.ts:53](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L53) 255 | 256 | ___ 257 | 258 | ### GAME\_ARCADE 259 | 260 | • **GAME\_ARCADE** 261 | 262 | #### Defined in 263 | 264 | [common/consts.ts:54](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L54) 265 | 266 | ___ 267 | 268 | ### GAME\_BOARD 269 | 270 | • **GAME\_BOARD** 271 | 272 | #### Defined in 273 | 274 | [common/consts.ts:55](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L55) 275 | 276 | ___ 277 | 278 | ### GAME\_CARD 279 | 280 | • **GAME\_CARD** 281 | 282 | #### Defined in 283 | 284 | [common/consts.ts:56](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L56) 285 | 286 | ___ 287 | 288 | ### GAME\_CASINO 289 | 290 | • **GAME\_CASINO** 291 | 292 | #### Defined in 293 | 294 | [common/consts.ts:57](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L57) 295 | 296 | ___ 297 | 298 | ### GAME\_CASUAL 299 | 300 | • **GAME\_CASUAL** 301 | 302 | #### Defined in 303 | 304 | [common/consts.ts:58](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L58) 305 | 306 | ___ 307 | 308 | ### GAME\_EDUCATIONAL 309 | 310 | • **GAME\_EDUCATIONAL** 311 | 312 | #### Defined in 313 | 314 | [common/consts.ts:59](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L59) 315 | 316 | ___ 317 | 318 | ### GAME\_MUSIC 319 | 320 | • **GAME\_MUSIC** 321 | 322 | #### Defined in 323 | 324 | [common/consts.ts:60](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L60) 325 | 326 | ___ 327 | 328 | ### GAME\_PUZZLE 329 | 330 | • **GAME\_PUZZLE** 331 | 332 | #### Defined in 333 | 334 | [common/consts.ts:61](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L61) 335 | 336 | ___ 337 | 338 | ### GAME\_RACING 339 | 340 | • **GAME\_RACING** 341 | 342 | #### Defined in 343 | 344 | [common/consts.ts:62](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L62) 345 | 346 | ___ 347 | 348 | ### GAME\_ROLE\_PLAYING 349 | 350 | • **GAME\_ROLE\_PLAYING** 351 | 352 | #### Defined in 353 | 354 | [common/consts.ts:63](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L63) 355 | 356 | ___ 357 | 358 | ### GAME\_SIMULATION 359 | 360 | • **GAME\_SIMULATION** 361 | 362 | #### Defined in 363 | 364 | [common/consts.ts:64](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L64) 365 | 366 | ___ 367 | 368 | ### GAME\_SPORTS 369 | 370 | • **GAME\_SPORTS** 371 | 372 | #### Defined in 373 | 374 | [common/consts.ts:65](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L65) 375 | 376 | ___ 377 | 378 | ### GAME\_STRATEGY 379 | 380 | • **GAME\_STRATEGY** 381 | 382 | #### Defined in 383 | 384 | [common/consts.ts:66](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L66) 385 | 386 | ___ 387 | 388 | ### GAME\_TRIVIA 389 | 390 | • **GAME\_TRIVIA** 391 | 392 | #### Defined in 393 | 394 | [common/consts.ts:67](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L67) 395 | 396 | ___ 397 | 398 | ### GAME\_WORD 399 | 400 | • **GAME\_WORD** 401 | 402 | #### Defined in 403 | 404 | [common/consts.ts:68](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L68) 405 | 406 | ___ 407 | 408 | ### HEALTH\_AND\_FITNESS 409 | 410 | • **HEALTH\_AND\_FITNESS** 411 | 412 | #### Defined in 413 | 414 | [common/consts.ts:31](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L31) 415 | 416 | ___ 417 | 418 | ### HOUSE\_AND\_HOME 419 | 420 | • **HOUSE\_AND\_HOME** 421 | 422 | #### Defined in 423 | 424 | [common/consts.ts:32](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L32) 425 | 426 | ___ 427 | 428 | ### LIBRARIES\_AND\_DEMO 429 | 430 | • **LIBRARIES\_AND\_DEMO** 431 | 432 | #### Defined in 433 | 434 | [common/consts.ts:33](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L33) 435 | 436 | ___ 437 | 438 | ### LIFESTYLE 439 | 440 | • **LIFESTYLE** 441 | 442 | #### Defined in 443 | 444 | [common/consts.ts:34](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L34) 445 | 446 | ___ 447 | 448 | ### MAPS\_AND\_NAVIGATION 449 | 450 | • **MAPS\_AND\_NAVIGATION** 451 | 452 | #### Defined in 453 | 454 | [common/consts.ts:35](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L35) 455 | 456 | ___ 457 | 458 | ### MEDICAL 459 | 460 | • **MEDICAL** 461 | 462 | #### Defined in 463 | 464 | [common/consts.ts:36](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L36) 465 | 466 | ___ 467 | 468 | ### MUSIC\_AND\_AUDIO 469 | 470 | • **MUSIC\_AND\_AUDIO** 471 | 472 | #### Defined in 473 | 474 | [common/consts.ts:37](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L37) 475 | 476 | ___ 477 | 478 | ### NEWS\_AND\_MAGAZINES 479 | 480 | • **NEWS\_AND\_MAGAZINES** 481 | 482 | #### Defined in 483 | 484 | [common/consts.ts:38](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L38) 485 | 486 | ___ 487 | 488 | ### PARENTING 489 | 490 | • **PARENTING** 491 | 492 | #### Defined in 493 | 494 | [common/consts.ts:39](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L39) 495 | 496 | ___ 497 | 498 | ### PERSONALIZATION 499 | 500 | • **PERSONALIZATION** 501 | 502 | #### Defined in 503 | 504 | [common/consts.ts:40](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L40) 505 | 506 | ___ 507 | 508 | ### PHOTOGRAPHY 509 | 510 | • **PHOTOGRAPHY** 511 | 512 | #### Defined in 513 | 514 | [common/consts.ts:41](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L41) 515 | 516 | ___ 517 | 518 | ### PRODUCTIVITY 519 | 520 | • **PRODUCTIVITY** 521 | 522 | #### Defined in 523 | 524 | [common/consts.ts:42](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L42) 525 | 526 | ___ 527 | 528 | ### SHOPPING 529 | 530 | • **SHOPPING** 531 | 532 | #### Defined in 533 | 534 | [common/consts.ts:43](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L43) 535 | 536 | ___ 537 | 538 | ### SOCIAL 539 | 540 | • **SOCIAL** 541 | 542 | #### Defined in 543 | 544 | [common/consts.ts:44](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L44) 545 | 546 | ___ 547 | 548 | ### SPORTS 549 | 550 | • **SPORTS** 551 | 552 | #### Defined in 553 | 554 | [common/consts.ts:45](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L45) 555 | 556 | ___ 557 | 558 | ### TOOLS 559 | 560 | • **TOOLS** 561 | 562 | #### Defined in 563 | 564 | [common/consts.ts:46](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L46) 565 | 566 | ___ 567 | 568 | ### TRAVEL\_AND\_LOCAL 569 | 570 | • **TRAVEL\_AND\_LOCAL** 571 | 572 | #### Defined in 573 | 574 | [common/consts.ts:47](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L47) 575 | 576 | ___ 577 | 578 | ### VIDEO\_PLAYERS 579 | 580 | • **VIDEO\_PLAYERS** 581 | 582 | #### Defined in 583 | 584 | [common/consts.ts:48](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L48) 585 | 586 | ___ 587 | 588 | ### WATCH\_FACE 589 | 590 | • **WATCH\_FACE** 591 | 592 | #### Defined in 593 | 594 | [common/consts.ts:50](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L50) 595 | 596 | ___ 597 | 598 | ### WEATHER 599 | 600 | • **WEATHER** 601 | 602 | #### Defined in 603 | 604 | [common/consts.ts:51](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L51) 605 | -------------------------------------------------------------------------------- /docs/enums/countries.md: -------------------------------------------------------------------------------- 1 | [parse-play - v3.1.0](../README.md) / countries 2 | 3 | # Enumeration: countries 4 | 5 | A country supported by the Play Store. 6 | 7 | ## Table of contents 8 | 9 | ### Enumeration Members 10 | 11 | - [AT](countries.md#at) 12 | - [AX](countries.md#ax) 13 | - [BE](countries.md#be) 14 | - [BG](countries.md#bg) 15 | - [BL](countries.md#bl) 16 | - [CY](countries.md#cy) 17 | - [CZ](countries.md#cz) 18 | - [DE](countries.md#de) 19 | - [DK](countries.md#dk) 20 | - [EE](countries.md#ee) 21 | - [ES](countries.md#es) 22 | - [FI](countries.md#fi) 23 | - [FO](countries.md#fo) 24 | - [FR](countries.md#fr) 25 | - [GB](countries.md#gb) 26 | - [GF](countries.md#gf) 27 | - [GI](countries.md#gi) 28 | - [GL](countries.md#gl) 29 | - [GP](countries.md#gp) 30 | - [GR](countries.md#gr) 31 | - [HR](countries.md#hr) 32 | - [HU](countries.md#hu) 33 | - [IE](countries.md#ie) 34 | - [IS](countries.md#is) 35 | - [IT](countries.md#it) 36 | - [LI](countries.md#li) 37 | - [LT](countries.md#lt) 38 | - [LU](countries.md#lu) 39 | - [LV](countries.md#lv) 40 | - [MC](countries.md#mc) 41 | - [MF](countries.md#mf) 42 | - [MQ](countries.md#mq) 43 | - [MT](countries.md#mt) 44 | - [NC](countries.md#nc) 45 | - [NL](countries.md#nl) 46 | - [NO](countries.md#no) 47 | - [PF](countries.md#pf) 48 | - [PL](countries.md#pl) 49 | - [PM](countries.md#pm) 50 | - [PT](countries.md#pt) 51 | - [RE](countries.md#re) 52 | - [RO](countries.md#ro) 53 | - [SE](countries.md#se) 54 | - [SI](countries.md#si) 55 | - [SJ](countries.md#sj) 56 | - [SK](countries.md#sk) 57 | - [SM](countries.md#sm) 58 | - [VA](countries.md#va) 59 | - [WF](countries.md#wf) 60 | - [YT](countries.md#yt) 61 | 62 | ## Enumeration Members 63 | 64 | ### AT 65 | 66 | • **AT** 67 | 68 | #### Defined in 69 | 70 | [common/consts.ts:87](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L87) 71 | 72 | ___ 73 | 74 | ### AX 75 | 76 | • **AX** 77 | 78 | #### Defined in 79 | 80 | [common/consts.ts:86](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L86) 81 | 82 | ___ 83 | 84 | ### BE 85 | 86 | • **BE** 87 | 88 | #### Defined in 89 | 90 | [common/consts.ts:88](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L88) 91 | 92 | ___ 93 | 94 | ### BG 95 | 96 | • **BG** 97 | 98 | #### Defined in 99 | 100 | [common/consts.ts:89](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L89) 101 | 102 | ___ 103 | 104 | ### BL 105 | 106 | • **BL** 107 | 108 | #### Defined in 109 | 110 | [common/consts.ts:128](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L128) 111 | 112 | ___ 113 | 114 | ### CY 115 | 116 | • **CY** 117 | 118 | #### Defined in 119 | 120 | [common/consts.ts:91](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L91) 121 | 122 | ___ 123 | 124 | ### CZ 125 | 126 | • **CZ** 127 | 128 | #### Defined in 129 | 130 | [common/consts.ts:92](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L92) 131 | 132 | ___ 133 | 134 | ### DE 135 | 136 | • **DE** 137 | 138 | #### Defined in 139 | 140 | [common/consts.ts:100](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L100) 141 | 142 | ___ 143 | 144 | ### DK 145 | 146 | • **DK** 147 | 148 | #### Defined in 149 | 150 | [common/consts.ts:93](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L93) 151 | 152 | ___ 153 | 154 | ### EE 155 | 156 | • **EE** 157 | 158 | #### Defined in 159 | 160 | [common/consts.ts:94](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L94) 161 | 162 | ___ 163 | 164 | ### ES 165 | 166 | • **ES** 167 | 168 | #### Defined in 169 | 170 | [common/consts.ts:127](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L127) 171 | 172 | ___ 173 | 174 | ### FI 175 | 176 | • **FI** 177 | 178 | #### Defined in 179 | 180 | [common/consts.ts:96](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L96) 181 | 182 | ___ 183 | 184 | ### FO 185 | 186 | • **FO** 187 | 188 | #### Defined in 189 | 190 | [common/consts.ts:95](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L95) 191 | 192 | ___ 193 | 194 | ### FR 195 | 196 | • **FR** 197 | 198 | #### Defined in 199 | 200 | [common/consts.ts:97](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L97) 201 | 202 | ___ 203 | 204 | ### GB 205 | 206 | • **GB** 207 | 208 | #### Defined in 209 | 210 | [common/consts.ts:133](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L133) 211 | 212 | ___ 213 | 214 | ### GF 215 | 216 | • **GF** 217 | 218 | #### Defined in 219 | 220 | [common/consts.ts:98](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L98) 221 | 222 | ___ 223 | 224 | ### GI 225 | 226 | • **GI** 227 | 228 | #### Defined in 229 | 230 | [common/consts.ts:101](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L101) 231 | 232 | ___ 233 | 234 | ### GL 235 | 236 | • **GL** 237 | 238 | #### Defined in 239 | 240 | [common/consts.ts:103](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L103) 241 | 242 | ___ 243 | 244 | ### GP 245 | 246 | • **GP** 247 | 248 | #### Defined in 249 | 250 | [common/consts.ts:104](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L104) 251 | 252 | ___ 253 | 254 | ### GR 255 | 256 | • **GR** 257 | 258 | #### Defined in 259 | 260 | [common/consts.ts:102](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L102) 261 | 262 | ___ 263 | 264 | ### HR 265 | 266 | • **HR** 267 | 268 | #### Defined in 269 | 270 | [common/consts.ts:90](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L90) 271 | 272 | ___ 273 | 274 | ### HU 275 | 276 | • **HU** 277 | 278 | #### Defined in 279 | 280 | [common/consts.ts:105](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L105) 281 | 282 | ___ 283 | 284 | ### IE 285 | 286 | • **IE** 287 | 288 | #### Defined in 289 | 290 | [common/consts.ts:107](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L107) 291 | 292 | ___ 293 | 294 | ### IS 295 | 296 | • **IS** 297 | 298 | #### Defined in 299 | 300 | [common/consts.ts:106](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L106) 301 | 302 | ___ 303 | 304 | ### IT 305 | 306 | • **IT** 307 | 308 | #### Defined in 309 | 310 | [common/consts.ts:108](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L108) 311 | 312 | ___ 313 | 314 | ### LI 315 | 316 | • **LI** 317 | 318 | #### Defined in 319 | 320 | [common/consts.ts:110](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L110) 321 | 322 | ___ 323 | 324 | ### LT 325 | 326 | • **LT** 327 | 328 | #### Defined in 329 | 330 | [common/consts.ts:111](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L111) 331 | 332 | ___ 333 | 334 | ### LU 335 | 336 | • **LU** 337 | 338 | #### Defined in 339 | 340 | [common/consts.ts:112](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L112) 341 | 342 | ___ 343 | 344 | ### LV 345 | 346 | • **LV** 347 | 348 | #### Defined in 349 | 350 | [common/consts.ts:109](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L109) 351 | 352 | ___ 353 | 354 | ### MC 355 | 356 | • **MC** 357 | 358 | #### Defined in 359 | 360 | [common/consts.ts:116](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L116) 361 | 362 | ___ 363 | 364 | ### MF 365 | 366 | • **MF** 367 | 368 | #### Defined in 369 | 370 | [common/consts.ts:129](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L129) 371 | 372 | ___ 373 | 374 | ### MQ 375 | 376 | • **MQ** 377 | 378 | #### Defined in 379 | 380 | [common/consts.ts:114](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L114) 381 | 382 | ___ 383 | 384 | ### MT 385 | 386 | • **MT** 387 | 388 | #### Defined in 389 | 390 | [common/consts.ts:113](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L113) 391 | 392 | ___ 393 | 394 | ### NC 395 | 396 | • **NC** 397 | 398 | #### Defined in 399 | 400 | [common/consts.ts:118](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L118) 401 | 402 | ___ 403 | 404 | ### NL 405 | 406 | • **NL** 407 | 408 | #### Defined in 409 | 410 | [common/consts.ts:117](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L117) 411 | 412 | ___ 413 | 414 | ### NO 415 | 416 | • **NO** 417 | 418 | #### Defined in 419 | 420 | [common/consts.ts:119](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L119) 421 | 422 | ___ 423 | 424 | ### PF 425 | 426 | • **PF** 427 | 428 | #### Defined in 429 | 430 | [common/consts.ts:99](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L99) 431 | 432 | ___ 433 | 434 | ### PL 435 | 436 | • **PL** 437 | 438 | #### Defined in 439 | 440 | [common/consts.ts:120](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L120) 441 | 442 | ___ 443 | 444 | ### PM 445 | 446 | • **PM** 447 | 448 | #### Defined in 449 | 450 | [common/consts.ts:130](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L130) 451 | 452 | ___ 453 | 454 | ### PT 455 | 456 | • **PT** 457 | 458 | #### Defined in 459 | 460 | [common/consts.ts:121](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L121) 461 | 462 | ___ 463 | 464 | ### RE 465 | 466 | • **RE** 467 | 468 | #### Defined in 469 | 470 | [common/consts.ts:122](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L122) 471 | 472 | ___ 473 | 474 | ### RO 475 | 476 | • **RO** 477 | 478 | #### Defined in 479 | 480 | [common/consts.ts:123](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L123) 481 | 482 | ___ 483 | 484 | ### SE 485 | 486 | • **SE** 487 | 488 | #### Defined in 489 | 490 | [common/consts.ts:132](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L132) 491 | 492 | ___ 493 | 494 | ### SI 495 | 496 | • **SI** 497 | 498 | #### Defined in 499 | 500 | [common/consts.ts:126](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L126) 501 | 502 | ___ 503 | 504 | ### SJ 505 | 506 | • **SJ** 507 | 508 | #### Defined in 509 | 510 | [common/consts.ts:131](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L131) 511 | 512 | ___ 513 | 514 | ### SK 515 | 516 | • **SK** 517 | 518 | #### Defined in 519 | 520 | [common/consts.ts:125](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L125) 521 | 522 | ___ 523 | 524 | ### SM 525 | 526 | • **SM** 527 | 528 | #### Defined in 529 | 530 | [common/consts.ts:124](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L124) 531 | 532 | ___ 533 | 534 | ### VA 535 | 536 | • **VA** 537 | 538 | #### Defined in 539 | 540 | [common/consts.ts:134](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L134) 541 | 542 | ___ 543 | 544 | ### WF 545 | 546 | • **WF** 547 | 548 | #### Defined in 549 | 550 | [common/consts.ts:135](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L135) 551 | 552 | ___ 553 | 554 | ### YT 555 | 556 | • **YT** 557 | 558 | #### Defined in 559 | 560 | [common/consts.ts:115](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L115) 561 | -------------------------------------------------------------------------------- /docs/enums/languages.md: -------------------------------------------------------------------------------- 1 | [parse-play - v3.1.0](../README.md) / languages 2 | 3 | # Enumeration: languages 4 | 5 | A language supported by the Play Store. 6 | 7 | ## Table of contents 8 | 9 | ### Enumeration Members 10 | 11 | - [AF](languages.md#af) 12 | - [AR](languages.md#ar) 13 | - [AZ](languages.md#az) 14 | - [BE](languages.md#be) 15 | - [BG](languages.md#bg) 16 | - [BH](languages.md#bh) 17 | - [BN](languages.md#bn) 18 | - [BS](languages.md#bs) 19 | - [CA](languages.md#ca) 20 | - [CS](languages.md#cs) 21 | - [CY](languages.md#cy) 22 | - [DA](languages.md#da) 23 | - [DE](languages.md#de) 24 | - [EL](languages.md#el) 25 | - [EN](languages.md#en) 26 | - [EO](languages.md#eo) 27 | - [ES](languages.md#es) 28 | - [ET](languages.md#et) 29 | - [EU](languages.md#eu) 30 | - [FA](languages.md#fa) 31 | - [FI](languages.md#fi) 32 | - [FO](languages.md#fo) 33 | - [FR](languages.md#fr) 34 | - [FY](languages.md#fy) 35 | - [GA](languages.md#ga) 36 | - [GD](languages.md#gd) 37 | - [GL](languages.md#gl) 38 | - [GU](languages.md#gu) 39 | - [HI](languages.md#hi) 40 | - [HR](languages.md#hr) 41 | - [HU](languages.md#hu) 42 | - [IA](languages.md#ia) 43 | - [ID](languages.md#id) 44 | - [IS](languages.md#is) 45 | - [IT](languages.md#it) 46 | - [IW](languages.md#iw) 47 | - [JA](languages.md#ja) 48 | - [JW](languages.md#jw) 49 | - [KA](languages.md#ka) 50 | - [KN](languages.md#kn) 51 | - [KO](languages.md#ko) 52 | - [LA](languages.md#la) 53 | - [LT](languages.md#lt) 54 | - [LV](languages.md#lv) 55 | - [MK](languages.md#mk) 56 | - [ML](languages.md#ml) 57 | - [MR](languages.md#mr) 58 | - [MS](languages.md#ms) 59 | - [MT](languages.md#mt) 60 | - [NE](languages.md#ne) 61 | - [NL](languages.md#nl) 62 | - [NN](languages.md#nn) 63 | - [NO](languages.md#no) 64 | - [OC](languages.md#oc) 65 | - [PA](languages.md#pa) 66 | - [PL](languages.md#pl) 67 | - [PT-BR](languages.md#pt-br) 68 | - [PT-PT](languages.md#pt-pt) 69 | - [RO](languages.md#ro) 70 | - [RU](languages.md#ru) 71 | - [SI](languages.md#si) 72 | - [SK](languages.md#sk) 73 | - [SL](languages.md#sl) 74 | - [SM](languages.md#sm) 75 | - [SQ](languages.md#sq) 76 | - [SR](languages.md#sr) 77 | - [SU](languages.md#su) 78 | - [SV](languages.md#sv) 79 | - [SW](languages.md#sw) 80 | - [TA](languages.md#ta) 81 | - [TE](languages.md#te) 82 | - [TH](languages.md#th) 83 | - [TI](languages.md#ti) 84 | - [TL](languages.md#tl) 85 | - [TR](languages.md#tr) 86 | - [UK](languages.md#uk) 87 | - [UR](languages.md#ur) 88 | - [UZ](languages.md#uz) 89 | - [VI](languages.md#vi) 90 | - [XH](languages.md#xh) 91 | - [ZH-CN](languages.md#zh-cn) 92 | - [ZH-TW](languages.md#zh-tw) 93 | - [ZU](languages.md#zu) 94 | 95 | ## Enumeration Members 96 | 97 | ### AF 98 | 99 | • **AF** 100 | 101 | #### Defined in 102 | 103 | [common/consts.ts:153](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L153) 104 | 105 | ___ 106 | 107 | ### AR 108 | 109 | • **AR** 110 | 111 | #### Defined in 112 | 113 | [common/consts.ts:156](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L156) 114 | 115 | ___ 116 | 117 | ### AZ 118 | 119 | • **AZ** 120 | 121 | #### Defined in 122 | 123 | [common/consts.ts:157](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L157) 124 | 125 | ___ 126 | 127 | ### BE 128 | 129 | • **BE** 130 | 131 | #### Defined in 132 | 133 | [common/consts.ts:159](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L159) 134 | 135 | ___ 136 | 137 | ### BG 138 | 139 | • **BG** 140 | 141 | #### Defined in 142 | 143 | [common/consts.ts:163](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L163) 144 | 145 | ___ 146 | 147 | ### BH 148 | 149 | • **BH** 150 | 151 | #### Defined in 152 | 153 | [common/consts.ts:161](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L161) 154 | 155 | ___ 156 | 157 | ### BN 158 | 159 | • **BN** 160 | 161 | #### Defined in 162 | 163 | [common/consts.ts:160](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L160) 164 | 165 | ___ 166 | 167 | ### BS 168 | 169 | • **BS** 170 | 171 | #### Defined in 172 | 173 | [common/consts.ts:162](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L162) 174 | 175 | ___ 176 | 177 | ### CA 178 | 179 | • **CA** 180 | 181 | #### Defined in 182 | 183 | [common/consts.ts:164](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L164) 184 | 185 | ___ 186 | 187 | ### CS 188 | 189 | • **CS** 190 | 191 | #### Defined in 192 | 193 | [common/consts.ts:168](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L168) 194 | 195 | ___ 196 | 197 | ### CY 198 | 199 | • **CY** 200 | 201 | #### Defined in 202 | 203 | [common/consts.ts:233](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L233) 204 | 205 | ___ 206 | 207 | ### DA 208 | 209 | • **DA** 210 | 211 | #### Defined in 212 | 213 | [common/consts.ts:169](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L169) 214 | 215 | ___ 216 | 217 | ### DE 218 | 219 | • **DE** 220 | 221 | #### Defined in 222 | 223 | [common/consts.ts:180](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L180) 224 | 225 | ___ 226 | 227 | ### EL 228 | 229 | • **EL** 230 | 231 | #### Defined in 232 | 233 | [common/consts.ts:181](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L181) 234 | 235 | ___ 236 | 237 | ### EN 238 | 239 | • **EN** 240 | 241 | #### Defined in 242 | 243 | [common/consts.ts:171](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L171) 244 | 245 | ___ 246 | 247 | ### EO 248 | 249 | • **EO** 250 | 251 | #### Defined in 252 | 253 | [common/consts.ts:172](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L172) 254 | 255 | ___ 256 | 257 | ### ES 258 | 259 | • **ES** 260 | 261 | #### Defined in 262 | 263 | [common/consts.ts:219](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L219) 264 | 265 | ___ 266 | 267 | ### ET 268 | 269 | • **ET** 270 | 271 | #### Defined in 272 | 273 | [common/consts.ts:173](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L173) 274 | 275 | ___ 276 | 277 | ### EU 278 | 279 | • **EU** 280 | 281 | #### Defined in 282 | 283 | [common/consts.ts:158](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L158) 284 | 285 | ___ 286 | 287 | ### FA 288 | 289 | • **FA** 290 | 291 | #### Defined in 292 | 293 | [common/consts.ts:207](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L207) 294 | 295 | ___ 296 | 297 | ### FI 298 | 299 | • **FI** 300 | 301 | #### Defined in 302 | 303 | [common/consts.ts:175](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L175) 304 | 305 | ___ 306 | 307 | ### FO 308 | 309 | • **FO** 310 | 311 | #### Defined in 312 | 313 | [common/consts.ts:174](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L174) 314 | 315 | ___ 316 | 317 | ### FR 318 | 319 | • **FR** 320 | 321 | #### Defined in 322 | 323 | [common/consts.ts:176](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L176) 324 | 325 | ___ 326 | 327 | ### FY 328 | 329 | • **FY** 330 | 331 | #### Defined in 332 | 333 | [common/consts.ts:177](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L177) 334 | 335 | ___ 336 | 337 | ### GA 338 | 339 | • **GA** 340 | 341 | #### Defined in 342 | 343 | [common/consts.ts:189](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L189) 344 | 345 | ___ 346 | 347 | ### GD 348 | 349 | • **GD** 350 | 351 | #### Defined in 352 | 353 | [common/consts.ts:214](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L214) 354 | 355 | ___ 356 | 357 | ### GL 358 | 359 | • **GL** 360 | 361 | #### Defined in 362 | 363 | [common/consts.ts:178](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L178) 364 | 365 | ___ 366 | 367 | ### GU 368 | 369 | • **GU** 370 | 371 | #### Defined in 372 | 373 | [common/consts.ts:182](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L182) 374 | 375 | ___ 376 | 377 | ### HI 378 | 379 | • **HI** 380 | 381 | #### Defined in 382 | 383 | [common/consts.ts:184](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L184) 384 | 385 | ___ 386 | 387 | ### HR 388 | 389 | • **HR** 390 | 391 | #### Defined in 392 | 393 | [common/consts.ts:167](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L167) 394 | 395 | ___ 396 | 397 | ### HU 398 | 399 | • **HU** 400 | 401 | #### Defined in 402 | 403 | [common/consts.ts:185](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L185) 404 | 405 | ___ 406 | 407 | ### IA 408 | 409 | • **IA** 410 | 411 | #### Defined in 412 | 413 | [common/consts.ts:188](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L188) 414 | 415 | ___ 416 | 417 | ### ID 418 | 419 | • **ID** 420 | 421 | #### Defined in 422 | 423 | [common/consts.ts:187](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L187) 424 | 425 | ___ 426 | 427 | ### IS 428 | 429 | • **IS** 430 | 431 | #### Defined in 432 | 433 | [common/consts.ts:186](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L186) 434 | 435 | ___ 436 | 437 | ### IT 438 | 439 | • **IT** 440 | 441 | #### Defined in 442 | 443 | [common/consts.ts:190](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L190) 444 | 445 | ___ 446 | 447 | ### IW 448 | 449 | • **IW** 450 | 451 | #### Defined in 452 | 453 | [common/consts.ts:183](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L183) 454 | 455 | ___ 456 | 457 | ### JA 458 | 459 | • **JA** 460 | 461 | #### Defined in 462 | 463 | [common/consts.ts:191](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L191) 464 | 465 | ___ 466 | 467 | ### JW 468 | 469 | • **JW** 470 | 471 | #### Defined in 472 | 473 | [common/consts.ts:192](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L192) 474 | 475 | ___ 476 | 477 | ### KA 478 | 479 | • **KA** 480 | 481 | #### Defined in 482 | 483 | [common/consts.ts:179](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L179) 484 | 485 | ___ 486 | 487 | ### KN 488 | 489 | • **KN** 490 | 491 | #### Defined in 492 | 493 | [common/consts.ts:193](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L193) 494 | 495 | ___ 496 | 497 | ### KO 498 | 499 | • **KO** 500 | 501 | #### Defined in 502 | 503 | [common/consts.ts:194](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L194) 504 | 505 | ___ 506 | 507 | ### LA 508 | 509 | • **LA** 510 | 511 | #### Defined in 512 | 513 | [common/consts.ts:195](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L195) 514 | 515 | ___ 516 | 517 | ### LT 518 | 519 | • **LT** 520 | 521 | #### Defined in 522 | 523 | [common/consts.ts:197](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L197) 524 | 525 | ___ 526 | 527 | ### LV 528 | 529 | • **LV** 530 | 531 | #### Defined in 532 | 533 | [common/consts.ts:196](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L196) 534 | 535 | ___ 536 | 537 | ### MK 538 | 539 | • **MK** 540 | 541 | #### Defined in 542 | 543 | [common/consts.ts:198](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L198) 544 | 545 | ___ 546 | 547 | ### ML 548 | 549 | • **ML** 550 | 551 | #### Defined in 552 | 553 | [common/consts.ts:200](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L200) 554 | 555 | ___ 556 | 557 | ### MR 558 | 559 | • **MR** 560 | 561 | #### Defined in 562 | 563 | [common/consts.ts:202](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L202) 564 | 565 | ___ 566 | 567 | ### MS 568 | 569 | • **MS** 570 | 571 | #### Defined in 572 | 573 | [common/consts.ts:199](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L199) 574 | 575 | ___ 576 | 577 | ### MT 578 | 579 | • **MT** 580 | 581 | #### Defined in 582 | 583 | [common/consts.ts:201](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L201) 584 | 585 | ___ 586 | 587 | ### NE 588 | 589 | • **NE** 590 | 591 | #### Defined in 592 | 593 | [common/consts.ts:203](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L203) 594 | 595 | ___ 596 | 597 | ### NL 598 | 599 | • **NL** 600 | 601 | #### Defined in 602 | 603 | [common/consts.ts:170](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L170) 604 | 605 | ___ 606 | 607 | ### NN 608 | 609 | • **NN** 610 | 611 | #### Defined in 612 | 613 | [common/consts.ts:205](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L205) 614 | 615 | ___ 616 | 617 | ### NO 618 | 619 | • **NO** 620 | 621 | #### Defined in 622 | 623 | [common/consts.ts:204](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L204) 624 | 625 | ___ 626 | 627 | ### OC 628 | 629 | • **OC** 630 | 631 | #### Defined in 632 | 633 | [common/consts.ts:206](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L206) 634 | 635 | ___ 636 | 637 | ### PA 638 | 639 | • **PA** 640 | 641 | #### Defined in 642 | 643 | [common/consts.ts:211](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L211) 644 | 645 | ___ 646 | 647 | ### PL 648 | 649 | • **PL** 650 | 651 | #### Defined in 652 | 653 | [common/consts.ts:208](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L208) 654 | 655 | ___ 656 | 657 | ### PT-BR 658 | 659 | • **PT-BR** 660 | 661 | #### Defined in 662 | 663 | [common/consts.ts:209](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L209) 664 | 665 | ___ 666 | 667 | ### PT-PT 668 | 669 | • **PT-PT** 670 | 671 | #### Defined in 672 | 673 | [common/consts.ts:210](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L210) 674 | 675 | ___ 676 | 677 | ### RO 678 | 679 | • **RO** 680 | 681 | #### Defined in 682 | 683 | [common/consts.ts:212](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L212) 684 | 685 | ___ 686 | 687 | ### RU 688 | 689 | • **RU** 690 | 691 | #### Defined in 692 | 693 | [common/consts.ts:213](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L213) 694 | 695 | ___ 696 | 697 | ### SI 698 | 699 | • **SI** 700 | 701 | #### Defined in 702 | 703 | [common/consts.ts:216](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L216) 704 | 705 | ___ 706 | 707 | ### SK 708 | 709 | • **SK** 710 | 711 | #### Defined in 712 | 713 | [common/consts.ts:217](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L217) 714 | 715 | ___ 716 | 717 | ### SL 718 | 719 | • **SL** 720 | 721 | #### Defined in 722 | 723 | [common/consts.ts:218](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L218) 724 | 725 | ___ 726 | 727 | ### SM 728 | 729 | • **SM** 730 | 731 | #### Defined in 732 | 733 | [common/consts.ts:155](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L155) 734 | 735 | ___ 736 | 737 | ### SQ 738 | 739 | • **SQ** 740 | 741 | #### Defined in 742 | 743 | [common/consts.ts:154](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L154) 744 | 745 | ___ 746 | 747 | ### SR 748 | 749 | • **SR** 750 | 751 | #### Defined in 752 | 753 | [common/consts.ts:215](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L215) 754 | 755 | ___ 756 | 757 | ### SU 758 | 759 | • **SU** 760 | 761 | #### Defined in 762 | 763 | [common/consts.ts:220](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L220) 764 | 765 | ___ 766 | 767 | ### SV 768 | 769 | • **SV** 770 | 771 | #### Defined in 772 | 773 | [common/consts.ts:222](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L222) 774 | 775 | ___ 776 | 777 | ### SW 778 | 779 | • **SW** 780 | 781 | #### Defined in 782 | 783 | [common/consts.ts:221](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L221) 784 | 785 | ___ 786 | 787 | ### TA 788 | 789 | • **TA** 790 | 791 | #### Defined in 792 | 793 | [common/consts.ts:224](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L224) 794 | 795 | ___ 796 | 797 | ### TE 798 | 799 | • **TE** 800 | 801 | #### Defined in 802 | 803 | [common/consts.ts:225](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L225) 804 | 805 | ___ 806 | 807 | ### TH 808 | 809 | • **TH** 810 | 811 | #### Defined in 812 | 813 | [common/consts.ts:226](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L226) 814 | 815 | ___ 816 | 817 | ### TI 818 | 819 | • **TI** 820 | 821 | #### Defined in 822 | 823 | [common/consts.ts:227](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L227) 824 | 825 | ___ 826 | 827 | ### TL 828 | 829 | • **TL** 830 | 831 | #### Defined in 832 | 833 | [common/consts.ts:223](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L223) 834 | 835 | ___ 836 | 837 | ### TR 838 | 839 | • **TR** 840 | 841 | #### Defined in 842 | 843 | [common/consts.ts:228](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L228) 844 | 845 | ___ 846 | 847 | ### UK 848 | 849 | • **UK** 850 | 851 | #### Defined in 852 | 853 | [common/consts.ts:229](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L229) 854 | 855 | ___ 856 | 857 | ### UR 858 | 859 | • **UR** 860 | 861 | #### Defined in 862 | 863 | [common/consts.ts:230](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L230) 864 | 865 | ___ 866 | 867 | ### UZ 868 | 869 | • **UZ** 870 | 871 | #### Defined in 872 | 873 | [common/consts.ts:231](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L231) 874 | 875 | ___ 876 | 877 | ### VI 878 | 879 | • **VI** 880 | 881 | #### Defined in 882 | 883 | [common/consts.ts:232](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L232) 884 | 885 | ___ 886 | 887 | ### XH 888 | 889 | • **XH** 890 | 891 | #### Defined in 892 | 893 | [common/consts.ts:234](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L234) 894 | 895 | ___ 896 | 897 | ### ZH-CN 898 | 899 | • **ZH-CN** 900 | 901 | #### Defined in 902 | 903 | [common/consts.ts:165](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L165) 904 | 905 | ___ 906 | 907 | ### ZH-TW 908 | 909 | • **ZH-TW** 910 | 911 | #### Defined in 912 | 913 | [common/consts.ts:166](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L166) 914 | 915 | ___ 916 | 917 | ### ZU 918 | 919 | • **ZU** 920 | 921 | #### Defined in 922 | 923 | [common/consts.ts:235](https://github.com/baltpeter/parse-play/blob/main/src/common/consts.ts#L235) 924 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parse-play", 3 | "description": "Library for fetching and parsing select data on Android apps from the Google Play Store via undocumented internal APIs.", 4 | "version": "3.1.0", 5 | "type": "module", 6 | "source": "src/index.ts", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "author": "Benjamin Altpeter ", 10 | "license": "MIT", 11 | "scripts": { 12 | "prepack": "rm -rf dist && yarn build && yarn typedoc", 13 | "build": "parcel build", 14 | "watch": "parcel watch", 15 | "test": "echo 'TODO: No test specified yet.'" 16 | }, 17 | "devDependencies": { 18 | "@parcel/packager-ts": "2.6.0", 19 | "@parcel/transformer-typescript-types": "2.6.0", 20 | "@types/assert": "^1.5.6", 21 | "@typescript-eslint/eslint-plugin": "^5.28.0", 22 | "@typescript-eslint/parser": "^5.28.0", 23 | "eslint": "^8.17.0", 24 | "eslint-config-prettier": "^8.5.0", 25 | "eslint-plugin-eslint-comments": "^3.2.0", 26 | "eslint-plugin-import": "^2.26.0", 27 | "husky": "4.3.7", 28 | "lint-staged": "^13.0.1", 29 | "parcel": "^2.6.0", 30 | "prettier": "^2.7.0", 31 | "typedoc": "^0.22.17", 32 | "typedoc-plugin-markdown": "^3.12.1", 33 | "typescript": "^4.7.3" 34 | }, 35 | "dependencies": { 36 | "assert": "^2.0.0", 37 | "cross-fetch": "^3.1.5" 38 | }, 39 | "files": [ 40 | "/dist" 41 | ], 42 | "husky": { 43 | "hooks": { 44 | "pre-commit": "lint-staged && tsc && typedoc && git add docs" 45 | } 46 | }, 47 | "lint-staged": { 48 | "*.{ts,js,scss,json}": [ 49 | "prettier --write" 50 | ], 51 | "*.{ts,js}": [ 52 | "eslint --fix" 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/common/assert.ts: -------------------------------------------------------------------------------- 1 | import { strict as strictAssert } from 'assert'; 2 | 3 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 4 | // @ts-ignore 5 | const actuallyAssert = !!process?.env?.ASSERT; 6 | 7 | export type AssertionFunction = (value: () => unknown, message?: string | Error) => asserts value; 8 | export const assert: AssertionFunction = actuallyAssert 9 | ? (value, message) => strictAssert(value(), message) 10 | : // eslint-disable-next-line @typescript-eslint/no-empty-function 11 | () => {}; 12 | -------------------------------------------------------------------------------- /src/common/consts.ts: -------------------------------------------------------------------------------- 1 | // +++++++++++++++ 2 | // +++ General +++ 3 | // +++++++++++++++ 4 | 5 | // The old web UI had a dropdown that listed these categories. That doesn't appear to be the case anymore… 6 | // To generate, run the following in the browser console on 7 | // : 8 | // Array.from(document.querySelectorAll('#action-dropdown-children-Categories .TEOqAc a')).reduce((acc, cur) => 9 | // ({...acc, [cur.href.match(/\/([^\/]+?)$/)[1]]: cur.innerText}), {}) 10 | /** 11 | * A category on the Play Store. 12 | * 13 | * @enum 14 | */ 15 | export const categories = { 16 | APPLICATION: 'Applications', 17 | GAME: 'Games', 18 | ART_AND_DESIGN: 'Art & Design', 19 | AUTO_AND_VEHICLES: 'Auto & Vehicles', 20 | BEAUTY: 'Beauty', 21 | BOOKS_AND_REFERENCE: 'Books & Reference', 22 | BUSINESS: 'Business', 23 | COMICS: 'Comics', 24 | COMMUNICATION: 'Communication', 25 | DATING: 'Dating', 26 | EDUCATION: 'Education', 27 | ENTERTAINMENT: 'Entertainment', 28 | EVENTS: 'Events', 29 | FINANCE: 'Finance', 30 | FOOD_AND_DRINK: 'Food & Drink', 31 | HEALTH_AND_FITNESS: 'Health & Fitness', 32 | HOUSE_AND_HOME: 'House & Home', 33 | LIBRARIES_AND_DEMO: 'Libraries & Demo', 34 | LIFESTYLE: 'Lifestyle', 35 | MAPS_AND_NAVIGATION: 'Maps & Navigation', 36 | MEDICAL: 'Medical', 37 | MUSIC_AND_AUDIO: 'Music & Audio', 38 | NEWS_AND_MAGAZINES: 'News & Magazines', 39 | PARENTING: 'Parenting', 40 | PERSONALIZATION: 'Personalization', 41 | PHOTOGRAPHY: 'Photography', 42 | PRODUCTIVITY: 'Productivity', 43 | SHOPPING: 'Shopping', 44 | SOCIAL: 'Social', 45 | SPORTS: 'Sports', 46 | TOOLS: 'Tools', 47 | TRAVEL_AND_LOCAL: 'Travel & Local', 48 | VIDEO_PLAYERS: 'Video Players & Editors', 49 | ANDROID_WEAR: 'Watch apps', 50 | WATCH_FACE: 'Watch faces', 51 | WEATHER: 'Weather', 52 | GAME_ACTION: 'Action', 53 | GAME_ADVENTURE: 'Adventure', 54 | GAME_ARCADE: 'Arcade', 55 | GAME_BOARD: 'Board', 56 | GAME_CARD: 'Card', 57 | GAME_CASINO: 'Casino', 58 | GAME_CASUAL: 'Casual', 59 | GAME_EDUCATIONAL: 'Educational', 60 | GAME_MUSIC: 'Music', 61 | GAME_PUZZLE: 'Puzzle', 62 | GAME_RACING: 'Racing', 63 | GAME_ROLE_PLAYING: 'Role Playing', 64 | GAME_SIMULATION: 'Simulation', 65 | GAME_SPORTS: 'Sports', 66 | GAME_STRATEGY: 'Strategy', 67 | GAME_TRIVIA: 'Trivia', 68 | GAME_WORD: 'Word', 69 | FAMILY: 'Kids', 70 | } as const; 71 | /** 72 | * The ID of a category on the Play Store. 73 | */ 74 | export type CategoryId = keyof typeof categories; 75 | 76 | // To generate, go to , open the country modal from the footer, and then run the 77 | // following in the browser console: 78 | // Array.from(document.querySelectorAll('ul.P2Hi5d.DMZ54e.bwNLcf li.xoKNSc')).reduce((acc, cur) => ({...acc, 79 | // [cur.dataset.gl]: cur.innerText}), {}) 80 | /** 81 | * A country supported by the Play Store. 82 | * 83 | * @enum 84 | */ 85 | export const countries = { 86 | AX: 'Åland Islands', 87 | AT: 'Austria', 88 | BE: 'Belgium', 89 | BG: 'Bulgaria', 90 | HR: 'Croatia', 91 | CY: 'Cyprus', 92 | CZ: 'Czechia', 93 | DK: 'Denmark', 94 | EE: 'Estonia', 95 | FO: 'Faroe Islands', 96 | FI: 'Finland', 97 | FR: 'France', 98 | GF: 'French Guiana', 99 | PF: 'French Polynesia', 100 | DE: 'Germany', 101 | GI: 'Gibraltar', 102 | GR: 'Greece', 103 | GL: 'Greenland', 104 | GP: 'Guadeloupe', 105 | HU: 'Hungary', 106 | IS: 'Iceland', 107 | IE: 'Ireland', 108 | IT: 'Italy', 109 | LV: 'Latvia', 110 | LI: 'Liechtenstein', 111 | LT: 'Lithuania', 112 | LU: 'Luxembourg', 113 | MT: 'Malta', 114 | MQ: 'Martinique', 115 | YT: 'Mayotte', 116 | MC: 'Monaco', 117 | NL: 'Netherlands', 118 | NC: 'New Caledonia', 119 | NO: 'Norway', 120 | PL: 'Poland', 121 | PT: 'Portugal', 122 | RE: 'Réunion', 123 | RO: 'Romania', 124 | SM: 'San Marino', 125 | SK: 'Slovakia', 126 | SI: 'Slovenia', 127 | ES: 'Spain', 128 | BL: 'St. Barthélemy', 129 | MF: 'St. Martin', 130 | PM: 'St. Pierre & Miquelon', 131 | SJ: 'Svalbard & Jan Mayen', 132 | SE: 'Sweden', 133 | GB: 'United Kingdom', 134 | VA: 'Vatican City', 135 | WF: 'Wallis & Futuna', 136 | } as const; 137 | /** 138 | * The country code of a country supported on the Play Store. 139 | */ 140 | export type CountryCode = keyof typeof countries; 141 | 142 | // To generate, go to , and run the following 143 | // in the browser console: 144 | // Array.from(document.querySelector('#supported-interface-languages ~ 145 | // div.devsite-table-wrapper').querySelectorAll('tr')).slice(1).reduce((acc, cur) => ({...acc, 146 | // [cur.children.item(1).innerText.toUpperCase()]: cur.children.item(0).innerText}), {}) 147 | /** 148 | * A language supported by the Play Store. 149 | * 150 | * @enum 151 | */ 152 | export const languages = { 153 | AF: 'Afrikaans', 154 | SQ: 'Albanian', 155 | SM: 'Amharic', 156 | AR: 'Arabic', 157 | AZ: 'Azerbaijani', 158 | EU: 'Basque', 159 | BE: 'Belarusian', 160 | BN: 'Bengali', 161 | BH: 'Bihari', 162 | BS: 'Bosnian', 163 | BG: 'Bulgarian', 164 | CA: 'Catalan', 165 | 'ZH-CN': 'Chinese (Simplified)', 166 | 'ZH-TW': 'Chinese (Traditional)', 167 | HR: 'Croatian', 168 | CS: 'Czech', 169 | DA: 'Danish', 170 | NL: 'Dutch', 171 | EN: 'English', 172 | EO: 'Esperanto', 173 | ET: 'Estonian', 174 | FO: 'Faroese', 175 | FI: 'Finnish', 176 | FR: 'French', 177 | FY: 'Frisian', 178 | GL: 'Galician', 179 | KA: 'Georgian', 180 | DE: 'German', 181 | EL: 'Greek', 182 | GU: 'Gujarati', 183 | IW: 'Hebrew', 184 | HI: 'Hindi', 185 | HU: 'Hungarian', 186 | IS: 'Icelandic', 187 | ID: 'Indonesian', 188 | IA: 'Interlingua', 189 | GA: 'Irish', 190 | IT: 'Italian', 191 | JA: 'Japanese', 192 | JW: 'Javanese', 193 | KN: 'Kannada', 194 | KO: 'Korean', 195 | LA: 'Latin', 196 | LV: 'Latvian', 197 | LT: 'Lithuanian', 198 | MK: 'Macedonian', 199 | MS: 'Malay', 200 | ML: 'Malayam', 201 | MT: 'Maltese', 202 | MR: 'Marathi', 203 | NE: 'Nepali', 204 | NO: 'Norwegian', 205 | NN: 'Norwegian (Nynorsk)', 206 | OC: 'Occitan', 207 | FA: 'Persian', 208 | PL: 'Polish', 209 | 'PT-BR': 'Portuguese (Brazil)', 210 | 'PT-PT': 'Portuguese (Portugal)', 211 | PA: 'Punjabi', 212 | RO: 'Romanian', 213 | RU: 'Russian', 214 | GD: 'Scots Gaelic', 215 | SR: 'Serbian', 216 | SI: 'Sinhalese', 217 | SK: 'Slovak', 218 | SL: 'Slovenian', 219 | ES: 'Spanish', 220 | SU: 'Sudanese', 221 | SW: 'Swahili', 222 | SV: 'Swedish', 223 | TL: 'Tagalog', 224 | TA: 'Tamil', 225 | TE: 'Telugu', 226 | TH: 'Thai', 227 | TI: 'Tigrinya', 228 | TR: 'Turkish', 229 | UK: 'Ukrainian', 230 | UR: 'Urdu', 231 | UZ: 'Uzbek', 232 | VI: 'Vietnamese', 233 | CY: 'Welsh', 234 | XH: 'Xhosa', 235 | ZU: 'Zulu', 236 | } as const; 237 | /** 238 | * The language code of a language supported on the Play Store. 239 | */ 240 | export type LanguageCode = keyof typeof languages; 241 | 242 | // ++++++++++++++++++++++++++ 243 | // +++ Data safety labels +++ 244 | // ++++++++++++++++++++++++++ 245 | 246 | /** 247 | * The categories that group multiple related data types in a data safety label. 248 | * 249 | * Taken from the official documentation: 250 | */ 251 | export const dataSafetyLabelDataCategories = [ 252 | 'App activity', 253 | 'App info and performance', 254 | 'Audio files', 255 | 'Calendar', 256 | 'Contacts', 257 | 'Device or other IDs', 258 | 'Files and docs', 259 | 'Financial info', 260 | 'Health and fitness', 261 | 'Location', 262 | 'Messages', 263 | 'Personal info', 264 | 'Photos and videos', 265 | 'Web browsing', 266 | ] as const; 267 | /** 268 | * A category that groups multiple related data types in a data safety label. 269 | */ 270 | export type DataSafetyLabelDataCategory = typeof dataSafetyLabelDataCategories[number]; 271 | /** 272 | * The types of data that can be declared in a data safety label. 273 | * 274 | * Taken from the official documentation: 275 | */ 276 | export const dataSafetyLabelDataTypes = [ 277 | 'Approximate location', 278 | 'Precise location', 279 | 'Name', 280 | 'Email address', 281 | 'User IDs', 282 | 'Address', 283 | 'Phone number', 284 | 'Race and ethnicity', 285 | 'Political or religious beliefs', 286 | 'Sexual orientation', 287 | 'Other info', 288 | 'User payment info', 289 | 'Purchase history', 290 | 'Credit score', 291 | 'Other financial info', 292 | 'Health info', 293 | 'Fitness info', 294 | 'Emails', 295 | 'SMS or MMS', 296 | 'Other in-app messages', 297 | 'Photos', 298 | 'Videos', 299 | 'Voice or sound recordings', 300 | 'Music files', 301 | 'Other audio files', 302 | 'Files and docs', 303 | 'Calendar events', 304 | 'Contacts', 305 | 'App interactions', 306 | 'In-app search history', 307 | 'Installed apps', 308 | 'Other user-generated content', 309 | 'Other actions', 310 | 'Web browsing history', 311 | 'Crash logs', 312 | 'Diagnostics', 313 | 'Other app performance data', 314 | 'Device or other IDs', 315 | ] as const; 316 | /** 317 | * A type of data that can be declared in a data safety label. 318 | */ 319 | export type DataSafetyLabelDataType = typeof dataSafetyLabelDataTypes[number]; 320 | /** 321 | * The purposes for which data collection or sharing can be declared in a data safety label. 322 | * 323 | * Taken from the official documentation: 324 | */ 325 | export const dataSafetyLabelPurposes = [ 326 | 'App functionality', 327 | 'Analytics', 328 | 'Developer communications', 329 | 'Advertising or marketing', 330 | 'Fraud prevention, security, and compliance', 331 | 'Personalization', 332 | 'Account management', 333 | ] as const; 334 | /** 335 | * A purpose for which data collection or sharing can be declared in a data safety label. 336 | */ 337 | export type DataSafetyLabelPurpose = typeof dataSafetyLabelPurposes[number]; 338 | -------------------------------------------------------------------------------- /src/common/data-format.ts: -------------------------------------------------------------------------------- 1 | import { LanguageCode, CountryCode } from './consts'; 2 | import type { DataTypeDeclaration, DataSafetyLabelSecurityPracticesDeclarations } from '../endpoints/data-safety'; 3 | 4 | /** A group of related permissions the app has access to. */ 5 | export type PermissionGroup = { 6 | /** A machine-readable ID for the group. */ 7 | id?: string; 8 | /** The name/label of the group. */ 9 | name?: string; 10 | /** The URL to the group's icon. */ 11 | icon_url?: string; 12 | /** The detailed permissions in this group the app has access to. */ 13 | permissions: string[]; 14 | }; 15 | 16 | /** 17 | * The full metadata that can theoretically be fetched for an app. The individual endpoints will only return a subset of 18 | * this, see {@link AppMetadata}. 19 | */ 20 | export type AppMetadataFull = { 21 | /** The app's position in a list (top chart, search results). */ 22 | position: number; 23 | /** The app's bundle ID. */ 24 | app_id: string; 25 | /** A URL to the app's icon. */ 26 | icon_url: string; 27 | /** URLs to screenshots of the app. */ 28 | screenshot_urls: string[]; 29 | /** The app's name. */ 30 | name: string; 31 | /** The app's review rating. */ 32 | rating: number | undefined; 33 | /** The number of each rating the app has received. */ 34 | rating_counts: { 35 | /** The number of 1-star ratings. */ 36 | 1: number; 37 | /** The number of 2-star ratings. */ 38 | 2: number; 39 | /** The number of 3-star ratings. */ 40 | 3: number; 41 | /** The number of 4-star ratings. */ 42 | 4: number; 43 | /** The number of 5-star ratings. */ 44 | 5: number; 45 | /** The total number of ratings. */ 46 | total: number; 47 | }; 48 | /** The app's main category. */ 49 | category: string; 50 | /** The app's price. Can be undefined for pre-release apps. */ 51 | price: string | undefined; 52 | /** A URL to the Play Store website to buy the app. */ 53 | buy_url: string | undefined; 54 | /** The relative path of the app on the Play Store website. */ 55 | store_path: string; 56 | /** A URL to a video trailer for the app. */ 57 | trailer_url: string | undefined; 58 | /** The app's description. */ 59 | description: string; 60 | /** The app's developer. */ 61 | developer: string; 62 | /** The relative path of the developer's page on the Play Store website. */ 63 | developer_path: string; 64 | /** The URL to the developer's website. */ 65 | developer_website_url: string | undefined; 66 | /** The developer's email address. */ 67 | developer_email: string; 68 | /** The developer's address. */ 69 | developer_address: string | undefined; 70 | /** The URL to the app's privacy policy. */ 71 | privacy_policy_url: string | undefined; 72 | /** An overview of the data that the app may share with other companies or organizations. */ 73 | data_shared: DataTypeDeclaration[] | undefined; 74 | /** An overview of the data the app may collect. */ 75 | data_collected: DataTypeDeclaration[] | undefined; 76 | /** An overview of the app's security practices. */ 77 | security_practices: DataSafetyLabelSecurityPracticesDeclarations | undefined; 78 | /** The approximate download count of the app as a string, as displayed on the Play Store website. */ 79 | downloads: string; 80 | /** The exact download count of the app. */ 81 | downloads_exact: number; 82 | /** A URL to the app's cover image. */ 83 | cover_image_url: string | undefined; 84 | /** The app's permissions, grouped by category. */ 85 | permissions: PermissionGroup[]; 86 | /** The date when the app was last updated. */ 87 | updated_on: Date; 88 | /** The date when the app was first published. */ 89 | released_on?: Date; 90 | /** The cost of in-app purchases for the app. */ 91 | in_app_purchases?: string; 92 | /** The app's content rating. */ 93 | content_rating?: { 94 | /** The label for the content rating. */ 95 | label: string; 96 | /** The URL to an icon for the content rating. */ 97 | icon_url: string; 98 | /** A description of interactive elements in the app. */ 99 | interactive_elements?: string; 100 | }; 101 | /** The app's placement on a top chart. */ 102 | top_chart_placement?: { 103 | /** The label for the placement. */ 104 | label: string; 105 | /** The app's position in the top chart. */ 106 | placement: string; 107 | }; 108 | /** A list of the app's categories and related search terms. */ 109 | tags?: { 110 | /** A machine-readable ID for the tag. */ 111 | id?: string; 112 | /** The name/label of the tag. */ 113 | name: string; 114 | /** The relative path of the category/search page on the Play Store website. */ 115 | path: string; 116 | }; 117 | /** The app's version. */ 118 | version?: string; 119 | /** The app's required version of Android. */ 120 | requires_android?: { version: string; api_level: number }; 121 | /** The company distributing the app on the Play Store. */ 122 | offered_by: string; 123 | }; 124 | /** A property that can be present in the metadata of an app. */ 125 | export type AppMetadataProperty = keyof AppMetadataFull; 126 | /** The metadata for a single app. The available properties depend on which endpoint this was fetched from. */ 127 | export type AppMetadata

= Pick; 128 | 129 | export const formatCurrency = ( 130 | value: number, 131 | currency: string, 132 | options: { language: LanguageCode; country: CountryCode } 133 | ) => new Intl.NumberFormat(`${options.language}-${options.country}`, { style: 'currency', currency }).format(value); 134 | 135 | const appMetadataProperties: Partial< 136 | Record any> 137 | > = { 138 | app_id: (d) => d[0][0], 139 | icon_url: (d) => d[1][3][2], 140 | screenshot_urls: (d) => d[2].map((s: any) => s[3][2]), 141 | name: (d) => d[3], 142 | rating: (d) => d[4][1], 143 | category: (d) => d[5], 144 | price: (d, o) => (d[8] ? formatCurrency(d[8]?.[1][0][0] / 1e6, d[8]?.[1][0][1], o) : undefined), 145 | buy_url: (d) => d[8]?.[6][5][2], 146 | store_path: (d) => d[10][4][2], 147 | trailer_url: (d) => d[12]?.[0][0][3][2], 148 | description: (d) => d[13][1], 149 | developer: (d) => d[14], 150 | downloads: (d) => d[15], 151 | cover_image_url: (d) => d[22][3]?.[2], 152 | }; 153 | /** Parse an app entry in a search or top chart response. */ 154 | export const parseAppEntry =

( 155 | entry: any, 156 | properties: P[] | readonly P[], 157 | options: { language: LanguageCode; country: CountryCode; idx?: number } 158 | ): AppMetadata

=> { 159 | const res: Record = {}; 160 | 161 | if (options.idx) res.position = options.idx + 1; 162 | 163 | for (const [property, getter] of Object.entries(appMetadataProperties).filter(([p]) => 164 | properties.includes(p as P) 165 | )) { 166 | res[property] = getter(entry, options); 167 | } 168 | 169 | return res as AppMetadata

; 170 | }; 171 | -------------------------------------------------------------------------------- /src/common/requests.ts: -------------------------------------------------------------------------------- 1 | import fetch from 'cross-fetch'; 2 | import { assert } from './assert'; 3 | 4 | export type RequestPayload = [string, string]; 5 | export type QueryParams = Record; 6 | 7 | const buildQueryString = (queryParams?: QueryParams) => 8 | queryParams 9 | ? `?${Object.entries(queryParams) 10 | .map(([key, value]) => `${key}=${value}`) 11 | .join('&')}` 12 | : ''; 13 | 14 | export const batchExecute = async (requests: RequestPayload[], queryParams?: QueryParams) => { 15 | const res = await fetch(`https://play.google.com/_/PlayStoreUi/data/batchexecute${buildQueryString(queryParams)}`, { 16 | method: 'POST', 17 | headers: { 18 | 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', 19 | }, 20 | // The (stringified) number at index 3 of each request is supposed to specify the order in which the responses 21 | // are returned (see: https://kovatch.medium.com/deciphering-google-batchexecute-74991e4e446c#ea4a). We want 22 | // them in the same order as the requests. 23 | // 24 | // From my testing, this doesn't always seem to be the case. But as the number is also returned in the response, 25 | // we can use it to manually sort the payloads later. 26 | body: `f.req=${encodeURIComponent(JSON.stringify([requests.map((r, idx) => [...r, null, '' + idx])]))}`, 27 | }).then((r) => r.text()); 28 | 29 | const messages: any[] = JSON.parse(res.split('\n')[2]!); 30 | assert(() => messages.length === requests.length + 2, 'Has response payload for each request.'); 31 | 32 | const payloads = messages.slice(0, requests.length).sort((a, b) => a[a.length - 1] - b[b.length - 1]); 33 | 34 | return payloads.map((payload, idx) => { 35 | assert(() => payload[0] === 'wrb.fr' && payload[1] === requests[idx]?.[0], 'Correct header.'); 36 | 37 | const data = JSON.parse(payload[2]); 38 | assert(() => data, 'Has inner data.'); 39 | return data; 40 | }); 41 | }; 42 | -------------------------------------------------------------------------------- /src/endpoints/app-details.ts: -------------------------------------------------------------------------------- 1 | import { batchExecute, RequestPayload } from '../common/requests'; 2 | import { assert } from '../common/assert'; 3 | import { formatCurrency, type AppMetadata } from '../common/data-format'; 4 | import type { DataTypeDeclaration } from './data-safety'; 5 | import { dataSafetyLabelPurposes, type LanguageCode, type CountryCode } from '../common/consts'; 6 | 7 | /** Parameters for a fetch app details request. */ 8 | export type AppDetailsRequest = { 9 | /** The app ID. */ 10 | appId: string; 11 | }; 12 | /** Parameters for all fetch app details requests in a {@link fetchAppDetails} call. */ 13 | export type AppDetailsOptions = { 14 | /** The country version of the Play Store to fetch from. */ 15 | country: CountryCode; 16 | /** The language for descriptions, etc. */ 17 | language: LanguageCode; 18 | }; 19 | 20 | /** The properties present when fetching app details. */ 21 | export const fetchAppDetailsMetadataProperties = [ 22 | 'app_id', 23 | 'name', 24 | 'content_rating', 25 | 'released_on', 26 | 'downloads', 27 | 'downloads_exact', 28 | 'in_app_purchases', 29 | 'offered_by', 30 | 'rating', 31 | 'rating_counts', 32 | 'price', 33 | 'buy_url', 34 | 'top_chart_placement', 35 | 'developer', 36 | 'developer_path', 37 | 'developer_website_url', 38 | 'developer_email', 39 | 'developer_address', 40 | 'description', 41 | 'permissions', 42 | 'screenshot_urls', 43 | 'category', 44 | 'icon_url', 45 | 'cover_image_url', 46 | 'privacy_policy_url', 47 | 'trailer_url', 48 | 'tags', 49 | 'data_shared', 50 | 'data_collected', 51 | 'security_practices', 52 | 'version', 53 | 'requires_android', 54 | 'updated_on', 55 | ] as const; 56 | /** A property present when fetching app details. */ 57 | export type AppMetadataPropertyFetchAppDetails = typeof fetchAppDetailsMetadataProperties[number]; 58 | /** The result of a fetch app details request. */ 59 | export type AppDetailsResult = AppMetadata; 60 | 61 | export const fetchAppDetailsRequestPayload = (request: AppDetailsRequest): RequestPayload => [ 62 | 'Ws7gDc', 63 | JSON.stringify([ 64 | null, 65 | null, 66 | [ 67 | [ 68 | 1, 9, 10, 11, 13, 14, 19, 20, 38, 43, 47, 49, 52, 58, 59, 63, 69, 70, 73, 74, 75, 78, 79, 80, 91, 92, 69 | 95, 96, 97, 100, 101, 103, 106, 112, 119, 129, 137, 138, 139, 141, 145, 146, 151, 155, 169, 70 | ], 71 | ], 72 | [ 73 | [ 74 | null, 75 | null, 76 | null, 77 | null, 78 | null, 79 | null, 80 | null, 81 | [null, 2], 82 | null, 83 | null, 84 | null, 85 | null, 86 | null, 87 | null, 88 | null, 89 | null, 90 | null, 91 | null, 92 | null, 93 | null, 94 | null, 95 | null, 96 | [1], 97 | ], 98 | [null, [[[]]], null, null, [1]], 99 | [null, [[[]]], null, [1]], 100 | [null, [[[]]]], 101 | null, 102 | null, 103 | null, 104 | null, 105 | [[[[]]]], 106 | [[[[]]]], 107 | ], 108 | null, 109 | [[request.appId, 7]], 110 | ]), 111 | ]; 112 | 113 | const parseDslCategory = (c: any) => ({ 114 | heading: c[1], 115 | description: c[2][1], 116 | icons: [c[0][3][2], c[0][10][2]], 117 | }); 118 | const parseDslSection = (d: any, idx: number): DataTypeDeclaration[] | undefined => 119 | !d 120 | ? undefined 121 | : !d[idx][0] 122 | ? [] 123 | : (d[idx][0] as any[]).flatMap((r: any) => 124 | (r[4] as any[]).map((d: any) => ({ 125 | category: parseDslCategory(r[0]).heading, 126 | type: d[0], 127 | purposes: dataSafetyLabelPurposes.filter((p) => (d[2] as string).includes(p)), 128 | optional: d[1], 129 | })) 130 | ); 131 | const parseSecurityPractices = (data: any) => { 132 | const securityPracticesEntries: any[] | undefined = data[137]?.[9]?.[2].map(parseDslCategory); 133 | assert(() => { 134 | if (!securityPracticesEntries) return true; 135 | 136 | const knownHeadings = new Set([ 137 | 'Data is encrypted in transit', 138 | 'You can request that data be deleted', 139 | 'Data can’t be deleted', 140 | 'Data isn’t encrypted', 141 | 'Committed to follow the Play Families Policy', 142 | 'Independent security review', 143 | ]); 144 | return securityPracticesEntries?.map((e) => e.heading).every((h) => knownHeadings.has(h)); 145 | }, 'Only known security practice entries.'); 146 | const hasSecurityPracticeAttribute = (positiveHeading?: string, negativeHeading?: string) => { 147 | if (positiveHeading && securityPracticesEntries?.find((e) => e.heading === positiveHeading)) return true; 148 | if (negativeHeading && securityPracticesEntries?.find((e) => e.heading === negativeHeading)) return false; 149 | return undefined; 150 | }; 151 | 152 | return securityPracticesEntries 153 | ? { 154 | data_encrypted_in_transit: hasSecurityPracticeAttribute( 155 | 'Data is encrypted in transit', 156 | 'Data isn’t encrypted' 157 | ), 158 | can_request_data_deletion: hasSecurityPracticeAttribute( 159 | 'You can request that data be deleted', 160 | 'Data can’t be deleted' 161 | ), 162 | committed_to_play_families_policy: hasSecurityPracticeAttribute( 163 | 'Committed to follow the Play Families Policy' 164 | ), 165 | independent_security_review: hasSecurityPracticeAttribute('Independent security review'), 166 | } 167 | : undefined; 168 | }; 169 | 170 | export const parseAppDetailsPayload = (payload: any, options: AppDetailsOptions): AppDetailsResult | undefined => { 171 | if (!payload) return undefined; 172 | assert( 173 | () => payload.length === 3 && payload[0].flat(Infinity).length === 0 && payload[1].length === 40, 174 | 'Expected inner data structure.' 175 | ); 176 | const data = payload[1][2]; 177 | 178 | return { 179 | app_id: payload[1][11][0][0] || data[77][0], 180 | name: data[0][0], 181 | content_rating: data[9] 182 | ? { label: data[9][0], icon_url: data[9][1][3][2], interactive_elements: data[9][3]?.[1] } 183 | : undefined, 184 | released_on: data[10] ? new Date(data[10][1][0] * 1000) : undefined, 185 | downloads: data[13][0], 186 | downloads_exact: data[13][2], 187 | in_app_purchases: data[19]?.[0], 188 | offered_by: data[37][0], 189 | rating: data[51][0][1], 190 | rating_counts: { 191 | 1: data[51][1][1][1], 192 | 2: data[51][1][2][1], 193 | 3: data[51][1][3][1], 194 | 4: data[51][1][4][1], 195 | 5: data[51][1][5][1], 196 | total: data[51][2][1], 197 | }, 198 | price: data[57][0][0][0][0] 199 | ? formatCurrency(data[57][0][0][0][0]?.[1][0][0] / 1e6, data[57][0][0][0][0]?.[1][0][1], options) 200 | : undefined, 201 | buy_url: data[57][0][0][0][0][6][5][2], 202 | top_chart_placement: data[58] ? { label: data[58][0], placement: data[58][2] } : undefined, 203 | developer: data[68][0], 204 | developer_path: data[68][1][4][2], 205 | developer_website_url: data[69][0]?.[5][2], 206 | developer_email: data[69][1][0], 207 | developer_address: data[69][2]?.[0], 208 | description: data[72][0][1], 209 | permissions: [ 210 | ...(data[74][2][0] || []), 211 | ...(data[74][2][1] || []), 212 | [undefined, undefined, data[74][2][2], undefined], 213 | ] 214 | .filter((g) => g[2]?.length > 0) 215 | .map((g) => ({ 216 | id: g[3]?.[0], 217 | name: g[0], 218 | icon_url: g[1]?.[3][2], 219 | permissions: g[2].map((p: any) => p[1]), 220 | })), 221 | screenshot_urls: data[78][0].map((s: any) => s[3][2]), 222 | category: data[79][0][0][0], 223 | icon_url: data[95][0][3][2], 224 | cover_image_url: data[96][0][3][2], 225 | privacy_policy_url: data[99]?.[0][5][2], 226 | trailer_url: data[100]?.[0][0][3][2], 227 | tags: data[118] 228 | ?.filter(Boolean) 229 | .map((g: any) => (typeof g[0][0][0] === 'string' ? g[0] : g[0][0])) 230 | .flat() 231 | .map((t: any) => ({ id: t[2], name: t[0], path: t[1][4][2] })), 232 | data_shared: parseDslSection(data[137][4], 0), 233 | data_collected: parseDslSection(data[137][4], 1), 234 | security_practices: parseSecurityPractices(data), 235 | version: data[140][0][0]?.[0], 236 | requires_android: data[140][1][1][0] 237 | ? { version: data[140][1][1][0][0][1], api_level: data[140][1][1][0][0][0] } 238 | : undefined, 239 | updated_on: new Date(data[145][0][1][0] * 1000), 240 | }; 241 | }; 242 | 243 | /** 244 | * Fetch the details/metadata of an app on the Google Play Store. 245 | * 246 | * This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `Ws7gDc`. 247 | * 248 | * @param request The parameters of which app to fetch the details of. 249 | * @param options Language and country options. 250 | * @returns The app details. 251 | */ 252 | export async function fetchAppDetails( 253 | request: AppDetailsRequest | [AppDetailsRequest], 254 | options: AppDetailsOptions 255 | ): Promise; 256 | /** 257 | * Same as {@link fetchAppDetails} but for fetching the details of multiple apps at once. The details are all fetched in 258 | * a single API request. 259 | * 260 | * @see {@link fetchAppDetails} 261 | * 262 | * @param requests An array of fetch app details requests. 263 | * @param options The options for _all_ requests. 264 | * @returns An array of the app details, in the same order as the requests. 265 | */ 266 | export async function fetchAppDetails( 267 | requests: AppDetailsRequest[], 268 | options: AppDetailsOptions 269 | ): Promise; 270 | export async function fetchAppDetails(requests: AppDetailsRequest | AppDetailsRequest[], options: AppDetailsOptions) { 271 | const _requests = Array.isArray(requests) ? requests : [requests]; 272 | const data = await batchExecute( 273 | _requests.map((r) => fetchAppDetailsRequestPayload(r)), 274 | { hl: options.language, gl: options.country } 275 | ); 276 | const res = data.map((d) => parseAppDetailsPayload(d, options)); 277 | return _requests.length === 1 ? res[0] : res; 278 | } 279 | -------------------------------------------------------------------------------- /src/endpoints/data-safety.ts: -------------------------------------------------------------------------------- 1 | import { batchExecute, RequestPayload } from '../common/requests'; 2 | import { 3 | dataSafetyLabelPurposes, 4 | LanguageCode, 5 | DataSafetyLabelDataCategory, 6 | DataSafetyLabelDataType, 7 | DataSafetyLabelPurpose, 8 | } from '../common/consts'; 9 | import { assert } from '../common/assert'; 10 | 11 | /** 12 | * Parameters for a single data safety label request. 13 | * 14 | * @deprecated The separate function for fetching data safety labels is deprecated and will be removed in a future 15 | * release. Instead, you can use the {@link fetchAppDetails} function to fetch an app's metadata, which includes the 16 | * data safety label. 17 | */ 18 | export type DataSafetyLabelRequest = { 19 | /** 20 | * The app's bundle ID. 21 | */ 22 | app_id: string; 23 | }; 24 | /** 25 | * Parameters for all data safety label requests in a {@link fetchDataSafetyLabels} call. 26 | */ 27 | export type DataSafetyLabelsOptions = { 28 | /** The language for descriptions, etc. */ 29 | language: LanguageCode; 30 | }; 31 | 32 | /** 33 | * An app's declaration for a single data type in a data safety label. 34 | */ 35 | export type DataTypeDeclaration = { 36 | /** The category the data type fits into. */ 37 | category: DataSafetyLabelDataCategory; 38 | /** The data type. */ 39 | type: DataSafetyLabelDataType; 40 | /** The purposes for which the data type is collected or shared. */ 41 | purposes: DataSafetyLabelPurpose[]; 42 | /** Whether the data type is marked as optional. */ 43 | optional: boolean; 44 | }; 45 | /** 46 | * An app's declared security practices in a data safety label. 47 | */ 48 | export type DataSafetyLabelSecurityPracticesDeclarations = { 49 | /** Whether data collected or shared by the app uses encryption in transit. */ 50 | data_encrypted_in_transit: boolean | undefined; 51 | /** Whether the app provides a way for users to request deletion of their data. */ 52 | can_request_data_deletion: boolean | undefined; 53 | /** 54 | * Whether the developer has reviewed the app's compliance with Google Play's [Families policy 55 | * requirements](https://support.google.com/googleplay/android-developer/answer/9893335) (only for 56 | * applicable apps). 57 | */ 58 | committed_to_play_families_policy: boolean | undefined; 59 | /** Whether the app has been independently validated against a global security standard. */ 60 | independent_security_review: boolean | undefined; 61 | }; 62 | /** 63 | * An app's data safety label. 64 | * 65 | * @deprecated The separate function for fetching data safety labels is deprecated and will be removed in a future 66 | * release. Instead, you can use the {@link fetchAppDetails} function to fetch an app's metadata, which includes the 67 | * data safety label. 68 | */ 69 | export type DataSafetyLabel = { 70 | /** The app's name. */ 71 | name: string; 72 | /** The app's bundle ID. */ 73 | app_id: string; 74 | /** Data about the app's developer. */ 75 | developer: { 76 | /** The developer's name */ 77 | name: string; 78 | /** The relative path of the developer's page on the Play Store website. */ 79 | path: string; 80 | /** The URL to the developer's website. */ 81 | website_url: string | undefined; 82 | /** The developer's email address. */ 83 | email: string; 84 | /** The developer's address. */ 85 | address: string | undefined; 86 | }; 87 | /** The URL to the app's icon. */ 88 | icon_url: string; 89 | /** The URL to the app's privacy policy. */ 90 | privacy_policy_url: string | undefined; 91 | /** An overview of the data that the app may share with other companies or organizations. */ 92 | data_shared: DataTypeDeclaration[] | undefined; 93 | /** An overview of the data the app may collect. */ 94 | data_collected: DataTypeDeclaration[] | undefined; 95 | /** An overview of the app's security practices. */ 96 | security_practices: DataSafetyLabelSecurityPracticesDeclarations | undefined; 97 | }; 98 | 99 | export const dataSafetyLabelsRequestPayload = (request: DataSafetyLabelRequest): RequestPayload => [ 100 | 'Ws7gDc', 101 | // The numbers seem to determine which data points are returned. 102 | JSON.stringify([null, null, [[1, 69, 70, 96, 100, 138]], null, null, [[request.app_id, 7]]]), 103 | ]; 104 | 105 | export const parseDataSafetyLabelPayload = (payload: any): DataSafetyLabel | undefined => { 106 | if (!payload) return undefined; 107 | assert( 108 | () => payload.length === 2 && payload[0].flat(Infinity).length === 0 && payload[1].length === 40, 109 | 'Expected inner data structure.' 110 | ); 111 | const data = payload[1][2]; 112 | 113 | const parseCategory = (c: any) => ({ 114 | heading: c[1], 115 | description: c[2][1], 116 | icons: [c[0][3][2], c[0][10][2]], 117 | }); 118 | const parseSection = (d: any, idx: number): DataTypeDeclaration[] | undefined => 119 | !d 120 | ? undefined 121 | : !d[idx][0] 122 | ? [] 123 | : (d[idx][0] as any[]).flatMap((r: any) => 124 | (r[4] as any[]).map((d: any) => ({ 125 | category: parseCategory(r[0]).heading, 126 | type: d[0], 127 | purposes: dataSafetyLabelPurposes.filter((p) => (d[2] as string).includes(p)), 128 | optional: d[1], 129 | })) 130 | ); 131 | 132 | const securityPracticesEntries: any[] | undefined = data[137][9]?.[2].map(parseCategory); 133 | assert(() => { 134 | if (!securityPracticesEntries) return true; 135 | 136 | const knownHeadings = new Set([ 137 | 'Data is encrypted in transit', 138 | 'You can request that data be deleted', 139 | 'Data can’t be deleted', 140 | 'Data isn’t encrypted', 141 | 'Committed to follow the Play Families Policy', 142 | 'Independent security review', 143 | ]); 144 | return securityPracticesEntries?.map((e) => e.heading).every((h) => knownHeadings.has(h)); 145 | }, 'Only known security practice entries.'); 146 | const hasSecurityPracticeAttribute = (positiveHeading?: string, negativeHeading?: string) => { 147 | if (positiveHeading && securityPracticesEntries?.find((e) => e.heading === positiveHeading)) return true; 148 | if (negativeHeading && securityPracticesEntries?.find((e) => e.heading === negativeHeading)) return false; 149 | return undefined; 150 | }; 151 | 152 | return { 153 | name: data[0][0], 154 | app_id: payload[1][11][0][0], 155 | developer: { 156 | name: data[68][0], 157 | path: data[68][1][4][2], 158 | website_url: data[69][0]?.[5][2], 159 | email: data[69][1][0], 160 | address: data[69][2]?.[0], 161 | }, 162 | icon_url: data[95][0][3][2], 163 | privacy_policy_url: data[99]?.[0][5][2], 164 | data_shared: parseSection(data[137][4], 0), 165 | data_collected: parseSection(data[137][4], 1), 166 | security_practices: securityPracticesEntries 167 | ? { 168 | data_encrypted_in_transit: hasSecurityPracticeAttribute( 169 | 'Data is encrypted in transit', 170 | 'Data isn’t encrypted' 171 | ), 172 | can_request_data_deletion: hasSecurityPracticeAttribute( 173 | 'You can request that data be deleted', 174 | 'Data can’t be deleted' 175 | ), 176 | committed_to_play_families_policy: hasSecurityPracticeAttribute( 177 | 'Committed to follow the Play Families Policy' 178 | ), 179 | independent_security_review: hasSecurityPracticeAttribute('Independent security review'), 180 | } 181 | : undefined, 182 | }; 183 | }; 184 | 185 | /** 186 | * Fetch and parse the given app's data safety label from the Google Play Store. 187 | * 188 | * This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `Ws7gDc`. 189 | * 190 | * @deprecated The separate function for fetching data safety labels is deprecated and will be removed in a future 191 | * release. Instead, you can use the {@link fetchAppDetails} function to fetch an app's metadata, which includes the 192 | * data safety label. 193 | * 194 | * @param request The parameters for which app to fetch. 195 | * @param options Language options. 196 | * @returns The data safety label. 197 | */ 198 | export async function fetchDataSafetyLabels( 199 | request: DataSafetyLabelRequest | [DataSafetyLabelRequest], 200 | options: DataSafetyLabelsOptions 201 | ): Promise; 202 | /** 203 | * Same as {@link fetchDataSafetyLabels} but for fetching multiple data safety labels at once. The data safety labels 204 | * are fetched in a single API request. 205 | * 206 | * @deprecated The separate function for fetching data safety labels is deprecated and will be removed in a future 207 | * release. Instead, you can use the {@link fetchAppDetails} function to fetch an app's metadata, which includes the 208 | * data safety label. 209 | * 210 | * @see {@link fetchDataSafetyLabels} 211 | * 212 | * @param requests An array of data safety label requests. 213 | * @param options The options for _all_ requests. 214 | * @returns An array of the data safety labels, in the same order as the requests. 215 | */ 216 | export async function fetchDataSafetyLabels( 217 | requests: DataSafetyLabelRequest[], 218 | options: DataSafetyLabelsOptions 219 | ): Promise<(DataSafetyLabel | undefined)[]>; 220 | export async function fetchDataSafetyLabels( 221 | requests: DataSafetyLabelRequest | DataSafetyLabelRequest[], 222 | options: DataSafetyLabelsOptions 223 | ) { 224 | const _requests = Array.isArray(requests) ? requests : [requests]; 225 | const data = await batchExecute( 226 | _requests.map((r) => dataSafetyLabelsRequestPayload(r)), 227 | { hl: options.language } 228 | ); 229 | const res = data.map(parseDataSafetyLabelPayload); 230 | return _requests.length === 1 ? res[0] : res; 231 | } 232 | -------------------------------------------------------------------------------- /src/endpoints/search.ts: -------------------------------------------------------------------------------- 1 | import { batchExecute, RequestPayload } from '../common/requests'; 2 | import { type LanguageCode, type CountryCode } from '../common/consts'; 3 | import { assert } from '../common/assert'; 4 | import { type AppMetadata, parseAppEntry, formatCurrency } from '../common/data-format'; 5 | 6 | /** 7 | * Parameters for a search apps request. 8 | */ 9 | export type SearchAppsRequest = { 10 | /** The term to search for. */ 11 | searchTerm: string; 12 | }; 13 | /** 14 | * Parameters for all search apps requests in a {@link searchApps} call. 15 | */ 16 | export type SearchAppsOptions = { 17 | /** The country version of the Play Store to search in. */ 18 | country: CountryCode; 19 | /** The language for descriptions, etc. */ 20 | language: LanguageCode; 21 | }; 22 | 23 | /** The properties present in the metadata of each app in the search results. */ 24 | export const searchAppMetadataProperties = [ 25 | 'position', 26 | 'app_id', 27 | 'icon_url', 28 | 'screenshot_urls', 29 | 'name', 30 | 'rating', 31 | 'category', 32 | 'price', 33 | 'buy_url', 34 | 'store_path', 35 | 'trailer_url', 36 | 'description', 37 | 'developer', 38 | 'downloads', 39 | 'cover_image_url', 40 | ] as const; 41 | /** A property present in the metadata of each app in the search results. */ 42 | export type AppMetadataPropertySearch = typeof searchAppMetadataProperties[number]; 43 | /** 44 | * A list of the search results. 45 | */ 46 | export type SearchAppsResults = AppMetadata[]; 47 | 48 | export const searchAppsRequestPayload = (request: SearchAppsRequest): RequestPayload => [ 49 | 'lGYRle', 50 | JSON.stringify([ 51 | [ 52 | [], 53 | [ 54 | // Number of results, but format is not understood. 55 | [8, [20, 50]], 56 | null, 57 | null, 58 | [ 59 | 96, 108, 72, 100, 27, 183, 222, 8, 57, 169, 110, 11, 184, 16, 1, 139, 152, 194, 165, 68, 163, 211, 60 | 9, 71, 31, 195, 12, 64, 151, 150, 148, 113, 104, 55, 56, 145, 32, 34, 10, 122, 61 | ], 62 | null, 63 | null, 64 | null, 65 | null, 66 | ], 67 | // Search term. 68 | [request.searchTerm], 69 | // Type/clusters, 4 is Apps & Games (potentially with featured app). 70 | 4, 71 | null, 72 | null, 73 | null, 74 | [], 75 | null, 76 | ], 77 | [1], 78 | ]), 79 | ]; 80 | 81 | export const parseSearchAppsPayload = (data: any, options: SearchAppsOptions): SearchAppsResults | undefined => { 82 | assert(() => data.length === 4 && data[0].length === 6, 'Expected outer data structure.'); 83 | 84 | const sections = data[0][1]; 85 | assert(() => sections.length === 2 || sections.length === 3, 'Has two or three sections.'); 86 | 87 | const hasFeaturedApp = sections.length === 3; 88 | 89 | if (!hasFeaturedApp && !sections[1][22]) return []; 90 | 91 | const mainEntries: any[] = hasFeaturedApp ? sections[2][22][0] : sections[1][22][0]; 92 | assert(() => Array.isArray(mainEntries), 'Has main results array.'); 93 | 94 | const mainEntriesParsed = mainEntries.map((e, idx) => { 95 | assert(() => e.length === 1, 'Expected entry structure.'); 96 | const meta = e[0]; 97 | 98 | assert(() => meta.length === 102 || meta.length === 101, 'Meta length.'); 99 | 100 | return parseAppEntry(meta, searchAppMetadataProperties, { ...options, idx: hasFeaturedApp ? idx + 1 : idx }); 101 | }); 102 | 103 | if (hasFeaturedApp) { 104 | const featuredEntry = sections[1][23]; 105 | 106 | assert(() => featuredEntry.length === 18, 'Expected featured entry structure.'); 107 | assert( 108 | () => featuredEntry[16].length === 40 && featuredEntry[16][2].length === 155, 109 | 'Featured entry inner meta length.' 110 | ); 111 | 112 | const featuredEntryParsed = { 113 | position: 1, 114 | app_id: featuredEntry[16][11][0][0], 115 | icon_url: featuredEntry[16][2][95][0][3][2], 116 | screenshot_urls: featuredEntry[16][2][78][0].map((s: any) => s[3][2]), 117 | name: featuredEntry[16][2][0][0], 118 | rating: featuredEntry[16][2][51][0][1], 119 | category: featuredEntry[16][2][79][0][0][0], 120 | price: featuredEntry[16][2][57] 121 | ? formatCurrency( 122 | featuredEntry[16][2][57][0][0][0][0][1][0][0] / 1e6, 123 | featuredEntry[16][2][57][0][0][0][0][1][0][1], 124 | options 125 | ) 126 | : undefined, 127 | buy_url: featuredEntry[16][2][57]?.[0][0][0][0][6][5][2], 128 | store_path: featuredEntry[17][0][0][4][2], 129 | trailer_url: featuredEntry[16][2][100]?.[0][0][3][2], 130 | description: featuredEntry[16][2][72][0][1], 131 | developer: featuredEntry[16][2][68][0], 132 | downloads: featuredEntry[16][2][13][0], 133 | cover_image_url: featuredEntry[16][2][96][0][3]?.[2], 134 | }; 135 | 136 | return [featuredEntryParsed, ...mainEntriesParsed]; 137 | } 138 | 139 | return mainEntriesParsed; 140 | }; 141 | 142 | /** 143 | * Search for apps on the Google Play Stroe. 144 | * 145 | * This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `lGYRle`. 146 | * 147 | * @param request The parameters for what to search for. 148 | * @param options Language options. 149 | * @returns The search results. 150 | */ 151 | export async function searchApps( 152 | request: SearchAppsRequest | [SearchAppsRequest], 153 | options: SearchAppsOptions 154 | ): Promise; 155 | /** 156 | * Same as {@link searchApps} but for doing multiple searches at once. The search results are fetched in a single API 157 | * request. 158 | * 159 | * @see {@link searchApps} 160 | * 161 | * @param requests An array of search apps requests. 162 | * @param options The options for _all_ requests. 163 | * @returns An array of the search results, in the same order as the requests. 164 | */ 165 | export async function searchApps( 166 | requests: SearchAppsRequest[], 167 | options: SearchAppsOptions 168 | ): Promise<(SearchAppsResults | undefined)[]>; 169 | export async function searchApps(requests: SearchAppsRequest | SearchAppsRequest[], options: SearchAppsOptions) { 170 | const _requests = Array.isArray(requests) ? requests : [requests]; 171 | const data = await batchExecute( 172 | _requests.map((r) => searchAppsRequestPayload(r)), 173 | { hl: options.language, gl: options.country } 174 | ); 175 | const res = data.map((d) => parseSearchAppsPayload(d, options)); 176 | return _requests.length === 1 ? res[0] : res; 177 | } 178 | -------------------------------------------------------------------------------- /src/endpoints/top-charts.ts: -------------------------------------------------------------------------------- 1 | import { batchExecute, RequestPayload } from '../common/requests'; 2 | import { CategoryId, LanguageCode, CountryCode } from '../common/consts'; 3 | import { assert } from '../common/assert'; 4 | import { AppMetadata, parseAppEntry } from '../common/data-format'; 5 | 6 | /** 7 | * Parameters for a single top charts request. 8 | */ 9 | export type TopChartsRequest = { 10 | /** 11 | * The chart to use, where `topselling_free`: Top free (or Top for €0, Top for $0, depending on the country); 12 | * `topgrossing`: Top grossing; `topselling_paid`: Top selling. 13 | */ 14 | chart: 'topselling_free' | 'topgrossing' | 'topselling_paid'; 15 | /** The category to use. Use `APPLICATION` for all apps, or `GAME` for all games, or one of the subcategory. */ 16 | category: CategoryId; 17 | /** The number of apps to include in the top list. This seems to be limited to 660 apps. */ 18 | count: number; 19 | }; 20 | /** 21 | * Parameters for all top charts requests in a {@link fetchTopCharts} call. 22 | */ 23 | export type TopChartsOptions = { 24 | /** The country for which to fetch the top chart(s). */ 25 | country: CountryCode; 26 | /** The language for descriptions, etc. */ 27 | language: LanguageCode; 28 | }; 29 | 30 | /** The properties present in the metadata of each app in the top chart. */ 31 | export const topChartsAppMetadataProperties = [ 32 | 'position', 33 | 'app_id', 34 | 'icon_url', 35 | 'screenshot_urls', 36 | 'name', 37 | 'rating', 38 | 'category', 39 | 'price', 40 | 'buy_url', 41 | 'store_path', 42 | 'trailer_url', 43 | 'description', 44 | 'developer', 45 | 'downloads', 46 | 'cover_image_url', 47 | ] as const; 48 | /** A property present in the metadata of each app in the top chart. */ 49 | export type AppMetadataPropertyTopCharts = typeof topChartsAppMetadataProperties[number]; 50 | 51 | /** 52 | * A single app and its associated metadata on a top chart. 53 | */ 54 | export type TopChartsEntry = AppMetadata; 55 | /** 56 | * A list of the entries on the respective top chart. 57 | */ 58 | export type TopChartsResult = TopChartsEntry[]; 59 | 60 | // This payload was determined by observing the network traffic on the web UI and then _drastically_ simplifying it 61 | // by throwing away everything that didn't affect the response. 62 | export const topChartsRequestPayload = (request: TopChartsRequest): RequestPayload => [ 63 | 'vyAe2', 64 | JSON.stringify([[null, [[null, [null, request.count]], null, null, [113]], [2, request.chart, request.category]]]), 65 | ]; 66 | 67 | /** 68 | * @deprecated This is now {@link parseAppEntry} instead. This alias will be removed in a future release. 69 | */ 70 | export const parseTopChartEntry = parseAppEntry; 71 | export const parseTopChartPayload = (data: any, options: TopChartsOptions): TopChartsEntry[] | undefined => { 72 | assert(() => data.length === 1, 'One top-level array entry.'); 73 | if (data[0][1] === null) return undefined; 74 | 75 | assert( 76 | () => 77 | data[0][1][0].length === 29 && 78 | data[0][1][0][3].length === 1 && 79 | data[0][1][0].filter((i: unknown) => i === null).length === 27, 80 | 'Expected inner data structure.' 81 | ); 82 | 83 | const entries: any[] = data[0][1][0][28][0]; 84 | assert(() => entries.length > 0, 'Has data.'); 85 | 86 | const parsed = entries.map((e, idx) => { 87 | assert(() => e.length === 3 && [0, 1, 2].includes(e[2]), 'Expected entry structure.'); 88 | 89 | const meta = e[0]; 90 | 91 | assert(() => meta.length === 23, 'Meta length.'); 92 | assert(() => meta[8][8][0] === 'CAE=', 'Weird buy param.'); 93 | assert(() => e[1].length === 1 && e[1][0].length === 3, 'Expected weird second meta object structure.'); 94 | const empty_meta = e[1][0].flat(Infinity); 95 | assert( 96 | () => 97 | empty_meta.filter((i: unknown) => i === null).length === empty_meta.length - 1 && 98 | empty_meta[3] === meta[5], 99 | 'Weird second meta object only has category.' 100 | ); 101 | 102 | return parseAppEntry(meta, topChartsAppMetadataProperties, { ...options, idx }); 103 | }); 104 | 105 | return parsed; 106 | }; 107 | 108 | /** 109 | * Fetch and parse the current top chart rankings from the Play Store for the given criteria. 110 | * 111 | * This uses the Play Store's internal `batchexecute` endpoint with an RPC ID of `vyAe2`. 112 | * 113 | * @param request The parameters for which top chart to fetch. 114 | * @param options Language and country options. 115 | * @returns The top chart. 116 | */ 117 | export async function fetchTopCharts( 118 | request: TopChartsRequest | [TopChartsRequest], 119 | options: TopChartsOptions 120 | ): Promise; 121 | /** 122 | * Same as {@link fetchTopCharts} but for fetching multiple top charts at once. The top charts are fetched in a single 123 | * API request. 124 | * 125 | * @see {@link fetchTopCharts} 126 | * 127 | * @param requests An array of top chart requests. 128 | * @param options The options for _all_ requests. 129 | * @returns An array of the top charts, in the same order as the requests. 130 | */ 131 | export async function fetchTopCharts( 132 | requests: TopChartsRequest[], 133 | options: TopChartsOptions 134 | ): Promise<(TopChartsResult | undefined)[]>; 135 | export async function fetchTopCharts(requests: TopChartsRequest | TopChartsRequest[], options: TopChartsOptions) { 136 | const _requests = Array.isArray(requests) ? requests : [requests]; 137 | const data = await batchExecute( 138 | _requests.map((r) => topChartsRequestPayload(r)), 139 | { hl: options.language, gl: options.country } 140 | ); 141 | const res = data.map((d) => parseTopChartPayload(d, options)); 142 | return _requests.length === 1 ? res[0] : res; 143 | } 144 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './endpoints/app-details'; 2 | export * from './endpoints/data-safety'; 3 | export * from './endpoints/search'; 4 | export * from './endpoints/top-charts'; 5 | 6 | export * from './common/consts'; 7 | 8 | export { parseAppEntry } from './common/data-format'; 9 | export type { AppMetadata, AppMetadataFull, AppMetadataProperty, PermissionGroup } from './common/data-format'; 10 | export { batchExecute } from './common/requests'; 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true, 4 | 5 | "lib": ["ESNext"], 6 | "esModuleInterop": true, 7 | "resolveJsonModule": true, 8 | 9 | "strict": true, 10 | "strictNullChecks": true, 11 | "noUncheckedIndexedAccess": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "skipLibCheck": true 14 | }, 15 | "include": ["src/**/*"] 16 | } 17 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | 4 | "plugin": ["typedoc-plugin-markdown"], 5 | "entryPoints": ["src/index.ts"], 6 | "out": "docs", 7 | "readme": "none", 8 | "excludeNotDocumented": true, 9 | "includeVersion": true, 10 | "githubPages": false, 11 | "gitRevision": "main" 12 | } 13 | --------------------------------------------------------------------------------