@lucidaquarian/app-version-checker 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lucidaquarian
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.
package/README.md ADDED
@@ -0,0 +1,240 @@
1
+ # @lucidaquarian/app-version-checker
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@lucidaquarian/app-version-checker.svg)](https://www.npmjs.com/package/@lucidaquarian/app-version-checker)
4
+ [![downloads](https://img.shields.io/npm/dm/@lucidaquarian/app-version-checker.svg)](https://www.npmjs.com/package/@lucidaquarian/app-version-checker)
5
+ [![license](https://img.shields.io/npm/l/@lucidaquarian/app-version-checker.svg)](./LICENSE)
6
+ [![node](https://img.shields.io/node/v/@lucidaquarian/app-version-checker.svg)](https://nodejs.org)
7
+
8
+ > Detect when your **Cordova** or **Capacitor** app is out of date and prompt users to update.
9
+
10
+ `@lucidaquarian/app-version-checker` reads the version installed on the device, compares it against the latest published version — from the **Apple App Store**, **Google Play**, or **your own API** — and hands back a single, actionable result: is an update available, what kind (major / minor / patch), and should it be forced?
11
+
12
+ ```js
13
+ const result = await checker.checkForUpdate();
14
+ // {
15
+ // currentVersion: '1.2.0',
16
+ // latestVersion: '1.3.1',
17
+ // updateAvailable: true,
18
+ // updateType: 'minor',
19
+ // forceUpdate: false,
20
+ // storeUrl: 'https://apps.apple.com/…',
21
+ // releaseNotes: 'Bug fixes and improvements',
22
+ // platform: 'capacitor',
23
+ // devicePlatform: 'ios'
24
+ // }
25
+ ```
26
+
27
+ ## Why
28
+
29
+ Mobile users routinely run months-old builds. Shipping a fix doesn't help anyone still on the old version. This library gives you the one signal you need at launch — *"is this device behind, and by how much?"* — so you can show an optional nudge or a hard "update required" gate.
30
+
31
+ ## Features
32
+
33
+ - **Dual platform** — works with both Cordova (`cordova-plugin-app-version`) and Capacitor (`@capacitor/app`)
34
+ - **Auto-detection** — picks the right platform at runtime, or set it explicitly
35
+ - **Multiple version sources** — Apple App Store (iTunes Lookup API), Google Play, or a custom endpoint
36
+ - **Forced updates** — define a minimum supported version locally or from your server
37
+ - **Semantic versioning** — built-in, spec-compliant semver parser and comparator (including prerelease ordering)
38
+ - **Network timeouts** — every remote lookup is bounded so a check can never hang
39
+ - **TypeScript ready** — ships with full `.d.ts` declarations
40
+ - **Zero runtime dependencies**
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ npm install @lucidaquarian/app-version-checker
46
+ ```
47
+
48
+ ### Platform prerequisites
49
+
50
+ **Cordova:**
51
+ ```bash
52
+ cordova plugin add cordova-plugin-app-version
53
+ ```
54
+
55
+ **Capacitor:**
56
+ ```bash
57
+ npm install @capacitor/app
58
+ npx cap sync
59
+ ```
60
+
61
+ > Requires **Node.js ≥ 18** (the store lookups use the global `fetch` API).
62
+
63
+ ## Quick start
64
+
65
+ ```js
66
+ import { AppVersionChecker } from '@lucidaquarian/app-version-checker';
67
+
68
+ const checker = new AppVersionChecker({
69
+ platform: 'auto', // 'cordova' | 'capacitor' | 'auto'
70
+ iosBundleId: 'com.yourcompany.yourapp',
71
+ androidPackageName: 'com.yourcompany.yourapp',
72
+ });
73
+
74
+ const result = await checker.checkForUpdate();
75
+
76
+ if (result.forceUpdate) {
77
+ // Block the user — they must update to continue
78
+ } else if (result.updateAvailable) {
79
+ // Show an optional "update available" prompt
80
+ }
81
+ ```
82
+
83
+ ## How it works
84
+
85
+ 1. **Detect the platform** — Capacitor is preferred when both are present; override with `platform`.
86
+ 2. **Read the installed version** from the native plugin.
87
+ 3. **Fetch the latest version**, chosen by device platform:
88
+ - `ios` → Apple App Store (needs `iosBundleId`)
89
+ - `android` → Google Play (needs `androidPackageName`)
90
+ - any platform → your `customEndpoint`, if configured (takes priority over the stores)
91
+ 4. **Compare** the two with the built-in semver engine and return the result.
92
+
93
+ ## Configuration
94
+
95
+ | Option | Type | Default | Description |
96
+ |---|---|---|---|
97
+ | `platform` | `'cordova' \| 'capacitor' \| 'auto'` | `'auto'` | Which platform provider to use |
98
+ | `iosBundleId` | `string` | `''` | iOS bundle ID for App Store lookups |
99
+ | `androidPackageName` | `string` | `''` | Android package name for Play Store lookups |
100
+ | `country` | `string` | `'us'` | Two-letter country code for the App Store region |
101
+ | `customEndpoint` | `string` | `''` | URL to your own version API (skips store lookups) |
102
+ | `customEndpointOptions` | `RequestInit` | `{}` | Extra `fetch` options for the custom endpoint |
103
+ | `minVersion` | `string` | `''` | Local minimum supported version for forced updates |
104
+ | `timeout` | `number` | `10000` | Network timeout (ms) for store / custom-endpoint requests |
105
+
106
+ ## Result shape
107
+
108
+ `checkForUpdate()` resolves to:
109
+
110
+ ```ts
111
+ {
112
+ currentVersion: string; // installed version, e.g. "1.2.0"
113
+ latestVersion: string; // latest available, e.g. "1.3.1"
114
+ updateAvailable: boolean; // true if latest > current
115
+ updateType: 'major' | 'minor' | 'patch' | 'prerelease' | 'none';
116
+ forceUpdate: boolean; // true if current is below the minimum supported version
117
+ storeUrl: string; // link to the store listing (if available)
118
+ releaseNotes: string; // release notes (if available)
119
+ platform: string; // 'cordova' | 'capacitor'
120
+ devicePlatform: string; // 'ios' | 'android' | 'web'
121
+ }
122
+ ```
123
+
124
+ ### Forced updates
125
+
126
+ An update is marked `forceUpdate: true` when the installed version is below the effective minimum. The minimum is resolved as **remote `minVersion` (from your custom endpoint) → local `minVersion` config**, and a remote `forceUpdate: true` flag also forces it.
127
+
128
+ ## API reference
129
+
130
+ ### `new AppVersionChecker(config?)`
131
+ Create a checker instance. See [Configuration](#configuration).
132
+
133
+ ### `checker.checkForUpdate(): Promise<VersionCheckResult>`
134
+ Run a full check — reads the installed version and the latest remote version, compares them, and returns the [result](#result-shape).
135
+
136
+ ### `checker.getCurrentVersion(): Promise<string>`
137
+ The installed version string.
138
+
139
+ ### `checker.getAppInfo(): Promise<AppInfo>`
140
+ Full app info: `{ versionName, versionCode, packageName, appName }`.
141
+
142
+ ### `checker.getLatestVersion(): Promise<object>`
143
+ Just the remote version info from the store or custom endpoint.
144
+
145
+ ### `checker.getDevicePlatform(): string`
146
+ The current OS platform — `'ios'`, `'android'`, or `'web'`.
147
+
148
+ ### `AppVersionChecker.compareVersions(current, latest)` *(static)*
149
+ Compare two version strings without any device dependency:
150
+
151
+ ```js
152
+ AppVersionChecker.compareVersions('1.0.0', '2.0.0');
153
+ // { updateAvailable: true, updateType: 'major' }
154
+ ```
155
+
156
+ ### `SemVer`
157
+
158
+ Standalone, spec-compliant semver utilities:
159
+
160
+ ```js
161
+ import { SemVer } from '@lucidaquarian/app-version-checker';
162
+
163
+ SemVer.parse('1.2.3'); // { major: 1, minor: 2, patch: 3, prerelease: '' }
164
+ SemVer.compare('1.0.0', '2.0.0'); // -1
165
+ SemVer.gt('2.0.0', '1.0.0'); // true
166
+ SemVer.lt('1.0.0', '2.0.0'); // true
167
+ SemVer.eq('1.0.0', '1.0.0'); // true
168
+ SemVer.gte('1.0.0', '1.0.0'); // true
169
+ SemVer.updateType('1.0.0', '2.0.0'); // 'major'
170
+ SemVer.isValid('1.2.3'); // true
171
+ SemVer.isValid('not-a-version'); // false
172
+ ```
173
+
174
+ Prerelease identifiers are compared per the SemVer spec (numeric identifiers compared numerically, ranked below alphanumeric), so `1.0.0-alpha.2 < 1.0.0-alpha.10`.
175
+
176
+ ### Store lookups
177
+
178
+ The store functions are also exported directly:
179
+
180
+ ```js
181
+ import {
182
+ fetchAppStoreVersion, // (bundleId, country?, timeoutMs?)
183
+ fetchPlayStoreVersion, // (packageName, timeoutMs?)
184
+ fetchCustomEndpoint, // (url, options?, timeoutMs?)
185
+ } from '@lucidaquarian/app-version-checker';
186
+ ```
187
+
188
+ > **Google Play note:** Google has no official public version API, so `fetchPlayStoreVersion` scrapes the store page and can break if Google changes their markup. For production Android checks, prefer a `customEndpoint` backed by your server or the Google Play Developer API.
189
+
190
+ ## Custom endpoint
191
+
192
+ Set `customEndpoint` and the checker fetches from your URL instead of the stores. Your endpoint should return JSON:
193
+
194
+ ```json
195
+ {
196
+ "version": "2.1.0",
197
+ "minVersion": "1.5.0",
198
+ "releaseNotes": "Performance improvements and bug fixes.",
199
+ "storeUrl": "https://apps.apple.com/app/id123456789",
200
+ "forceUpdate": false
201
+ }
202
+ ```
203
+
204
+ Only `version` is required; all other fields are optional. Any extra fields you include are passed through on the result.
205
+
206
+ ```js
207
+ const checker = new AppVersionChecker({
208
+ customEndpoint: 'https://api.example.com/app/version',
209
+ customEndpointOptions: {
210
+ headers: { Authorization: 'Bearer TOKEN' },
211
+ },
212
+ timeout: 8000,
213
+ });
214
+ ```
215
+
216
+ ## Framework examples
217
+
218
+ See the [`examples/`](./examples) directory for complete integration examples:
219
+
220
+ - [`cordova-usage.js`](./examples/cordova-usage.js) — Cordova with native dialogs
221
+ - [`capacitor-usage.js`](./examples/capacitor-usage.js) — Capacitor with Ionic Angular and a React hook
222
+
223
+ ## TypeScript
224
+
225
+ Type declarations ship with the package — no `@types` install needed:
226
+
227
+ ```ts
228
+ import { AppVersionChecker, VersionCheckResult } from '@lucidaquarian/app-version-checker';
229
+ ```
230
+
231
+ ## Running tests
232
+
233
+ ```bash
234
+ npm test # unit tests (no network — fetch and native globals are mocked)
235
+ npm run lint # zero-dependency syntax check over src/
236
+ ```
237
+
238
+ ## License
239
+
240
+ [MIT](./LICENSE)
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Example: Using @lucidaquarian/app-version-checker in a Capacitor application.
3
+ *
4
+ * Prerequisites:
5
+ * npm install @capacitor/app
6
+ * npm install @lucidaquarian/app-version-checker
7
+ *
8
+ * Works with Capacitor 4+ / 5+ and Ionic frameworks.
9
+ */
10
+
11
+ const { AppVersionChecker } = require('@lucidaquarian/app-version-checker');
12
+
13
+ // ─── Option A: Store-based lookup ────────────────────────────────────
14
+
15
+ const checker = new AppVersionChecker({
16
+ platform: 'capacitor', // explicitly use Capacitor provider
17
+ iosBundleId: 'com.yourcompany.yourapp',
18
+ androidPackageName: 'com.yourcompany.yourapp',
19
+ country: 'us',
20
+ });
21
+
22
+ // ─── Option B: Custom API endpoint ───────────────────────────────────
23
+
24
+ const checkerWithCustomEndpoint = new AppVersionChecker({
25
+ platform: 'capacitor',
26
+ customEndpoint: 'https://api.yourcompany.com/app/version',
27
+ customEndpointOptions: {
28
+ headers: { 'Authorization': 'Bearer YOUR_TOKEN' },
29
+ },
30
+ minVersion: '1.5.0', // force-update below this version
31
+ });
32
+
33
+ // ─── Run the Check ───────────────────────────────────────────────────
34
+
35
+ async function performVersionCheck() {
36
+ try {
37
+ const result = await checker.checkForUpdate();
38
+
39
+ console.log(JSON.stringify(result, null, 2));
40
+ // {
41
+ // currentVersion: "1.2.0",
42
+ // latestVersion: "1.3.1",
43
+ // updateAvailable: true,
44
+ // updateType: "minor",
45
+ // forceUpdate: false,
46
+ // storeUrl: "https://apps.apple.com/...",
47
+ // releaseNotes: "Bug fixes and improvements",
48
+ // platform: "capacitor",
49
+ // devicePlatform: "ios"
50
+ // }
51
+
52
+ return result;
53
+ } catch (err) {
54
+ console.warn('Version check failed:', err.message);
55
+ return null;
56
+ }
57
+ }
58
+
59
+ // ─── Ionic / Angular Integration Example ─────────────────────────────
60
+
61
+ /*
62
+ // In an Ionic Angular service (version-check.service.ts):
63
+
64
+ import { Injectable } from '@angular/core';
65
+ import { AlertController } from '@ionic/angular';
66
+ import { AppVersionChecker } from '@lucidaquarian/app-version-checker';
67
+ import { Browser } from '@capacitor/browser';
68
+
69
+ @Injectable({ providedIn: 'root' })
70
+ export class VersionCheckService {
71
+ private checker = new AppVersionChecker({
72
+ platform: 'capacitor',
73
+ iosBundleId: 'com.yourcompany.yourapp',
74
+ androidPackageName: 'com.yourcompany.yourapp',
75
+ });
76
+
77
+ constructor(private alertCtrl: AlertController) {}
78
+
79
+ async checkOnLaunch(): Promise<void> {
80
+ try {
81
+ const result = await this.checker.checkForUpdate();
82
+
83
+ if (result.forceUpdate) {
84
+ await this.showForceUpdate(result);
85
+ } else if (result.updateAvailable) {
86
+ await this.showOptionalUpdate(result);
87
+ }
88
+ } catch {
89
+ // Silently fail — don't block the user
90
+ }
91
+ }
92
+
93
+ private async showForceUpdate(result) {
94
+ const alert = await this.alertCtrl.create({
95
+ header: 'Update Required',
96
+ message: `Please update to version ${result.latestVersion} to continue.`,
97
+ backdropDismiss: false,
98
+ buttons: [{
99
+ text: 'Update Now',
100
+ handler: () => Browser.open({ url: result.storeUrl }),
101
+ }],
102
+ });
103
+ await alert.present();
104
+ }
105
+
106
+ private async showOptionalUpdate(result) {
107
+ const alert = await this.alertCtrl.create({
108
+ header: 'Update Available',
109
+ message: `Version ${result.latestVersion} is available. ${result.releaseNotes}`,
110
+ buttons: [
111
+ { text: 'Later', role: 'cancel' },
112
+ { text: 'Update', handler: () => Browser.open({ url: result.storeUrl }) },
113
+ ],
114
+ });
115
+ await alert.present();
116
+ }
117
+ }
118
+ */
119
+
120
+ // ─── React / Capacitor Integration Example ───────────────────────────
121
+
122
+ /*
123
+ // In a React component (useVersionCheck.ts):
124
+
125
+ import { useEffect, useState } from 'react';
126
+ import { AppVersionChecker, VersionCheckResult } from '@lucidaquarian/app-version-checker';
127
+
128
+ const checker = new AppVersionChecker({
129
+ platform: 'auto',
130
+ iosBundleId: 'com.yourcompany.yourapp',
131
+ androidPackageName: 'com.yourcompany.yourapp',
132
+ });
133
+
134
+ export function useVersionCheck() {
135
+ const [result, setResult] = useState<VersionCheckResult | null>(null);
136
+ const [loading, setLoading] = useState(true);
137
+
138
+ useEffect(() => {
139
+ checker.checkForUpdate()
140
+ .then(setResult)
141
+ .catch(() => setResult(null))
142
+ .finally(() => setLoading(false));
143
+ }, []);
144
+
145
+ return { result, loading };
146
+ }
147
+ */
148
+
149
+ module.exports = { performVersionCheck };
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Example: Using @lucidaquarian/app-version-checker in a Cordova application.
3
+ *
4
+ * Prerequisites:
5
+ * cordova plugin add cordova-plugin-app-version
6
+ * npm install @lucidaquarian/app-version-checker
7
+ */
8
+
9
+ const { AppVersionChecker } = require('@lucidaquarian/app-version-checker');
10
+
11
+ // ─── Basic Setup ─────────────────────────────────────────────────────
12
+
13
+ const checker = new AppVersionChecker({
14
+ platform: 'cordova', // explicitly use Cordova provider
15
+ iosBundleId: 'com.yourcompany.yourapp', // for iOS App Store lookup
16
+ androidPackageName: 'com.yourcompany.yourapp', // for Google Play lookup
17
+ country: 'us', // App Store region
18
+ });
19
+
20
+ // ─── Check on App Launch ─────────────────────────────────────────────
21
+
22
+ document.addEventListener('deviceready', async () => {
23
+ try {
24
+ const result = await checker.checkForUpdate();
25
+
26
+ console.log('Current version:', result.currentVersion);
27
+ console.log('Latest version:', result.latestVersion);
28
+ console.log('Update available:', result.updateAvailable);
29
+ console.log('Update type:', result.updateType);
30
+ console.log('Force update:', result.forceUpdate);
31
+
32
+ if (result.forceUpdate) {
33
+ // Show a blocking dialog – user MUST update
34
+ showForceUpdateDialog(result);
35
+ } else if (result.updateAvailable) {
36
+ // Show a dismissible prompt
37
+ showOptionalUpdateDialog(result);
38
+ }
39
+ } catch (err) {
40
+ console.warn('Version check failed:', err.message);
41
+ // Gracefully continue — don't block the user
42
+ }
43
+ });
44
+
45
+ // ─── UI Helpers (replace with your framework's dialogs) ──────────────
46
+
47
+ function showForceUpdateDialog(result) {
48
+ if (navigator.notification) {
49
+ navigator.notification.alert(
50
+ `Version ${result.latestVersion} is required to continue.\n\n${result.releaseNotes}`,
51
+ () => openStore(result.storeUrl),
52
+ 'Update Required',
53
+ 'Update Now'
54
+ );
55
+ }
56
+ }
57
+
58
+ function showOptionalUpdateDialog(result) {
59
+ if (navigator.notification) {
60
+ navigator.notification.confirm(
61
+ `Version ${result.latestVersion} is available!\n\n${result.releaseNotes}`,
62
+ (buttonIndex) => {
63
+ if (buttonIndex === 1) openStore(result.storeUrl);
64
+ },
65
+ 'Update Available',
66
+ ['Update', 'Later']
67
+ );
68
+ }
69
+ }
70
+
71
+ function openStore(url) {
72
+ if (url && window.cordova?.InAppBrowser) {
73
+ window.cordova.InAppBrowser.open(url, '_system');
74
+ }
75
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@lucidaquarian/app-version-checker",
3
+ "version": "1.0.0",
4
+ "description": "A cross-platform version checker plugin for Cordova and Capacitor-based mobile applications. Compare local app versions against remote sources and prompt users to update.",
5
+ "main": "src/index.js",
6
+ "types": "src/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "files": [
11
+ "src/",
12
+ "examples/"
13
+ ],
14
+ "scripts": {
15
+ "test": "node test/test.js && node test/providers.test.js && node test/stores.test.js",
16
+ "lint": "node scripts/lint.js",
17
+ "prepublishOnly": "npm run lint && npm test",
18
+ "example:cordova": "node examples/cordova-usage.js",
19
+ "example:capacitor": "node examples/capacitor-usage.js"
20
+ },
21
+ "keywords": [
22
+ "cordova",
23
+ "capacitor",
24
+ "version-check",
25
+ "app-update",
26
+ "mobile",
27
+ "ionic",
28
+ "hybrid-app",
29
+ "app-store",
30
+ "play-store",
31
+ "version-compare"
32
+ ],
33
+ "author": "lucidaquarian",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/lucidaquarian/app-version-check.git"
38
+ },
39
+ "homepage": "https://github.com/lucidaquarian/app-version-check#readme",
40
+ "bugs": {
41
+ "url": "https://github.com/lucidaquarian/app-version-check/issues"
42
+ },
43
+ "engines": {
44
+ "node": ">=18.0.0"
45
+ },
46
+ "peerDependencies": {},
47
+ "devDependencies": {}
48
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,160 @@
1
+ /**
2
+ * @lucidaquarian/app-version-checker
3
+ * Cross-platform version checker for Cordova and Capacitor mobile applications.
4
+ */
5
+
6
+ // ─── SemVer ──────────────────────────────────────────────────────────
7
+
8
+ export interface ParsedVersion {
9
+ major: number;
10
+ minor: number;
11
+ patch: number;
12
+ prerelease: string;
13
+ }
14
+
15
+ export class SemVer {
16
+ static parse(version: string): ParsedVersion;
17
+ static compare(versionA: string, versionB: string): -1 | 0 | 1;
18
+ static gt(versionA: string, versionB: string): boolean;
19
+ static lt(versionA: string, versionB: string): boolean;
20
+ static eq(versionA: string, versionB: string): boolean;
21
+ static gte(versionA: string, versionB: string): boolean;
22
+ static lte(versionA: string, versionB: string): boolean;
23
+ static updateType(
24
+ currentVersion: string,
25
+ latestVersion: string
26
+ ): 'major' | 'minor' | 'patch' | 'prerelease' | 'none';
27
+ static isValid(version: string): boolean;
28
+ }
29
+
30
+ // ─── Providers ───────────────────────────────────────────────────────
31
+
32
+ export interface AppInfo {
33
+ versionName: string;
34
+ versionCode: string | number;
35
+ packageName: string;
36
+ appName: string;
37
+ }
38
+
39
+ export class CordovaProvider {
40
+ readonly name: 'cordova';
41
+ isAvailable(): boolean;
42
+ getAppInfo(): Promise<AppInfo>;
43
+ getVersion(): Promise<string>;
44
+ getBuildNumber(): Promise<string | number>;
45
+ getPlatform(): string;
46
+ }
47
+
48
+ export class CapacitorProvider {
49
+ readonly name: 'capacitor';
50
+ isAvailable(): boolean;
51
+ isNative(): boolean;
52
+ getAppInfo(): Promise<AppInfo>;
53
+ getVersion(): Promise<string>;
54
+ getBuildNumber(): Promise<string>;
55
+ getPlatform(): string;
56
+ getDeviceInfo(): Promise<object | null>;
57
+ }
58
+
59
+ // ─── Store Lookups ───────────────────────────────────────────────────
60
+
61
+ export interface AppStoreResult {
62
+ version: string;
63
+ releaseNotes: string;
64
+ storeUrl: string;
65
+ releaseDate: string;
66
+ minimumOsVersion: string;
67
+ }
68
+
69
+ export interface PlayStoreResult {
70
+ version: string;
71
+ storeUrl: string;
72
+ }
73
+
74
+ export interface CustomEndpointResult {
75
+ version: string;
76
+ minVersion: string | null;
77
+ releaseNotes: string;
78
+ storeUrl: string;
79
+ forceUpdate: boolean;
80
+ [key: string]: any;
81
+ }
82
+
83
+ export function fetchAppStoreVersion(
84
+ bundleId: string,
85
+ country?: string,
86
+ timeoutMs?: number
87
+ ): Promise<AppStoreResult>;
88
+
89
+ export function fetchPlayStoreVersion(
90
+ packageName: string,
91
+ timeoutMs?: number
92
+ ): Promise<PlayStoreResult>;
93
+
94
+ export function fetchCustomEndpoint(
95
+ url: string,
96
+ options?: RequestInit,
97
+ timeoutMs?: number
98
+ ): Promise<CustomEndpointResult>;
99
+
100
+ // ─── Main Checker ────────────────────────────────────────────────────
101
+
102
+ export interface AppVersionCheckerConfig {
103
+ /** Platform to use. Defaults to 'auto'. */
104
+ platform?: 'cordova' | 'capacitor' | 'auto';
105
+
106
+ /** iOS bundle identifier for App Store lookup. */
107
+ iosBundleId?: string;
108
+
109
+ /** Android package name for Play Store lookup. */
110
+ androidPackageName?: string;
111
+
112
+ /** Two-letter country code for App Store. Defaults to 'us'. */
113
+ country?: string;
114
+
115
+ /** Custom endpoint URL returning JSON with a `version` field. */
116
+ customEndpoint?: string;
117
+
118
+ /** Extra fetch options for the custom endpoint. */
119
+ customEndpointOptions?: RequestInit;
120
+
121
+ /** Local minimum supported version override. */
122
+ minVersion?: string;
123
+
124
+ /** Network timeout (ms) for store / custom-endpoint requests. Defaults to 10000. */
125
+ timeout?: number;
126
+ }
127
+
128
+ export interface VersionCheckResult {
129
+ currentVersion: string;
130
+ latestVersion: string;
131
+ updateAvailable: boolean;
132
+ updateType: 'major' | 'minor' | 'patch' | 'prerelease' | 'none';
133
+ forceUpdate: boolean;
134
+ storeUrl: string;
135
+ releaseNotes: string;
136
+ platform: string;
137
+ devicePlatform: string;
138
+ }
139
+
140
+ export interface StaticCompareResult {
141
+ updateAvailable: boolean;
142
+ updateType: 'major' | 'minor' | 'patch' | 'prerelease' | 'none';
143
+ }
144
+
145
+ export class AppVersionChecker {
146
+ constructor(config?: AppVersionCheckerConfig);
147
+
148
+ getProvider(): CordovaProvider | CapacitorProvider;
149
+ getPlatformName(): string;
150
+ getCurrentVersion(): Promise<string>;
151
+ getAppInfo(): Promise<AppInfo>;
152
+ getDevicePlatform(): string;
153
+ getLatestVersion(): Promise<AppStoreResult | PlayStoreResult | CustomEndpointResult>;
154
+ checkForUpdate(): Promise<VersionCheckResult>;
155
+
156
+ static compareVersions(
157
+ currentVersion: string,
158
+ latestVersion: string
159
+ ): StaticCompareResult;
160
+ }