@esslassi/electron-printer 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -167
- package/lib/electronPrinter.d.ts +52 -24
- package/lib/electronPrinter.js +82 -31
- package/package.json +1 -1
- package/src/linux_printer.cpp +312 -112
- package/src/linux_printer.h +21 -11
- package/src/mac_printer.cpp +317 -110
- package/src/mac_printer.h +21 -12
- package/src/main.cpp +42 -13
- package/src/print.cpp +288 -207
- package/src/printer_interface.h +48 -10
- package/src/windows_printer.cpp +271 -134
- package/src/windows_printer.h +40 -11
- package/test.js +120 -0
package/src/print.cpp
CHANGED
|
@@ -1,272 +1,353 @@
|
|
|
1
1
|
#include <napi.h>
|
|
2
|
+
#include <fstream>
|
|
3
|
+
#include <vector>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <functional>
|
|
6
|
+
|
|
2
7
|
#include "printer_factory.h"
|
|
8
|
+
#include "printer_interface.h"
|
|
3
9
|
|
|
4
|
-
|
|
10
|
+
static std::unique_ptr<PrinterInterface> P()
|
|
5
11
|
{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
std::function<void(PrinterWorker *)> work;
|
|
9
|
-
PrinterInfo printerResult;
|
|
10
|
-
std::vector<PrinterInfo> printersResult;
|
|
11
|
-
bool isMultiplePrinters;
|
|
12
|
-
bool success;
|
|
12
|
+
return PrinterFactory::Create();
|
|
13
|
+
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
/* =========================================================
|
|
16
|
+
JS Converters
|
|
17
|
+
========================================================= */
|
|
18
|
+
|
|
19
|
+
static Napi::Object JsPrinterDetails(Napi::Env env, const PrinterDetailsNative &p)
|
|
20
|
+
{
|
|
21
|
+
Napi::Object o = Napi::Object::New(env);
|
|
22
|
+
o.Set("name", p.name);
|
|
23
|
+
o.Set("isDefault", p.isDefault);
|
|
24
|
+
|
|
25
|
+
Napi::Object opts = Napi::Object::New(env);
|
|
26
|
+
for (auto &kv : p.options)
|
|
27
|
+
opts.Set(kv.first, kv.second);
|
|
28
|
+
|
|
29
|
+
o.Set("options", opts);
|
|
30
|
+
return o;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static Napi::Object JsDriverOptions(Napi::Env env, const DriverOptions &opts)
|
|
34
|
+
{
|
|
35
|
+
Napi::Object out = Napi::Object::New(env);
|
|
36
|
+
for (auto &group : opts)
|
|
20
37
|
{
|
|
21
|
-
|
|
38
|
+
Napi::Object choices = Napi::Object::New(env);
|
|
39
|
+
for (auto &choice : group.second)
|
|
40
|
+
choices.Set(choice.first, Napi::Boolean::New(env, choice.second));
|
|
41
|
+
out.Set(group.first, choices);
|
|
22
42
|
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static Napi::Object JsJobDetails(Napi::Env env, const JobDetailsNative &j)
|
|
47
|
+
{
|
|
48
|
+
Napi::Object o = Napi::Object::New(env);
|
|
49
|
+
o.Set("id", j.id);
|
|
50
|
+
o.Set("name", j.name);
|
|
51
|
+
o.Set("printerName", j.printerName);
|
|
52
|
+
o.Set("user", j.user);
|
|
53
|
+
o.Set("format", j.format);
|
|
54
|
+
o.Set("priority", j.priority);
|
|
55
|
+
o.Set("size", j.size);
|
|
56
|
+
|
|
57
|
+
Napi::Array st = Napi::Array::New(env, j.status.size());
|
|
58
|
+
for (size_t i = 0; i < j.status.size(); i++)
|
|
59
|
+
st.Set((uint32_t)i, j.status[i]);
|
|
60
|
+
o.Set("status", st);
|
|
61
|
+
|
|
62
|
+
o.Set("completedTime", Napi::Date::New(env, (double)j.completedTime * 1000.0));
|
|
63
|
+
o.Set("creationTime", Napi::Date::New(env, (double)j.creationTime * 1000.0));
|
|
64
|
+
o.Set("processingTime", Napi::Date::New(env, (double)j.processingTime * 1000.0));
|
|
65
|
+
|
|
66
|
+
return o;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* =========================================================
|
|
70
|
+
Sync Methods
|
|
71
|
+
========================================================= */
|
|
72
|
+
|
|
73
|
+
Napi::Value getPrinters(const Napi::CallbackInfo &info)
|
|
74
|
+
{
|
|
75
|
+
auto env = info.Env();
|
|
76
|
+
auto printer = P();
|
|
77
|
+
auto list = printer->GetPrinters();
|
|
78
|
+
|
|
79
|
+
Napi::Array arr = Napi::Array::New(env, list.size());
|
|
80
|
+
for (size_t i = 0; i < list.size(); i++)
|
|
81
|
+
arr.Set((uint32_t)i, JsPrinterDetails(env, list[i]));
|
|
82
|
+
|
|
83
|
+
return arr;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
Napi::Value getPrinter(const Napi::CallbackInfo &info)
|
|
87
|
+
{
|
|
88
|
+
auto env = info.Env();
|
|
89
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
90
|
+
Napi::TypeError::New(env, "printerName required").ThrowAsJavaScriptException();
|
|
91
|
+
|
|
92
|
+
auto printer = P();
|
|
93
|
+
auto p = printer->GetPrinter(info[0].As<Napi::String>().Utf8Value());
|
|
94
|
+
return JsPrinterDetails(env, p);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Napi::Value getPrinterDriverOptions(const Napi::CallbackInfo &info)
|
|
98
|
+
{
|
|
99
|
+
auto env = info.Env();
|
|
100
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
101
|
+
Napi::TypeError::New(env, "printerName required").ThrowAsJavaScriptException();
|
|
102
|
+
|
|
103
|
+
auto printer = P();
|
|
104
|
+
auto opts = printer->GetPrinterDriverOptions(info[0].As<Napi::String>().Utf8Value());
|
|
105
|
+
return JsDriverOptions(env, opts);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
Napi::Value getSelectedPaperSize(const Napi::CallbackInfo &info)
|
|
109
|
+
{
|
|
110
|
+
auto env = info.Env();
|
|
111
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
112
|
+
Napi::TypeError::New(env, "printerName required").ThrowAsJavaScriptException();
|
|
113
|
+
|
|
114
|
+
auto printer = P();
|
|
115
|
+
auto ps = printer->GetSelectedPaperSize(info[0].As<Napi::String>().Utf8Value());
|
|
116
|
+
return Napi::String::New(env, ps);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
Napi::Value getDefaultPrinterName(const Napi::CallbackInfo &info)
|
|
120
|
+
{
|
|
121
|
+
auto env = info.Env();
|
|
122
|
+
auto printer = P();
|
|
123
|
+
auto name = printer->GetDefaultPrinterName();
|
|
124
|
+
if (name.empty())
|
|
125
|
+
return env.Undefined();
|
|
126
|
+
return Napi::String::New(env, name);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
Napi::Value getSupportedPrintFormats(const Napi::CallbackInfo &info)
|
|
130
|
+
{
|
|
131
|
+
auto env = info.Env();
|
|
132
|
+
auto printer = P();
|
|
133
|
+
auto formats = printer->GetSupportedPrintFormats();
|
|
134
|
+
|
|
135
|
+
Napi::Array arr = Napi::Array::New(env, formats.size());
|
|
136
|
+
for (size_t i = 0; i < formats.size(); i++)
|
|
137
|
+
arr.Set((uint32_t)i, formats[i]);
|
|
138
|
+
|
|
139
|
+
return arr;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
Napi::Value getSupportedJobCommands(const Napi::CallbackInfo &info)
|
|
143
|
+
{
|
|
144
|
+
auto env = info.Env();
|
|
145
|
+
auto printer = P();
|
|
146
|
+
auto cmds = printer->GetSupportedJobCommands();
|
|
147
|
+
|
|
148
|
+
Napi::Array arr = Napi::Array::New(env, cmds.size());
|
|
149
|
+
for (size_t i = 0; i < cmds.size(); i++)
|
|
150
|
+
arr.Set((uint32_t)i, cmds[i]);
|
|
151
|
+
|
|
152
|
+
return arr;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
Napi::Value getJob(const Napi::CallbackInfo &info)
|
|
156
|
+
{
|
|
157
|
+
auto env = info.Env();
|
|
158
|
+
if (info.Length() < 2 || !info[0].IsString() || !info[1].IsNumber())
|
|
159
|
+
Napi::TypeError::New(env, "getJob(printerName, jobId)").ThrowAsJavaScriptException();
|
|
160
|
+
|
|
161
|
+
auto printer = P();
|
|
162
|
+
auto job = printer->GetJob(
|
|
163
|
+
info[0].As<Napi::String>().Utf8Value(),
|
|
164
|
+
info[1].As<Napi::Number>().Int32Value());
|
|
165
|
+
|
|
166
|
+
return JsJobDetails(env, job);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
Napi::Value setJob(const Napi::CallbackInfo &info)
|
|
170
|
+
{
|
|
171
|
+
auto env = info.Env();
|
|
172
|
+
if (info.Length() < 3 || !info[0].IsString() || !info[1].IsNumber() || !info[2].IsString())
|
|
173
|
+
Napi::TypeError::New(env, "setJob(printerName, jobId, command)").ThrowAsJavaScriptException();
|
|
174
|
+
|
|
175
|
+
auto printer = P();
|
|
176
|
+
printer->SetJob(
|
|
177
|
+
info[0].As<Napi::String>().Utf8Value(),
|
|
178
|
+
info[1].As<Napi::Number>().Int32Value(),
|
|
179
|
+
info[2].As<Napi::String>().Utf8Value());
|
|
180
|
+
|
|
181
|
+
return env.Undefined();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* =========================================================
|
|
185
|
+
Async Print Worker
|
|
186
|
+
========================================================= */
|
|
187
|
+
|
|
188
|
+
class PrintWorker : public Napi::AsyncWorker
|
|
189
|
+
{
|
|
190
|
+
public:
|
|
191
|
+
PrintWorker(
|
|
192
|
+
Napi::Function successCb,
|
|
193
|
+
Napi::Function errorCb,
|
|
194
|
+
std::function<int()> workFn)
|
|
195
|
+
: Napi::AsyncWorker(successCb),
|
|
196
|
+
successRef(Napi::Persistent(successCb)),
|
|
197
|
+
errorRef(Napi::Persistent(errorCb)),
|
|
198
|
+
work(workFn)
|
|
199
|
+
{}
|
|
23
200
|
|
|
24
201
|
void Execute() override
|
|
25
202
|
{
|
|
26
|
-
|
|
203
|
+
try
|
|
27
204
|
{
|
|
28
|
-
work(
|
|
205
|
+
jobId = work();
|
|
206
|
+
if (jobId <= 0)
|
|
207
|
+
SetError("Print failed");
|
|
29
208
|
}
|
|
30
|
-
|
|
209
|
+
catch (...)
|
|
31
210
|
{
|
|
32
|
-
SetError("
|
|
211
|
+
SetError("Print failed (exception)");
|
|
33
212
|
}
|
|
34
213
|
}
|
|
35
214
|
|
|
36
215
|
void OnOK() override
|
|
37
216
|
{
|
|
38
|
-
Napi::
|
|
39
|
-
Napi::
|
|
40
|
-
|
|
41
|
-
if (isMultiplePrinters)
|
|
42
|
-
{
|
|
43
|
-
Napi::Array result = Napi::Array::New(env, printersResult.size());
|
|
44
|
-
for (size_t i = 0; i < printersResult.size(); i++)
|
|
45
|
-
{
|
|
46
|
-
result.Set(i, CreatePrinterObject(env, printersResult[i]));
|
|
47
|
-
}
|
|
48
|
-
Callback().Call({env.Null(), result});
|
|
49
|
-
}
|
|
50
|
-
else
|
|
51
|
-
{
|
|
52
|
-
Callback().Call({env.Null(), CreatePrinterObject(env, printerResult)});
|
|
53
|
-
}
|
|
217
|
+
Napi::HandleScope scope(Env());
|
|
218
|
+
successRef.Call({ Napi::String::New(Env(), std::to_string(jobId)) });
|
|
54
219
|
}
|
|
55
220
|
|
|
56
|
-
|
|
57
|
-
void SetPrinterResult(const PrinterInfo &result) { printerResult = result; }
|
|
58
|
-
void SetPrintersResult(const std::vector<PrinterInfo> &result)
|
|
221
|
+
void OnError(const Napi::Error &e) override
|
|
59
222
|
{
|
|
60
|
-
|
|
61
|
-
|
|
223
|
+
Napi::HandleScope scope(Env());
|
|
224
|
+
errorRef.Call({ e.Value() });
|
|
62
225
|
}
|
|
63
|
-
void SetSuccess(bool value) { success = value; }
|
|
64
|
-
bool GetSuccess() const { return success; }
|
|
65
226
|
|
|
66
227
|
private:
|
|
67
|
-
Napi::
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
result.Set("status", printer.status);
|
|
72
|
-
|
|
73
|
-
// Só incluir estes campos se NÃO for um resultado do PrintDirect
|
|
74
|
-
if (!success)
|
|
75
|
-
{ // Se success for true, é um PrintDirect
|
|
76
|
-
result.Set("isDefault", printer.isDefault);
|
|
77
|
-
|
|
78
|
-
Napi::Object details = Napi::Object::New(env);
|
|
79
|
-
for (const auto &detail : printer.details)
|
|
80
|
-
{
|
|
81
|
-
details.Set(detail.first, detail.second);
|
|
82
|
-
}
|
|
83
|
-
result.Set("details", details);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
228
|
+
Napi::FunctionReference successRef;
|
|
229
|
+
Napi::FunctionReference errorRef;
|
|
230
|
+
std::function<int()> work;
|
|
231
|
+
int jobId = 0;
|
|
88
232
|
};
|
|
89
233
|
|
|
90
|
-
Napi::
|
|
234
|
+
static Napi::Function SafeCb(Napi::Env env, Napi::Object opt, const char *key)
|
|
91
235
|
{
|
|
92
|
-
|
|
236
|
+
if (opt.Has(key) && opt.Get(key).IsFunction())
|
|
237
|
+
return opt.Get(key).As<Napi::Function>();
|
|
238
|
+
|
|
239
|
+
return Napi::Function::New(env, [](const Napi::CallbackInfo &) {});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* =========================================================
|
|
243
|
+
printDirect
|
|
244
|
+
========================================================= */
|
|
245
|
+
|
|
246
|
+
Napi::Value printDirect(const Napi::CallbackInfo &info)
|
|
247
|
+
{
|
|
248
|
+
auto env = info.Env();
|
|
93
249
|
|
|
94
250
|
if (info.Length() < 1 || !info[0].IsObject())
|
|
95
|
-
|
|
96
|
-
Napi::TypeError::New(env, "Expected an object as argument").ThrowAsJavaScriptException();
|
|
97
|
-
return env.Null();
|
|
98
|
-
}
|
|
251
|
+
Napi::TypeError::New(env, "options object required").ThrowAsJavaScriptException();
|
|
99
252
|
|
|
100
|
-
Napi::Object
|
|
253
|
+
Napi::Object opt = info[0].As<Napi::Object>();
|
|
101
254
|
|
|
102
|
-
if (!
|
|
103
|
-
|
|
104
|
-
Napi::TypeError::New(env, "Object must have 'printerName' and 'data' properties").ThrowAsJavaScriptException();
|
|
105
|
-
return env.Null();
|
|
106
|
-
}
|
|
255
|
+
if (!opt.Has("data"))
|
|
256
|
+
Napi::TypeError::New(env, "options.data required").ThrowAsJavaScriptException();
|
|
107
257
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return env.Null();
|
|
112
|
-
}
|
|
258
|
+
std::string printerName;
|
|
259
|
+
if (opt.Has("printer") && opt.Get("printer").IsString())
|
|
260
|
+
printerName = opt.Get("printer").As<Napi::String>().Utf8Value();
|
|
113
261
|
|
|
114
|
-
|
|
115
|
-
if (
|
|
262
|
+
std::string type = "RAW";
|
|
263
|
+
if (opt.Has("type") && opt.Get("type").IsString())
|
|
264
|
+
type = opt.Get("type").As<Napi::String>().Utf8Value();
|
|
265
|
+
|
|
266
|
+
StringMap driverOpts;
|
|
267
|
+
if (opt.Has("options") && opt.Get("options").IsObject())
|
|
116
268
|
{
|
|
117
|
-
Napi::
|
|
118
|
-
|
|
269
|
+
Napi::Object o = opt.Get("options").As<Napi::Object>();
|
|
270
|
+
auto props = o.GetPropertyNames();
|
|
271
|
+
for (uint32_t i = 0; i < props.Length(); i++)
|
|
272
|
+
{
|
|
273
|
+
auto k = props.Get(i).As<Napi::String>().Utf8Value();
|
|
274
|
+
auto v = o.Get(k).ToString().Utf8Value();
|
|
275
|
+
driverOpts[k] = v;
|
|
276
|
+
}
|
|
119
277
|
}
|
|
120
278
|
|
|
121
|
-
std::
|
|
122
|
-
|
|
279
|
+
std::vector<uint8_t> data;
|
|
280
|
+
auto d = opt.Get("data");
|
|
123
281
|
|
|
124
|
-
if (
|
|
282
|
+
if (d.IsBuffer())
|
|
125
283
|
{
|
|
126
|
-
|
|
127
|
-
|
|
284
|
+
auto b = d.As<Napi::Buffer<uint8_t>>();
|
|
285
|
+
data.assign(b.Data(), b.Data() + b.Length());
|
|
128
286
|
}
|
|
129
287
|
else
|
|
130
288
|
{
|
|
131
|
-
|
|
132
|
-
|
|
289
|
+
auto s = d.ToString().Utf8Value();
|
|
290
|
+
data.assign(s.begin(), s.end());
|
|
133
291
|
}
|
|
134
292
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
{
|
|
138
|
-
dataType = options.Get("dataType").As<Napi::String>().Utf8Value();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
|
|
142
|
-
|
|
143
|
-
auto callback = Napi::Function::New(env, [deferred](const Napi::CallbackInfo &info)
|
|
144
|
-
{
|
|
145
|
-
if (info[0].IsNull()) {
|
|
146
|
-
deferred.Resolve(info[1]);
|
|
147
|
-
} else {
|
|
148
|
-
deferred.Reject(info[0].As<Napi::Error>().Value());
|
|
149
|
-
}
|
|
150
|
-
return info.Env().Undefined(); });
|
|
293
|
+
auto successCb = SafeCb(env, opt, "success");
|
|
294
|
+
auto errorCb = SafeCb(env, opt, "error");
|
|
151
295
|
|
|
152
|
-
auto worker = new
|
|
153
|
-
|
|
154
|
-
|
|
296
|
+
auto worker = new PrintWorker(
|
|
297
|
+
successCb,
|
|
298
|
+
errorCb,
|
|
299
|
+
[printerName, data, type, driverOpts]() -> int
|
|
155
300
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
result.status = success ? "success" : "failed";
|
|
161
|
-
worker->SetPrinterResult(result);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
worker->Queue();
|
|
165
|
-
return deferred.Promise();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
Napi::Value GetPrinters(const Napi::CallbackInfo &info)
|
|
169
|
-
{
|
|
170
|
-
Napi::Env env = info.Env();
|
|
171
|
-
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
|
|
172
|
-
|
|
173
|
-
auto callback = Napi::Function::New(env, [deferred](const Napi::CallbackInfo &info)
|
|
174
|
-
{
|
|
175
|
-
if (info[0].IsNull()) {
|
|
176
|
-
deferred.Resolve(info[1]);
|
|
177
|
-
} else {
|
|
178
|
-
deferred.Reject(info[0].As<Napi::Error>().Value());
|
|
179
|
-
}
|
|
180
|
-
return info.Env().Undefined(); });
|
|
301
|
+
auto printer = P();
|
|
302
|
+
std::string usePrinter = printerName.empty()
|
|
303
|
+
? printer->GetDefaultPrinterName()
|
|
304
|
+
: printerName;
|
|
181
305
|
|
|
182
|
-
|
|
183
|
-
callback,
|
|
184
|
-
[](PrinterWorker *worker)
|
|
185
|
-
{
|
|
186
|
-
auto printers = worker->GetPrinter()->GetPrinters();
|
|
187
|
-
worker->SetPrintersResult(printers);
|
|
306
|
+
return printer->PrintDirect(usePrinter, data, type, driverOpts);
|
|
188
307
|
});
|
|
189
308
|
|
|
190
309
|
worker->Queue();
|
|
191
|
-
return
|
|
310
|
+
return env.Undefined();
|
|
192
311
|
}
|
|
193
312
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
|
|
198
|
-
|
|
199
|
-
auto callback = Napi::Function::New(env, [deferred](const Napi::CallbackInfo &info)
|
|
200
|
-
{
|
|
201
|
-
if (info[0].IsNull()) {
|
|
202
|
-
deferred.Resolve(info[1]);
|
|
203
|
-
} else {
|
|
204
|
-
deferred.Reject(info[0].As<Napi::Error>().Value());
|
|
205
|
-
}
|
|
206
|
-
return info.Env().Undefined(); });
|
|
313
|
+
/* =========================================================
|
|
314
|
+
printFile
|
|
315
|
+
========================================================= */
|
|
207
316
|
|
|
208
|
-
|
|
209
|
-
callback,
|
|
210
|
-
[](PrinterWorker *worker)
|
|
211
|
-
{
|
|
212
|
-
auto printer = worker->GetPrinter()->GetSystemDefaultPrinter();
|
|
213
|
-
worker->SetPrinterResult(printer);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
worker->Queue();
|
|
217
|
-
return deferred.Promise();
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
Napi::Value GetStatusPrinter(const Napi::CallbackInfo &info)
|
|
317
|
+
Napi::Value printFile(const Napi::CallbackInfo &info)
|
|
221
318
|
{
|
|
222
|
-
|
|
319
|
+
auto env = info.Env();
|
|
223
320
|
|
|
224
321
|
if (info.Length() < 1 || !info[0].IsObject())
|
|
225
|
-
|
|
226
|
-
Napi::TypeError::New(env, "Expected an object as argument").ThrowAsJavaScriptException();
|
|
227
|
-
return env.Null();
|
|
228
|
-
}
|
|
322
|
+
Napi::TypeError::New(env, "options object required").ThrowAsJavaScriptException();
|
|
229
323
|
|
|
230
|
-
Napi::Object
|
|
231
|
-
|
|
232
|
-
Napi::Array propertyNames = options.GetPropertyNames();
|
|
233
|
-
for (uint32_t i = 0; i < propertyNames.Length(); i++)
|
|
234
|
-
{
|
|
235
|
-
propertyNames.Get(i).As<Napi::String>();
|
|
236
|
-
}
|
|
324
|
+
Napi::Object opt = info[0].As<Napi::Object>();
|
|
237
325
|
|
|
238
|
-
if (!
|
|
239
|
-
|
|
240
|
-
Napi::TypeError::New(env, "Object must have 'printerName' property").ThrowAsJavaScriptException();
|
|
241
|
-
return env.Null();
|
|
242
|
-
}
|
|
326
|
+
if (!opt.Has("filename") || !opt.Get("filename").IsString())
|
|
327
|
+
Napi::TypeError::New(env, "options.filename required").ThrowAsJavaScriptException();
|
|
243
328
|
|
|
244
|
-
|
|
245
|
-
{
|
|
246
|
-
Napi::TypeError::New(env, "printerName must be a string").ThrowAsJavaScriptException();
|
|
247
|
-
return env.Null();
|
|
248
|
-
}
|
|
329
|
+
std::string filename = opt.Get("filename").As<Napi::String>().Utf8Value();
|
|
249
330
|
|
|
250
|
-
std::string printerName
|
|
251
|
-
|
|
331
|
+
std::string printerName;
|
|
332
|
+
if (opt.Has("printer") && opt.Get("printer").IsString())
|
|
333
|
+
printerName = opt.Get("printer").As<Napi::String>().Utf8Value();
|
|
252
334
|
|
|
253
|
-
auto
|
|
254
|
-
|
|
255
|
-
if (info[0].IsNull()) {
|
|
256
|
-
deferred.Resolve(info[1]);
|
|
257
|
-
} else {
|
|
258
|
-
deferred.Reject(info[0].As<Napi::Error>().Value());
|
|
259
|
-
}
|
|
260
|
-
return info.Env().Undefined(); });
|
|
335
|
+
auto successCb = SafeCb(env, opt, "success");
|
|
336
|
+
auto errorCb = SafeCb(env, opt, "error");
|
|
261
337
|
|
|
262
|
-
auto worker = new
|
|
263
|
-
|
|
264
|
-
|
|
338
|
+
auto worker = new PrintWorker(
|
|
339
|
+
successCb,
|
|
340
|
+
errorCb,
|
|
341
|
+
[printerName, filename]() -> int
|
|
265
342
|
{
|
|
266
|
-
auto printer =
|
|
267
|
-
|
|
343
|
+
auto printer = P();
|
|
344
|
+
std::string usePrinter = printerName.empty()
|
|
345
|
+
? printer->GetDefaultPrinterName()
|
|
346
|
+
: printerName;
|
|
347
|
+
|
|
348
|
+
return printer->PrintFile(usePrinter, filename);
|
|
268
349
|
});
|
|
269
350
|
|
|
270
351
|
worker->Queue();
|
|
271
|
-
return
|
|
272
|
-
}
|
|
352
|
+
return env.Undefined();
|
|
353
|
+
}
|
package/src/printer_interface.h
CHANGED
|
@@ -5,13 +5,30 @@
|
|
|
5
5
|
#include <vector>
|
|
6
6
|
#include <map>
|
|
7
7
|
#include <cstdint>
|
|
8
|
+
#include <ctime>
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
using StringMap = std::map<std::string, std::string>;
|
|
11
|
+
using DriverOptions = std::map<std::string, std::map<std::string, bool>>;
|
|
12
|
+
|
|
13
|
+
struct PrinterDetailsNative {
|
|
14
|
+
std::string name;
|
|
15
|
+
bool isDefault = false;
|
|
16
|
+
StringMap options; // matches TS: options: { [k:string]: string }
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
struct JobDetailsNative {
|
|
20
|
+
int id = 0;
|
|
11
21
|
std::string name;
|
|
12
|
-
|
|
13
|
-
std::
|
|
14
|
-
std::string
|
|
22
|
+
std::string printerName;
|
|
23
|
+
std::string user;
|
|
24
|
+
std::string format;
|
|
25
|
+
int priority = 0;
|
|
26
|
+
int size = 0;
|
|
27
|
+
|
|
28
|
+
std::vector<std::string> status; // TS: JobStatus[]
|
|
29
|
+
std::time_t completedTime = 0;
|
|
30
|
+
std::time_t creationTime = 0;
|
|
31
|
+
std::time_t processingTime = 0;
|
|
15
32
|
};
|
|
16
33
|
|
|
17
34
|
class PrinterInterface
|
|
@@ -19,11 +36,32 @@ class PrinterInterface
|
|
|
19
36
|
public:
|
|
20
37
|
virtual ~PrinterInterface() = default;
|
|
21
38
|
|
|
22
|
-
|
|
23
|
-
virtual std::vector<
|
|
24
|
-
virtual
|
|
25
|
-
virtual
|
|
26
|
-
|
|
39
|
+
// Printers
|
|
40
|
+
virtual std::vector<PrinterDetailsNative> GetPrinters() = 0;
|
|
41
|
+
virtual PrinterDetailsNative GetPrinter(const std::string &printerName) = 0;
|
|
42
|
+
virtual std::string GetDefaultPrinterName() = 0;
|
|
43
|
+
|
|
44
|
+
// Driver options & paper
|
|
45
|
+
virtual DriverOptions GetPrinterDriverOptions(const std::string &printerName) = 0;
|
|
46
|
+
virtual std::string GetSelectedPaperSize(const std::string &printerName) = 0;
|
|
47
|
+
|
|
48
|
+
// Printing
|
|
49
|
+
// return jobId (>0) or 0 on failure
|
|
50
|
+
virtual int PrintDirect(const std::string &printerName,
|
|
51
|
+
const std::vector<uint8_t> &data,
|
|
52
|
+
const std::string &type,
|
|
53
|
+
const StringMap &options) = 0;
|
|
54
|
+
|
|
55
|
+
virtual int PrintFile(const std::string &printerName,
|
|
56
|
+
const std::string &filename) = 0;
|
|
57
|
+
|
|
58
|
+
// Capabilities
|
|
59
|
+
virtual std::vector<std::string> GetSupportedPrintFormats() = 0;
|
|
60
|
+
|
|
61
|
+
// Jobs
|
|
62
|
+
virtual JobDetailsNative GetJob(const std::string &printerName, int jobId) = 0;
|
|
63
|
+
virtual void SetJob(const std::string &printerName, int jobId, const std::string &command) = 0;
|
|
64
|
+
virtual std::vector<std::string> GetSupportedJobCommands() = 0;
|
|
27
65
|
};
|
|
28
66
|
|
|
29
67
|
#endif
|