Skip to content

Commit

Permalink
Fixes #12: Searching for apps (#13)
Browse files Browse the repository at this point in the history
* Create endpoints folder to keep things organized

* Move common types and consts to separate file

* Fixes #12: Searching for apps
  • Loading branch information
baltpeter authored Jun 11, 2024
1 parent a8230c5 commit b733096
Show file tree
Hide file tree
Showing 7 changed files with 428 additions and 169 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

> Library for fetching select data on iOS apps from the Apple Apple Store via undocumented internal iTunes APIs.
This library is able to fetch and parse data from undocumented internal API endpoints of the Apple App Store. Currently, it can fetch the charts of the most popular apps, according to various criteria, and details (including privacy labels) for individual apps. We'll extend the supported API endpoints in the future. The focus will mostly be on functions useful for research into mobile privacy and data protection.
This library is able to fetch and parse data from undocumented internal API endpoints of the Apple App Store. Currently, it has the following features:

* Fetch the **charts of the most popular apps**, including filtering by genre and chart.
* **Fetch details** (including **privacy labels**) for individual apps.
* **Search** for apps.

We'll extend the supported API endpoints in the future. The focus will mostly be on functions useful for research into mobile privacy and data protection.

As all the used endpoints are undocumented, we had to resort to reverse-engineering them. It is possible that we have misinterpreted the meaning of parameters or endpoints. 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.

Expand Down Expand Up @@ -196,6 +202,26 @@ The response looks like this:

</details>

### Search for apps

The following example searches the German App Store for apps with the term "education" and lists their names:

```ts
import { fetchAppDetails } from 'parse-tunes';

(async () => {
const apps = await searchApps({ searchTerm: 'education', country: 'DE', language: 'en-GB' });

for (const app of apps) console.log(app.name);
// Microsoft OneNote
// Goodnotes 6
// StudyCards - Karteikarten
//
})();
```

The metadata in the search results has the same format as for the app details, but here, you cannot choose which fields you want to fetch.

## License

This code is licensed under the MIT license, see the [`LICENSE`](LICENSE) file for details.
Expand Down
151 changes: 126 additions & 25 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ parse-tunes
- [AppDetailsRequest](README.md#appdetailsrequest)
- [AppDetailsResponse](README.md#appdetailsresponse)
- [AppDetailsResponseFragmentPerAttribute](README.md#appdetailsresponsefragmentperattribute)
- [AppSearchRequest](README.md#appsearchrequest)
- [AppSearchResponse](README.md#appsearchresponse)
- [AppSearchReturnedAttribute](README.md#appsearchreturnedattribute)
- [Chart](README.md#chart)
- [Genre](README.md#genre)
- [GenreName](README.md#genrename)
Expand Down Expand Up @@ -47,6 +50,7 @@ parse-tunes
- [fetchAppDetails](README.md#fetchappdetails)
- [fetchMediaApiToken](README.md#fetchmediaapitoken)
- [fetchTopApps](README.md#fetchtopapps)
- [searchApps](README.md#searchapps)

## Type Aliases

Expand Down Expand Up @@ -88,7 +92,7 @@ An artwork image in a response fragment.

#### Defined in

[app-details.ts:169](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L169)
[common/app-meta.ts:123](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L123)

___

Expand All @@ -100,45 +104,46 @@ An attribute (field) that can be requested from the app details endpoint.

#### Defined in

[app-details.ts:131](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L131)
[common/app-meta.ts:84](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L84)

___

### AppDetailsPlatformInRequest

Ƭ **AppDetailsPlatformInRequest**: ``"web"`` \| ``"iphone"`` \| ``"appletv"`` \| ``"ipad"`` \| ``"mac"`` \| ``"watch"``

A platform that can appear in the `platform` or `additionalPlatforms` parameter of a request to the app details
endpoint.
A platform that can appear in the `platform` or `additionalPlatforms` parameter of a request to the app details or
search endpoint.

#### Defined in

[app-details.ts:139](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L139)
[common/app-meta.ts:92](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L92)

___

### AppDetailsPlatformInResponse

Ƭ **AppDetailsPlatformInResponse**: [`AppDetailsPlatformInResponseForRequest`](README.md#appdetailsplatforminresponseforrequest)[keyof [`AppDetailsPlatformInResponseForRequest`](README.md#appdetailsplatforminresponseforrequest)]

A platform that can appear in the response from the app details endpoint as a key of the `platformAttributes` object.
A platform that can appear in the response from the app details or search endpoint as a key of the
`platformAttributes` object.

**`See`**

[https://github.com/tweaselORG/parse-tunes/issues/6#issuecomment-1400240548](https://github.com/tweaselORG/parse-tunes/issues/6#issuecomment-1400240548)

#### Defined in

[app-details.ts:159](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L159)
[common/app-meta.ts:113](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L113)

___

### AppDetailsPlatformInResponseForRequest

Ƭ **AppDetailsPlatformInResponseForRequest**: `Object`

A type mapping from the platforms that can appear in a request to the app details endpoint to the key of the
`platformAttributes` object in the response that they cause to be included.
A type mapping from the platforms that can appear in a request to the app details or search endpoint to the key of
the `platformAttributes` object in the response that they cause to be included.

**`See`**

Expand All @@ -157,7 +162,7 @@ A type mapping from the platforms that can appear in a request to the app detail

#### Defined in

[app-details.ts:146](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L146)
[common/app-meta.ts:99](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L99)

___

Expand Down Expand Up @@ -188,7 +193,7 @@ Parameters for an app details request.

#### Defined in

[app-details.ts:356](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L356)
[endpoints/app-details.ts:58](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/app-details.ts#L58)

___

Expand All @@ -210,7 +215,7 @@ tested responses. They may not be 100 % accurate.

#### Defined in

[app-details.ts:406](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L406)
[endpoints/app-details.ts:108](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/app-details.ts#L108)

___

Expand Down Expand Up @@ -334,7 +339,70 @@ Type mapping from the possible attributes to the additional data they add in the

#### Defined in

[app-details.ts:213](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L213)
[common/app-meta.ts:167](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L167)

___

### AppSearchRequest

Ƭ **AppSearchRequest**<`Country`, `Platforms`\>: `Object`

Parameters for an app search request.

#### Type parameters

| Name | Type |
| :------ | :------ |
| `Country` | extends [`MediaApiCountry`](README.md#mediaapicountry) |
| `Platforms` | extends [`AppDetailsPlatformInRequest`](README.md#appdetailsplatforminrequest)[] |

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `country` | `Country` | Which country's App Store to use. |
| `language` | [`AllowedLanguagesPerCountryInMediaApi`](README.md#allowedlanguagespercountryinmediaapi)[`Country`] | The language in which to fetch the app details. |
| `platforms?` | `Platforms` | The platform(s) for which to fetch details about the found apps. Will fetch details for all platforms if this parameter isn't specified. |
| `searchTerm` | `string` | The term to search for. |

#### Defined in

[endpoints/search.ts:12](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/search.ts#L12)

___

### AppSearchResponse

Ƭ **AppSearchResponse**<`Platforms`\>: `UnionToIntersection`<[`AppDetailsResponseFragmentPerAttribute`](README.md#appdetailsresponsefragmentperattribute)<`Platforms`\>[[`AppSearchReturnedAttribute`](README.md#appsearchreturnedattribute)]\>[]

The response from the app search API.

Note: There is no publicly available documentation for the API responses. The types were extrapolated from a few
tested responses. They may not be 100 % accurate.

#### Type parameters

| Name | Type |
| :------ | :------ |
| `Platforms` | extends [`AppDetailsPlatformInResponse`](README.md#appdetailsplatforminresponse) |

#### Defined in

[endpoints/search.ts:99](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/search.ts#L99)

___

### AppSearchReturnedAttribute

Ƭ **AppSearchReturnedAttribute**: ``"supportsArcade"`` \| ``"familyShareEnabledDate"`` \| ``"isFirstPartyHideableApp"`` \| ``"contentRatingsBySystem"`` \| ``"deviceFamilies"`` \| ``"chartPositions"`` \| ``"url"`` \| ``"usesLocationBackgroundMode"`` \| ``"userRating"`` \| ``"name"`` \| ``"genreDisplayName"`` \| ``"isPreorder"`` \| ``"isIOSBinaryMacOSCompatible"`` \| ``"artistName"`` \| ``"reviewsRestricted"`` \| ``"sellerLabel"`` \| ``"hasEula"`` \| ``"seller"`` \| ``"copyright"`` \| ``"minimumMacOSVersion"`` \| ``"isStandaloneWithCompanionForWatchOS"`` \| ``"isAppleWatchSupported"`` \| ``"is32bitOnly"`` \| ``"hasSafariExtension"`` \| ``"languageList"`` \| ``"requiresGameController"`` \| ``"requiredCapabilities"`` \| ``"offers"`` \| ``"supportedLocales"`` \| ``"requires32bit"`` \| ``"isSiriSupported"`` \| ``"isGameCenterEnabled"`` \| ``"releaseDate"`` \| ``"minimumOSVersion"`` \| ``"hasInAppPurchases"`` \| ``"bundleId"`` \| ``"hasMessagesExtension"`` \| ``"supportsGameController"`` \| ``"artwork"`` \| ``"hasFamilyShareableInAppPurchases"`` \| ``"isStandaloneForWatchOS"`` \| ``"isHiddenFromSpringboard"`` \| ``"isDeliveredInIOSAppForWatchOS"`` \| ``"hasPrivacyPolicyText"`` \| ``"editorialArtwork"`` \| ``"supportsPassbook"`` \| ``"requirementsString"`` \| ``"externalVersionId"``

The attributes that are returned in the app search response.

These are currently not configurable.

#### Defined in

[endpoints/search.ts:43](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/search.ts#L43)

___

Expand All @@ -346,7 +414,7 @@ The `popId` of a chart on the App Store.

#### Defined in

[top-charts.ts:18](https://github.com/tweaselORG/parse-tunes/blob/main/src/top-charts.ts#L18)
[endpoints/top-charts.ts:18](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/top-charts.ts#L18)

___

Expand Down Expand Up @@ -407,7 +475,7 @@ Small helper for response fragments that are listed under `platformAttributes`.

#### Defined in

[app-details.ts:163](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L163)
[common/app-meta.ts:117](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L117)

___

Expand All @@ -420,7 +488,7 @@ attribute.

#### Defined in

[app-details.ts:193](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L193)
[common/app-meta.ts:147](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L147)

___

Expand All @@ -432,7 +500,7 @@ A list of privacy types as declared in a privacy label, in short format as retur

#### Defined in

[app-details.ts:180](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L180)
[common/app-meta.ts:134](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L134)

___

Expand Down Expand Up @@ -530,7 +598,7 @@ Parameters for a top chart request.

#### Defined in

[top-charts.ts:21](https://github.com/tweaselORG/parse-tunes/blob/main/src/top-charts.ts#L21)
[endpoints/top-charts.ts:21](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/top-charts.ts#L21)

___

Expand All @@ -542,7 +610,7 @@ A list of the app IDs of the apps on the requested top chart.

#### Defined in

[top-charts.ts:31](https://github.com/tweaselORG/parse-tunes/blob/main/src/top-charts.ts#L31)
[endpoints/top-charts.ts:31](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/top-charts.ts#L31)

## Variables

Expand Down Expand Up @@ -763,7 +831,7 @@ Compiled through trial and error and from looking at requests made by the App St

#### Defined in

[app-details.ts:61](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L61)
[common/app-meta.ts:14](https://github.com/tweaselORG/parse-tunes/blob/main/src/common/app-meta.ts#L14)

___

Expand All @@ -780,7 +848,7 @@ These are in the order of their response size. We'll try the smallest one first.

#### Defined in

[app-details.ts:12](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L12)
[endpoints/app-details.ts:19](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/app-details.ts#L19)

___

Expand All @@ -807,7 +875,7 @@ https://github.com/tweaselORG/parse-tunes/issues/2#issuecomment-1377239436

#### Defined in

[top-charts.ts:9](https://github.com/tweaselORG/parse-tunes/blob/main/src/top-charts.ts#L9)
[endpoints/top-charts.ts:9](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/top-charts.ts#L9)

___

Expand Down Expand Up @@ -1167,7 +1235,7 @@ The app details, typed according to the attributes you specified.

#### Defined in

[app-details.ts:420](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L420)
[endpoints/app-details.ts:122](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/app-details.ts#L122)

___

Expand All @@ -1193,7 +1261,7 @@ The token.

#### Defined in

[app-details.ts:29](https://github.com/tweaselORG/parse-tunes/blob/main/src/app-details.ts#L29)
[endpoints/app-details.ts:36](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/app-details.ts#L36)

___

Expand All @@ -1218,4 +1286,37 @@ A list of numerical app IDs in the requested top chart. The list is sorted by ra

#### Defined in

[top-charts.ts:44](https://github.com/tweaselORG/parse-tunes/blob/main/src/top-charts.ts#L44)
[endpoints/top-charts.ts:44](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/top-charts.ts#L44)

___

### searchApps

**searchApps**<`Country`, `Platforms`\>(`request`): `Promise`<[`AppSearchResponse`](README.md#appsearchresponse)<[`AppDetailsPlatformInResponseForRequest`](README.md#appdetailsplatforminresponseforrequest)[`Platforms`[`number`]]\>\>

Search for apps on the the App Store. You can request a lot of different information about the app. The `attributes`
parameter specifies which attributes to fetch. See [appDetailsAvailableAttributes](README.md#appdetailsavailableattributes) for a list of all available
attributes.

#### Type parameters

| Name | Type |
| :------ | :------ |
| `Country` | extends ``"DZ"`` \| ``"AO"`` \| ``"AI"`` \| ``"AG"`` \| ``"AR"`` \| ``"AM"`` \| ``"AU"`` \| ``"AT"`` \| ``"AZ"`` \| ``"BH"`` \| ``"BB"`` \| ``"BY"`` \| ``"BE"`` \| ``"BZ"`` \| ``"BM"`` \| ``"BO"`` \| ``"BW"`` \| ``"BR"`` \| ``"VG"`` \| ``"BN"`` \| ``"BG"`` \| ``"CA"`` \| ``"KY"`` \| ``"CL"`` \| ``"CN"`` \| ``"CO"`` \| ``"CR"`` \| ``"CI"`` \| ``"HR"`` \| ``"CY"`` \| ``"CZ"`` \| ``"DK"`` \| ``"DM"`` \| ``"DO"`` \| ``"EC"`` \| ``"EG"`` \| ``"SV"`` \| ``"EE"`` \| ``"FI"`` \| ``"FR"`` \| ``"DE"`` \| ``"GH"`` \| ``"GR"`` \| ``"GD"`` \| ``"GT"`` \| ``"GY"`` \| ``"HN"`` \| ``"HK"`` \| ``"HU"`` \| ``"IS"`` \| ``"IN"`` \| ``"ID"`` \| ``"IE"`` \| ``"IL"`` \| ``"IT"`` \| ``"JM"`` \| ``"JP"`` \| ``"JO"`` \| ``"KZ"`` \| ``"KE"`` \| ``"KR"`` \| ``"KW"`` \| ``"LV"`` \| ``"LB"`` \| ``"LT"`` \| ``"LU"`` \| ``"MO"`` \| ``"MK"`` \| ``"MG"`` \| ``"MY"`` \| ``"MV"`` \| ``"ML"`` \| ``"MT"`` \| ``"MU"`` \| ``"MX"`` \| ``"MD"`` \| ``"MS"`` \| ``"NP"`` \| ``"NL"`` \| ``"NZ"`` \| ``"NI"`` \| ``"NE"`` \| ``"NG"`` \| ``"NO"`` \| ``"OM"`` \| ``"PK"`` \| ``"PA"`` \| ``"PY"`` \| ``"PE"`` \| ``"PH"`` \| ``"PL"`` \| ``"PT"`` \| ``"QA"`` \| ``"RO"`` \| ``"RU"`` \| ``"SA"`` \| ``"SN"`` \| ``"RS"`` \| ``"SG"`` \| ``"SK"`` \| ``"SI"`` \| ``"ZA"`` \| ``"ES"`` \| ``"LK"`` \| ``"KN"`` \| ``"LC"`` \| ``"VC"`` \| ``"SR"`` \| ``"SE"`` \| ``"CH"`` \| ``"TW"`` \| ``"TZ"`` \| ``"TH"`` \| ``"BS"`` \| ``"TT"`` \| ``"TN"`` \| ``"TR"`` \| ``"TC"`` \| ``"UG"`` \| ``"GB"`` \| ``"UA"`` \| ``"AE"`` \| ``"UY"`` \| ``"US"`` \| ``"UZ"`` \| ``"VE"`` \| ``"VN"`` \| ``"YE"`` \| ``"AF"`` \| ``"AL"`` \| ``"BJ"`` \| ``"BT"`` \| ``"BA"`` \| ``"BF"`` \| ``"KH"`` \| ``"CM"`` \| ``"CV"`` \| ``"TD"`` \| ``"CD"`` \| ``"SZ"`` \| ``"FJ"`` \| ``"GA"`` \| ``"GM"`` \| ``"GE"`` \| ``"GW"`` \| ``"IQ"`` \| ``"XK"`` \| ``"KG"`` \| ``"LA"`` \| ``"LR"`` \| ``"LY"`` \| ``"MW"`` \| ``"MR"`` \| ``"FM"`` \| ``"MN"`` \| ``"ME"`` \| ``"MA"`` \| ``"MZ"`` \| ``"MM"`` \| ``"NA"`` \| ``"NR"`` \| ``"PW"`` \| ``"PG"`` \| ``"CG"`` \| ``"RW"`` \| ``"SC"`` \| ``"SL"`` \| ``"SB"`` \| ``"ST"`` \| ``"TJ"`` \| ``"TO"`` \| ``"TM"`` \| ``"VU"`` \| ``"ZM"`` \| ``"ZW"`` |
| `Platforms` | extends [`AppDetailsPlatformInRequest`](README.md#appdetailsplatforminrequest)[] |

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `request` | [`AppSearchRequest`](README.md#appsearchrequest)<`Country`, `Platforms`\> | The request parameters. |

#### Returns

`Promise`<[`AppSearchResponse`](README.md#appsearchresponse)<[`AppDetailsPlatformInResponseForRequest`](README.md#appdetailsplatforminresponseforrequest)[`Platforms`[`number`]]\>\>

The app details, typed according to the attributes you specified.

#### Defined in

[endpoints/search.ts:112](https://github.com/tweaselORG/parse-tunes/blob/main/src/endpoints/search.ts#L112)
Loading

0 comments on commit b733096

Please sign in to comment.