@simplysm/capacitor-plugin-auto-update 13.0.76 → 13.0.77
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/README.md +16 -21
- package/android/src/main/java/kr/co/simplysm/capacitor/apkinstaller/ApkInstallerPlugin.java +23 -30
- package/dist/ApkInstaller.d.ts +8 -9
- package/dist/ApkInstaller.d.ts.map +1 -1
- package/dist/ApkInstaller.js +8 -16
- package/dist/ApkInstaller.js.map +1 -1
- package/dist/ApkInstallerPlugin.d.ts +16 -0
- package/dist/ApkInstallerPlugin.d.ts.map +1 -0
- package/dist/ApkInstallerPlugin.js +1 -0
- package/dist/AutoUpdate.d.ts.map +1 -1
- package/dist/AutoUpdate.js +18 -14
- package/dist/AutoUpdate.js.map +1 -1
- package/dist/env.d.js +1 -0
- package/dist/env.d.js.map +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/web/ApkInstallerWeb.d.ts +6 -8
- package/dist/web/ApkInstallerWeb.d.ts.map +1 -1
- package/dist/web/ApkInstallerWeb.js +4 -8
- package/dist/web/ApkInstallerWeb.js.map +1 -1
- package/package.json +6 -6
- package/src/ApkInstaller.ts +10 -19
- package/src/ApkInstallerPlugin.ts +11 -0
- package/src/AutoUpdate.ts +18 -14
- package/src/env.d.ts +7 -0
- package/src/index.ts +1 -1
- package/src/web/ApkInstallerWeb.ts +7 -12
- package/dist/IApkInstallerPlugin.d.ts +0 -18
- package/dist/IApkInstallerPlugin.d.ts.map +0 -1
- package/dist/IApkInstallerPlugin.js +0 -1
- package/src/IApkInstallerPlugin.ts +0 -12
- /package/dist/{IApkInstallerPlugin.js.map → ApkInstallerPlugin.js.map} +0 -0
package/README.md
CHANGED
|
@@ -19,19 +19,16 @@ pnpm add @simplysm/capacitor-plugin-auto-update
|
|
|
19
19
|
Abstract class with static methods that wrap the native `ApkInstaller` Capacitor plugin.
|
|
20
20
|
|
|
21
21
|
- Android: executes APK install intent and manages `REQUEST_INSTALL_PACKAGES` permission.
|
|
22
|
-
- Browser (web fallback): shows an alert
|
|
22
|
+
- Browser (web fallback): `checkPermissions` returns `{ granted: true, manifest: true }`, `install` shows an alert and returns normally.
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
25
|
import { ApkInstaller } from "@simplysm/capacitor-plugin-auto-update";
|
|
26
26
|
|
|
27
|
-
// Check whether REQUEST_INSTALL_PACKAGES is declared in the manifest
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
// Check whether REQUEST_INSTALL_PACKAGES is currently granted
|
|
31
|
-
const granted = await ApkInstaller.hasPermission();
|
|
27
|
+
// Check whether REQUEST_INSTALL_PACKAGES is declared in the manifest and currently granted
|
|
28
|
+
const { granted, manifest } = await ApkInstaller.checkPermissions();
|
|
32
29
|
|
|
33
30
|
// Navigate the user to the settings page to grant the permission
|
|
34
|
-
await ApkInstaller.
|
|
31
|
+
await ApkInstaller.requestPermissions();
|
|
35
32
|
|
|
36
33
|
// Install an APK given a content:// FileProvider URI
|
|
37
34
|
await ApkInstaller.install("content://com.example/files/latest.apk");
|
|
@@ -46,11 +43,10 @@ const info = await ApkInstaller.getVersionInfo();
|
|
|
46
43
|
|
|
47
44
|
| Method | Signature | Description |
|
|
48
45
|
|---|---|---|
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `requestPermission` | `() => Promise<void>` | Opens the system settings screen for the user to grant the permission. |
|
|
46
|
+
| `checkPermissions` | `() => Promise<{ granted: boolean; manifest: boolean }>` | Returns whether `REQUEST_INSTALL_PACKAGES` is granted and declared in the manifest. |
|
|
47
|
+
| `requestPermissions` | `() => Promise<void>` | Opens the system settings screen for the user to grant the permission. |
|
|
52
48
|
| `install` | `(apkUri: string) => Promise<void>` | Fires the install intent for the given `content://` URI. |
|
|
53
|
-
| `getVersionInfo` | `() => Promise<
|
|
49
|
+
| `getVersionInfo` | `() => Promise<VersionInfo>` | Returns the running app's `versionName` and `versionCode`. |
|
|
54
50
|
|
|
55
51
|
---
|
|
56
52
|
|
|
@@ -125,31 +121,30 @@ await AutoUpdate.runByExternalStorage({
|
|
|
125
121
|
|
|
126
122
|
## Types
|
|
127
123
|
|
|
128
|
-
### `
|
|
124
|
+
### `VersionInfo`
|
|
129
125
|
|
|
130
126
|
Version information returned by `ApkInstaller.getVersionInfo()`.
|
|
131
127
|
|
|
132
128
|
```ts
|
|
133
|
-
import type {
|
|
129
|
+
import type { VersionInfo } from "@simplysm/capacitor-plugin-auto-update";
|
|
134
130
|
|
|
135
|
-
interface
|
|
131
|
+
interface VersionInfo {
|
|
136
132
|
versionName: string; // Human-readable version string, e.g. "1.2.3"
|
|
137
133
|
versionCode: string; // Integer build number as a string, e.g. "10203"
|
|
138
134
|
}
|
|
139
135
|
```
|
|
140
136
|
|
|
141
|
-
### `
|
|
137
|
+
### `ApkInstallerPlugin`
|
|
142
138
|
|
|
143
139
|
Low-level interface implemented by the native Capacitor plugin. Use `ApkInstaller` (the abstract class) instead of this interface directly.
|
|
144
140
|
|
|
145
141
|
```ts
|
|
146
|
-
import type {
|
|
142
|
+
import type { ApkInstallerPlugin } from "@simplysm/capacitor-plugin-auto-update";
|
|
147
143
|
|
|
148
|
-
interface
|
|
144
|
+
interface ApkInstallerPlugin {
|
|
149
145
|
install(options: { uri: string }): Promise<void>;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
getVersionInfo(): Promise<IVersionInfo>;
|
|
146
|
+
checkPermissions(): Promise<{ granted: boolean; manifest: boolean }>;
|
|
147
|
+
requestPermissions(): Promise<void>;
|
|
148
|
+
getVersionInfo(): Promise<VersionInfo>;
|
|
154
149
|
}
|
|
155
150
|
```
|
|
@@ -44,7 +44,8 @@ public class ApkInstallerPlugin extends Plugin {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
@PluginMethod
|
|
47
|
-
public void
|
|
47
|
+
public void checkPermissions(PluginCall call) {
|
|
48
|
+
// Check granted
|
|
48
49
|
boolean granted;
|
|
49
50
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
50
51
|
granted = getContext().getPackageManager().canRequestPackageInstalls();
|
|
@@ -52,50 +53,42 @@ public class ApkInstallerPlugin extends Plugin {
|
|
|
52
53
|
granted = true;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
call.resolve(ret);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@PluginMethod
|
|
61
|
-
public void requestPermission(PluginCall call) {
|
|
62
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
63
|
-
Context context = getContext();
|
|
64
|
-
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
|
|
65
|
-
intent.setData(Uri.parse("package:" + context.getPackageName()));
|
|
66
|
-
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
67
|
-
context.startActivity(intent);
|
|
68
|
-
}
|
|
69
|
-
call.resolve();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@PluginMethod
|
|
73
|
-
public void hasPermissionManifest(PluginCall call) {
|
|
56
|
+
// Check manifest
|
|
57
|
+
boolean manifest = false;
|
|
74
58
|
try {
|
|
75
59
|
Context context = getContext();
|
|
76
60
|
String targetPermission = "android.permission.REQUEST_INSTALL_PACKAGES";
|
|
77
|
-
|
|
78
61
|
String[] requestedPermissions = context.getPackageManager()
|
|
79
62
|
.getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS)
|
|
80
63
|
.requestedPermissions;
|
|
81
|
-
|
|
82
|
-
boolean declared = false;
|
|
83
64
|
if (requestedPermissions != null) {
|
|
84
65
|
for (String perm : requestedPermissions) {
|
|
85
66
|
if (targetPermission.equals(perm)) {
|
|
86
|
-
|
|
67
|
+
manifest = true;
|
|
87
68
|
break;
|
|
88
69
|
}
|
|
89
70
|
}
|
|
90
71
|
}
|
|
91
|
-
|
|
92
|
-
JSObject ret = new JSObject();
|
|
93
|
-
ret.put("declared", declared);
|
|
94
|
-
call.resolve(ret);
|
|
95
72
|
} catch (Exception e) {
|
|
96
|
-
Log.e(TAG, "
|
|
97
|
-
|
|
73
|
+
Log.e(TAG, "checkPermissions manifest check failed", e);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
JSObject ret = new JSObject();
|
|
77
|
+
ret.put("granted", granted);
|
|
78
|
+
ret.put("manifest", manifest);
|
|
79
|
+
call.resolve(ret);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@PluginMethod
|
|
83
|
+
public void requestPermissions(PluginCall call) {
|
|
84
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
85
|
+
Context context = getContext();
|
|
86
|
+
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
|
|
87
|
+
intent.setData(Uri.parse("package:" + context.getPackageName()));
|
|
88
|
+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
89
|
+
context.startActivity(intent);
|
|
98
90
|
}
|
|
91
|
+
call.resolve();
|
|
99
92
|
}
|
|
100
93
|
|
|
101
94
|
@PluginMethod
|
package/dist/ApkInstaller.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VersionInfo } from "./ApkInstallerPlugin";
|
|
2
2
|
/**
|
|
3
3
|
* APK installation plugin
|
|
4
4
|
* - Android: Executes APK install intent, manages REQUEST_INSTALL_PACKAGES permission
|
|
@@ -6,17 +6,16 @@ import type { IVersionInfo } from "./IApkInstallerPlugin";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare abstract class ApkInstaller {
|
|
8
8
|
/**
|
|
9
|
-
* Check
|
|
9
|
+
* Check permissions (install permission granted + manifest declared)
|
|
10
10
|
*/
|
|
11
|
-
static
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
static hasPermission(): Promise<boolean>;
|
|
11
|
+
static checkPermissions(): Promise<{
|
|
12
|
+
granted: boolean;
|
|
13
|
+
manifest: boolean;
|
|
14
|
+
}>;
|
|
16
15
|
/**
|
|
17
16
|
* Request REQUEST_INSTALL_PACKAGES permission (navigates to settings)
|
|
18
17
|
*/
|
|
19
|
-
static
|
|
18
|
+
static requestPermissions(): Promise<void>;
|
|
20
19
|
/**
|
|
21
20
|
* Install APK
|
|
22
21
|
* @param apkUri content:// URI (FileProvider URI)
|
|
@@ -25,6 +24,6 @@ export declare abstract class ApkInstaller {
|
|
|
25
24
|
/**
|
|
26
25
|
* Get app version info
|
|
27
26
|
*/
|
|
28
|
-
static getVersionInfo(): Promise<
|
|
27
|
+
static getVersionInfo(): Promise<VersionInfo>;
|
|
29
28
|
}
|
|
30
29
|
//# sourceMappingURL=ApkInstaller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApkInstaller.d.ts","sourceRoot":"","sources":["..\\src\\ApkInstaller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ApkInstaller.d.ts","sourceRoot":"","sources":["..\\src\\ApkInstaller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAS5E;;;;GAIG;AACH,8BAAsB,YAAY;IAChC;;OAEG;WACU,gBAAgB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAIjF;;OAEG;WACU,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhD;;;OAGG;WACU,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD;;OAEG;WACU,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;CAGpD"}
|
package/dist/ApkInstaller.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { registerPlugin } from "@capacitor/core";
|
|
2
|
-
const
|
|
2
|
+
const apkInstallerPlugin = registerPlugin("ApkInstaller", {
|
|
3
3
|
web: async () => {
|
|
4
4
|
const { ApkInstallerWeb } = await import("./web/ApkInstallerWeb");
|
|
5
5
|
return new ApkInstallerWeb();
|
|
@@ -7,37 +7,29 @@ const ApkInstallerPlugin = registerPlugin("ApkInstaller", {
|
|
|
7
7
|
});
|
|
8
8
|
class ApkInstaller {
|
|
9
9
|
/**
|
|
10
|
-
* Check
|
|
10
|
+
* Check permissions (install permission granted + manifest declared)
|
|
11
11
|
*/
|
|
12
|
-
static async
|
|
13
|
-
|
|
14
|
-
return result.declared;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Check if REQUEST_INSTALL_PACKAGES permission is granted
|
|
18
|
-
*/
|
|
19
|
-
static async hasPermission() {
|
|
20
|
-
const result = await ApkInstallerPlugin.hasPermission();
|
|
21
|
-
return result.granted;
|
|
12
|
+
static async checkPermissions() {
|
|
13
|
+
return apkInstallerPlugin.checkPermissions();
|
|
22
14
|
}
|
|
23
15
|
/**
|
|
24
16
|
* Request REQUEST_INSTALL_PACKAGES permission (navigates to settings)
|
|
25
17
|
*/
|
|
26
|
-
static async
|
|
27
|
-
await
|
|
18
|
+
static async requestPermissions() {
|
|
19
|
+
await apkInstallerPlugin.requestPermissions();
|
|
28
20
|
}
|
|
29
21
|
/**
|
|
30
22
|
* Install APK
|
|
31
23
|
* @param apkUri content:// URI (FileProvider URI)
|
|
32
24
|
*/
|
|
33
25
|
static async install(apkUri) {
|
|
34
|
-
await
|
|
26
|
+
await apkInstallerPlugin.install({ uri: apkUri });
|
|
35
27
|
}
|
|
36
28
|
/**
|
|
37
29
|
* Get app version info
|
|
38
30
|
*/
|
|
39
31
|
static async getVersionInfo() {
|
|
40
|
-
return
|
|
32
|
+
return apkInstallerPlugin.getVersionInfo();
|
|
41
33
|
}
|
|
42
34
|
}
|
|
43
35
|
export {
|
package/dist/ApkInstaller.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ApkInstaller.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,sBAAsB;AAG/B,MAAM,qBAAqB,
|
|
4
|
+
"mappings": "AAAA,SAAS,sBAAsB;AAG/B,MAAM,qBAAqB,eAAmC,gBAAgB;AAAA,EAC5E,KAAK,YAAY;AACf,UAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,uBAAuB;AAChE,WAAO,IAAI,gBAAgB;AAAA,EAC7B;AACF,CAAC;AAOM,MAAe,aAAa;AAAA;AAAA;AAAA;AAAA,EAIjC,aAAa,mBAAqE;AAChF,WAAO,mBAAmB,iBAAiB;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,qBAAoC;AAC/C,UAAM,mBAAmB,mBAAmB;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,QAAQ,QAA+B;AAClD,UAAM,mBAAmB,QAAQ,EAAE,KAAK,OAAO,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,iBAAuC;AAClD,WAAO,mBAAmB,eAAe;AAAA,EAC3C;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface VersionInfo {
|
|
2
|
+
versionName: string;
|
|
3
|
+
versionCode: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ApkInstallerPlugin {
|
|
6
|
+
install(options: {
|
|
7
|
+
uri: string;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
checkPermissions(): Promise<{
|
|
10
|
+
granted: boolean;
|
|
11
|
+
manifest: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
requestPermissions(): Promise<void>;
|
|
14
|
+
getVersionInfo(): Promise<VersionInfo>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ApkInstallerPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApkInstallerPlugin.d.ts","sourceRoot":"","sources":["..\\src\\ApkInstallerPlugin.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrE,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;CACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=ApkInstallerPlugin.js.map
|
package/dist/AutoUpdate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoUpdate.d.ts","sourceRoot":"","sources":["..\\src\\AutoUpdate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAK9D,8BAAsB,UAAU;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAWjC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAExC;IAEF,OAAO,CAAC,MAAM,CAAC,oBAAoB;mBAsBd,gBAAgB;
|
|
1
|
+
{"version":3,"file":"AutoUpdate.d.ts","sourceRoot":"","sources":["..\\src\\AutoUpdate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAK9D,8BAAsB,UAAU;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAWjC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAExC;IAEF,OAAO,CAAC,MAAM,CAAC,oBAAoB;mBAsBd,gBAAgB;mBAyChB,WAAW;IAgBhC,OAAO,CAAC,MAAM,CAAC,gBAAgB;mBAQV,UAAU;WAIlB,GAAG,CAAC,GAAG,EAAE;QAAE,GAAG,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,aAAa,EAAE,aAAa,CAAA;KAAE;WA6D7E,oBAAoB,CAAC,GAAG,EAAE;QAAE,GAAG,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CA6D/F"}
|
package/dist/AutoUpdate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
|
|
2
|
-
import { html,
|
|
2
|
+
import { html, wait, path } from "@simplysm/core-common";
|
|
3
3
|
import { fetchUrlBytes } from "@simplysm/core-browser";
|
|
4
4
|
import semver from "semver";
|
|
5
5
|
import { ApkInstaller } from "./ApkInstaller.js";
|
|
@@ -40,16 +40,19 @@ class AutoUpdate {
|
|
|
40
40
|
if (!navigator.userAgent.toLowerCase().includes("android")) {
|
|
41
41
|
throw new Error("Only Android is supported.");
|
|
42
42
|
}
|
|
43
|
+
let granted;
|
|
43
44
|
try {
|
|
44
|
-
|
|
45
|
+
const result = await ApkInstaller.checkPermissions();
|
|
46
|
+
if (!result.manifest) {
|
|
45
47
|
this._throwAboutReinstall(1, targetHref);
|
|
46
48
|
}
|
|
49
|
+
granted = result.granted;
|
|
47
50
|
} catch (err) {
|
|
48
|
-
console.error("[AutoUpdate]
|
|
51
|
+
console.error("[AutoUpdate] checkPermissions manifest check failed:", err);
|
|
49
52
|
this._throwAboutReinstall(2, targetHref);
|
|
53
|
+
return;
|
|
50
54
|
}
|
|
51
|
-
|
|
52
|
-
if (!hasPerm) {
|
|
55
|
+
if (!granted) {
|
|
53
56
|
log(html`
|
|
54
57
|
Installation permission must be enabled.
|
|
55
58
|
<style>
|
|
@@ -58,10 +61,11 @@ class AutoUpdate {
|
|
|
58
61
|
</style>
|
|
59
62
|
<button onclick="location.reload()">Retry</button>
|
|
60
63
|
`);
|
|
61
|
-
await ApkInstaller.
|
|
62
|
-
await
|
|
64
|
+
await ApkInstaller.requestPermissions();
|
|
65
|
+
await wait.until(
|
|
63
66
|
async () => {
|
|
64
|
-
|
|
67
|
+
const result = await ApkInstaller.checkPermissions();
|
|
68
|
+
return result.granted;
|
|
65
69
|
},
|
|
66
70
|
1e3,
|
|
67
71
|
300
|
|
@@ -77,7 +81,7 @@ class AutoUpdate {
|
|
|
77
81
|
</style>
|
|
78
82
|
<button onclick="location.reload()">Retry</button>
|
|
79
83
|
`);
|
|
80
|
-
const apkFileUri = await FileSystem.
|
|
84
|
+
const apkFileUri = await FileSystem.getUri(apkFilePath);
|
|
81
85
|
await ApkInstaller.install(apkFileUri);
|
|
82
86
|
}
|
|
83
87
|
static _getErrorMessage(err) {
|
|
@@ -126,7 +130,7 @@ class AutoUpdate {
|
|
|
126
130
|
}
|
|
127
131
|
);
|
|
128
132
|
const storagePath = await FileSystem.getStoragePath("appCache");
|
|
129
|
-
const apkFilePath =
|
|
133
|
+
const apkFilePath = path.join(storagePath, `latest.apk`);
|
|
130
134
|
await FileSystem.writeFile(apkFilePath, buffer);
|
|
131
135
|
await this._installApk(opt.log, apkFilePath);
|
|
132
136
|
await this._freezeApp();
|
|
@@ -141,11 +145,11 @@ class AutoUpdate {
|
|
|
141
145
|
await this._checkPermission(opt.log);
|
|
142
146
|
opt.log(`Checking latest version...`);
|
|
143
147
|
const externalPath = await FileSystem.getStoragePath("external");
|
|
144
|
-
const fileInfos = await FileSystem.readdir(
|
|
148
|
+
const fileInfos = await FileSystem.readdir(path.join(externalPath, opt.dirPath));
|
|
145
149
|
const versions = fileInfos.filter((fileInfo) => !fileInfo.isDirectory).map((fileInfo) => ({
|
|
146
150
|
fileName: fileInfo.name,
|
|
147
|
-
version:
|
|
148
|
-
extName:
|
|
151
|
+
version: path.basename(fileInfo.name, path.extname(fileInfo.name)),
|
|
152
|
+
extName: path.extname(fileInfo.name)
|
|
149
153
|
})).filter((item) => {
|
|
150
154
|
return item.extName === ".apk" && /^[0-9.]*$/.test(item.version);
|
|
151
155
|
});
|
|
@@ -166,7 +170,7 @@ class AutoUpdate {
|
|
|
166
170
|
if (!semver.gt(latestVersion, currentVersionInfo.versionName)) {
|
|
167
171
|
return;
|
|
168
172
|
}
|
|
169
|
-
const apkFilePath =
|
|
173
|
+
const apkFilePath = path.join(externalPath, opt.dirPath, latestVersion + ".apk");
|
|
170
174
|
await this._installApk(opt.log, apkFilePath);
|
|
171
175
|
await this._freezeApp();
|
|
172
176
|
} catch (err) {
|
package/dist/AutoUpdate.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/AutoUpdate.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,MAAM,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/env.d.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=env.d.js.map
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAGrC,cAAc,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
|
-
import type {
|
|
3
|
-
export declare class ApkInstallerWeb extends WebPlugin implements
|
|
2
|
+
import type { ApkInstallerPlugin, VersionInfo } from "../ApkInstallerPlugin";
|
|
3
|
+
export declare class ApkInstallerWeb extends WebPlugin implements ApkInstallerPlugin {
|
|
4
4
|
install(_options: {
|
|
5
5
|
uri: string;
|
|
6
6
|
}): Promise<void>;
|
|
7
|
-
|
|
7
|
+
checkPermissions(): Promise<{
|
|
8
8
|
granted: boolean;
|
|
9
|
+
manifest: boolean;
|
|
9
10
|
}>;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
declared: boolean;
|
|
13
|
-
}>;
|
|
14
|
-
getVersionInfo(): Promise<IVersionInfo>;
|
|
11
|
+
requestPermissions(): Promise<void>;
|
|
12
|
+
getVersionInfo(): Promise<VersionInfo>;
|
|
15
13
|
}
|
|
16
14
|
//# sourceMappingURL=ApkInstallerWeb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApkInstallerWeb.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\ApkInstallerWeb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"ApkInstallerWeb.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\ApkInstallerWeb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE7E,qBAAa,eAAgB,SAAQ,SAAU,YAAW,kBAAkB;IAC1E,OAAO,CAAC,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,gBAAgB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAK9D,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzC,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;CAOvC"}
|
|
@@ -4,18 +4,14 @@ class ApkInstallerWeb extends WebPlugin {
|
|
|
4
4
|
alert("[ApkInstaller] APK installation is not supported in web environment.");
|
|
5
5
|
return Promise.resolve();
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
return Promise.resolve({ granted: true });
|
|
7
|
+
checkPermissions() {
|
|
8
|
+
return Promise.resolve({ granted: true, manifest: true });
|
|
9
9
|
}
|
|
10
|
-
async
|
|
11
|
-
}
|
|
12
|
-
hasPermissionManifest() {
|
|
13
|
-
return Promise.resolve({ declared: true });
|
|
10
|
+
async requestPermissions() {
|
|
14
11
|
}
|
|
15
12
|
getVersionInfo() {
|
|
16
|
-
var _a;
|
|
17
13
|
return Promise.resolve({
|
|
18
|
-
versionName:
|
|
14
|
+
versionName: import.meta.env.__VER__ ?? "0.0.0",
|
|
19
15
|
versionCode: "0"
|
|
20
16
|
});
|
|
21
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/web/ApkInstallerWeb.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,iBAAiB;AAGnB,MAAM,wBAAwB,
|
|
4
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAGnB,MAAM,wBAAwB,UAAwC;AAAA,EAC3E,QAAQ,UAA0C;AAChD,UAAM,sEAAsE;AAC5E,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,mBAAqE;AAEnE,WAAO,QAAQ,QAAQ,EAAE,SAAS,MAAM,UAAU,KAAK,CAAC;AAAA,EAC1D;AAAA,EAEA,MAAM,qBAAoC;AAAA,EAE1C;AAAA,EAEA,iBAAuC;AACrC,WAAO,QAAQ,QAAQ;AAAA,MACrB,aACE,YAAY,IAAI,WAAW;AAAA,MAC7B,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/capacitor-plugin-auto-update",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.77",
|
|
4
4
|
"description": "Simplysm Package - Capacitor Auto Update Plugin",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"semver": "^7.7.4",
|
|
22
|
-
"@simplysm/
|
|
23
|
-
"@simplysm/
|
|
24
|
-
"@simplysm/
|
|
25
|
-
"@simplysm/
|
|
26
|
-
"@simplysm/service-common": "13.0.
|
|
22
|
+
"@simplysm/core-browser": "13.0.77",
|
|
23
|
+
"@simplysm/capacitor-plugin-file-system": "13.0.77",
|
|
24
|
+
"@simplysm/core-common": "13.0.77",
|
|
25
|
+
"@simplysm/service-client": "13.0.77",
|
|
26
|
+
"@simplysm/service-common": "13.0.77"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@capacitor/core": "^7.5.0",
|
package/src/ApkInstaller.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { registerPlugin } from "@capacitor/core";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ApkInstallerPlugin, VersionInfo } from "./ApkInstallerPlugin";
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const apkInstallerPlugin = registerPlugin<ApkInstallerPlugin>("ApkInstaller", {
|
|
5
5
|
web: async () => {
|
|
6
6
|
const { ApkInstallerWeb } = await import("./web/ApkInstallerWeb");
|
|
7
7
|
return new ApkInstallerWeb();
|
|
@@ -15,26 +15,17 @@ const ApkInstallerPlugin = registerPlugin<IApkInstallerPlugin>("ApkInstaller", {
|
|
|
15
15
|
*/
|
|
16
16
|
export abstract class ApkInstaller {
|
|
17
17
|
/**
|
|
18
|
-
* Check
|
|
18
|
+
* Check permissions (install permission granted + manifest declared)
|
|
19
19
|
*/
|
|
20
|
-
static async
|
|
21
|
-
|
|
22
|
-
return result.declared;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Check if REQUEST_INSTALL_PACKAGES permission is granted
|
|
27
|
-
*/
|
|
28
|
-
static async hasPermission(): Promise<boolean> {
|
|
29
|
-
const result = await ApkInstallerPlugin.hasPermission();
|
|
30
|
-
return result.granted;
|
|
20
|
+
static async checkPermissions(): Promise<{ granted: boolean; manifest: boolean }> {
|
|
21
|
+
return apkInstallerPlugin.checkPermissions();
|
|
31
22
|
}
|
|
32
23
|
|
|
33
24
|
/**
|
|
34
25
|
* Request REQUEST_INSTALL_PACKAGES permission (navigates to settings)
|
|
35
26
|
*/
|
|
36
|
-
static async
|
|
37
|
-
await
|
|
27
|
+
static async requestPermissions(): Promise<void> {
|
|
28
|
+
await apkInstallerPlugin.requestPermissions();
|
|
38
29
|
}
|
|
39
30
|
|
|
40
31
|
/**
|
|
@@ -42,13 +33,13 @@ export abstract class ApkInstaller {
|
|
|
42
33
|
* @param apkUri content:// URI (FileProvider URI)
|
|
43
34
|
*/
|
|
44
35
|
static async install(apkUri: string): Promise<void> {
|
|
45
|
-
await
|
|
36
|
+
await apkInstallerPlugin.install({ uri: apkUri });
|
|
46
37
|
}
|
|
47
38
|
|
|
48
39
|
/**
|
|
49
40
|
* Get app version info
|
|
50
41
|
*/
|
|
51
|
-
static async getVersionInfo(): Promise<
|
|
52
|
-
return
|
|
42
|
+
static async getVersionInfo(): Promise<VersionInfo> {
|
|
43
|
+
return apkInstallerPlugin.getVersionInfo();
|
|
53
44
|
}
|
|
54
45
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface VersionInfo {
|
|
2
|
+
versionName: string;
|
|
3
|
+
versionCode: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface ApkInstallerPlugin {
|
|
7
|
+
install(options: { uri: string }): Promise<void>;
|
|
8
|
+
checkPermissions(): Promise<{ granted: boolean; manifest: boolean }>;
|
|
9
|
+
requestPermissions(): Promise<void>;
|
|
10
|
+
getVersionInfo(): Promise<VersionInfo>;
|
|
11
|
+
}
|
package/src/AutoUpdate.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FileSystem } from "@simplysm/capacitor-plugin-file-system";
|
|
2
|
-
import { html,
|
|
2
|
+
import { html, wait, path } from "@simplysm/core-common";
|
|
3
3
|
import { fetchUrlBytes } from "@simplysm/core-browser";
|
|
4
4
|
import type { ServiceClient } from "@simplysm/service-client";
|
|
5
5
|
import type { AutoUpdateService } from "@simplysm/service-common";
|
|
@@ -51,18 +51,21 @@ export abstract class AutoUpdate {
|
|
|
51
51
|
throw new Error("Only Android is supported.");
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
let granted: boolean;
|
|
54
55
|
try {
|
|
55
|
-
|
|
56
|
+
const result = await ApkInstaller.checkPermissions();
|
|
57
|
+
if (!result.manifest) {
|
|
56
58
|
this._throwAboutReinstall(1, targetHref);
|
|
57
59
|
}
|
|
60
|
+
granted = result.granted;
|
|
58
61
|
} catch (err) {
|
|
59
62
|
// eslint-disable-next-line no-console
|
|
60
|
-
console.error("[AutoUpdate]
|
|
63
|
+
console.error("[AutoUpdate] checkPermissions manifest check failed:", err);
|
|
61
64
|
this._throwAboutReinstall(2, targetHref);
|
|
65
|
+
return; // unreachable — _throwAboutReinstall always throws
|
|
62
66
|
}
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
if (!hasPerm) {
|
|
68
|
+
if (!granted) {
|
|
66
69
|
log(html`
|
|
67
70
|
Installation permission must be enabled.
|
|
68
71
|
<style>
|
|
@@ -71,11 +74,12 @@ export abstract class AutoUpdate {
|
|
|
71
74
|
</style>
|
|
72
75
|
<button onclick="location.reload()">Retry</button>
|
|
73
76
|
`);
|
|
74
|
-
await ApkInstaller.
|
|
77
|
+
await ApkInstaller.requestPermissions();
|
|
75
78
|
// Wait up to 5 minutes (300 seconds) - time for user to grant permission in settings
|
|
76
|
-
await
|
|
79
|
+
await wait.until(
|
|
77
80
|
async () => {
|
|
78
|
-
|
|
81
|
+
const result = await ApkInstaller.checkPermissions();
|
|
82
|
+
return result.granted;
|
|
79
83
|
},
|
|
80
84
|
1000,
|
|
81
85
|
300,
|
|
@@ -95,7 +99,7 @@ export abstract class AutoUpdate {
|
|
|
95
99
|
</style>
|
|
96
100
|
<button onclick="location.reload()">Retry</button>
|
|
97
101
|
`);
|
|
98
|
-
const apkFileUri = await FileSystem.
|
|
102
|
+
const apkFileUri = await FileSystem.getUri(apkFilePath);
|
|
99
103
|
await ApkInstaller.install(apkFileUri);
|
|
100
104
|
}
|
|
101
105
|
|
|
@@ -161,7 +165,7 @@ export abstract class AutoUpdate {
|
|
|
161
165
|
},
|
|
162
166
|
);
|
|
163
167
|
const storagePath = await FileSystem.getStoragePath("appCache");
|
|
164
|
-
const apkFilePath =
|
|
168
|
+
const apkFilePath = path.join(storagePath, `latest.apk`);
|
|
165
169
|
await FileSystem.writeFile(apkFilePath, buffer);
|
|
166
170
|
|
|
167
171
|
await this._installApk(opt.log, apkFilePath);
|
|
@@ -181,14 +185,14 @@ export abstract class AutoUpdate {
|
|
|
181
185
|
|
|
182
186
|
// Get versions
|
|
183
187
|
const externalPath = await FileSystem.getStoragePath("external");
|
|
184
|
-
const fileInfos = await FileSystem.readdir(
|
|
188
|
+
const fileInfos = await FileSystem.readdir(path.join(externalPath, opt.dirPath));
|
|
185
189
|
|
|
186
190
|
const versions = fileInfos
|
|
187
191
|
.filter((fileInfo) => !fileInfo.isDirectory)
|
|
188
192
|
.map((fileInfo) => ({
|
|
189
193
|
fileName: fileInfo.name,
|
|
190
|
-
version:
|
|
191
|
-
extName:
|
|
194
|
+
version: path.basename(fileInfo.name, path.extname(fileInfo.name)),
|
|
195
|
+
extName: path.extname(fileInfo.name),
|
|
192
196
|
}))
|
|
193
197
|
.filter((item) => {
|
|
194
198
|
return item.extName === ".apk" && /^[0-9.]*$/.test(item.version);
|
|
@@ -225,7 +229,7 @@ export abstract class AutoUpdate {
|
|
|
225
229
|
return;
|
|
226
230
|
}
|
|
227
231
|
|
|
228
|
-
const apkFilePath =
|
|
232
|
+
const apkFilePath = path.join(externalPath, opt.dirPath, latestVersion + ".apk");
|
|
229
233
|
await this._installApk(opt.log, apkFilePath);
|
|
230
234
|
await this._freezeApp();
|
|
231
235
|
} catch (err) {
|
package/src/env.d.ts
ADDED
package/src/index.ts
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ApkInstallerPlugin, VersionInfo } from "../ApkInstallerPlugin";
|
|
3
3
|
|
|
4
|
-
export class ApkInstallerWeb extends WebPlugin implements
|
|
4
|
+
export class ApkInstallerWeb extends WebPlugin implements ApkInstallerPlugin {
|
|
5
5
|
install(_options: { uri: string }): Promise<void> {
|
|
6
6
|
alert("[ApkInstaller] APK installation is not supported in web environment.");
|
|
7
7
|
return Promise.resolve();
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
checkPermissions(): Promise<{ granted: boolean; manifest: boolean }> {
|
|
11
11
|
// Skip permission check on web
|
|
12
|
-
return Promise.resolve({ granted: true });
|
|
12
|
+
return Promise.resolve({ granted: true, manifest: true });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
async
|
|
15
|
+
async requestPermissions(): Promise<void> {
|
|
16
16
|
// No-op on web
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
// Skip manifest check on web
|
|
21
|
-
return Promise.resolve({ declared: true });
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
getVersionInfo(): Promise<IVersionInfo> {
|
|
19
|
+
getVersionInfo(): Promise<VersionInfo> {
|
|
25
20
|
return Promise.resolve({
|
|
26
21
|
versionName:
|
|
27
|
-
|
|
22
|
+
import.meta.env.__VER__ ?? "0.0.0",
|
|
28
23
|
versionCode: "0",
|
|
29
24
|
});
|
|
30
25
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface IVersionInfo {
|
|
2
|
-
versionName: string;
|
|
3
|
-
versionCode: string;
|
|
4
|
-
}
|
|
5
|
-
export interface IApkInstallerPlugin {
|
|
6
|
-
install(options: {
|
|
7
|
-
uri: string;
|
|
8
|
-
}): Promise<void>;
|
|
9
|
-
hasPermission(): Promise<{
|
|
10
|
-
granted: boolean;
|
|
11
|
-
}>;
|
|
12
|
-
requestPermission(): Promise<void>;
|
|
13
|
-
hasPermissionManifest(): Promise<{
|
|
14
|
-
declared: boolean;
|
|
15
|
-
}>;
|
|
16
|
-
getVersionInfo(): Promise<IVersionInfo>;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=IApkInstallerPlugin.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IApkInstallerPlugin.d.ts","sourceRoot":"","sources":["..\\src\\IApkInstallerPlugin.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,aAAa,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,qBAAqB,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACxD,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;CACzC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=IApkInstallerPlugin.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface IVersionInfo {
|
|
2
|
-
versionName: string;
|
|
3
|
-
versionCode: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface IApkInstallerPlugin {
|
|
7
|
-
install(options: { uri: string }): Promise<void>;
|
|
8
|
-
hasPermission(): Promise<{ granted: boolean }>;
|
|
9
|
-
requestPermission(): Promise<void>;
|
|
10
|
-
hasPermissionManifest(): Promise<{ declared: boolean }>;
|
|
11
|
-
getVersionInfo(): Promise<IVersionInfo>;
|
|
12
|
-
}
|
|
File without changes
|