@simplymobile/capacitor-printer-usb 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Package.swift +28 -0
- package/README.md +94 -0
- package/SimplymobileCapacitorPrinterUsb.podspec +17 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/pl/simplymobile/plugins/printerusb/PrinterUsbPlugin.java +228 -0
- package/android/src/main/java/pl/simplymobile/plugins/printerusb/UsbPrinter.java +84 -0
- package/dist/docs.json +118 -0
- package/dist/esm/definitions.d.ts +56 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +18 -0
- package/dist/esm/web.js +16 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +30 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +33 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/PrinterUsbPlugin/PrinterUsb.swift +8 -0
- package/ios/Sources/PrinterUsbPlugin/PrinterUsbPlugin.swift +33 -0
- package/ios/Tests/PrinterUsbPluginTests/PrinterUsbTests.swift +25 -0
- package/package.json +82 -0
package/Package.swift
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// swift-tools-version: 5.9
|
|
2
|
+
import PackageDescription
|
|
3
|
+
|
|
4
|
+
let package = Package(
|
|
5
|
+
name: "SimplymobileCapacitorPrinterUsb",
|
|
6
|
+
platforms: [.iOS(.v15)],
|
|
7
|
+
products: [
|
|
8
|
+
.library(
|
|
9
|
+
name: "SimplymobileCapacitorPrinterUsb",
|
|
10
|
+
targets: ["PrinterUsbPlugin"])
|
|
11
|
+
],
|
|
12
|
+
dependencies: [
|
|
13
|
+
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
|
|
14
|
+
],
|
|
15
|
+
targets: [
|
|
16
|
+
.target(
|
|
17
|
+
name: "PrinterUsbPlugin",
|
|
18
|
+
dependencies: [
|
|
19
|
+
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
20
|
+
.product(name: "Cordova", package: "capacitor-swift-pm")
|
|
21
|
+
],
|
|
22
|
+
path: "ios/Sources/PrinterUsbPlugin"),
|
|
23
|
+
.testTarget(
|
|
24
|
+
name: "PrinterUsbPluginTests",
|
|
25
|
+
dependencies: ["PrinterUsbPlugin"],
|
|
26
|
+
path: "ios/Tests/PrinterUsbPluginTests")
|
|
27
|
+
]
|
|
28
|
+
)
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @simplymobile/capacitor-printer-usb
|
|
2
|
+
|
|
3
|
+
Capacitor plugin for sending raw data to USB printers (devices with interface class
|
|
4
|
+
`USB_CLASS_PRINTER`). Android-only; on iOS and web every method is unimplemented.
|
|
5
|
+
|
|
6
|
+
USB permission is requested at runtime through the Android system dialog the first time a printer
|
|
7
|
+
is used. No manifest permissions are required.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @simplymobile/capacitor-printer-usb
|
|
13
|
+
npx cap sync
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## API
|
|
17
|
+
|
|
18
|
+
<docgen-index>
|
|
19
|
+
|
|
20
|
+
* [`scan()`](#scan)
|
|
21
|
+
* [`print(...)`](#print)
|
|
22
|
+
* [`test(...)`](#test)
|
|
23
|
+
* [Interfaces](#interfaces)
|
|
24
|
+
|
|
25
|
+
</docgen-index>
|
|
26
|
+
|
|
27
|
+
<docgen-api>
|
|
28
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
29
|
+
|
|
30
|
+
### scan()
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
scan() => Promise<{ printers: UsbPrinterDevice[]; }>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Scan for connected USB printers (devices whose interface class is `USB_CLASS_PRINTER`).
|
|
37
|
+
|
|
38
|
+
**Returns:** <code>Promise<{ printers: UsbPrinterDevice[]; }></code>
|
|
39
|
+
|
|
40
|
+
--------------------
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### print(...)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
print(options: { printerName: string; text: string; }) => Promise<{ message: string; }>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Send raw text to a USB printer identified by its product name.
|
|
50
|
+
|
|
51
|
+
Requests USB permission (system dialog) if it has not been granted yet. The returned promise
|
|
52
|
+
resolves once the data has been transferred, and rejects if permission is denied or an error
|
|
53
|
+
occurs.
|
|
54
|
+
|
|
55
|
+
| Param | Type |
|
|
56
|
+
| ------------- | --------------------------------------------------- |
|
|
57
|
+
| **`options`** | <code>{ printerName: string; text: string; }</code> |
|
|
58
|
+
|
|
59
|
+
**Returns:** <code>Promise<{ message: string; }></code>
|
|
60
|
+
|
|
61
|
+
--------------------
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### test(...)
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
test(options: { printerName: string; }) => Promise<{ message: string; }>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Send a predefined test command (`~WC`) to the given USB printer.
|
|
71
|
+
|
|
72
|
+
| Param | Type |
|
|
73
|
+
| ------------- | ------------------------------------- |
|
|
74
|
+
| **`options`** | <code>{ printerName: string; }</code> |
|
|
75
|
+
|
|
76
|
+
**Returns:** <code>Promise<{ message: string; }></code>
|
|
77
|
+
|
|
78
|
+
--------------------
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Interfaces
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#### UsbPrinterDevice
|
|
85
|
+
|
|
86
|
+
| Prop | Type | Description |
|
|
87
|
+
| ---------------------- | --------------------------- | --------------------------------------------------------------------- |
|
|
88
|
+
| **`productName`** | <code>string \| null</code> | USB product name reported by the device. |
|
|
89
|
+
| **`manufacturerName`** | <code>string \| null</code> | USB manufacturer name reported by the device. |
|
|
90
|
+
| **`deviceId`** | <code>number</code> | Android USB device id. |
|
|
91
|
+
| **`serialNumber`** | <code>string \| null</code> | USB serial number (may be `null` if not readable without permission). |
|
|
92
|
+
| **`vendorId`** | <code>number</code> | USB vendor id. |
|
|
93
|
+
|
|
94
|
+
</docgen-api>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'SimplymobileCapacitorPrinterUsb'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '15.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.swift_version = '5.1'
|
|
17
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
repositories {
|
|
10
|
+
google()
|
|
11
|
+
mavenCentral()
|
|
12
|
+
}
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.13.0'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
apply plugin: 'com.android.library'
|
|
19
|
+
|
|
20
|
+
android {
|
|
21
|
+
namespace = "pl.simplymobile.plugins.printerusb"
|
|
22
|
+
compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
|
|
23
|
+
defaultConfig {
|
|
24
|
+
minSdkVersion = project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
|
|
25
|
+
targetSdkVersion = project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
|
|
26
|
+
versionCode 1
|
|
27
|
+
versionName "1.0"
|
|
28
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
29
|
+
}
|
|
30
|
+
buildTypes {
|
|
31
|
+
release {
|
|
32
|
+
minifyEnabled false
|
|
33
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
lintOptions {
|
|
37
|
+
abortOnError = false
|
|
38
|
+
}
|
|
39
|
+
compileOptions {
|
|
40
|
+
sourceCompatibility JavaVersion.VERSION_21
|
|
41
|
+
targetCompatibility JavaVersion.VERSION_21
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
repositories {
|
|
46
|
+
google()
|
|
47
|
+
mavenCentral()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
dependencies {
|
|
52
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
53
|
+
implementation project(':capacitor-android')
|
|
54
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
55
|
+
testImplementation "junit:junit:$junitVersion"
|
|
56
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
57
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
58
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
package pl.simplymobile.plugins.printerusb;
|
|
2
|
+
|
|
3
|
+
import android.app.PendingIntent;
|
|
4
|
+
import android.content.BroadcastReceiver;
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import android.content.Intent;
|
|
7
|
+
import android.content.IntentFilter;
|
|
8
|
+
import android.hardware.usb.UsbDevice;
|
|
9
|
+
import android.hardware.usb.UsbManager;
|
|
10
|
+
import android.os.Build;
|
|
11
|
+
import android.util.Log;
|
|
12
|
+
import com.getcapacitor.JSArray;
|
|
13
|
+
import com.getcapacitor.JSObject;
|
|
14
|
+
import com.getcapacitor.Plugin;
|
|
15
|
+
import com.getcapacitor.PluginCall;
|
|
16
|
+
import com.getcapacitor.PluginMethod;
|
|
17
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
18
|
+
import java.util.List;
|
|
19
|
+
|
|
20
|
+
@CapacitorPlugin(name = "PrinterUsb")
|
|
21
|
+
public class PrinterUsbPlugin extends Plugin {
|
|
22
|
+
|
|
23
|
+
private static final String LOG_TAG = "PrinterUsb";
|
|
24
|
+
private static final String ACTION_USB_PERMISSION = "pl.simplymobile.plugins.printerusb.USB_PERMISSION";
|
|
25
|
+
private static final String TEST_MESSAGE = "~WC";
|
|
26
|
+
private static final String PRINT_SUCCESS_MESSAGE = "It was printed correctly...";
|
|
27
|
+
|
|
28
|
+
private UsbManager usbManager;
|
|
29
|
+
private UsbPrinter usbPrinter;
|
|
30
|
+
|
|
31
|
+
// State of an in-flight print operation (resolved when the transfer completes).
|
|
32
|
+
private PluginCall currentCall;
|
|
33
|
+
private String currentMessage;
|
|
34
|
+
private boolean receiverRegistered;
|
|
35
|
+
|
|
36
|
+
@PluginMethod
|
|
37
|
+
public void scan(PluginCall call) {
|
|
38
|
+
try {
|
|
39
|
+
UsbPrinter printer = new UsbPrinter(getUsbManager());
|
|
40
|
+
List<UsbDevice> devices = printer.findPrinters();
|
|
41
|
+
|
|
42
|
+
JSArray printers = new JSArray();
|
|
43
|
+
for (UsbDevice device : devices) {
|
|
44
|
+
JSObject obj = new JSObject();
|
|
45
|
+
obj.put("productName", device.getProductName());
|
|
46
|
+
obj.put("manufacturerName", device.getManufacturerName());
|
|
47
|
+
obj.put("deviceId", device.getDeviceId());
|
|
48
|
+
obj.put("serialNumber", safeSerialNumber(device));
|
|
49
|
+
obj.put("vendorId", device.getVendorId());
|
|
50
|
+
printers.put(obj);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
JSObject ret = new JSObject();
|
|
54
|
+
ret.put("printers", printers);
|
|
55
|
+
call.resolve(ret);
|
|
56
|
+
} catch (Exception e) {
|
|
57
|
+
Log.e(LOG_TAG, "scan failed", e);
|
|
58
|
+
call.reject(e.getMessage(), e);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@PluginMethod
|
|
63
|
+
public void print(PluginCall call) {
|
|
64
|
+
String printerName = call.getString("printerName");
|
|
65
|
+
String text = call.getString("text");
|
|
66
|
+
if (printerName == null || printerName.isEmpty()) {
|
|
67
|
+
call.reject("Missing required parameter: printerName");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (text == null || text.isEmpty()) {
|
|
71
|
+
call.reject("Missing required parameter: text");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
startPrint(call, printerName, text);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@PluginMethod
|
|
78
|
+
public void test(PluginCall call) {
|
|
79
|
+
String printerName = call.getString("printerName");
|
|
80
|
+
if (printerName == null || printerName.isEmpty()) {
|
|
81
|
+
call.reject("Missing required parameter: printerName");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
startPrint(call, printerName, TEST_MESSAGE);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// region Print flow
|
|
88
|
+
|
|
89
|
+
private void startPrint(PluginCall call, String printerName, String message) {
|
|
90
|
+
if (currentCall != null) {
|
|
91
|
+
call.reject("A print operation is already in progress.");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
UsbManager manager = getUsbManager();
|
|
96
|
+
usbPrinter = new UsbPrinter(manager);
|
|
97
|
+
UsbDevice device = usbPrinter.findPrinterByName(printerName);
|
|
98
|
+
if (device == null) {
|
|
99
|
+
call.reject("There are no printers connected with name: " + printerName);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
currentCall = call;
|
|
104
|
+
currentMessage = message;
|
|
105
|
+
|
|
106
|
+
// If permission was already granted there is no need to show the system dialog.
|
|
107
|
+
if (manager.hasPermission(device)) {
|
|
108
|
+
transfer(device);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_MUTABLE : 0;
|
|
114
|
+
Intent intent = new Intent(ACTION_USB_PERMISSION).setPackage(getContext().getPackageName());
|
|
115
|
+
PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, intent, flags);
|
|
116
|
+
|
|
117
|
+
registerUsbReceiver();
|
|
118
|
+
manager.requestPermission(device, pendingIntent);
|
|
119
|
+
} catch (Exception e) {
|
|
120
|
+
Log.e(LOG_TAG, "requestPermission failed", e);
|
|
121
|
+
rejectCurrent(e.getMessage());
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
|
|
126
|
+
@Override
|
|
127
|
+
public void onReceive(Context context, Intent intent) {
|
|
128
|
+
if (!ACTION_USB_PERMISSION.equals(intent.getAction())) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
synchronized (this) {
|
|
132
|
+
unregisterUsbReceiver();
|
|
133
|
+
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
|
134
|
+
boolean granted = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
|
|
135
|
+
if (granted && device != null) {
|
|
136
|
+
transfer(device);
|
|
137
|
+
} else {
|
|
138
|
+
rejectCurrent("USB permission denied.");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
private void transfer(final UsbDevice device) {
|
|
145
|
+
final PluginCall call = currentCall;
|
|
146
|
+
final String message = currentMessage;
|
|
147
|
+
new Thread(
|
|
148
|
+
new Runnable() {
|
|
149
|
+
@Override
|
|
150
|
+
public void run() {
|
|
151
|
+
try {
|
|
152
|
+
usbPrinter.open(device);
|
|
153
|
+
usbPrinter.print(message);
|
|
154
|
+
JSObject ret = new JSObject();
|
|
155
|
+
ret.put("message", PRINT_SUCCESS_MESSAGE);
|
|
156
|
+
if (call != null) {
|
|
157
|
+
call.resolve(ret);
|
|
158
|
+
}
|
|
159
|
+
} catch (Exception e) {
|
|
160
|
+
Log.e(LOG_TAG, "print failed", e);
|
|
161
|
+
if (call != null) {
|
|
162
|
+
call.reject(e.getMessage(), e);
|
|
163
|
+
}
|
|
164
|
+
} finally {
|
|
165
|
+
usbPrinter.close();
|
|
166
|
+
currentCall = null;
|
|
167
|
+
currentMessage = null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
).start();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// endregion
|
|
175
|
+
|
|
176
|
+
// region Helpers
|
|
177
|
+
|
|
178
|
+
private UsbManager getUsbManager() {
|
|
179
|
+
if (usbManager == null) {
|
|
180
|
+
usbManager = (UsbManager) getContext().getSystemService(Context.USB_SERVICE);
|
|
181
|
+
}
|
|
182
|
+
return usbManager;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private void registerUsbReceiver() {
|
|
186
|
+
if (receiverRegistered) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
|
|
190
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
191
|
+
getContext().registerReceiver(usbReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
|
|
192
|
+
} else {
|
|
193
|
+
getContext().registerReceiver(usbReceiver, filter);
|
|
194
|
+
}
|
|
195
|
+
receiverRegistered = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private void unregisterUsbReceiver() {
|
|
199
|
+
if (!receiverRegistered) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
getContext().unregisterReceiver(usbReceiver);
|
|
204
|
+
} catch (IllegalArgumentException e) {
|
|
205
|
+
Log.w(LOG_TAG, "receiver already unregistered", e);
|
|
206
|
+
}
|
|
207
|
+
receiverRegistered = false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private void rejectCurrent(String message) {
|
|
211
|
+
if (currentCall != null) {
|
|
212
|
+
currentCall.reject(message);
|
|
213
|
+
currentCall = null;
|
|
214
|
+
currentMessage = null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private String safeSerialNumber(UsbDevice device) {
|
|
219
|
+
try {
|
|
220
|
+
return device.getSerialNumber();
|
|
221
|
+
} catch (SecurityException e) {
|
|
222
|
+
// getSerialNumber() requires USB permission on Android 10+.
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// endregion
|
|
228
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
package pl.simplymobile.plugins.printerusb;
|
|
2
|
+
|
|
3
|
+
import android.hardware.usb.UsbConstants;
|
|
4
|
+
import android.hardware.usb.UsbDevice;
|
|
5
|
+
import android.hardware.usb.UsbDeviceConnection;
|
|
6
|
+
import android.hardware.usb.UsbEndpoint;
|
|
7
|
+
import android.hardware.usb.UsbInterface;
|
|
8
|
+
import android.hardware.usb.UsbManager;
|
|
9
|
+
import java.nio.charset.StandardCharsets;
|
|
10
|
+
import java.util.ArrayList;
|
|
11
|
+
import java.util.List;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Thin wrapper around the Android USB API for talking to a USB printer
|
|
15
|
+
* (interface 0, endpoint 1, bulk transfer).
|
|
16
|
+
*/
|
|
17
|
+
class UsbPrinter {
|
|
18
|
+
|
|
19
|
+
private final UsbManager usbManager;
|
|
20
|
+
|
|
21
|
+
private UsbDeviceConnection connection;
|
|
22
|
+
private UsbInterface usbInterface;
|
|
23
|
+
private UsbEndpoint usbEndpoint;
|
|
24
|
+
|
|
25
|
+
UsbPrinter(UsbManager usbManager) {
|
|
26
|
+
this.usbManager = usbManager;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @return all connected USB devices whose interface class is {@code USB_CLASS_PRINTER}.
|
|
31
|
+
*/
|
|
32
|
+
List<UsbDevice> findPrinters() {
|
|
33
|
+
List<UsbDevice> printers = new ArrayList<>();
|
|
34
|
+
for (UsbDevice device : usbManager.getDeviceList().values()) {
|
|
35
|
+
if (device.getInterfaceCount() > 0 && device.getInterface(0).getInterfaceClass() == UsbConstants.USB_CLASS_PRINTER) {
|
|
36
|
+
printers.add(device);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return printers;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
UsbDevice findPrinterByName(String name) {
|
|
43
|
+
if (name == null) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
for (UsbDevice device : usbManager.getDeviceList().values()) {
|
|
47
|
+
if (name.equals(device.getProductName())) {
|
|
48
|
+
return device;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void open(UsbDevice printerDevice) throws Exception {
|
|
55
|
+
// The first interface and its second endpoint are where the printer communication happens.
|
|
56
|
+
usbInterface = printerDevice.getInterface(0);
|
|
57
|
+
usbEndpoint = usbInterface.getEndpoint(1);
|
|
58
|
+
connection = usbManager.openDevice(printerDevice);
|
|
59
|
+
if (connection == null) {
|
|
60
|
+
throw new Exception("Could not open a connection to the USB device.");
|
|
61
|
+
}
|
|
62
|
+
if (!connection.claimInterface(usbInterface, true)) {
|
|
63
|
+
throw new Exception("Could not claim the USB interface.");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void print(String message) throws Exception {
|
|
68
|
+
byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
|
|
69
|
+
int transferred = connection.bulkTransfer(usbEndpoint, bytes, bytes.length, 5000);
|
|
70
|
+
if (transferred < 0) {
|
|
71
|
+
throw new Exception("USB bulk transfer failed.");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void close() {
|
|
76
|
+
if (connection != null) {
|
|
77
|
+
if (usbInterface != null) {
|
|
78
|
+
connection.releaseInterface(usbInterface);
|
|
79
|
+
}
|
|
80
|
+
connection.close();
|
|
81
|
+
connection = null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dist/docs.json
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
{
|
|
2
|
+
"api": {
|
|
3
|
+
"name": "PrinterUsbPlugin",
|
|
4
|
+
"slug": "printerusbplugin",
|
|
5
|
+
"docs": "",
|
|
6
|
+
"tags": [],
|
|
7
|
+
"methods": [
|
|
8
|
+
{
|
|
9
|
+
"name": "scan",
|
|
10
|
+
"signature": "() => Promise<{ printers: UsbPrinterDevice[]; }>",
|
|
11
|
+
"parameters": [],
|
|
12
|
+
"returns": "Promise<{ printers: UsbPrinterDevice[]; }>",
|
|
13
|
+
"tags": [],
|
|
14
|
+
"docs": "Scan for connected USB printers (devices whose interface class is `USB_CLASS_PRINTER`).",
|
|
15
|
+
"complexTypes": [
|
|
16
|
+
"UsbPrinterDevice"
|
|
17
|
+
],
|
|
18
|
+
"slug": "scan"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "print",
|
|
22
|
+
"signature": "(options: { printerName: string; text: string; }) => Promise<{ message: string; }>",
|
|
23
|
+
"parameters": [
|
|
24
|
+
{
|
|
25
|
+
"name": "options",
|
|
26
|
+
"docs": "",
|
|
27
|
+
"type": "{ printerName: string; text: string; }"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"returns": "Promise<{ message: string; }>",
|
|
31
|
+
"tags": [
|
|
32
|
+
{
|
|
33
|
+
"name": "param",
|
|
34
|
+
"text": "options.printerName USB product name of the target printer."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "param",
|
|
38
|
+
"text": "options.text Raw text/commands to send to the printer."
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"docs": "Send raw text to a USB printer identified by its product name.\n\nRequests USB permission (system dialog) if it has not been granted yet. The returned promise\nresolves once the data has been transferred, and rejects if permission is denied or an error\noccurs.",
|
|
42
|
+
"complexTypes": [],
|
|
43
|
+
"slug": "print"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "test",
|
|
47
|
+
"signature": "(options: { printerName: string; }) => Promise<{ message: string; }>",
|
|
48
|
+
"parameters": [
|
|
49
|
+
{
|
|
50
|
+
"name": "options",
|
|
51
|
+
"docs": "",
|
|
52
|
+
"type": "{ printerName: string; }"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"returns": "Promise<{ message: string; }>",
|
|
56
|
+
"tags": [
|
|
57
|
+
{
|
|
58
|
+
"name": "param",
|
|
59
|
+
"text": "options.printerName USB product name of the target printer."
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"docs": "Send a predefined test command (`~WC`) to the given USB printer.",
|
|
63
|
+
"complexTypes": [],
|
|
64
|
+
"slug": "test"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"properties": []
|
|
68
|
+
},
|
|
69
|
+
"interfaces": [
|
|
70
|
+
{
|
|
71
|
+
"name": "UsbPrinterDevice",
|
|
72
|
+
"slug": "usbprinterdevice",
|
|
73
|
+
"docs": "",
|
|
74
|
+
"tags": [],
|
|
75
|
+
"methods": [],
|
|
76
|
+
"properties": [
|
|
77
|
+
{
|
|
78
|
+
"name": "productName",
|
|
79
|
+
"tags": [],
|
|
80
|
+
"docs": "USB product name reported by the device.",
|
|
81
|
+
"complexTypes": [],
|
|
82
|
+
"type": "string | null"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "manufacturerName",
|
|
86
|
+
"tags": [],
|
|
87
|
+
"docs": "USB manufacturer name reported by the device.",
|
|
88
|
+
"complexTypes": [],
|
|
89
|
+
"type": "string | null"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "deviceId",
|
|
93
|
+
"tags": [],
|
|
94
|
+
"docs": "Android USB device id.",
|
|
95
|
+
"complexTypes": [],
|
|
96
|
+
"type": "number"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "serialNumber",
|
|
100
|
+
"tags": [],
|
|
101
|
+
"docs": "USB serial number (may be `null` if not readable without permission).",
|
|
102
|
+
"complexTypes": [],
|
|
103
|
+
"type": "string | null"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"name": "vendorId",
|
|
107
|
+
"tags": [],
|
|
108
|
+
"docs": "USB vendor id.",
|
|
109
|
+
"complexTypes": [],
|
|
110
|
+
"type": "number"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"enums": [],
|
|
116
|
+
"typeAliases": [],
|
|
117
|
+
"pluginConfigs": []
|
|
118
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface UsbPrinterDevice {
|
|
2
|
+
/**
|
|
3
|
+
* USB product name reported by the device.
|
|
4
|
+
*/
|
|
5
|
+
productName: string | null;
|
|
6
|
+
/**
|
|
7
|
+
* USB manufacturer name reported by the device.
|
|
8
|
+
*/
|
|
9
|
+
manufacturerName: string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Android USB device id.
|
|
12
|
+
*/
|
|
13
|
+
deviceId: number;
|
|
14
|
+
/**
|
|
15
|
+
* USB serial number (may be `null` if not readable without permission).
|
|
16
|
+
*/
|
|
17
|
+
serialNumber: string | null;
|
|
18
|
+
/**
|
|
19
|
+
* USB vendor id.
|
|
20
|
+
*/
|
|
21
|
+
vendorId: number;
|
|
22
|
+
}
|
|
23
|
+
export interface PrinterUsbPlugin {
|
|
24
|
+
/**
|
|
25
|
+
* Scan for connected USB printers (devices whose interface class is `USB_CLASS_PRINTER`).
|
|
26
|
+
*/
|
|
27
|
+
scan(): Promise<{
|
|
28
|
+
printers: UsbPrinterDevice[];
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Send raw text to a USB printer identified by its product name.
|
|
32
|
+
*
|
|
33
|
+
* Requests USB permission (system dialog) if it has not been granted yet. The returned promise
|
|
34
|
+
* resolves once the data has been transferred, and rejects if permission is denied or an error
|
|
35
|
+
* occurs.
|
|
36
|
+
*
|
|
37
|
+
* @param options.printerName USB product name of the target printer.
|
|
38
|
+
* @param options.text Raw text/commands to send to the printer.
|
|
39
|
+
*/
|
|
40
|
+
print(options: {
|
|
41
|
+
printerName: string;
|
|
42
|
+
text: string;
|
|
43
|
+
}): Promise<{
|
|
44
|
+
message: string;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Send a predefined test command (`~WC`) to the given USB printer.
|
|
48
|
+
*
|
|
49
|
+
* @param options.printerName USB product name of the target printer.
|
|
50
|
+
*/
|
|
51
|
+
test(options: {
|
|
52
|
+
printerName: string;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
message: string;
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface UsbPrinterDevice {\n /**\n * USB product name reported by the device.\n */\n productName: string | null;\n /**\n * USB manufacturer name reported by the device.\n */\n manufacturerName: string | null;\n /**\n * Android USB device id.\n */\n deviceId: number;\n /**\n * USB serial number (may be `null` if not readable without permission).\n */\n serialNumber: string | null;\n /**\n * USB vendor id.\n */\n vendorId: number;\n}\n\nexport interface PrinterUsbPlugin {\n /**\n * Scan for connected USB printers (devices whose interface class is `USB_CLASS_PRINTER`).\n */\n scan(): Promise<{ printers: UsbPrinterDevice[] }>;\n\n /**\n * Send raw text to a USB printer identified by its product name.\n *\n * Requests USB permission (system dialog) if it has not been granted yet. The returned promise\n * resolves once the data has been transferred, and rejects if permission is denied or an error\n * occurs.\n *\n * @param options.printerName USB product name of the target printer.\n * @param options.text Raw text/commands to send to the printer.\n */\n print(options: { printerName: string; text: string }): Promise<{ message: string }>;\n\n /**\n * Send a predefined test command (`~WC`) to the given USB printer.\n *\n * @param options.printerName USB product name of the target printer.\n */\n test(options: { printerName: string }): Promise<{ message: string }>;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,UAAU,GAAG,cAAc,CAAmB,YAAY,EAAE;IAChE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;CAC9D,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { PrinterUsbPlugin } from './definitions';\n\nconst PrinterUsb = registerPlugin<PrinterUsbPlugin>('PrinterUsb', {\n web: () => import('./web').then((m) => new m.PrinterUsbWeb()),\n});\n\nexport * from './definitions';\nexport { PrinterUsb };\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
import type { PrinterUsbPlugin, UsbPrinterDevice } from './definitions';
|
|
3
|
+
export declare class PrinterUsbWeb extends WebPlugin implements PrinterUsbPlugin {
|
|
4
|
+
scan(): Promise<{
|
|
5
|
+
printers: UsbPrinterDevice[];
|
|
6
|
+
}>;
|
|
7
|
+
print(options: {
|
|
8
|
+
printerName: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
message: string;
|
|
12
|
+
}>;
|
|
13
|
+
test(options: {
|
|
14
|
+
printerName: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
message: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
package/dist/esm/web.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
export class PrinterUsbWeb extends WebPlugin {
|
|
3
|
+
async scan() {
|
|
4
|
+
console.log('NOT IMPLEMENTED');
|
|
5
|
+
return { printers: [] };
|
|
6
|
+
}
|
|
7
|
+
async print(options) {
|
|
8
|
+
console.log('NOT IMPLEMENTED', options.printerName, options.text);
|
|
9
|
+
return { message: 'NOT IMPLEMENTED' };
|
|
10
|
+
}
|
|
11
|
+
async test(options) {
|
|
12
|
+
console.log('NOT IMPLEMENTED', options.printerName);
|
|
13
|
+
return { message: 'NOT IMPLEMENTED' };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAA8C;QACxD,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAgC;QACzC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;IACxC,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { PrinterUsbPlugin, UsbPrinterDevice } from './definitions';\n\nexport class PrinterUsbWeb extends WebPlugin implements PrinterUsbPlugin {\n async scan(): Promise<{ printers: UsbPrinterDevice[] }> {\n console.log('NOT IMPLEMENTED');\n return { printers: [] };\n }\n\n async print(options: { printerName: string; text: string }): Promise<{ message: string }> {\n console.log('NOT IMPLEMENTED', options.printerName, options.text);\n return { message: 'NOT IMPLEMENTED' };\n }\n\n async test(options: { printerName: string }): Promise<{ message: string }> {\n console.log('NOT IMPLEMENTED', options.printerName);\n return { message: 'NOT IMPLEMENTED' };\n }\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@capacitor/core');
|
|
4
|
+
|
|
5
|
+
const PrinterUsb = core.registerPlugin('PrinterUsb', {
|
|
6
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PrinterUsbWeb()),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
class PrinterUsbWeb extends core.WebPlugin {
|
|
10
|
+
async scan() {
|
|
11
|
+
console.log('NOT IMPLEMENTED');
|
|
12
|
+
return { printers: [] };
|
|
13
|
+
}
|
|
14
|
+
async print(options) {
|
|
15
|
+
console.log('NOT IMPLEMENTED', options.printerName, options.text);
|
|
16
|
+
return { message: 'NOT IMPLEMENTED' };
|
|
17
|
+
}
|
|
18
|
+
async test(options) {
|
|
19
|
+
console.log('NOT IMPLEMENTED', options.printerName);
|
|
20
|
+
return { message: 'NOT IMPLEMENTED' };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
25
|
+
__proto__: null,
|
|
26
|
+
PrinterUsbWeb: PrinterUsbWeb
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
exports.PrinterUsb = PrinterUsb;
|
|
30
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst PrinterUsb = registerPlugin('PrinterUsb', {\n web: () => import('./web').then((m) => new m.PrinterUsbWeb()),\n});\nexport * from './definitions';\nexport { PrinterUsb };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PrinterUsbWeb extends WebPlugin {\n async scan() {\n console.log('NOT IMPLEMENTED');\n return { printers: [] };\n }\n async print(options) {\n console.log('NOT IMPLEMENTED', options.printerName, options.text);\n return { message: 'NOT IMPLEMENTED' };\n }\n async test(options) {\n console.log('NOT IMPLEMENTED', options.printerName);\n return { message: 'NOT IMPLEMENTED' };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;AAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;AACjE,CAAC;;ACFM,MAAM,aAAa,SAASC,cAAS,CAAC;AAC7C,IAAI,MAAM,IAAI,GAAG;AACjB,QAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;AACtC,QAAQ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;AAC/B,IAAI;AACJ,IAAI,MAAM,KAAK,CAAC,OAAO,EAAE;AACzB,QAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC;AACzE,QAAQ,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE;AAC7C,IAAI;AACJ,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC;AAC3D,QAAQ,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE;AAC7C,IAAI;AACJ;;;;;;;;;"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var capacitorPrinterUsb = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const PrinterUsb = core.registerPlugin('PrinterUsb', {
|
|
5
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PrinterUsbWeb()),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
class PrinterUsbWeb extends core.WebPlugin {
|
|
9
|
+
async scan() {
|
|
10
|
+
console.log('NOT IMPLEMENTED');
|
|
11
|
+
return { printers: [] };
|
|
12
|
+
}
|
|
13
|
+
async print(options) {
|
|
14
|
+
console.log('NOT IMPLEMENTED', options.printerName, options.text);
|
|
15
|
+
return { message: 'NOT IMPLEMENTED' };
|
|
16
|
+
}
|
|
17
|
+
async test(options) {
|
|
18
|
+
console.log('NOT IMPLEMENTED', options.printerName);
|
|
19
|
+
return { message: 'NOT IMPLEMENTED' };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
24
|
+
__proto__: null,
|
|
25
|
+
PrinterUsbWeb: PrinterUsbWeb
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
exports.PrinterUsb = PrinterUsb;
|
|
29
|
+
|
|
30
|
+
return exports;
|
|
31
|
+
|
|
32
|
+
})({}, capacitorExports);
|
|
33
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst PrinterUsb = registerPlugin('PrinterUsb', {\n web: () => import('./web').then((m) => new m.PrinterUsbWeb()),\n});\nexport * from './definitions';\nexport { PrinterUsb };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PrinterUsbWeb extends WebPlugin {\n async scan() {\n console.log('NOT IMPLEMENTED');\n return { printers: [] };\n }\n async print(options) {\n console.log('NOT IMPLEMENTED', options.printerName, options.text);\n return { message: 'NOT IMPLEMENTED' };\n }\n async test(options) {\n console.log('NOT IMPLEMENTED', options.printerName);\n return { message: 'NOT IMPLEMENTED' };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;IAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC;;ICFM,MAAM,aAAa,SAASC,cAAS,CAAC;IAC7C,IAAI,MAAM,IAAI,GAAG;IACjB,QAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACtC,QAAQ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC/B,IAAI;IACJ,IAAI,MAAM,KAAK,CAAC,OAAO,EAAE;IACzB,QAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC;IACzE,QAAQ,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE;IAC7C,IAAI;IACJ,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,WAAW,CAAC;IAC3D,QAAQ,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE;IAC7C,IAAI;IACJ;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* USB printer plugin.
|
|
6
|
+
*
|
|
7
|
+
* This is an Android-only plugin. On iOS every method rejects with `unimplemented`.
|
|
8
|
+
* Please read the Capacitor iOS Plugin Development Guide
|
|
9
|
+
* here: https://capacitorjs.com/docs/plugins/ios
|
|
10
|
+
*/
|
|
11
|
+
@objc(PrinterUsbPlugin)
|
|
12
|
+
public class PrinterUsbPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
13
|
+
public let identifier = "PrinterUsbPlugin"
|
|
14
|
+
public let jsName = "PrinterUsb"
|
|
15
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
16
|
+
CAPPluginMethod(name: "scan", returnType: CAPPluginReturnPromise),
|
|
17
|
+
CAPPluginMethod(name: "print", returnType: CAPPluginReturnPromise),
|
|
18
|
+
CAPPluginMethod(name: "test", returnType: CAPPluginReturnPromise)
|
|
19
|
+
]
|
|
20
|
+
private let implementation = PrinterUsb()
|
|
21
|
+
|
|
22
|
+
@objc func scan(_ call: CAPPluginCall) {
|
|
23
|
+
call.unimplemented("PrinterUsb is Android-only.")
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@objc func print(_ call: CAPPluginCall) {
|
|
27
|
+
call.unimplemented("PrinterUsb is Android-only.")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@objc func test(_ call: CAPPluginCall) {
|
|
31
|
+
call.unimplemented("PrinterUsb is Android-only.")
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
@testable import PrinterUsbPlugin
|
|
3
|
+
|
|
4
|
+
class PrinterUsbTests: XCTestCase {
|
|
5
|
+
override func setUp() {
|
|
6
|
+
super.setUp()
|
|
7
|
+
// Put setup code here. This method is called before the invocation of each test method in the class.
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
override func tearDown() {
|
|
11
|
+
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
|
12
|
+
super.tearDown()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func testEcho() {
|
|
16
|
+
// This is an example of a functional test case for a plugin.
|
|
17
|
+
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
|
18
|
+
|
|
19
|
+
let implementation = PrinterUsb()
|
|
20
|
+
let value = "Hello, World!"
|
|
21
|
+
let result = implementation.echo(value)
|
|
22
|
+
|
|
23
|
+
XCTAssertEqual(value, result)
|
|
24
|
+
}
|
|
25
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@simplymobile/capacitor-printer-usb",
|
|
3
|
+
"version": "8.0.0",
|
|
4
|
+
"description": "Capacitor USB printer plugin",
|
|
5
|
+
"author": "SimplyMobile",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"main": "dist/plugin.cjs.js",
|
|
8
|
+
"module": "dist/esm/index.js",
|
|
9
|
+
"types": "dist/esm/index.d.ts",
|
|
10
|
+
"unpkg": "dist/plugin.js",
|
|
11
|
+
"files": [
|
|
12
|
+
"android/src/main/",
|
|
13
|
+
"android/build.gradle",
|
|
14
|
+
"dist/",
|
|
15
|
+
"ios/Sources",
|
|
16
|
+
"ios/Tests",
|
|
17
|
+
"Package.swift",
|
|
18
|
+
"SimplymobileCapacitorPrinterUsb.podspec"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"capacitor",
|
|
22
|
+
"plugin",
|
|
23
|
+
"native",
|
|
24
|
+
"usb",
|
|
25
|
+
"printer"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
29
|
+
"verify:ios": "xcodebuild -scheme SimplymobileCapacitorPrinterUsb -destination generic/platform=iOS",
|
|
30
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
31
|
+
"verify:web": "npm run build",
|
|
32
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
33
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
34
|
+
"eslint": "eslint . --ext ts",
|
|
35
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
|
|
36
|
+
"swiftlint": "node-swiftlint",
|
|
37
|
+
"docgen": "docgen --api PrinterUsbPlugin --output-readme README.md --output-json dist/docs.json",
|
|
38
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
39
|
+
"clean": "rimraf ./dist",
|
|
40
|
+
"watch": "tsc --watch",
|
|
41
|
+
"prepublishOnly": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@capacitor/android": "^8.0.0",
|
|
45
|
+
"@capacitor/core": "^8.0.0",
|
|
46
|
+
"@capacitor/docgen": "^0.3.1",
|
|
47
|
+
"@capacitor/ios": "^8.0.0",
|
|
48
|
+
"@ionic/eslint-config": "^0.4.0",
|
|
49
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
50
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
51
|
+
"eslint": "^8.57.1",
|
|
52
|
+
"prettier": "^3.6.2",
|
|
53
|
+
"prettier-plugin-java": "^2.7.7",
|
|
54
|
+
"rimraf": "^6.1.0",
|
|
55
|
+
"rollup": "^4.53.2",
|
|
56
|
+
"swiftlint": "^2.0.0",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@capacitor/core": ">=8.0.0"
|
|
61
|
+
},
|
|
62
|
+
"eslintConfig": {
|
|
63
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
64
|
+
},
|
|
65
|
+
"prettier": "@ionic/prettier-config",
|
|
66
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "git+https://github.com/.git"
|
|
70
|
+
},
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/issues"
|
|
73
|
+
},
|
|
74
|
+
"capacitor": {
|
|
75
|
+
"ios": {
|
|
76
|
+
"src": "ios"
|
|
77
|
+
},
|
|
78
|
+
"android": {
|
|
79
|
+
"src": "android"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|