@simplysm/capacitor-plugin-usb-storage 13.0.75 → 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 +28 -28
- package/android/src/main/java/kr/co/simplysm/capacitor/usbstorage/UsbStoragePlugin.java +5 -5
- package/dist/UsbStorage.d.ts +6 -6
- package/dist/UsbStorage.d.ts.map +1 -1
- package/dist/UsbStorage.js +11 -11
- package/dist/UsbStorage.js.map +1 -1
- package/dist/{IUsbStoragePlugin.d.ts → UsbStoragePlugin.d.ts} +11 -11
- package/dist/UsbStoragePlugin.d.ts.map +1 -0
- package/dist/UsbStoragePlugin.js +1 -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/UsbStorageWeb.d.ts +10 -10
- package/dist/web/UsbStorageWeb.d.ts.map +1 -1
- package/dist/web/UsbStorageWeb.js +5 -5
- package/dist/web/UsbStorageWeb.js.map +1 -1
- package/dist/web/VirtualUsbStorage.d.ts +9 -9
- package/dist/web/VirtualUsbStorage.d.ts.map +1 -1
- package/dist/web/VirtualUsbStorage.js +7 -48
- package/dist/web/VirtualUsbStorage.js.map +1 -1
- package/package.json +3 -2
- package/src/UsbStorage.ts +18 -18
- package/src/UsbStoragePlugin.ts +25 -0
- package/src/index.ts +1 -1
- package/src/web/UsbStorageWeb.ts +15 -15
- package/src/web/VirtualUsbStorage.ts +10 -59
- package/dist/IUsbStoragePlugin.d.ts.map +0 -1
- package/dist/IUsbStoragePlugin.js +0 -1
- package/dist/web/IndexedDbStore.d.ts +0 -16
- package/dist/web/IndexedDbStore.d.ts.map +0 -1
- package/dist/web/IndexedDbStore.js +0 -76
- package/dist/web/IndexedDbStore.js.map +0 -6
- package/src/IUsbStoragePlugin.ts +0 -25
- package/src/web/IndexedDbStore.ts +0 -88
- /package/dist/{IUsbStoragePlugin.js.map → UsbStoragePlugin.js.map} +0 -0
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ import { UsbStorage } from "@simplysm/capacitor-plugin-usb-storage";
|
|
|
28
28
|
Returns a list of currently connected USB devices.
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
|
-
static async getDevices(): Promise<
|
|
31
|
+
static async getDevices(): Promise<UsbDeviceInfo[]>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
```typescript
|
|
@@ -38,31 +38,31 @@ for (const device of devices) {
|
|
|
38
38
|
}
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
#### `UsbStorage.
|
|
41
|
+
#### `UsbStorage.requestPermissions(filter)`
|
|
42
42
|
|
|
43
43
|
Requests access permission for a specific USB device identified by its vendor and product IDs.
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
static async
|
|
46
|
+
static async requestPermissions(filter: UsbDeviceFilter): Promise<boolean>
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
|
-
const granted = await UsbStorage.
|
|
50
|
+
const granted = await UsbStorage.requestPermissions({ vendorId: 0x1234, productId: 0x5678 });
|
|
51
51
|
if (granted) {
|
|
52
52
|
console.log("Permission granted");
|
|
53
53
|
}
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
#### `UsbStorage.
|
|
56
|
+
#### `UsbStorage.checkPermissions(filter)`
|
|
57
57
|
|
|
58
58
|
Checks whether access permission for a specific USB device is currently held.
|
|
59
59
|
|
|
60
60
|
```typescript
|
|
61
|
-
static async
|
|
61
|
+
static async checkPermissions(filter: UsbDeviceFilter): Promise<boolean>
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
```typescript
|
|
65
|
-
const alreadyGranted = await UsbStorage.
|
|
65
|
+
const alreadyGranted = await UsbStorage.checkPermissions({ vendorId: 0x1234, productId: 0x5678 });
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
#### `UsbStorage.readdir(filter, dirPath)`
|
|
@@ -70,7 +70,7 @@ const alreadyGranted = await UsbStorage.hasPermission({ vendorId: 0x1234, produc
|
|
|
70
70
|
Reads the contents of a directory on the USB storage device.
|
|
71
71
|
|
|
72
72
|
```typescript
|
|
73
|
-
static async readdir(filter:
|
|
73
|
+
static async readdir(filter: UsbDeviceFilter, dirPath: string): Promise<UsbFileInfo[]>
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
```typescript
|
|
@@ -81,17 +81,17 @@ for (const entry of entries) {
|
|
|
81
81
|
}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
#### `UsbStorage.
|
|
84
|
+
#### `UsbStorage.readFile(filter, filePath)`
|
|
85
85
|
|
|
86
86
|
Reads a file from the USB storage device and returns its contents as `Bytes`. Returns `undefined` if the file does not exist.
|
|
87
87
|
|
|
88
88
|
```typescript
|
|
89
|
-
static async
|
|
89
|
+
static async readFile(filter: UsbDeviceFilter, filePath: string): Promise<Bytes | undefined>
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
```typescript
|
|
93
93
|
const filter = { vendorId: 0x1234, productId: 0x5678 };
|
|
94
|
-
const bytes = await UsbStorage.
|
|
94
|
+
const bytes = await UsbStorage.readFile(filter, "/data/file.bin");
|
|
95
95
|
if (bytes !== undefined) {
|
|
96
96
|
console.log("File size:", bytes.length);
|
|
97
97
|
}
|
|
@@ -101,19 +101,19 @@ if (bytes !== undefined) {
|
|
|
101
101
|
|
|
102
102
|
```typescript
|
|
103
103
|
import type {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
UsbDeviceInfo,
|
|
105
|
+
UsbDeviceFilter,
|
|
106
|
+
UsbFileInfo,
|
|
107
|
+
UsbStoragePlugin,
|
|
108
108
|
} from "@simplysm/capacitor-plugin-usb-storage";
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
### `
|
|
111
|
+
### `UsbDeviceInfo`
|
|
112
112
|
|
|
113
113
|
Describes a connected USB device.
|
|
114
114
|
|
|
115
115
|
```typescript
|
|
116
|
-
interface
|
|
116
|
+
interface UsbDeviceInfo {
|
|
117
117
|
deviceName: string;
|
|
118
118
|
manufacturerName: string;
|
|
119
119
|
productName: string;
|
|
@@ -122,38 +122,38 @@ interface IUsbDeviceInfo {
|
|
|
122
122
|
}
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
### `
|
|
125
|
+
### `UsbDeviceFilter`
|
|
126
126
|
|
|
127
127
|
Identifies a USB device by its vendor and product IDs. Used as a selector in permission and file-system calls.
|
|
128
128
|
|
|
129
129
|
```typescript
|
|
130
|
-
interface
|
|
130
|
+
interface UsbDeviceFilter {
|
|
131
131
|
vendorId: number;
|
|
132
132
|
productId: number;
|
|
133
133
|
}
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
### `
|
|
136
|
+
### `UsbFileInfo`
|
|
137
137
|
|
|
138
138
|
Describes a single entry (file or directory) returned by `readdir`.
|
|
139
139
|
|
|
140
140
|
```typescript
|
|
141
|
-
interface
|
|
141
|
+
interface UsbFileInfo {
|
|
142
142
|
name: string;
|
|
143
143
|
isDirectory: boolean;
|
|
144
144
|
}
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
### `
|
|
147
|
+
### `UsbStoragePlugin`
|
|
148
148
|
|
|
149
149
|
The raw Capacitor plugin interface registered under the `"UsbStorage"` plugin name. Prefer using the `UsbStorage` abstract class instead of calling this interface directly.
|
|
150
150
|
|
|
151
151
|
```typescript
|
|
152
|
-
interface
|
|
153
|
-
getDevices(): Promise<{ devices:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
readdir(options:
|
|
157
|
-
|
|
152
|
+
interface UsbStoragePlugin {
|
|
153
|
+
getDevices(): Promise<{ devices: UsbDeviceInfo[] }>;
|
|
154
|
+
requestPermissions(options: UsbDeviceFilter): Promise<{ granted: boolean }>;
|
|
155
|
+
checkPermissions(options: UsbDeviceFilter): Promise<{ granted: boolean }>;
|
|
156
|
+
readdir(options: UsbDeviceFilter & { path: string }): Promise<{ files: UsbFileInfo[] }>;
|
|
157
|
+
readFile(options: UsbDeviceFilter & { path: string }): Promise<{ data: string | null }>;
|
|
158
158
|
}
|
|
159
159
|
```
|
|
@@ -62,7 +62,7 @@ public class UsbStoragePlugin extends Plugin {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
@PluginMethod
|
|
65
|
-
public void
|
|
65
|
+
public void requestPermissions(PluginCall call) {
|
|
66
66
|
Integer vendorId = call.getInt("vendorId");
|
|
67
67
|
Integer productId = call.getInt("productId");
|
|
68
68
|
|
|
@@ -120,7 +120,7 @@ public class UsbStoragePlugin extends Plugin {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
@PluginMethod
|
|
123
|
-
public void
|
|
123
|
+
public void checkPermissions(PluginCall call) {
|
|
124
124
|
Integer vendorId = call.getInt("vendorId");
|
|
125
125
|
Integer productId = call.getInt("productId");
|
|
126
126
|
|
|
@@ -197,7 +197,7 @@ public class UsbStoragePlugin extends Plugin {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
@PluginMethod
|
|
200
|
-
public void
|
|
200
|
+
public void readFile(PluginCall call) {
|
|
201
201
|
Integer vendorId = call.getInt("vendorId");
|
|
202
202
|
Integer productId = call.getInt("productId");
|
|
203
203
|
String path = call.getString("path");
|
|
@@ -258,8 +258,8 @@ public class UsbStoragePlugin extends Plugin {
|
|
|
258
258
|
device.close();
|
|
259
259
|
}
|
|
260
260
|
} catch (Exception e) {
|
|
261
|
-
Log.e(TAG, "
|
|
262
|
-
call.reject("
|
|
261
|
+
Log.e(TAG, "readFile failed", e);
|
|
262
|
+
call.reject("readFile failed: " + e.getMessage());
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
package/dist/UsbStorage.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UsbDeviceFilter, UsbDeviceInfo, UsbFileInfo } from "./UsbStoragePlugin";
|
|
2
2
|
import type { Bytes } from "@simplysm/core-common";
|
|
3
3
|
/**
|
|
4
4
|
* Plugin for interacting with USB storage devices
|
|
@@ -10,32 +10,32 @@ export declare abstract class UsbStorage {
|
|
|
10
10
|
* Get list of connected USB devices
|
|
11
11
|
* @returns Array of connected USB device info
|
|
12
12
|
*/
|
|
13
|
-
static getDevices(): Promise<
|
|
13
|
+
static getDevices(): Promise<UsbDeviceInfo[]>;
|
|
14
14
|
/**
|
|
15
15
|
* Request USB device access permission
|
|
16
16
|
* @param filter vendorId and productId of the USB device to request permission for
|
|
17
17
|
* @returns Whether permission was granted
|
|
18
18
|
*/
|
|
19
|
-
static
|
|
19
|
+
static requestPermissions(filter: UsbDeviceFilter): Promise<boolean>;
|
|
20
20
|
/**
|
|
21
21
|
* Check if USB device access permission is granted
|
|
22
22
|
* @param filter vendorId and productId of the USB device to check permission for
|
|
23
23
|
* @returns Whether permission is held
|
|
24
24
|
*/
|
|
25
|
-
static
|
|
25
|
+
static checkPermissions(filter: UsbDeviceFilter): Promise<boolean>;
|
|
26
26
|
/**
|
|
27
27
|
* Read directory contents from USB storage device
|
|
28
28
|
* @param filter vendorId and productId of the target USB device
|
|
29
29
|
* @param dirPath Directory path to read
|
|
30
30
|
* @returns Array of file/folder info in the directory
|
|
31
31
|
*/
|
|
32
|
-
static readdir(filter:
|
|
32
|
+
static readdir(filter: UsbDeviceFilter, dirPath: string): Promise<UsbFileInfo[]>;
|
|
33
33
|
/**
|
|
34
34
|
* Read a file from USB storage device
|
|
35
35
|
* @param filter vendorId and productId of the target USB device
|
|
36
36
|
* @param filePath File path to read
|
|
37
37
|
* @returns Bytes containing file data, or undefined
|
|
38
38
|
*/
|
|
39
|
-
static
|
|
39
|
+
static readFile(filter: UsbDeviceFilter, filePath: string): Promise<Bytes | undefined>;
|
|
40
40
|
}
|
|
41
41
|
//# sourceMappingURL=UsbStorage.d.ts.map
|
package/dist/UsbStorage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UsbStorage.d.ts","sourceRoot":"","sources":["..\\src\\UsbStorage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"UsbStorage.d.ts","sourceRoot":"","sources":["..\\src\\UsbStorage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,WAAW,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAUnD;;;;GAIG;AACH,8BAAsB,UAAU;IAC9B;;;OAGG;WACU,UAAU,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAKnD;;;;OAIG;WACU,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1E;;;;OAIG;WACU,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxE;;;;;OAKG;WACU,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAKtF;;;;;OAKG;WACU,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAO7F"}
|
package/dist/UsbStorage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { registerPlugin } from "@capacitor/core";
|
|
2
|
-
import {
|
|
3
|
-
const
|
|
2
|
+
import { bytes } from "@simplysm/core-common";
|
|
3
|
+
const usbStoragePlugin = registerPlugin("UsbStorage", {
|
|
4
4
|
web: async () => {
|
|
5
5
|
const { UsbStorageWeb } = await import("./web/UsbStorageWeb");
|
|
6
6
|
return new UsbStorageWeb();
|
|
@@ -12,7 +12,7 @@ class UsbStorage {
|
|
|
12
12
|
* @returns Array of connected USB device info
|
|
13
13
|
*/
|
|
14
14
|
static async getDevices() {
|
|
15
|
-
const result = await
|
|
15
|
+
const result = await usbStoragePlugin.getDevices();
|
|
16
16
|
return result.devices;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
@@ -20,8 +20,8 @@ class UsbStorage {
|
|
|
20
20
|
* @param filter vendorId and productId of the USB device to request permission for
|
|
21
21
|
* @returns Whether permission was granted
|
|
22
22
|
*/
|
|
23
|
-
static async
|
|
24
|
-
const result = await
|
|
23
|
+
static async requestPermissions(filter) {
|
|
24
|
+
const result = await usbStoragePlugin.requestPermissions(filter);
|
|
25
25
|
return result.granted;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
@@ -29,8 +29,8 @@ class UsbStorage {
|
|
|
29
29
|
* @param filter vendorId and productId of the USB device to check permission for
|
|
30
30
|
* @returns Whether permission is held
|
|
31
31
|
*/
|
|
32
|
-
static async
|
|
33
|
-
const result = await
|
|
32
|
+
static async checkPermissions(filter) {
|
|
33
|
+
const result = await usbStoragePlugin.checkPermissions(filter);
|
|
34
34
|
return result.granted;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
@@ -40,7 +40,7 @@ class UsbStorage {
|
|
|
40
40
|
* @returns Array of file/folder info in the directory
|
|
41
41
|
*/
|
|
42
42
|
static async readdir(filter, dirPath) {
|
|
43
|
-
const result = await
|
|
43
|
+
const result = await usbStoragePlugin.readdir({ ...filter, path: dirPath });
|
|
44
44
|
return result.files;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
@@ -49,12 +49,12 @@ class UsbStorage {
|
|
|
49
49
|
* @param filePath File path to read
|
|
50
50
|
* @returns Bytes containing file data, or undefined
|
|
51
51
|
*/
|
|
52
|
-
static async
|
|
53
|
-
const result = await
|
|
52
|
+
static async readFile(filter, filePath) {
|
|
53
|
+
const result = await usbStoragePlugin.readFile({ ...filter, path: filePath });
|
|
54
54
|
if (result.data == null) {
|
|
55
55
|
return void 0;
|
|
56
56
|
}
|
|
57
|
-
return
|
|
57
|
+
return bytes.fromBase64(result.data);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
export {
|
package/dist/UsbStorage.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/UsbStorage.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,sBAAsB;AAQ/B,SAAS,
|
|
4
|
+
"mappings": "AAAA,SAAS,sBAAsB;AAQ/B,SAAS,aAAa;AAEtB,MAAM,mBAAmB,eAAiC,cAAc;AAAA,EACtE,KAAK,YAAY;AACf,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,qBAAqB;AAC5D,WAAO,IAAI,cAAc;AAAA,EAC3B;AACF,CAAC;AAOM,MAAe,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAK/B,aAAa,aAAuC;AAClD,UAAM,SAAS,MAAM,iBAAiB,WAAW;AACjD,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,mBAAmB,QAA2C;AACzE,UAAM,SAAS,MAAM,iBAAiB,mBAAmB,MAAM;AAC/D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,iBAAiB,QAA2C;AACvE,UAAM,SAAS,MAAM,iBAAiB,iBAAiB,MAAM;AAC7D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,QAAQ,QAAyB,SAAyC;AACrF,UAAM,SAAS,MAAM,iBAAiB,QAAQ,EAAE,GAAG,QAAQ,MAAM,QAAQ,CAAC;AAC1E,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,SAAS,QAAyB,UAA8C;AAC3F,UAAM,SAAS,MAAM,iBAAiB,SAAS,EAAE,GAAG,QAAQ,MAAM,SAAS,CAAC;AAC5E,QAAI,OAAO,QAAQ,MAAM;AACvB,aAAO;AAAA,IACT;AACA,WAAO,MAAM,WAAW,OAAO,IAAI;AAAA,EACrC;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface UsbDeviceInfo {
|
|
2
2
|
deviceName: string;
|
|
3
3
|
manufacturerName: string;
|
|
4
4
|
productName: string;
|
|
5
5
|
vendorId: number;
|
|
6
6
|
productId: number;
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
8
|
+
export interface UsbDeviceFilter {
|
|
9
9
|
vendorId: number;
|
|
10
10
|
productId: number;
|
|
11
11
|
}
|
|
12
|
-
export interface
|
|
12
|
+
export interface UsbFileInfo {
|
|
13
13
|
name: string;
|
|
14
14
|
isDirectory: boolean;
|
|
15
15
|
}
|
|
16
|
-
export interface
|
|
16
|
+
export interface UsbStoragePlugin {
|
|
17
17
|
getDevices(): Promise<{
|
|
18
|
-
devices:
|
|
18
|
+
devices: UsbDeviceInfo[];
|
|
19
19
|
}>;
|
|
20
|
-
|
|
20
|
+
requestPermissions(options: UsbDeviceFilter): Promise<{
|
|
21
21
|
granted: boolean;
|
|
22
22
|
}>;
|
|
23
|
-
|
|
23
|
+
checkPermissions(options: UsbDeviceFilter): Promise<{
|
|
24
24
|
granted: boolean;
|
|
25
25
|
}>;
|
|
26
|
-
readdir(options:
|
|
26
|
+
readdir(options: UsbDeviceFilter & {
|
|
27
27
|
path: string;
|
|
28
28
|
}): Promise<{
|
|
29
|
-
files:
|
|
29
|
+
files: UsbFileInfo[];
|
|
30
30
|
}>;
|
|
31
|
-
|
|
31
|
+
readFile(options: UsbDeviceFilter & {
|
|
32
32
|
path: string;
|
|
33
33
|
}): Promise<{
|
|
34
34
|
data: string | null;
|
|
35
35
|
}>;
|
|
36
36
|
}
|
|
37
|
-
//# sourceMappingURL=
|
|
37
|
+
//# sourceMappingURL=UsbStoragePlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UsbStoragePlugin.d.ts","sourceRoot":"","sources":["..\\src\\UsbStoragePlugin.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC,CAAC;IACpD,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC5E,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC,CAAC;IACxF,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACzF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=UsbStoragePlugin.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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AACA,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
|
-
import type {
|
|
3
|
-
export declare class UsbStorageWeb extends WebPlugin implements
|
|
2
|
+
import type { UsbDeviceFilter, UsbDeviceInfo, UsbFileInfo, UsbStoragePlugin } from "../UsbStoragePlugin";
|
|
3
|
+
export declare class UsbStorageWeb extends WebPlugin implements UsbStoragePlugin {
|
|
4
4
|
private readonly _storage;
|
|
5
5
|
getDevices(): Promise<{
|
|
6
|
-
devices:
|
|
6
|
+
devices: UsbDeviceInfo[];
|
|
7
7
|
}>;
|
|
8
|
-
|
|
8
|
+
requestPermissions(_options: UsbDeviceFilter): Promise<{
|
|
9
9
|
granted: boolean;
|
|
10
10
|
}>;
|
|
11
|
-
|
|
11
|
+
checkPermissions(_options: UsbDeviceFilter): Promise<{
|
|
12
12
|
granted: boolean;
|
|
13
13
|
}>;
|
|
14
|
-
readdir(options:
|
|
14
|
+
readdir(options: UsbDeviceFilter & {
|
|
15
15
|
path: string;
|
|
16
16
|
}): Promise<{
|
|
17
|
-
files:
|
|
17
|
+
files: UsbFileInfo[];
|
|
18
18
|
}>;
|
|
19
|
-
|
|
19
|
+
readFile(options: UsbDeviceFilter & {
|
|
20
20
|
path: string;
|
|
21
21
|
}): Promise<{
|
|
22
22
|
data: string | null;
|
|
@@ -34,10 +34,10 @@ export declare class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugi
|
|
|
34
34
|
/**
|
|
35
35
|
* Add a file to a virtual USB device. (For testing/development)
|
|
36
36
|
*/
|
|
37
|
-
addVirtualFile(filter:
|
|
37
|
+
addVirtualFile(filter: UsbDeviceFilter, filePath: string, data: Uint8Array): Promise<void>;
|
|
38
38
|
/**
|
|
39
39
|
* Add a directory to a virtual USB device. (For testing/development)
|
|
40
40
|
*/
|
|
41
|
-
addVirtualDirectory(filter:
|
|
41
|
+
addVirtualDirectory(filter: UsbDeviceFilter, dirPath: string): Promise<void>;
|
|
42
42
|
}
|
|
43
43
|
//# sourceMappingURL=UsbStorageWeb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UsbStorageWeb.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\UsbStorageWeb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"UsbStorageWeb.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\UsbStorageWeb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,WAAW,EACX,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAI7B,qBAAa,aAAc,SAAQ,SAAU,YAAW,gBAAgB;IACtE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAE9C,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAanD,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAI5E,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAI1E,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;IAevF,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAc7F;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE;QAC7B,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjB;;OAEG;IACG,cAAc,CAClB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC;IAahB;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAInF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
2
|
import { VirtualUsbStorage } from "./VirtualUsbStorage.js";
|
|
3
|
-
import {
|
|
3
|
+
import { bytes } from "@simplysm/core-common";
|
|
4
4
|
class UsbStorageWeb extends WebPlugin {
|
|
5
5
|
_storage = new VirtualUsbStorage();
|
|
6
6
|
async getDevices() {
|
|
@@ -15,10 +15,10 @@ class UsbStorageWeb extends WebPlugin {
|
|
|
15
15
|
}))
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
async
|
|
18
|
+
async requestPermissions(_options) {
|
|
19
19
|
return Promise.resolve({ granted: true });
|
|
20
20
|
}
|
|
21
|
-
async
|
|
21
|
+
async checkPermissions(_options) {
|
|
22
22
|
return Promise.resolve({ granted: true });
|
|
23
23
|
}
|
|
24
24
|
async readdir(options) {
|
|
@@ -35,7 +35,7 @@ class UsbStorageWeb extends WebPlugin {
|
|
|
35
35
|
const children = await this._storage.listChildren(deviceKey, options.path);
|
|
36
36
|
return { files: children };
|
|
37
37
|
}
|
|
38
|
-
async
|
|
38
|
+
async readFile(options) {
|
|
39
39
|
const deviceKey = `${options.vendorId}:${options.productId}`;
|
|
40
40
|
const devices = await this._storage.getDevices();
|
|
41
41
|
const deviceExists = devices.some((d) => d.key === deviceKey);
|
|
@@ -66,7 +66,7 @@ class UsbStorageWeb extends WebPlugin {
|
|
|
66
66
|
deviceKey,
|
|
67
67
|
path: filePath,
|
|
68
68
|
kind: "file",
|
|
69
|
-
dataBase64:
|
|
69
|
+
dataBase64: bytes.toBase64(data)
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/web/UsbStorageWeb.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,iBAAiB;AAO1B,SAAS,yBAAyB;AAClC,SAAS,
|
|
4
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAO1B,SAAS,yBAAyB;AAClC,SAAS,aAAa;AAEf,MAAM,sBAAsB,UAAsC;AAAA,EACtD,WAAW,IAAI,kBAAkB;AAAA,EAElD,MAAM,aAAoD;AACxD,UAAM,UAAU,MAAM,KAAK,SAAS,WAAW;AAC/C,WAAO;AAAA,MACL,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,QAC3B,YAAY,EAAE;AAAA,QACd,kBAAkB,EAAE;AAAA,QACpB,aAAa,EAAE;AAAA,QACf,UAAU,EAAE;AAAA,QACZ,WAAW,EAAE;AAAA,MACf,EAAE;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAM,mBAAmB,UAA0D;AACjF,WAAO,QAAQ,QAAQ,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,iBAAiB,UAA0D;AAC/E,WAAO,QAAQ,QAAQ,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,QAAQ,SAAgF;AAC5F,UAAM,YAAY,GAAG,QAAQ,QAAQ,IAAI,QAAQ,SAAS;AAC1D,UAAM,UAAU,MAAM,KAAK,SAAS,WAAW;AAC/C,UAAM,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,SAAS;AAC5D,QAAI,CAAC,cAAc;AACjB,aAAO,EAAE,OAAO,CAAC,EAAE;AAAA,IACrB;AACA,UAAM,QAAQ,MAAM,KAAK,SAAS,SAAS,WAAW,QAAQ,IAAI;AAClE,QAAI,CAAC,SAAS,MAAM,SAAS,OAAO;AAClC,aAAO,EAAE,OAAO,CAAC,EAAE;AAAA,IACrB;AACA,UAAM,WAAW,MAAM,KAAK,SAAS,aAAa,WAAW,QAAQ,IAAI;AACzE,WAAO,EAAE,OAAO,SAAS;AAAA,EAC3B;AAAA,EAEA,MAAM,SAAS,SAA+E;AAC5F,UAAM,YAAY,GAAG,QAAQ,QAAQ,IAAI,QAAQ,SAAS;AAC1D,UAAM,UAAU,MAAM,KAAK,SAAS,WAAW;AAC/C,UAAM,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,SAAS;AAC5D,QAAI,CAAC,cAAc;AACjB,aAAO,EAAE,MAAM,KAAK;AAAA,IACtB;AACA,UAAM,QAAQ,MAAM,KAAK,SAAS,SAAS,WAAW,QAAQ,IAAI;AAClE,QAAI,CAAC,SAAS,MAAM,SAAS,UAAU,MAAM,cAAc,MAAM;AAC/D,aAAO,EAAE,MAAM,KAAK;AAAA,IACtB;AACA,WAAO,EAAE,MAAM,MAAM,WAAW;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,QAML;AAChB,UAAM,KAAK,SAAS,UAAU,MAAM;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,QACA,UACA,MACe;AACf,UAAM,YAAY,GAAG,OAAO,QAAQ,IAAI,OAAO,SAAS;AACxD,UAAM,MAAM,SAAS,YAAY,GAAG;AACpC,UAAM,MAAM,QAAQ,KAAK,MAAM,SAAS,UAAU,GAAG,GAAG,KAAK;AAC7D,UAAM,KAAK,SAAS,UAAU,WAAW,GAAG;AAC5C,UAAM,KAAK,SAAS,SAAS;AAAA,MAC3B;AAAA,MACA,MAAM;AAAA,MACN,MAAM;AAAA,MACN,YAAY,MAAM,SAAS,IAAI;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,QAAyB,SAAgC;AACjF,UAAM,YAAY,GAAG,OAAO,QAAQ,IAAI,OAAO,SAAS;AACxD,UAAM,KAAK,SAAS,UAAU,WAAW,OAAO;AAAA,EAClD;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { VirtualFsEntry } from "@simplysm/core-browser";
|
|
1
2
|
interface VirtualDevice {
|
|
2
3
|
key: string;
|
|
3
4
|
vendorId: number;
|
|
@@ -6,22 +7,21 @@ interface VirtualDevice {
|
|
|
6
7
|
manufacturerName: string;
|
|
7
8
|
productName: string;
|
|
8
9
|
}
|
|
9
|
-
interface VirtualEntry {
|
|
10
|
-
fullKey: string;
|
|
11
|
-
deviceKey: string;
|
|
12
|
-
path: string;
|
|
13
|
-
kind: "file" | "dir";
|
|
14
|
-
dataBase64?: string;
|
|
15
|
-
}
|
|
16
10
|
export declare class VirtualUsbStorage {
|
|
17
11
|
private readonly _DEVICES_STORE;
|
|
18
12
|
private readonly _FILES_STORE;
|
|
19
13
|
private readonly _db;
|
|
14
|
+
private readonly _vfs;
|
|
20
15
|
constructor();
|
|
21
16
|
addDevice(device: Omit<VirtualDevice, "key">): Promise<void>;
|
|
22
17
|
getDevices(): Promise<VirtualDevice[]>;
|
|
23
|
-
getEntry(deviceKey: string, path: string): Promise<
|
|
24
|
-
putEntry(entry:
|
|
18
|
+
getEntry(deviceKey: string, path: string): Promise<VirtualFsEntry | undefined>;
|
|
19
|
+
putEntry(entry: {
|
|
20
|
+
deviceKey: string;
|
|
21
|
+
path: string;
|
|
22
|
+
kind: "file" | "dir";
|
|
23
|
+
dataBase64?: string;
|
|
24
|
+
}): Promise<void>;
|
|
25
25
|
listChildren(deviceKey: string, dirPath: string): Promise<{
|
|
26
26
|
name: string;
|
|
27
27
|
isDirectory: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualUsbStorage.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\VirtualUsbStorage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VirtualUsbStorage.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\VirtualUsbStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAa;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;;IAUpC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5D,UAAU,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAItC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAK9E,QAAQ,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9G,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAK9C,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGnE"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { IndexedDbStore } from "
|
|
1
|
+
import { IndexedDbStore, IndexedDbVirtualFs } from "@simplysm/core-browser";
|
|
2
2
|
class VirtualUsbStorage {
|
|
3
3
|
_DEVICES_STORE = "devices";
|
|
4
4
|
_FILES_STORE = "files";
|
|
5
5
|
_db;
|
|
6
|
+
_vfs;
|
|
6
7
|
constructor() {
|
|
7
8
|
this._db = new IndexedDbStore("capacitor_usb_virtual_storage", 1, [
|
|
8
9
|
{ name: this._DEVICES_STORE, keyPath: "key" },
|
|
9
10
|
{ name: this._FILES_STORE, keyPath: "fullKey" }
|
|
10
11
|
]);
|
|
12
|
+
this._vfs = new IndexedDbVirtualFs(this._db, this._FILES_STORE, "fullKey");
|
|
11
13
|
}
|
|
12
14
|
async addDevice(device) {
|
|
13
15
|
const key = `${device.vendorId}:${device.productId}`;
|
|
@@ -19,61 +21,18 @@ class VirtualUsbStorage {
|
|
|
19
21
|
}
|
|
20
22
|
async getEntry(deviceKey, path) {
|
|
21
23
|
const fullKey = `${deviceKey}:${path}`;
|
|
22
|
-
return this.
|
|
24
|
+
return this._vfs.getEntry(fullKey);
|
|
23
25
|
}
|
|
24
26
|
async putEntry(entry) {
|
|
25
27
|
const fullKey = `${entry.deviceKey}:${entry.path}`;
|
|
26
|
-
|
|
27
|
-
return this._db.put(this._FILES_STORE, fullEntry);
|
|
28
|
+
return this._vfs.putEntry(fullKey, entry.kind, entry.dataBase64);
|
|
28
29
|
}
|
|
29
30
|
async listChildren(deviceKey, dirPath) {
|
|
30
31
|
const prefix = `${deviceKey}:${dirPath === "/" ? "/" : dirPath + "/"}`;
|
|
31
|
-
return this.
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
const req = store.openCursor();
|
|
34
|
-
const map = /* @__PURE__ */ new Map();
|
|
35
|
-
req.onsuccess = () => {
|
|
36
|
-
const cursor = req.result;
|
|
37
|
-
if (!cursor) {
|
|
38
|
-
resolve(
|
|
39
|
-
Array.from(map.entries()).map(([name, isDirectory]) => ({ name, isDirectory }))
|
|
40
|
-
);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const key = String(cursor.key);
|
|
44
|
-
if (key.startsWith(prefix)) {
|
|
45
|
-
const rest = key.slice(prefix.length);
|
|
46
|
-
if (rest) {
|
|
47
|
-
const segments = rest.split("/").filter(Boolean);
|
|
48
|
-
if (segments.length > 0) {
|
|
49
|
-
const firstName = segments[0];
|
|
50
|
-
if (!map.has(firstName)) {
|
|
51
|
-
const isDir = segments.length > 1 || cursor.value.kind === "dir";
|
|
52
|
-
map.set(firstName, isDir);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
cursor.continue();
|
|
58
|
-
};
|
|
59
|
-
req.onerror = () => reject(req.error);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
32
|
+
return this._vfs.listChildren(prefix);
|
|
62
33
|
}
|
|
63
34
|
async ensureDir(deviceKey, dirPath) {
|
|
64
|
-
|
|
65
|
-
await this.putEntry({ deviceKey, path: "/", kind: "dir" });
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const segments = dirPath.split("/").filter(Boolean);
|
|
69
|
-
let acc = "";
|
|
70
|
-
for (const seg of segments) {
|
|
71
|
-
acc += "/" + seg;
|
|
72
|
-
const existing = await this.getEntry(deviceKey, acc);
|
|
73
|
-
if (!existing) {
|
|
74
|
-
await this.putEntry({ deviceKey, path: acc, kind: "dir" });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
35
|
+
return this._vfs.ensureDir((path) => `${deviceKey}:${path}`, dirPath);
|
|
77
36
|
}
|
|
78
37
|
}
|
|
79
38
|
export {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/web/VirtualUsbStorage.ts"],
|
|
4
|
-
"mappings": "
|
|
4
|
+
"mappings": "AACA,SAAS,gBAAgB,0BAA0B;AAW5C,MAAM,kBAAkB;AAAA,EACZ,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EAEjB,cAAc;AACZ,SAAK,MAAM,IAAI,eAAe,iCAAiC,GAAG;AAAA,MAChE,EAAE,MAAM,KAAK,gBAAgB,SAAS,MAAM;AAAA,MAC5C,EAAE,MAAM,KAAK,cAAc,SAAS,UAAU;AAAA,IAChD,CAAC;AACD,SAAK,OAAO,IAAI,mBAAmB,KAAK,KAAK,KAAK,cAAc,SAAS;AAAA,EAC3E;AAAA,EAEA,MAAM,UAAU,QAAmD;AACjE,UAAM,MAAM,GAAG,OAAO,QAAQ,IAAI,OAAO,SAAS;AAClD,UAAM,QAAuB,EAAE,GAAG,QAAQ,IAAI;AAC9C,WAAO,KAAK,IAAI,IAAI,KAAK,gBAAgB,KAAK;AAAA,EAChD;AAAA,EAEA,MAAM,aAAuC;AAC3C,WAAO,KAAK,IAAI,OAAsB,KAAK,cAAc;AAAA,EAC3D;AAAA,EAEA,MAAM,SAAS,WAAmB,MAAmD;AACnF,UAAM,UAAU,GAAG,SAAS,IAAI,IAAI;AACpC,WAAO,KAAK,KAAK,SAAS,OAAO;AAAA,EACnC;AAAA,EAEA,MAAM,SAAS,OAAsG;AACnH,UAAM,UAAU,GAAG,MAAM,SAAS,IAAI,MAAM,IAAI;AAChD,WAAO,KAAK,KAAK,SAAS,SAAS,MAAM,MAAM,MAAM,UAAU;AAAA,EACjE;AAAA,EAEA,MAAM,aACJ,WACA,SACmD;AACnD,UAAM,SAAS,GAAG,SAAS,IAAI,YAAY,MAAM,MAAM,UAAU,GAAG;AACpE,WAAO,KAAK,KAAK,aAAa,MAAM;AAAA,EACtC;AAAA,EAEA,MAAM,UAAU,WAAmB,SAAgC;AACjE,WAAO,KAAK,KAAK,UAAU,CAAC,SAAS,GAAG,SAAS,IAAI,IAAI,IAAI,OAAO;AAAA,EACtE;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/capacitor-plugin-usb-storage",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.77",
|
|
4
4
|
"description": "Simplysm Package - Capacitor USB Storage Plugin",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"android"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@simplysm/core-
|
|
21
|
+
"@simplysm/core-browser": "13.0.77",
|
|
22
|
+
"@simplysm/core-common": "13.0.77"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@capacitor/core": "^7.5.0"
|
package/src/UsbStorage.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { registerPlugin } from "@capacitor/core";
|
|
2
2
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "./
|
|
3
|
+
UsbDeviceFilter,
|
|
4
|
+
UsbDeviceInfo,
|
|
5
|
+
UsbFileInfo,
|
|
6
|
+
UsbStoragePlugin,
|
|
7
|
+
} from "./UsbStoragePlugin";
|
|
8
8
|
import type { Bytes } from "@simplysm/core-common";
|
|
9
|
-
import {
|
|
9
|
+
import { bytes } from "@simplysm/core-common";
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const usbStoragePlugin = registerPlugin<UsbStoragePlugin>("UsbStorage", {
|
|
12
12
|
web: async () => {
|
|
13
13
|
const { UsbStorageWeb } = await import("./web/UsbStorageWeb");
|
|
14
14
|
return new UsbStorageWeb();
|
|
@@ -25,8 +25,8 @@ export abstract class UsbStorage {
|
|
|
25
25
|
* Get list of connected USB devices
|
|
26
26
|
* @returns Array of connected USB device info
|
|
27
27
|
*/
|
|
28
|
-
static async getDevices(): Promise<
|
|
29
|
-
const result = await
|
|
28
|
+
static async getDevices(): Promise<UsbDeviceInfo[]> {
|
|
29
|
+
const result = await usbStoragePlugin.getDevices();
|
|
30
30
|
return result.devices;
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -35,8 +35,8 @@ export abstract class UsbStorage {
|
|
|
35
35
|
* @param filter vendorId and productId of the USB device to request permission for
|
|
36
36
|
* @returns Whether permission was granted
|
|
37
37
|
*/
|
|
38
|
-
static async
|
|
39
|
-
const result = await
|
|
38
|
+
static async requestPermissions(filter: UsbDeviceFilter): Promise<boolean> {
|
|
39
|
+
const result = await usbStoragePlugin.requestPermissions(filter);
|
|
40
40
|
return result.granted;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -45,8 +45,8 @@ export abstract class UsbStorage {
|
|
|
45
45
|
* @param filter vendorId and productId of the USB device to check permission for
|
|
46
46
|
* @returns Whether permission is held
|
|
47
47
|
*/
|
|
48
|
-
static async
|
|
49
|
-
const result = await
|
|
48
|
+
static async checkPermissions(filter: UsbDeviceFilter): Promise<boolean> {
|
|
49
|
+
const result = await usbStoragePlugin.checkPermissions(filter);
|
|
50
50
|
return result.granted;
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -56,8 +56,8 @@ export abstract class UsbStorage {
|
|
|
56
56
|
* @param dirPath Directory path to read
|
|
57
57
|
* @returns Array of file/folder info in the directory
|
|
58
58
|
*/
|
|
59
|
-
static async readdir(filter:
|
|
60
|
-
const result = await
|
|
59
|
+
static async readdir(filter: UsbDeviceFilter, dirPath: string): Promise<UsbFileInfo[]> {
|
|
60
|
+
const result = await usbStoragePlugin.readdir({ ...filter, path: dirPath });
|
|
61
61
|
return result.files;
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -67,11 +67,11 @@ export abstract class UsbStorage {
|
|
|
67
67
|
* @param filePath File path to read
|
|
68
68
|
* @returns Bytes containing file data, or undefined
|
|
69
69
|
*/
|
|
70
|
-
static async
|
|
71
|
-
const result = await
|
|
70
|
+
static async readFile(filter: UsbDeviceFilter, filePath: string): Promise<Bytes | undefined> {
|
|
71
|
+
const result = await usbStoragePlugin.readFile({ ...filter, path: filePath });
|
|
72
72
|
if (result.data == null) {
|
|
73
73
|
return undefined;
|
|
74
74
|
}
|
|
75
|
-
return
|
|
75
|
+
return bytes.fromBase64(result.data);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface UsbDeviceInfo {
|
|
2
|
+
deviceName: string;
|
|
3
|
+
manufacturerName: string;
|
|
4
|
+
productName: string;
|
|
5
|
+
vendorId: number;
|
|
6
|
+
productId: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface UsbDeviceFilter {
|
|
10
|
+
vendorId: number;
|
|
11
|
+
productId: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface UsbFileInfo {
|
|
15
|
+
name: string;
|
|
16
|
+
isDirectory: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface UsbStoragePlugin {
|
|
20
|
+
getDevices(): Promise<{ devices: UsbDeviceInfo[] }>;
|
|
21
|
+
requestPermissions(options: UsbDeviceFilter): Promise<{ granted: boolean }>;
|
|
22
|
+
checkPermissions(options: UsbDeviceFilter): Promise<{ granted: boolean }>;
|
|
23
|
+
readdir(options: UsbDeviceFilter & { path: string }): Promise<{ files: UsbFileInfo[] }>;
|
|
24
|
+
readFile(options: UsbDeviceFilter & { path: string }): Promise<{ data: string | null }>;
|
|
25
|
+
}
|
package/src/index.ts
CHANGED
package/src/web/UsbStorageWeb.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
2
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "../
|
|
3
|
+
UsbDeviceFilter,
|
|
4
|
+
UsbDeviceInfo,
|
|
5
|
+
UsbFileInfo,
|
|
6
|
+
UsbStoragePlugin,
|
|
7
|
+
} from "../UsbStoragePlugin";
|
|
8
8
|
import { VirtualUsbStorage } from "./VirtualUsbStorage";
|
|
9
|
-
import {
|
|
9
|
+
import { bytes } from "@simplysm/core-common";
|
|
10
10
|
|
|
11
|
-
export class UsbStorageWeb extends WebPlugin implements
|
|
11
|
+
export class UsbStorageWeb extends WebPlugin implements UsbStoragePlugin {
|
|
12
12
|
private readonly _storage = new VirtualUsbStorage();
|
|
13
13
|
|
|
14
|
-
async getDevices(): Promise<{ devices:
|
|
14
|
+
async getDevices(): Promise<{ devices: UsbDeviceInfo[] }> {
|
|
15
15
|
const devices = await this._storage.getDevices();
|
|
16
16
|
return {
|
|
17
17
|
devices: devices.map((d) => ({
|
|
@@ -24,15 +24,15 @@ export class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugin {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
async
|
|
27
|
+
async requestPermissions(_options: UsbDeviceFilter): Promise<{ granted: boolean }> {
|
|
28
28
|
return Promise.resolve({ granted: true });
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
async
|
|
31
|
+
async checkPermissions(_options: UsbDeviceFilter): Promise<{ granted: boolean }> {
|
|
32
32
|
return Promise.resolve({ granted: true });
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
async readdir(options:
|
|
35
|
+
async readdir(options: UsbDeviceFilter & { path: string }): Promise<{ files: UsbFileInfo[] }> {
|
|
36
36
|
const deviceKey = `${options.vendorId}:${options.productId}`;
|
|
37
37
|
const devices = await this._storage.getDevices();
|
|
38
38
|
const deviceExists = devices.some((d) => d.key === deviceKey);
|
|
@@ -47,7 +47,7 @@ export class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugin {
|
|
|
47
47
|
return { files: children };
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
async
|
|
50
|
+
async readFile(options: UsbDeviceFilter & { path: string }): Promise<{ data: string | null }> {
|
|
51
51
|
const deviceKey = `${options.vendorId}:${options.productId}`;
|
|
52
52
|
const devices = await this._storage.getDevices();
|
|
53
53
|
const deviceExists = devices.some((d) => d.key === deviceKey);
|
|
@@ -78,7 +78,7 @@ export class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugin {
|
|
|
78
78
|
* Add a file to a virtual USB device. (For testing/development)
|
|
79
79
|
*/
|
|
80
80
|
async addVirtualFile(
|
|
81
|
-
filter:
|
|
81
|
+
filter: UsbDeviceFilter,
|
|
82
82
|
filePath: string,
|
|
83
83
|
data: Uint8Array,
|
|
84
84
|
): Promise<void> {
|
|
@@ -90,14 +90,14 @@ export class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugin {
|
|
|
90
90
|
deviceKey,
|
|
91
91
|
path: filePath,
|
|
92
92
|
kind: "file",
|
|
93
|
-
dataBase64:
|
|
93
|
+
dataBase64: bytes.toBase64(data),
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* Add a directory to a virtual USB device. (For testing/development)
|
|
99
99
|
*/
|
|
100
|
-
async addVirtualDirectory(filter:
|
|
100
|
+
async addVirtualDirectory(filter: UsbDeviceFilter, dirPath: string): Promise<void> {
|
|
101
101
|
const deviceKey = `${filter.vendorId}:${filter.productId}`;
|
|
102
102
|
await this._storage.ensureDir(deviceKey, dirPath);
|
|
103
103
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { VirtualFsEntry } from "@simplysm/core-browser";
|
|
2
|
+
import { IndexedDbStore, IndexedDbVirtualFs } from "@simplysm/core-browser";
|
|
2
3
|
|
|
3
4
|
interface VirtualDevice {
|
|
4
5
|
key: string;
|
|
@@ -9,24 +10,18 @@ interface VirtualDevice {
|
|
|
9
10
|
productName: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
interface VirtualEntry {
|
|
13
|
-
fullKey: string;
|
|
14
|
-
deviceKey: string;
|
|
15
|
-
path: string;
|
|
16
|
-
kind: "file" | "dir";
|
|
17
|
-
dataBase64?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
13
|
export class VirtualUsbStorage {
|
|
21
14
|
private readonly _DEVICES_STORE = "devices";
|
|
22
15
|
private readonly _FILES_STORE = "files";
|
|
23
16
|
private readonly _db: IndexedDbStore;
|
|
17
|
+
private readonly _vfs: IndexedDbVirtualFs;
|
|
24
18
|
|
|
25
19
|
constructor() {
|
|
26
20
|
this._db = new IndexedDbStore("capacitor_usb_virtual_storage", 1, [
|
|
27
21
|
{ name: this._DEVICES_STORE, keyPath: "key" },
|
|
28
22
|
{ name: this._FILES_STORE, keyPath: "fullKey" },
|
|
29
23
|
]);
|
|
24
|
+
this._vfs = new IndexedDbVirtualFs(this._db, this._FILES_STORE, "fullKey");
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
async addDevice(device: Omit<VirtualDevice, "key">): Promise<void> {
|
|
@@ -39,15 +34,14 @@ export class VirtualUsbStorage {
|
|
|
39
34
|
return this._db.getAll<VirtualDevice>(this._DEVICES_STORE);
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
async getEntry(deviceKey: string, path: string): Promise<
|
|
37
|
+
async getEntry(deviceKey: string, path: string): Promise<VirtualFsEntry | undefined> {
|
|
43
38
|
const fullKey = `${deviceKey}:${path}`;
|
|
44
|
-
return this.
|
|
39
|
+
return this._vfs.getEntry(fullKey);
|
|
45
40
|
}
|
|
46
41
|
|
|
47
|
-
async putEntry(entry:
|
|
42
|
+
async putEntry(entry: { deviceKey: string; path: string; kind: "file" | "dir"; dataBase64?: string }): Promise<void> {
|
|
48
43
|
const fullKey = `${entry.deviceKey}:${entry.path}`;
|
|
49
|
-
|
|
50
|
-
return this._db.put(this._FILES_STORE, fullEntry);
|
|
44
|
+
return this._vfs.putEntry(fullKey, entry.kind, entry.dataBase64);
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
async listChildren(
|
|
@@ -55,53 +49,10 @@ export class VirtualUsbStorage {
|
|
|
55
49
|
dirPath: string,
|
|
56
50
|
): Promise<{ name: string; isDirectory: boolean }[]> {
|
|
57
51
|
const prefix = `${deviceKey}:${dirPath === "/" ? "/" : dirPath + "/"}`;
|
|
58
|
-
return this.
|
|
59
|
-
return new Promise((resolve, reject) => {
|
|
60
|
-
const req = store.openCursor();
|
|
61
|
-
const map = new Map<string, boolean>();
|
|
62
|
-
req.onsuccess = () => {
|
|
63
|
-
const cursor = req.result;
|
|
64
|
-
if (!cursor) {
|
|
65
|
-
resolve(
|
|
66
|
-
Array.from(map.entries()).map(([name, isDirectory]) => ({ name, isDirectory })),
|
|
67
|
-
);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
const key = String(cursor.key);
|
|
71
|
-
if (key.startsWith(prefix)) {
|
|
72
|
-
const rest = key.slice(prefix.length);
|
|
73
|
-
if (rest) {
|
|
74
|
-
const segments = rest.split("/").filter(Boolean);
|
|
75
|
-
if (segments.length > 0) {
|
|
76
|
-
const firstName = segments[0];
|
|
77
|
-
if (!map.has(firstName)) {
|
|
78
|
-
const isDir =
|
|
79
|
-
segments.length > 1 || (cursor.value as VirtualEntry).kind === "dir";
|
|
80
|
-
map.set(firstName, isDir);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
cursor.continue();
|
|
86
|
-
};
|
|
87
|
-
req.onerror = () => reject(req.error);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
52
|
+
return this._vfs.listChildren(prefix);
|
|
90
53
|
}
|
|
91
54
|
|
|
92
55
|
async ensureDir(deviceKey: string, dirPath: string): Promise<void> {
|
|
93
|
-
|
|
94
|
-
await this.putEntry({ deviceKey, path: "/", kind: "dir" });
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const segments = dirPath.split("/").filter(Boolean);
|
|
98
|
-
let acc = "";
|
|
99
|
-
for (const seg of segments) {
|
|
100
|
-
acc += "/" + seg;
|
|
101
|
-
const existing = await this.getEntry(deviceKey, acc);
|
|
102
|
-
if (!existing) {
|
|
103
|
-
await this.putEntry({ deviceKey, path: acc, kind: "dir" });
|
|
104
|
-
}
|
|
105
|
-
}
|
|
56
|
+
return this._vfs.ensureDir((path) => `${deviceKey}:${path}`, dirPath);
|
|
106
57
|
}
|
|
107
58
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IUsbStoragePlugin.d.ts","sourceRoot":"","sources":["..\\src\\IUsbStoragePlugin.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IACrD,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC5E,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACxE,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC,CAAC;IAC1F,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACtF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=IUsbStoragePlugin.js.map
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export interface IStoreConfig {
|
|
2
|
-
name: string;
|
|
3
|
-
keyPath: string;
|
|
4
|
-
}
|
|
5
|
-
export declare class IndexedDbStore {
|
|
6
|
-
private readonly _dbName;
|
|
7
|
-
private readonly _dbVersion;
|
|
8
|
-
private readonly _storeConfigs;
|
|
9
|
-
constructor(_dbName: string, _dbVersion: number, _storeConfigs: IStoreConfig[]);
|
|
10
|
-
open(): Promise<IDBDatabase>;
|
|
11
|
-
withStore<T>(storeName: string, mode: IDBTransactionMode, fn: (store: IDBObjectStore) => Promise<T>): Promise<T>;
|
|
12
|
-
get<T>(storeName: string, key: IDBValidKey): Promise<T | undefined>;
|
|
13
|
-
put(storeName: string, value: unknown): Promise<void>;
|
|
14
|
-
getAll<T>(storeName: string): Promise<T[]>;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=IndexedDbStore.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IndexedDbStore.d.ts","sourceRoot":"","sources":["..\\..\\src\\web\\IndexedDbStore.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAFb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,YAAY,EAAE;IAG1C,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC;IAiB5B,SAAS,CAAC,CAAC,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,kBAAkB,EACxB,EAAE,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC;IAyBP,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAUnE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;CASjD"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
class IndexedDbStore {
|
|
2
|
-
constructor(_dbName, _dbVersion, _storeConfigs) {
|
|
3
|
-
this._dbName = _dbName;
|
|
4
|
-
this._dbVersion = _dbVersion;
|
|
5
|
-
this._storeConfigs = _storeConfigs;
|
|
6
|
-
}
|
|
7
|
-
async open() {
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
const req = indexedDB.open(this._dbName, this._dbVersion);
|
|
10
|
-
req.onupgradeneeded = () => {
|
|
11
|
-
const db = req.result;
|
|
12
|
-
for (const config of this._storeConfigs) {
|
|
13
|
-
if (!db.objectStoreNames.contains(config.name)) {
|
|
14
|
-
db.createObjectStore(config.name, { keyPath: config.keyPath });
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
req.onsuccess = () => resolve(req.result);
|
|
19
|
-
req.onerror = () => reject(req.error);
|
|
20
|
-
req.onblocked = () => reject(new Error("Database blocked by another connection"));
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
async withStore(storeName, mode, fn) {
|
|
24
|
-
const db = await this.open();
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
const tx = db.transaction(storeName, mode);
|
|
27
|
-
const store = tx.objectStore(storeName);
|
|
28
|
-
let result;
|
|
29
|
-
Promise.resolve(fn(store)).then((r) => {
|
|
30
|
-
result = r;
|
|
31
|
-
}).catch((err) => {
|
|
32
|
-
db.close();
|
|
33
|
-
reject(err);
|
|
34
|
-
});
|
|
35
|
-
tx.oncomplete = () => {
|
|
36
|
-
db.close();
|
|
37
|
-
resolve(result);
|
|
38
|
-
};
|
|
39
|
-
tx.onerror = () => {
|
|
40
|
-
db.close();
|
|
41
|
-
reject(tx.error);
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
async get(storeName, key) {
|
|
46
|
-
return this.withStore(storeName, "readonly", async (store) => {
|
|
47
|
-
return new Promise((resolve, reject) => {
|
|
48
|
-
const req = store.get(key);
|
|
49
|
-
req.onsuccess = () => resolve(req.result);
|
|
50
|
-
req.onerror = () => reject(req.error);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
async put(storeName, value) {
|
|
55
|
-
return this.withStore(storeName, "readwrite", async (store) => {
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
const req = store.put(value);
|
|
58
|
-
req.onsuccess = () => resolve();
|
|
59
|
-
req.onerror = () => reject(req.error);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
async getAll(storeName) {
|
|
64
|
-
return this.withStore(storeName, "readonly", async (store) => {
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
const req = store.getAll();
|
|
67
|
-
req.onsuccess = () => resolve(req.result);
|
|
68
|
-
req.onerror = () => reject(req.error);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
export {
|
|
74
|
-
IndexedDbStore
|
|
75
|
-
};
|
|
76
|
-
//# sourceMappingURL=IndexedDbStore.js.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/web/IndexedDbStore.ts"],
|
|
4
|
-
"mappings": "AAKO,MAAM,eAAe;AAAA,EAC1B,YACmB,SACA,YACA,eACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAEH,MAAM,OAA6B;AACjC,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,MAAM,UAAU,KAAK,KAAK,SAAS,KAAK,UAAU;AACxD,UAAI,kBAAkB,MAAM;AAC1B,cAAM,KAAK,IAAI;AACf,mBAAW,UAAU,KAAK,eAAe;AACvC,cAAI,CAAC,GAAG,iBAAiB,SAAS,OAAO,IAAI,GAAG;AAC9C,eAAG,kBAAkB,OAAO,MAAM,EAAE,SAAS,OAAO,QAAQ,CAAC;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AACA,UAAI,YAAY,MAAM,QAAQ,IAAI,MAAM;AACxC,UAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AACpC,UAAI,YAAY,MAAM,OAAO,IAAI,MAAM,wCAAwC,CAAC;AAAA,IAClF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UACJ,WACA,MACA,IACY;AACZ,UAAM,KAAK,MAAM,KAAK,KAAK;AAC3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,KAAK,GAAG,YAAY,WAAW,IAAI;AACzC,YAAM,QAAQ,GAAG,YAAY,SAAS;AACtC,UAAI;AACJ,cAAQ,QAAQ,GAAG,KAAK,CAAC,EACtB,KAAK,CAAC,MAAM;AACX,iBAAS;AAAA,MACX,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,WAAG,MAAM;AACT,eAAO,GAAG;AAAA,MACZ,CAAC;AACH,SAAG,aAAa,MAAM;AACpB,WAAG,MAAM;AACT,gBAAQ,MAAM;AAAA,MAChB;AACA,SAAG,UAAU,MAAM;AACjB,WAAG,MAAM;AACT,eAAO,GAAG,KAAK;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAO,WAAmB,KAA0C;AACxE,WAAO,KAAK,UAAU,WAAW,YAAY,OAAO,UAAU;AAC5D,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,MAAM,MAAM,IAAI,GAAG;AACzB,YAAI,YAAY,MAAM,QAAQ,IAAI,MAAuB;AACzD,YAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,WAAmB,OAA+B;AAC1D,WAAO,KAAK,UAAU,WAAW,aAAa,OAAO,UAAU;AAC7D,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,MAAM,MAAM,IAAI,KAAK;AAC3B,YAAI,YAAY,MAAM,QAAQ;AAC9B,YAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAU,WAAiC;AAC/C,WAAO,KAAK,UAAU,WAAW,YAAY,OAAO,UAAU;AAC5D,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,MAAM,MAAM,OAAO;AACzB,YAAI,YAAY,MAAM,QAAQ,IAAI,MAAa;AAC/C,YAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;",
|
|
5
|
-
"names": []
|
|
6
|
-
}
|
package/src/IUsbStoragePlugin.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export interface IUsbDeviceInfo {
|
|
2
|
-
deviceName: string;
|
|
3
|
-
manufacturerName: string;
|
|
4
|
-
productName: string;
|
|
5
|
-
vendorId: number;
|
|
6
|
-
productId: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface IUsbDeviceFilter {
|
|
10
|
-
vendorId: number;
|
|
11
|
-
productId: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface IUsbFileInfo {
|
|
15
|
-
name: string;
|
|
16
|
-
isDirectory: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface IUsbStoragePlugin {
|
|
20
|
-
getDevices(): Promise<{ devices: IUsbDeviceInfo[] }>;
|
|
21
|
-
requestPermission(options: IUsbDeviceFilter): Promise<{ granted: boolean }>;
|
|
22
|
-
hasPermission(options: IUsbDeviceFilter): Promise<{ granted: boolean }>;
|
|
23
|
-
readdir(options: IUsbDeviceFilter & { path: string }): Promise<{ files: IUsbFileInfo[] }>;
|
|
24
|
-
read(options: IUsbDeviceFilter & { path: string }): Promise<{ data: string | null }>;
|
|
25
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
export interface IStoreConfig {
|
|
2
|
-
name: string;
|
|
3
|
-
keyPath: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export class IndexedDbStore {
|
|
7
|
-
constructor(
|
|
8
|
-
private readonly _dbName: string,
|
|
9
|
-
private readonly _dbVersion: number,
|
|
10
|
-
private readonly _storeConfigs: IStoreConfig[],
|
|
11
|
-
) {}
|
|
12
|
-
|
|
13
|
-
async open(): Promise<IDBDatabase> {
|
|
14
|
-
return new Promise((resolve, reject) => {
|
|
15
|
-
const req = indexedDB.open(this._dbName, this._dbVersion);
|
|
16
|
-
req.onupgradeneeded = () => {
|
|
17
|
-
const db = req.result;
|
|
18
|
-
for (const config of this._storeConfigs) {
|
|
19
|
-
if (!db.objectStoreNames.contains(config.name)) {
|
|
20
|
-
db.createObjectStore(config.name, { keyPath: config.keyPath });
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
req.onsuccess = () => resolve(req.result);
|
|
25
|
-
req.onerror = () => reject(req.error);
|
|
26
|
-
req.onblocked = () => reject(new Error("Database blocked by another connection"));
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async withStore<T>(
|
|
31
|
-
storeName: string,
|
|
32
|
-
mode: IDBTransactionMode,
|
|
33
|
-
fn: (store: IDBObjectStore) => Promise<T>,
|
|
34
|
-
): Promise<T> {
|
|
35
|
-
const db = await this.open();
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
const tx = db.transaction(storeName, mode);
|
|
38
|
-
const store = tx.objectStore(storeName);
|
|
39
|
-
let result: T;
|
|
40
|
-
Promise.resolve(fn(store))
|
|
41
|
-
.then((r) => {
|
|
42
|
-
result = r;
|
|
43
|
-
})
|
|
44
|
-
.catch((err) => {
|
|
45
|
-
db.close();
|
|
46
|
-
reject(err);
|
|
47
|
-
});
|
|
48
|
-
tx.oncomplete = () => {
|
|
49
|
-
db.close();
|
|
50
|
-
resolve(result);
|
|
51
|
-
};
|
|
52
|
-
tx.onerror = () => {
|
|
53
|
-
db.close();
|
|
54
|
-
reject(tx.error);
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async get<T>(storeName: string, key: IDBValidKey): Promise<T | undefined> {
|
|
60
|
-
return this.withStore(storeName, "readonly", async (store) => {
|
|
61
|
-
return new Promise((resolve, reject) => {
|
|
62
|
-
const req = store.get(key);
|
|
63
|
-
req.onsuccess = () => resolve(req.result as T | undefined);
|
|
64
|
-
req.onerror = () => reject(req.error);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async put(storeName: string, value: unknown): Promise<void> {
|
|
70
|
-
return this.withStore(storeName, "readwrite", async (store) => {
|
|
71
|
-
return new Promise((resolve, reject) => {
|
|
72
|
-
const req = store.put(value);
|
|
73
|
-
req.onsuccess = () => resolve();
|
|
74
|
-
req.onerror = () => reject(req.error);
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async getAll<T>(storeName: string): Promise<T[]> {
|
|
80
|
-
return this.withStore(storeName, "readonly", async (store) => {
|
|
81
|
-
return new Promise((resolve, reject) => {
|
|
82
|
-
const req = store.getAll();
|
|
83
|
-
req.onsuccess = () => resolve(req.result as T[]);
|
|
84
|
-
req.onerror = () => reject(req.error);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
File without changes
|