From 615ec858501ddc2518c80f896d31e5fb99ad88ff Mon Sep 17 00:00:00 2001 From: Olivier Bouillet Date: Sun, 7 Sep 2025 22:02:37 +0200 Subject: [PATCH] feat: add release details --- README.md | 199 ++++++++++-------- .../src/needUpdate.js | 22 +- .../src/providers/appStore.js | 3 + .../src/providers/playStore.js | 10 +- .../src/providers/types.js | 1 + 5 files changed, 137 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 6fbda8d5..a91482d4 100644 --- a/README.md +++ b/README.md @@ -11,29 +11,38 @@ This library gets the latest app version by parsing google play store, apple app Parsing code is referenced from [here](http://itmir.tistory.com/524) ### Looking for maintainers! + I have almost zero experience in ios development, and I am no longer working on mobile app development(doing backend and devops works mainly and some web frontend). It makes it hard to maintain this library actively. Hope to have someone to help maintaining react-native-version-check! ### expo + react-native-version-check supports [expo](https://expo.io)! with [react-native-version-check-expo](https://www.npmjs.com/package/react-native-version-check-expo) + - usage + ```js // import -import VersionCheck from 'react-native-version-check-expo' +import VersionCheck from 'react-native-version-check-expo'; -VersionCheck.getCountry().then(country => console.log(country)) +VersionCheck.getCountry().then(country => console.log(country)); ``` ## Getting started - - npm - ```bash - $ npm install react-native-version-check - ``` - - yarn - ```bash - $ yarn add react-native-version-check - ``` + +- npm + +```bash +$ npm install react-native-version-check +``` + +- yarn + +```bash +$ yarn add react-native-version-check +``` ### Example + ```bash $ git clone https://github.com/kimxogus/react-native-version-check.git $ cd react-native-version-check/example @@ -42,35 +51,43 @@ $ react-native run-android # or react-native run-ios ``` ### Automatic Installation + ```bash $ react-native link react-native-version-check ``` ### Manual Installation + #### - iOS - Link Manually -* Add ```.xcodeproj``` file as library to XCode project. + +- Add `.xcodeproj` file as library to XCode project. + 1. In project navigator, right click Libraries - 2. Select ```Add Files to [PROJECT_NAME]``` - 3. Add the ```node_modules/react-native-version-check/ios/RNVersionCheck.xcodeproj``` file + 2. Select `Add Files to [PROJECT_NAME]` + 3. Add the `node_modules/react-native-version-check/ios/RNVersionCheck.xcodeproj` file -* Add the ```libRNVersionCheck.a``` from the ```RNVersionCheck``` project to your project's Build Phases > Link Binary With Libraries +- Add the `libRNVersionCheck.a` from the `RNVersionCheck` project to your project's Build Phases > Link Binary With Libraries #### iOS - CocoaPods Package Manager -* Add to your `Podfile` (assuming it's in `ios/Podfile`): + +- Add to your `Podfile` (assuming it's in `ios/Podfile`): ```ruby pod 'react-native-version-check', :path => '../node_modules/react-native-version-check' ``` -* Reinstall pod with `cd ios && pod install && cd ..` +- Reinstall pod with `cd ios && pod install && cd ..` #### - Android -* Append the following lines to `android/settings.gradle`: +- Append the following lines to `android/settings.gradle`: + ```gradle ... include ':react-native-version-check' project(':react-native-version-check').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-version-check/android') ``` -* Insert the following lines inside the dependencies block in `android/app/build.gradle`: + +- Insert the following lines inside the dependencies block in `android/app/build.gradle`: + ```gradle ... dependencies { @@ -78,7 +95,9 @@ dependencies { compile project(':react-native-version-check') } ``` -* Open up `android/app/src/main/java/[...]/MainApplication.java` + +- Open up `android/app/src/main/java/[...]/MainApplication.java` + ```java ...... import io.xogus.reactnative.versioncheck.RNVersionCheckPackage; // <--- HERE @@ -94,79 +113,75 @@ protected List getPackages() { ``` ## Usage + ```javascript import { Linking } from 'react-native'; import VersionCheck from 'react-native-version-check'; -VersionCheck.getCountry() - .then(country => console.log(country)); // KR -console.log(VersionCheck.getPackageName()); // com.reactnative.app +VersionCheck.getCountry().then(country => console.log(country)); // KR +console.log(VersionCheck.getPackageName()); // com.reactnative.app console.log(VersionCheck.getCurrentBuildNumber()); // 10 -console.log(VersionCheck.getCurrentVersion()); // 0.1.1 +console.log(VersionCheck.getCurrentVersion()); // 0.1.1 -VersionCheck.getLatestVersion() - .then(latestVersion => { - console.log(latestVersion); // 0.1.2 - }); +VersionCheck.getLatestVersion().then(latestVersion => { + console.log(latestVersion); // 0.1.2 +}); VersionCheck.getLatestVersion({ - provider: 'appStore' // for iOS - }) - .then(latestVersion => { - console.log(latestVersion); // 0.1.2 - }); + provider: 'appStore', // for iOS +}).then(latestVersion => { + console.log(latestVersion); // 0.1.2 +}); VersionCheck.getLatestVersion({ - provider: 'playStore' // for Android - }) - .then(latestVersion => { - console.log(latestVersion); // 0.1.2 - }); + provider: 'playStore', // for Android +}).then(latestVersion => { + console.log(latestVersion); // 0.1.2 +}); -VersionCheck.getLatestVersion() // Automatically choose profer provider using `Platform.select` by device platform. +VersionCheck.getLatestVersion() // Automatically choose profer provider using `Platform.select` by device platform. .then(latestVersion => { - console.log(latestVersion); // 0.1.2 + console.log(latestVersion); // 0.1.2 }); VersionCheck.getLatestVersion({ forceUpdate: true, - provider: () => fetch('http://your.own/api') - .then(r => r.json()) - .then(({version}) => version), // You can get latest version from your own api. -}).then(latestVersion =>{ + provider: () => + fetch('http://your.own/api') + .then(r => r.json()) + .then(({ version }) => version), // You can get latest version from your own api. +}).then(latestVersion => { console.log(latestVersion); }); -VersionCheck.needUpdate() - .then(async res => { - console.log(res.isNeeded); // true - if (res.isNeeded) { - Linking.openURL(res.storeUrl); // open store if update is needed. - } - }); +VersionCheck.needUpdate().then(async res => { + console.log(res.isNeeded); // true + if (res.isNeeded) { + Linking.openURL(res.storeUrl); // open store if update is needed. + } +}); VersionCheck.needUpdate({ - depth: 2 + depth: 2, }).then(res => { console.log(res.isNeeded); // false; because first two fields of current and the latest versions are the same as "0.1". }); VersionCheck.needUpdate({ - currentVersion: "1.0", - latestVersion: "2.0" + currentVersion: '1.0', + latestVersion: '2.0', }).then(res => { - console.log(res.isNeeded); // true + console.log(res.isNeeded); // true }); VersionCheck.needUpdate({ depth: 1, - currentVersion: "2.1", - latestVersion: "2.0", + currentVersion: '2.1', + latestVersion: '2.0', }).then(res => { - console.log(res.isNeeded); // false + console.log(res.isNeeded); // false }); - ``` ## Methods @@ -176,58 +191,62 @@ VersionCheck.needUpdate({ - #**`getCurrentBuildNumber()`** _(buildNumber: Number)_ - Returns current app build number. - #**`getStoreUrl([option: Object])`** _(Promise)_ - Returns url of Play Market or App Store of app. - #**`getAppStoreUrl([option: Object])`** _(Promise)_ - Returns url of App Store of app. + - Option - Field | Type | Default - --- | --- | --- - appID | _string_ | App ID - ignoreErrors | _boolean_ | true + | Field | Type | Default | + | ------------ | --------- | ------- | + | appID | _string_ | App ID | + | ignoreErrors | _boolean_ | true | + - #**`getPlayStoreUrl([option: Object])`** _(Promise)_ - Returns url of Play Store of app. + - Option - Field | Type | Default - --- | --- | --- - packageName | _string_ | Package Name - ignoreErrors | _boolean_ | true + | Field | Type | Default | + | ------------ | --------- | ------------ | + | packageName | _string_ | Package Name | + | ignoreErrors | _boolean_ | true | - #**`getCurrentVersion()`** _(currentVersion: String)_ - Returns current app version. - #**`getLatestVersion([option: Object])`** _(Promise)_ - Returns the latest app version parsed from url. Returns `null` when parsing error occurs. + - Option - Field | Type | Default - --- | --- | --- - forceUpdate | _boolean_ | ```false``` - provider | _string_ or _function_ | provider name or function that returns promise or value of the latest version - fetchOptions | _object_ | isomorphic-fetch options (https://github.github.io/fetch/) - ignoreErrors | _boolean_ | true + | Field | Type | Default | + | ------------ | ---------------------- | ----------------------------------------------------------------------------- | + | forceUpdate | _boolean_ | `false` | + | provider | _string_ or _function_ | provider name or function that returns promise or value of the latest version | + | fetchOptions | _object_ | isomorphic-fetch options (https://github.github.io/fetch/) | + | ignoreErrors | _boolean_ | true | - #**`needUpdate([option: Object])`** _(Promise)_ - Returns an object contains with boolean value whether update needed, current version and latest version. Current and the latest app versions are first split by delimiter, and check each split numbers into depth. + - Option - Field | Type | Default - --- | --- | --- - currentVersion | _string_ | app's current version from [getCurrentVersion()](#getCurrentVersion) - latestVersion | _string_ | app's latest version from [getLatestVersion()](#getLatestVersion) - depth | _number_ | ```Infinity``` - forceUpdate | _boolean_ | ```false``` - provider | _string_ or _function_ | provider name or function that returns promise or value of the latest version - fetchOptions | _object_ | isomorphic-fetch options (https://github.github.io/fetch/) - ignoreErrors | _boolean_ | true + | Field | Type | Default | + | -------------- | ---------------------- | ----------------------------------------------------------------------------- | + | currentVersion | _string_ | app's current version from [getCurrentVersion()](#getCurrentVersion) | + | latestVersion | _string_ | app's latest version from [getLatestVersion()](#getLatestVersion) | + | depth | _number_ | `Infinity` | + | forceUpdate | _boolean_ | `false` | + | provider | _string_ or _function_ | provider name or function that returns promise or value of the latest version | + | fetchOptions | _object_ | isomorphic-fetch options (https://github.github.io/fetch/) | + | ignoreErrors | _boolean_ | true | - Result - Field | Type - --- | --- - isNeeded | _boolean_ - storeUrl | _string_ - currentVersion | _string_ - latestVersion | _string_ - - + | Field | Type | + | -------------- | --------- | + | isNeeded | _boolean_ | + | storeUrl | _string_ | + | currentVersion | _string_ | + | latestVersion | _string_ | + | releaseNote | _string_ | ## License -MIT +MIT [npm-image]: https://img.shields.io/npm/v/react-native-version-check.svg [npm-url]: https://npmjs.org/package/react-native-version-check diff --git a/packages/react-native-version-check/src/needUpdate.js b/packages/react-native-version-check/src/needUpdate.js index 6ecfbf28..9326c1c5 100644 --- a/packages/react-native-version-check/src/needUpdate.js +++ b/packages/react-native-version-check/src/needUpdate.js @@ -38,6 +38,7 @@ export type NeedUpdateResult = { storeUrl: string, currentVersion: string, latestVersion: string, + releaseNote?: string, }; export default async function needUpdate( @@ -59,23 +60,31 @@ export default async function needUpdate( let latestVersion; let providerStoreUrl = ''; + let storeReleaseNote; if (isNil(option.latestVersion)) { if (option.provider.getVersion) { const { version, storeUrl, + releaseNote, }: IVersionAndStoreUrl = await option.provider.getVersion(option); latestVersion = version; providerStoreUrl = storeUrl; + storeReleaseNote = releaseNote; } if (providers[option.provider]) { - const { version, storeUrl }: IVersionAndStoreUrl = await providers[ - option.provider - ].getVersion(option); + const { + version, + storeUrl, + releaseNote, + }: IVersionAndStoreUrl = await providers[option.provider].getVersion( + option + ); latestVersion = version; providerStoreUrl = storeUrl; + storeReleaseNote = releaseNote; } option.latestVersion = latestVersion || (await getLatestVersion(option)); @@ -85,7 +94,8 @@ export default async function needUpdate( option.currentVersion, option.latestVersion, option, - providerStoreUrl + providerStoreUrl, + storeReleaseNote, ); } catch (e) { if (option.ignoreErrors) { @@ -100,7 +110,8 @@ function checkIfUpdateNeeded( currentVersion, latestVersion, option, - providerStoreUrl + providerStoreUrl, + releaseNote ) { const currentVersionWithDepth = getVersionWithDepth( currentVersion, @@ -116,6 +127,7 @@ function checkIfUpdateNeeded( storeUrl: providerStoreUrl, currentVersion, latestVersion, + releaseNote, }; return Promise.resolve(response); diff --git a/packages/react-native-version-check/src/providers/appStore.js b/packages/react-native-version-check/src/providers/appStore.js index ac4c6b0e..55c6e09a 100644 --- a/packages/react-native-version-check/src/providers/appStore.js +++ b/packages/react-native-version-check/src/providers/appStore.js @@ -8,6 +8,7 @@ export type AppStoreGetVersionOption = { packageName?: string, fetchOptions?: any, ignoreErrors?: boolean, + releaseNote?: boolean, }; export interface IAppStoreProvider extends IProvider { @@ -38,10 +39,12 @@ class AppStoreProvider implements IProvider { if (json.resultCount) { const version = json.results[0].version; const appId = json.results[0].trackId; + const releaseNote = json.results[0].releaseNotes; const storeUrl = `itms-apps://apps.apple.com/${countryCode}app/id${appId}`; return Promise.resolve({ version, storeUrl, + releaseNote, }); } return Promise.reject('No info about this app.'); diff --git a/packages/react-native-version-check/src/providers/playStore.js b/packages/react-native-version-check/src/providers/playStore.js index 8a91ddc3..9bf14070 100644 --- a/packages/react-native-version-check/src/providers/playStore.js +++ b/packages/react-native-version-check/src/providers/playStore.js @@ -34,7 +34,7 @@ class PlayStoreProvider implements IProvider { ...opt.fetchOptions, }; - const storeUrl = `https://play.google.com/store/apps/details?id=${opt.packageName}&hl=en&gl=US`; + const storeUrl = `https://play.google.com/store/apps/details?id=${opt.packageName}&hl=${opt.language || 'en'}`; return fetch(storeUrl, opt.fetchOptions) .then(res => res.text()) @@ -49,8 +49,12 @@ class PlayStoreProvider implements IProvider { const matchNewLayout = text.match(/\[\[\["([\d-.]+?)"\]\]/); if (matchNewLayout) { const latestVersion = matchNewLayout[1].trim(); - - return Promise.resolve({ version: latestVersion, storeUrl }); + const releaseNoteMatch = text.match(/
([\s\S]*?)<\/div>/); + return Promise.resolve({ + version: latestVersion, + storeUrl, + releaseNote: releaseNoteMatch?.[1]?.replace(/
/g, '\n'), + }); } return Promise.reject(error(text)); diff --git a/packages/react-native-version-check/src/providers/types.js b/packages/react-native-version-check/src/providers/types.js index 78a81f6d..e59ec1fa 100644 --- a/packages/react-native-version-check/src/providers/types.js +++ b/packages/react-native-version-check/src/providers/types.js @@ -6,4 +6,5 @@ export interface IProvider { export interface IVersionAndStoreUrl { version: string; storeUrl: string; + releaseNote?: string; }