@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.
Files changed (35) hide show
  1. package/README.md +28 -28
  2. package/android/src/main/java/kr/co/simplysm/capacitor/usbstorage/UsbStoragePlugin.java +5 -5
  3. package/dist/UsbStorage.d.ts +6 -6
  4. package/dist/UsbStorage.d.ts.map +1 -1
  5. package/dist/UsbStorage.js +11 -11
  6. package/dist/UsbStorage.js.map +1 -1
  7. package/dist/{IUsbStoragePlugin.d.ts → UsbStoragePlugin.d.ts} +11 -11
  8. package/dist/UsbStoragePlugin.d.ts.map +1 -0
  9. package/dist/UsbStoragePlugin.js +1 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/web/UsbStorageWeb.d.ts +10 -10
  14. package/dist/web/UsbStorageWeb.d.ts.map +1 -1
  15. package/dist/web/UsbStorageWeb.js +5 -5
  16. package/dist/web/UsbStorageWeb.js.map +1 -1
  17. package/dist/web/VirtualUsbStorage.d.ts +9 -9
  18. package/dist/web/VirtualUsbStorage.d.ts.map +1 -1
  19. package/dist/web/VirtualUsbStorage.js +7 -48
  20. package/dist/web/VirtualUsbStorage.js.map +1 -1
  21. package/package.json +3 -2
  22. package/src/UsbStorage.ts +18 -18
  23. package/src/UsbStoragePlugin.ts +25 -0
  24. package/src/index.ts +1 -1
  25. package/src/web/UsbStorageWeb.ts +15 -15
  26. package/src/web/VirtualUsbStorage.ts +10 -59
  27. package/dist/IUsbStoragePlugin.d.ts.map +0 -1
  28. package/dist/IUsbStoragePlugin.js +0 -1
  29. package/dist/web/IndexedDbStore.d.ts +0 -16
  30. package/dist/web/IndexedDbStore.d.ts.map +0 -1
  31. package/dist/web/IndexedDbStore.js +0 -76
  32. package/dist/web/IndexedDbStore.js.map +0 -6
  33. package/src/IUsbStoragePlugin.ts +0 -25
  34. package/src/web/IndexedDbStore.ts +0 -88
  35. /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<IUsbDeviceInfo[]>
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.requestPermission(filter)`
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 requestPermission(filter: IUsbDeviceFilter): Promise<boolean>
46
+ static async requestPermissions(filter: UsbDeviceFilter): Promise<boolean>
47
47
  ```
48
48
 
49
49
  ```typescript
50
- const granted = await UsbStorage.requestPermission({ vendorId: 0x1234, productId: 0x5678 });
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.hasPermission(filter)`
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 hasPermission(filter: IUsbDeviceFilter): Promise<boolean>
61
+ static async checkPermissions(filter: UsbDeviceFilter): Promise<boolean>
62
62
  ```
63
63
 
64
64
  ```typescript
65
- const alreadyGranted = await UsbStorage.hasPermission({ vendorId: 0x1234, productId: 0x5678 });
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: IUsbDeviceFilter, dirPath: string): Promise<IUsbFileInfo[]>
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.read(filter, filePath)`
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 read(filter: IUsbDeviceFilter, filePath: string): Promise<Bytes | undefined>
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.read(filter, "/data/file.bin");
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
- IUsbDeviceInfo,
105
- IUsbDeviceFilter,
106
- IUsbFileInfo,
107
- IUsbStoragePlugin,
104
+ UsbDeviceInfo,
105
+ UsbDeviceFilter,
106
+ UsbFileInfo,
107
+ UsbStoragePlugin,
108
108
  } from "@simplysm/capacitor-plugin-usb-storage";
109
109
  ```
110
110
 
111
- ### `IUsbDeviceInfo`
111
+ ### `UsbDeviceInfo`
112
112
 
113
113
  Describes a connected USB device.
114
114
 
115
115
  ```typescript
116
- interface IUsbDeviceInfo {
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
- ### `IUsbDeviceFilter`
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 IUsbDeviceFilter {
130
+ interface UsbDeviceFilter {
131
131
  vendorId: number;
132
132
  productId: number;
133
133
  }
134
134
  ```
135
135
 
136
- ### `IUsbFileInfo`
136
+ ### `UsbFileInfo`
137
137
 
138
138
  Describes a single entry (file or directory) returned by `readdir`.
139
139
 
140
140
  ```typescript
141
- interface IUsbFileInfo {
141
+ interface UsbFileInfo {
142
142
  name: string;
143
143
  isDirectory: boolean;
144
144
  }
145
145
  ```
146
146
 
147
- ### `IUsbStoragePlugin`
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 IUsbStoragePlugin {
153
- getDevices(): Promise<{ devices: IUsbDeviceInfo[] }>;
154
- requestPermission(options: IUsbDeviceFilter): Promise<{ granted: boolean }>;
155
- hasPermission(options: IUsbDeviceFilter): Promise<{ granted: boolean }>;
156
- readdir(options: IUsbDeviceFilter & { path: string }): Promise<{ files: IUsbFileInfo[] }>;
157
- read(options: IUsbDeviceFilter & { path: string }): Promise<{ data: string | null }>;
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 requestPermission(PluginCall call) {
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 hasPermission(PluginCall call) {
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 read(PluginCall call) {
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, "read failed", e);
262
- call.reject("read failed: " + e.getMessage());
261
+ Log.e(TAG, "readFile failed", e);
262
+ call.reject("readFile failed: " + e.getMessage());
263
263
  }
264
264
  }
265
265
 
@@ -1,4 +1,4 @@
1
- import type { IUsbDeviceFilter, IUsbDeviceInfo, IUsbFileInfo } from "./IUsbStoragePlugin";
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<IUsbDeviceInfo[]>;
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 requestPermission(filter: IUsbDeviceFilter): Promise<boolean>;
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 hasPermission(filter: IUsbDeviceFilter): Promise<boolean>;
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: IUsbDeviceFilter, dirPath: string): Promise<IUsbFileInfo[]>;
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 read(filter: IUsbDeviceFilter, filePath: string): Promise<Bytes | undefined>;
39
+ static readFile(filter: UsbDeviceFilter, filePath: string): Promise<Bytes | undefined>;
40
40
  }
41
41
  //# sourceMappingURL=UsbStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"UsbStorage.d.ts","sourceRoot":"","sources":["..\\src\\UsbStorage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,YAAY,EAEb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAUnD;;;;GAIG;AACH,8BAAsB,UAAU;IAC9B;;;OAGG;WACU,UAAU,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAKpD;;;;OAIG;WACU,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAK1E;;;;OAIG;WACU,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtE;;;;;OAKG;WACU,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAKxF;;;;;OAKG;WACU,IAAI,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAO1F"}
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"}
@@ -1,6 +1,6 @@
1
1
  import { registerPlugin } from "@capacitor/core";
2
- import { bytesFromBase64 } from "@simplysm/core-common";
3
- const UsbStoragePlugin = registerPlugin("UsbStorage", {
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 UsbStoragePlugin.getDevices();
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 requestPermission(filter) {
24
- const result = await UsbStoragePlugin.requestPermission(filter);
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 hasPermission(filter) {
33
- const result = await UsbStoragePlugin.hasPermission(filter);
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 UsbStoragePlugin.readdir({ ...filter, path: dirPath });
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 read(filter, filePath) {
53
- const result = await UsbStoragePlugin.read({ ...filter, path: filePath });
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 bytesFromBase64(result.data);
57
+ return bytes.fromBase64(result.data);
58
58
  }
59
59
  }
60
60
  export {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/UsbStorage.ts"],
4
- "mappings": "AAAA,SAAS,sBAAsB;AAQ/B,SAAS,uBAAuB;AAEhC,MAAM,mBAAmB,eAAkC,cAAc;AAAA,EACvE,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,aAAwC;AACnD,UAAM,SAAS,MAAM,iBAAiB,WAAW;AACjD,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,kBAAkB,QAA4C;AACzE,UAAM,SAAS,MAAM,iBAAiB,kBAAkB,MAAM;AAC9D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,cAAc,QAA4C;AACrE,UAAM,SAAS,MAAM,iBAAiB,cAAc,MAAM;AAC1D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,QAAQ,QAA0B,SAA0C;AACvF,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,KAAK,QAA0B,UAA8C;AACxF,UAAM,SAAS,MAAM,iBAAiB,KAAK,EAAE,GAAG,QAAQ,MAAM,SAAS,CAAC;AACxE,QAAI,OAAO,QAAQ,MAAM;AACvB,aAAO;AAAA,IACT;AACA,WAAO,gBAAgB,OAAO,IAAI;AAAA,EACpC;AACF;",
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 IUsbDeviceInfo {
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 IUsbDeviceFilter {
8
+ export interface UsbDeviceFilter {
9
9
  vendorId: number;
10
10
  productId: number;
11
11
  }
12
- export interface IUsbFileInfo {
12
+ export interface UsbFileInfo {
13
13
  name: string;
14
14
  isDirectory: boolean;
15
15
  }
16
- export interface IUsbStoragePlugin {
16
+ export interface UsbStoragePlugin {
17
17
  getDevices(): Promise<{
18
- devices: IUsbDeviceInfo[];
18
+ devices: UsbDeviceInfo[];
19
19
  }>;
20
- requestPermission(options: IUsbDeviceFilter): Promise<{
20
+ requestPermissions(options: UsbDeviceFilter): Promise<{
21
21
  granted: boolean;
22
22
  }>;
23
- hasPermission(options: IUsbDeviceFilter): Promise<{
23
+ checkPermissions(options: UsbDeviceFilter): Promise<{
24
24
  granted: boolean;
25
25
  }>;
26
- readdir(options: IUsbDeviceFilter & {
26
+ readdir(options: UsbDeviceFilter & {
27
27
  path: string;
28
28
  }): Promise<{
29
- files: IUsbFileInfo[];
29
+ files: UsbFileInfo[];
30
30
  }>;
31
- read(options: IUsbDeviceFilter & {
31
+ readFile(options: UsbDeviceFilter & {
32
32
  path: string;
33
33
  }): Promise<{
34
34
  data: string | null;
35
35
  }>;
36
36
  }
37
- //# sourceMappingURL=IUsbStoragePlugin.d.ts.map
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
@@ -1,3 +1,3 @@
1
- export * from "./IUsbStoragePlugin";
1
+ export * from "./UsbStoragePlugin";
2
2
  export * from "./UsbStorage";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["..\\src\\index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,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,3 +1,3 @@
1
- export * from "./IUsbStoragePlugin.js";
1
+ export * from "./UsbStoragePlugin.js";
2
2
  export * from "./UsbStorage.js";
3
3
  //# sourceMappingURL=index.js.map
@@ -1,22 +1,22 @@
1
1
  import { WebPlugin } from "@capacitor/core";
2
- import type { IUsbDeviceFilter, IUsbDeviceInfo, IUsbFileInfo, IUsbStoragePlugin } from "../IUsbStoragePlugin";
3
- export declare class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugin {
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: IUsbDeviceInfo[];
6
+ devices: UsbDeviceInfo[];
7
7
  }>;
8
- requestPermission(_options: IUsbDeviceFilter): Promise<{
8
+ requestPermissions(_options: UsbDeviceFilter): Promise<{
9
9
  granted: boolean;
10
10
  }>;
11
- hasPermission(_options: IUsbDeviceFilter): Promise<{
11
+ checkPermissions(_options: UsbDeviceFilter): Promise<{
12
12
  granted: boolean;
13
13
  }>;
14
- readdir(options: IUsbDeviceFilter & {
14
+ readdir(options: UsbDeviceFilter & {
15
15
  path: string;
16
16
  }): Promise<{
17
- files: IUsbFileInfo[];
17
+ files: UsbFileInfo[];
18
18
  }>;
19
- read(options: IUsbDeviceFilter & {
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: IUsbDeviceFilter, filePath: string, data: Uint8Array): Promise<void>;
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: IUsbDeviceFilter, dirPath: string): Promise<void>;
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,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAI9B,qBAAa,aAAc,SAAQ,SAAU,YAAW,iBAAiB;IACvE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IAE9C,UAAU,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;IAapD,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAI5E,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIxE,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IAezF,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAc1F;;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,gBAAgB,EACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC;IAahB;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAIpF"}
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 { bytesToBase64 } from "@simplysm/core-common";
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 requestPermission(_options) {
18
+ async requestPermissions(_options) {
19
19
  return Promise.resolve({ granted: true });
20
20
  }
21
- async hasPermission(_options) {
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 read(options) {
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: bytesToBase64(data)
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,qBAAqB;AAEvB,MAAM,sBAAsB,UAAuC;AAAA,EACvD,WAAW,IAAI,kBAAkB;AAAA,EAElD,MAAM,aAAqD;AACzD,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,kBAAkB,UAA2D;AACjF,WAAO,QAAQ,QAAQ,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,cAAc,UAA2D;AAC7E,WAAO,QAAQ,QAAQ,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,QAAQ,SAAkF;AAC9F,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,KAAK,SAAgF;AACzF,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,cAAc,IAAI;AAAA,IAChC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,QAA0B,SAAgC;AAClF,UAAM,YAAY,GAAG,OAAO,QAAQ,IAAI,OAAO,SAAS;AACxD,UAAM,KAAK,SAAS,UAAU,WAAW,OAAO;AAAA,EAClD;AACF;",
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<VirtualEntry | undefined>;
24
- putEntry(entry: Omit<VirtualEntry, "fullKey">): Promise<void>;
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":"AAEA,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,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,UAAU,CAAC,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;;IAS/B,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,YAAY,GAAG,SAAS,CAAC;IAK5E,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D,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;IAoC9C,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAenE"}
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 "./IndexedDbStore.js";
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._db.get(this._FILES_STORE, fullKey);
24
+ return this._vfs.getEntry(fullKey);
23
25
  }
24
26
  async putEntry(entry) {
25
27
  const fullKey = `${entry.deviceKey}:${entry.path}`;
26
- const fullEntry = { ...entry, fullKey };
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._db.withStore(this._FILES_STORE, "readonly", async (store) => {
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
- if (dirPath === "/") {
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": "AAAA,SAAS,sBAAsB;AAmBxB,MAAM,kBAAkB;AAAA,EACZ,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf;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;AAAA,EACH;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,MAAiD;AACjF,UAAM,UAAU,GAAG,SAAS,IAAI,IAAI;AACpC,WAAO,KAAK,IAAI,IAAkB,KAAK,cAAc,OAAO;AAAA,EAC9D;AAAA,EAEA,MAAM,SAAS,OAAqD;AAClE,UAAM,UAAU,GAAG,MAAM,SAAS,IAAI,MAAM,IAAI;AAChD,UAAM,YAA0B,EAAE,GAAG,OAAO,QAAQ;AACpD,WAAO,KAAK,IAAI,IAAI,KAAK,cAAc,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,aACJ,WACA,SACmD;AACnD,UAAM,SAAS,GAAG,SAAS,IAAI,YAAY,MAAM,MAAM,UAAU,GAAG;AACpE,WAAO,KAAK,IAAI,UAAU,KAAK,cAAc,YAAY,OAAO,UAAU;AACxE,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,MAAM,MAAM,WAAW;AAC7B,cAAM,MAAM,oBAAI,IAAqB;AACrC,YAAI,YAAY,MAAM;AACpB,gBAAM,SAAS,IAAI;AACnB,cAAI,CAAC,QAAQ;AACX;AAAA,cACE,MAAM,KAAK,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,WAAW,OAAO,EAAE,MAAM,YAAY,EAAE;AAAA,YAChF;AACA;AAAA,UACF;AACA,gBAAM,MAAM,OAAO,OAAO,GAAG;AAC7B,cAAI,IAAI,WAAW,MAAM,GAAG;AAC1B,kBAAM,OAAO,IAAI,MAAM,OAAO,MAAM;AACpC,gBAAI,MAAM;AACR,oBAAM,WAAW,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,kBAAI,SAAS,SAAS,GAAG;AACvB,sBAAM,YAAY,SAAS,CAAC;AAC5B,oBAAI,CAAC,IAAI,IAAI,SAAS,GAAG;AACvB,wBAAM,QACJ,SAAS,SAAS,KAAM,OAAO,MAAuB,SAAS;AACjE,sBAAI,IAAI,WAAW,KAAK;AAAA,gBAC1B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,iBAAO,SAAS;AAAA,QAClB;AACA,YAAI,UAAU,MAAM,OAAO,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,WAAmB,SAAgC;AACjE,QAAI,YAAY,KAAK;AACnB,YAAM,KAAK,SAAS,EAAE,WAAW,MAAM,KAAK,MAAM,MAAM,CAAC;AACzD;AAAA,IACF;AACA,UAAM,WAAW,QAAQ,MAAM,GAAG,EAAE,OAAO,OAAO;AAClD,QAAI,MAAM;AACV,eAAW,OAAO,UAAU;AAC1B,aAAO,MAAM;AACb,YAAM,WAAW,MAAM,KAAK,SAAS,WAAW,GAAG;AACnD,UAAI,CAAC,UAAU;AACb,cAAM,KAAK,SAAS,EAAE,WAAW,MAAM,KAAK,MAAM,MAAM,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACF;",
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.75",
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-common": "13.0.75"
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
- IUsbDeviceFilter,
4
- IUsbDeviceInfo,
5
- IUsbFileInfo,
6
- IUsbStoragePlugin,
7
- } from "./IUsbStoragePlugin";
3
+ UsbDeviceFilter,
4
+ UsbDeviceInfo,
5
+ UsbFileInfo,
6
+ UsbStoragePlugin,
7
+ } from "./UsbStoragePlugin";
8
8
  import type { Bytes } from "@simplysm/core-common";
9
- import { bytesFromBase64 } from "@simplysm/core-common";
9
+ import { bytes } from "@simplysm/core-common";
10
10
 
11
- const UsbStoragePlugin = registerPlugin<IUsbStoragePlugin>("UsbStorage", {
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<IUsbDeviceInfo[]> {
29
- const result = await UsbStoragePlugin.getDevices();
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 requestPermission(filter: IUsbDeviceFilter): Promise<boolean> {
39
- const result = await UsbStoragePlugin.requestPermission(filter);
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 hasPermission(filter: IUsbDeviceFilter): Promise<boolean> {
49
- const result = await UsbStoragePlugin.hasPermission(filter);
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: IUsbDeviceFilter, dirPath: string): Promise<IUsbFileInfo[]> {
60
- const result = await UsbStoragePlugin.readdir({ ...filter, path: dirPath });
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 read(filter: IUsbDeviceFilter, filePath: string): Promise<Bytes | undefined> {
71
- const result = await UsbStoragePlugin.read({ ...filter, path: filePath });
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 bytesFromBase64(result.data);
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
@@ -1,3 +1,3 @@
1
1
  // USB Storage
2
- export * from "./IUsbStoragePlugin";
2
+ export * from "./UsbStoragePlugin";
3
3
  export * from "./UsbStorage";
@@ -1,17 +1,17 @@
1
1
  import { WebPlugin } from "@capacitor/core";
2
2
  import type {
3
- IUsbDeviceFilter,
4
- IUsbDeviceInfo,
5
- IUsbFileInfo,
6
- IUsbStoragePlugin,
7
- } from "../IUsbStoragePlugin";
3
+ UsbDeviceFilter,
4
+ UsbDeviceInfo,
5
+ UsbFileInfo,
6
+ UsbStoragePlugin,
7
+ } from "../UsbStoragePlugin";
8
8
  import { VirtualUsbStorage } from "./VirtualUsbStorage";
9
- import { bytesToBase64 } from "@simplysm/core-common";
9
+ import { bytes } from "@simplysm/core-common";
10
10
 
11
- export class UsbStorageWeb extends WebPlugin implements IUsbStoragePlugin {
11
+ export class UsbStorageWeb extends WebPlugin implements UsbStoragePlugin {
12
12
  private readonly _storage = new VirtualUsbStorage();
13
13
 
14
- async getDevices(): Promise<{ devices: IUsbDeviceInfo[] }> {
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 requestPermission(_options: IUsbDeviceFilter): Promise<{ granted: boolean }> {
27
+ async requestPermissions(_options: UsbDeviceFilter): Promise<{ granted: boolean }> {
28
28
  return Promise.resolve({ granted: true });
29
29
  }
30
30
 
31
- async hasPermission(_options: IUsbDeviceFilter): Promise<{ granted: boolean }> {
31
+ async checkPermissions(_options: UsbDeviceFilter): Promise<{ granted: boolean }> {
32
32
  return Promise.resolve({ granted: true });
33
33
  }
34
34
 
35
- async readdir(options: IUsbDeviceFilter & { path: string }): Promise<{ files: IUsbFileInfo[] }> {
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 read(options: IUsbDeviceFilter & { path: string }): Promise<{ data: string | null }> {
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: IUsbDeviceFilter,
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: bytesToBase64(data),
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: IUsbDeviceFilter, dirPath: string): Promise<void> {
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 { IndexedDbStore } from "./IndexedDbStore";
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<VirtualEntry | undefined> {
37
+ async getEntry(deviceKey: string, path: string): Promise<VirtualFsEntry | undefined> {
43
38
  const fullKey = `${deviceKey}:${path}`;
44
- return this._db.get<VirtualEntry>(this._FILES_STORE, fullKey);
39
+ return this._vfs.getEntry(fullKey);
45
40
  }
46
41
 
47
- async putEntry(entry: Omit<VirtualEntry, "fullKey">): Promise<void> {
42
+ async putEntry(entry: { deviceKey: string; path: string; kind: "file" | "dir"; dataBase64?: string }): Promise<void> {
48
43
  const fullKey = `${entry.deviceKey}:${entry.path}`;
49
- const fullEntry: VirtualEntry = { ...entry, fullKey };
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._db.withStore(this._FILES_STORE, "readonly", async (store) => {
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
- if (dirPath === "/") {
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
- }
@@ -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
- }