enhanced-printer 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Akshay Malaviya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,313 @@
1
+ # Enhanced Printer Library
2
+
3
+ A powerful Node.js/Electron library for advanced PDF printing with job tracking, custom page sizes, and tray selection. Compatible with **Node.js 20+** and **Electron 39+**.
4
+
5
+ ## Features
6
+
7
+ ✅ **PDF Printing** - Print PDF files with full control
8
+ ✅ **Job ID Tracking** - Retrieve Windows print spooler job IDs
9
+ ✅ **Custom Page Sizes** - Support for standard and custom paper sizes
10
+ ✅ **Tray Selection** - Select specific printer trays/bins
11
+ ✅ **Default Preferences** - Automatically uses printer defaults when settings not specified
12
+ ✅ **Job Monitoring** - Query job status and manage print queue
13
+ ✅ **Electron Compatible** - Works seamlessly with Electron 39+
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install enhanced-printer
19
+ ```
20
+
21
+ > **Note**: Replace `enhanced-printer` with the actual package name you choose when publishing to npm.
22
+ > Check `PUBLISH-CHECKLIST.md` for publishing steps.
23
+
24
+ ## Requirements
25
+
26
+ - **Node.js**: 20.0.0 or higher
27
+ - **Electron**: 39.0.0 or higher (optional)
28
+ - **OS**: Windows (uses PowerShell for job tracking)
29
+
30
+ ## Quick Start
31
+
32
+ ```javascript
33
+ const { print, getPrinters } = require('enhanced-printer');
34
+
35
+ async function printPDF() {
36
+ // Get available printers
37
+ const printers = await getPrinters();
38
+ console.log('Available printers:', printers);
39
+
40
+ // Print with default settings
41
+ const result = await print({
42
+ printerName: 'Your Printer Name',
43
+ filePath: 'C:\\path\\to\\document.pdf'
44
+ });
45
+
46
+ console.log('Success:', result.success);
47
+ console.log('Job ID:', result.jobId);
48
+ }
49
+
50
+ printPDF();
51
+ ```
52
+
53
+ ## API Reference
54
+
55
+ ### `print(options: PrintOptions): Promise<PrintResult>`
56
+
57
+ Prints a PDF file with the specified options.
58
+
59
+ **Parameters:**
60
+
61
+ ```typescript
62
+ interface PrintOptions {
63
+ printerName: string; // Required: Name of the printer
64
+ filePath: string; // Required: Path to PDF file
65
+
66
+ // Optional settings - defaults to printer preferences if not specified
67
+ pageSize?: string; // e.g., "A4", "A5", "A6", "Letter", "Legal"
68
+ tray?: string | number; // Tray name or number
69
+ jobName?: string; // Document/job name for tracking
70
+ copies?: number; // Number of copies
71
+ orientation?: 'portrait' | 'landscape';
72
+ duplex?: 'simplex' | 'duplex';
73
+ monochrome?: boolean; // Black & white printing
74
+ pages?: string; // e.g., "1-3,5" to print specific pages
75
+ subset?: 'odd' | 'even'; // Print only odd or even pages
76
+ }
77
+ ```
78
+
79
+ **Returns:**
80
+
81
+ ```typescript
82
+ interface PrintResult {
83
+ success: boolean;
84
+ jobId?: number; // Job ID from print spooler (if available)
85
+ jobName: string; // Document name used for tracking
86
+ error?: string; // Error message if print failed
87
+ }
88
+ ```
89
+
90
+ **Example:**
91
+
92
+ ```javascript
93
+ const result = await print({
94
+ printerName: 'HP LaserJet',
95
+ filePath: './invoice.pdf',
96
+ pageSize: 'A4',
97
+ tray: 2,
98
+ copies: 2
99
+ });
100
+ ```
101
+
102
+ ### `getPrinters(): Promise<PrinterInfo[]>`
103
+
104
+ Gets a list of available printers.
105
+
106
+ **Returns:**
107
+
108
+ ```typescript
109
+ interface PrinterInfo {
110
+ name: string;
111
+ isDefault: boolean;
112
+ status: string;
113
+ }
114
+ ```
115
+
116
+ **Example:**
117
+
118
+ ```javascript
119
+ const printers = await getPrinters();
120
+ printers.forEach(p => {
121
+ console.log(`${p.name} - ${p.status} ${p.isDefault ? '(Default)' : ''}`);
122
+ });
123
+ ```
124
+
125
+ ### `getDefaultPrinter(): Promise<string | null>`
126
+
127
+ Gets the name of the default printer.
128
+
129
+ ### `getJobStatus(printerName: string, jobId: number): Promise<JobInfo | null>`
130
+
131
+ Gets information about a specific print job.
132
+
133
+ **Example:**
134
+
135
+ ```javascript
136
+ const jobInfo = await getJobStatus('HP LaserJet', 123);
137
+ console.log('Status:', jobInfo.status);
138
+ console.log('Pages:', jobInfo.pages);
139
+ ```
140
+
141
+ ### `getPrinterJobs(printerName: string): Promise<JobInfo[]>`
142
+
143
+ Gets all print jobs for a specific printer.
144
+
145
+ ### `cancelJob(printerName: string, jobId: number): Promise<boolean>`
146
+
147
+ Cancels a print job.
148
+
149
+ ## Usage Examples
150
+
151
+ ### Using Printer Defaults
152
+
153
+ When you don't specify optional settings, the library automatically uses the printer's default configuration:
154
+
155
+ ```javascript
156
+ // Uses printer's default page size, tray, and other settings
157
+ const result = await print({
158
+ printerName: 'My Printer',
159
+ filePath: './document.pdf'
160
+ });
161
+ ```
162
+
163
+ ### Custom Page Size with Default Tray
164
+
165
+ ```javascript
166
+ // Custom page size, but uses printer's default tray
167
+ const result = await print({
168
+ printerName: 'Label Printer',
169
+ filePath: './label.pdf',
170
+ pageSize: 'A6' // 4x6 inches for labels
171
+ // tray not specified - uses default
172
+ });
173
+ ```
174
+
175
+ ### Custom Tray with Default Page Size
176
+
177
+ ```javascript
178
+ // Specific tray, but uses printer's default page size
179
+ const result = await print({
180
+ printerName: 'Office Printer',
181
+ filePath: './document.pdf',
182
+ tray: 'Tray 2' // or use number: tray: 2
183
+ // pageSize not specified - uses default
184
+ });
185
+ ```
186
+
187
+ ### Multiple Custom Settings
188
+
189
+ ```javascript
190
+ const result = await print({
191
+ printerName: 'My Printer',
192
+ filePath: './document.pdf',
193
+ pageSize: 'Legal',
194
+ tray: 1,
195
+ copies: 3,
196
+ orientation: 'landscape',
197
+ duplex: 'duplex',
198
+ monochrome: true,
199
+ jobName: 'Important-Document'
200
+ });
201
+ ```
202
+
203
+ ### Job Tracking
204
+
205
+ ```javascript
206
+ const result = await print({
207
+ printerName: 'My Printer',
208
+ filePath: './document.pdf'
209
+ });
210
+
211
+ if (result.jobId) {
212
+ // Monitor job status
213
+ const jobInfo = await getJobStatus('My Printer', result.jobId);
214
+ console.log(`Job ${jobInfo.jobId}: ${jobInfo.status}`);
215
+
216
+ // Cancel if needed
217
+ // await cancelJob('My Printer', result.jobId);
218
+ }
219
+ ```
220
+
221
+ ## Electron Integration
222
+
223
+ See `examples/electron-integration.js` for a complete example.
224
+
225
+ **Main Process:**
226
+
227
+ ```javascript
228
+ const { ipcMain } = require('electron');
229
+ const { print, getPrinters } = require('@your-org/enhanced-printer');
230
+
231
+ ipcMain.handle('print-pdf', async (event, options) => {
232
+ return await print(options);
233
+ });
234
+
235
+ ipcMain.handle('get-printers', async () => {
236
+ return await getPrinters();
237
+ });
238
+ ```
239
+
240
+ **Renderer Process:**
241
+
242
+ ```javascript
243
+ const result = await window.printerAPI.print({
244
+ printerName: 'My Printer',
245
+ filePath: pdfPath
246
+ });
247
+ ```
248
+
249
+ ## TypeScript Support
250
+
251
+ This library is written in TypeScript and includes full type definitions.
252
+
253
+ ```typescript
254
+ import { print, PrintOptions, PrintResult } from '@your-org/enhanced-printer';
255
+
256
+ const options: PrintOptions = {
257
+ printerName: 'My Printer',
258
+ filePath: './document.pdf',
259
+ pageSize: 'A4'
260
+ };
261
+
262
+ const result: PrintResult = await print(options);
263
+ ```
264
+
265
+ ## How It Works
266
+
267
+ 1. **PDF Printing**: Uses `pdf-to-printer` library which wraps SumatraPDF on Windows
268
+ 2. **Job ID Retrieval**: Queries Windows print spooler using PowerShell commands
269
+ 3. **Default Settings**: When settings aren't specified, SumatraPDF uses the printer's DEVMODE defaults
270
+
271
+ ## Limitations
272
+
273
+ - **Windows Only**: Job ID tracking requires PowerShell (Windows-specific)
274
+ - **PDF Files**: Designed for PDF printing (for raw data, convert to PDF first)
275
+ - **Job ID Timing**: Very fast printers may complete jobs before ID can be retrieved
276
+
277
+ ## Examples
278
+
279
+ See the `examples/` directory for complete working examples:
280
+
281
+ - `basic-print.js` - Simple printing with defaults
282
+ - `custom-settings.js` - Custom page sizes, trays, and options
283
+ - `job-monitoring.js` - Job status tracking
284
+ - `electron-integration.js` - Electron app integration
285
+
286
+ ## Troubleshooting
287
+
288
+ ### Job ID is undefined
289
+
290
+ This can happen if:
291
+ - The print job completes very quickly
292
+ - The printer isn't accessible
293
+ - PowerShell execution is blocked
294
+
295
+ The library will still print successfully; only job ID retrieval may fail.
296
+
297
+ ### Custom page size not working
298
+
299
+ Ensure the page size is either:
300
+ 1. A standard size name ("A4", "Letter", etc.)
301
+ 2. A custom size that's been pre-configured in Windows printer settings
302
+
303
+ ### Printer not found
304
+
305
+ Use `getPrinters()` to see available printers and verify the exact printer name (case-sensitive).
306
+
307
+ ## License
308
+
309
+ MIT
310
+
311
+ ## Contributing
312
+
313
+ Contributions welcome! Please open an issue or pull request.
package/lib/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Enhanced Printer Library
3
+ *
4
+ * A Node.js/Electron library for advanced PDF printing with job tracking.
5
+ * Compatible with Node.js 20+ and Electron 39+.
6
+ *
7
+ * Features:
8
+ * - Print PDFs with custom page sizes and tray selection
9
+ * - Retrieve job IDs from Windows print spooler
10
+ * - Automatic use of printer defaults when settings not specified
11
+ * - Query job status and printer information
12
+ */
13
+ export { print, getPrinters, getDefaultPrinter, getJobStatus, getPrinterJobs, cancelJob } from './print-manager';
14
+ export { PrintOptions, PrintResult, PrinterInfo, JobInfo } from './types';
package/lib/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Enhanced Printer Library
4
+ *
5
+ * A Node.js/Electron library for advanced PDF printing with job tracking.
6
+ * Compatible with Node.js 20+ and Electron 39+.
7
+ *
8
+ * Features:
9
+ * - Print PDFs with custom page sizes and tray selection
10
+ * - Retrieve job IDs from Windows print spooler
11
+ * - Automatic use of printer defaults when settings not specified
12
+ * - Query job status and printer information
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.cancelJob = exports.getPrinterJobs = exports.getJobStatus = exports.getDefaultPrinter = exports.getPrinters = exports.print = void 0;
16
+ var print_manager_1 = require("./print-manager");
17
+ Object.defineProperty(exports, "print", { enumerable: true, get: function () { return print_manager_1.print; } });
18
+ Object.defineProperty(exports, "getPrinters", { enumerable: true, get: function () { return print_manager_1.getPrinters; } });
19
+ Object.defineProperty(exports, "getDefaultPrinter", { enumerable: true, get: function () { return print_manager_1.getDefaultPrinter; } });
20
+ Object.defineProperty(exports, "getJobStatus", { enumerable: true, get: function () { return print_manager_1.getJobStatus; } });
21
+ Object.defineProperty(exports, "getPrinterJobs", { enumerable: true, get: function () { return print_manager_1.getPrinterJobs; } });
22
+ Object.defineProperty(exports, "cancelJob", { enumerable: true, get: function () { return print_manager_1.cancelJob; } });
@@ -0,0 +1,13 @@
1
+ import { JobInfo } from './types';
2
+ /**
3
+ * Retrieves job ID by document name using PowerShell
4
+ */
5
+ export declare function getJobIdByName(printerName: string, jobName: string, maxRetries?: number, retryDelay?: number): Promise<number | null>;
6
+ /**
7
+ * Gets detailed information about a print job
8
+ */
9
+ export declare function getJobInfo(printerName: string, jobId: number): Promise<JobInfo | null>;
10
+ /**
11
+ * Gets all print jobs for a printer
12
+ */
13
+ export declare function getAllJobs(printerName: string): Promise<JobInfo[]>;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getJobIdByName = getJobIdByName;
4
+ exports.getJobInfo = getJobInfo;
5
+ exports.getAllJobs = getAllJobs;
6
+ const child_process_1 = require("child_process");
7
+ /**
8
+ * Retrieves job ID by document name using PowerShell
9
+ */
10
+ async function getJobIdByName(printerName, jobName, maxRetries = 3, retryDelay = 200) {
11
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
12
+ const jobId = await queryJobId(printerName, jobName);
13
+ if (jobId !== null) {
14
+ return jobId;
15
+ }
16
+ // Wait before retrying (job might not be in spooler yet)
17
+ if (attempt < maxRetries - 1) {
18
+ await sleep(retryDelay);
19
+ }
20
+ }
21
+ return null;
22
+ }
23
+ /**
24
+ * Gets detailed information about a print job
25
+ */
26
+ async function getJobInfo(printerName, jobId) {
27
+ const script = `
28
+ Get-PrintJob -PrinterName "${escapePowerShellString(printerName)}" |
29
+ Where-Object {$_.Id -eq ${jobId}} |
30
+ Select-Object Id, DocumentName, JobStatus, TotalPages, Size |
31
+ ConvertTo-Json
32
+ `;
33
+ try {
34
+ const output = await executePowerShell(script);
35
+ const result = JSON.parse(output);
36
+ if (!result || !result.Id) {
37
+ return null;
38
+ }
39
+ return {
40
+ jobId: result.Id,
41
+ jobName: result.DocumentName || '',
42
+ printerName: printerName,
43
+ status: result.JobStatus || 'Unknown',
44
+ pages: result.TotalPages || 0,
45
+ size: result.Size
46
+ };
47
+ }
48
+ catch (error) {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * Gets all print jobs for a printer
54
+ */
55
+ async function getAllJobs(printerName) {
56
+ const script = `
57
+ Get-PrintJob -PrinterName "${escapePowerShellString(printerName)}" |
58
+ Select-Object Id, DocumentName, JobStatus, TotalPages, Size |
59
+ ConvertTo-Json
60
+ `;
61
+ try {
62
+ const output = await executePowerShell(script);
63
+ const result = JSON.parse(output);
64
+ // Handle single result vs array
65
+ const jobs = Array.isArray(result) ? result : (result ? [result] : []);
66
+ return jobs.map((job) => ({
67
+ jobId: job.Id,
68
+ jobName: job.DocumentName || '',
69
+ printerName: printerName,
70
+ status: job.JobStatus || 'Unknown',
71
+ pages: job.TotalPages || 0,
72
+ size: job.Size
73
+ }));
74
+ }
75
+ catch (error) {
76
+ return [];
77
+ }
78
+ }
79
+ /**
80
+ * Query job ID by document name
81
+ */
82
+ async function queryJobId(printerName, jobName) {
83
+ const script = `
84
+ Get-PrintJob -PrinterName "${escapePowerShellString(printerName)}" |
85
+ Where-Object {$_.DocumentName -eq "${escapePowerShellString(jobName)}"} |
86
+ Select-Object Id |
87
+ ConvertTo-Json
88
+ `;
89
+ try {
90
+ const output = await executePowerShell(script);
91
+ const result = JSON.parse(output);
92
+ return result?.Id || null;
93
+ }
94
+ catch (error) {
95
+ return null;
96
+ }
97
+ }
98
+ /**
99
+ * Executes a PowerShell script and returns output
100
+ */
101
+ function executePowerShell(script) {
102
+ return new Promise((resolve, reject) => {
103
+ const ps = (0, child_process_1.spawn)('powershell.exe', [
104
+ '-NoProfile',
105
+ '-NonInteractive',
106
+ '-Command',
107
+ script
108
+ ]);
109
+ let output = '';
110
+ let errorOutput = '';
111
+ ps.stdout.on('data', (data) => {
112
+ output += data.toString();
113
+ });
114
+ ps.stderr.on('data', (data) => {
115
+ errorOutput += data.toString();
116
+ });
117
+ ps.on('close', (code) => {
118
+ if (code === 0 && output.trim()) {
119
+ resolve(output.trim());
120
+ }
121
+ else {
122
+ reject(new Error(`PowerShell error: ${errorOutput || 'Unknown error'}`));
123
+ }
124
+ });
125
+ ps.on('error', (err) => {
126
+ reject(err);
127
+ });
128
+ });
129
+ }
130
+ /**
131
+ * Escapes string for use in PowerShell
132
+ */
133
+ function escapePowerShellString(str) {
134
+ return str.replace(/["'`$]/g, '`$&');
135
+ }
136
+ /**
137
+ * Sleep utility
138
+ */
139
+ function sleep(ms) {
140
+ return new Promise(resolve => setTimeout(resolve, ms));
141
+ }
@@ -0,0 +1,25 @@
1
+ import { PrintOptions, PrintResult, PrinterInfo, JobInfo } from './types';
2
+ /**
3
+ * Prints a PDF file with the specified options
4
+ */
5
+ export declare function print(options: PrintOptions): Promise<PrintResult>;
6
+ /**
7
+ * Gets a list of available printers
8
+ */
9
+ export declare function getPrinters(): Promise<PrinterInfo[]>;
10
+ /**
11
+ * Gets the default printer name
12
+ */
13
+ export declare function getDefaultPrinter(): Promise<string | null>;
14
+ /**
15
+ * Gets information about a specific print job
16
+ */
17
+ export declare function getJobStatus(printerName: string, jobId: number): Promise<JobInfo | null>;
18
+ /**
19
+ * Gets all print jobs for a specific printer
20
+ */
21
+ export declare function getPrinterJobs(printerName: string): Promise<JobInfo[]>;
22
+ /**
23
+ * Cancels a print job
24
+ */
25
+ export declare function cancelJob(printerName: string, jobId: number): Promise<boolean>;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.print = print;
7
+ exports.getPrinters = getPrinters;
8
+ exports.getDefaultPrinter = getDefaultPrinter;
9
+ exports.getJobStatus = getJobStatus;
10
+ exports.getPrinterJobs = getPrinterJobs;
11
+ exports.cancelJob = cancelJob;
12
+ const pdf_to_printer_1 = __importDefault(require("pdf-to-printer"));
13
+ const uuid_1 = require("uuid");
14
+ const child_process_1 = require("child_process");
15
+ const job_tracker_1 = require("./job-tracker");
16
+ /**
17
+ * Prints a PDF file with the specified options
18
+ */
19
+ async function print(options) {
20
+ try {
21
+ // Validate required options
22
+ if (!options.printerName) {
23
+ return {
24
+ success: false,
25
+ jobName: '',
26
+ error: 'Printer name is required'
27
+ };
28
+ }
29
+ if (!options.filePath) {
30
+ return {
31
+ success: false,
32
+ jobName: '',
33
+ error: 'File path is required'
34
+ };
35
+ }
36
+ // Generate unique job name if not provided
37
+ const jobName = options.jobName || `PrintJob_${(0, uuid_1.v4)()}`;
38
+ // Build pdf-to-printer options
39
+ // Only include settings that user explicitly provided
40
+ const printOptions = {
41
+ printer: options.printerName
42
+ };
43
+ // Optional settings - only add if provided
44
+ if (options.pageSize !== undefined) {
45
+ printOptions.paperSize = options.pageSize;
46
+ }
47
+ if (options.tray !== undefined) {
48
+ printOptions.bin = options.tray;
49
+ }
50
+ if (options.copies !== undefined) {
51
+ printOptions.copies = options.copies;
52
+ }
53
+ if (options.orientation !== undefined) {
54
+ printOptions.orientation = options.orientation;
55
+ }
56
+ if (options.duplex !== undefined) {
57
+ printOptions.side = options.duplex;
58
+ }
59
+ if (options.monochrome !== undefined) {
60
+ printOptions.monochrome = options.monochrome;
61
+ }
62
+ if (options.pages !== undefined) {
63
+ printOptions.pages = options.pages;
64
+ }
65
+ if (options.subset !== undefined) {
66
+ printOptions.subset = options.subset;
67
+ }
68
+ // Set the document name for job tracking
69
+ printOptions.win32 = ['-print-settings', `${jobName}`];
70
+ // Print the document
71
+ await pdf_to_printer_1.default.print(options.filePath, printOptions);
72
+ // Try to retrieve job ID
73
+ const jobId = await (0, job_tracker_1.getJobIdByName)(options.printerName, jobName);
74
+ return {
75
+ success: true,
76
+ jobId: jobId || undefined,
77
+ jobName: jobName
78
+ };
79
+ }
80
+ catch (error) {
81
+ return {
82
+ success: false,
83
+ jobName: options.jobName || '',
84
+ error: error.message || 'Unknown error occurred'
85
+ };
86
+ }
87
+ }
88
+ /**
89
+ * Gets a list of available printers
90
+ */
91
+ async function getPrinters() {
92
+ const script = `
93
+ Get-Printer | Select-Object Name, PrinterStatus, Default |
94
+ ConvertTo-Json
95
+ `;
96
+ try {
97
+ const output = await executePowerShell(script);
98
+ const result = JSON.parse(output);
99
+ // Handle single result vs array
100
+ const printers = Array.isArray(result) ? result : (result ? [result] : []);
101
+ return printers.map((printer) => ({
102
+ name: printer.Name,
103
+ isDefault: printer.Default === true,
104
+ status: printer.PrinterStatus || 'Unknown'
105
+ }));
106
+ }
107
+ catch (error) {
108
+ return [];
109
+ }
110
+ }
111
+ /**
112
+ * Gets the default printer name
113
+ */
114
+ async function getDefaultPrinter() {
115
+ const printers = await getPrinters();
116
+ const defaultPrinter = printers.find(p => p.isDefault);
117
+ return defaultPrinter ? defaultPrinter.name : null;
118
+ }
119
+ /**
120
+ * Gets information about a specific print job
121
+ */
122
+ async function getJobStatus(printerName, jobId) {
123
+ return (0, job_tracker_1.getJobInfo)(printerName, jobId);
124
+ }
125
+ /**
126
+ * Gets all print jobs for a specific printer
127
+ */
128
+ async function getPrinterJobs(printerName) {
129
+ return (0, job_tracker_1.getAllJobs)(printerName);
130
+ }
131
+ /**
132
+ * Cancels a print job
133
+ */
134
+ async function cancelJob(printerName, jobId) {
135
+ const script = `
136
+ Remove-PrintJob -PrinterName "${escapePowerShellString(printerName)}" -ID ${jobId}
137
+ `;
138
+ try {
139
+ await executePowerShell(script);
140
+ return true;
141
+ }
142
+ catch (error) {
143
+ return false;
144
+ }
145
+ }
146
+ /**
147
+ * Executes a PowerShell script and returns output
148
+ */
149
+ function executePowerShell(script) {
150
+ return new Promise((resolve, reject) => {
151
+ const ps = (0, child_process_1.spawn)('powershell.exe', [
152
+ '-NoProfile',
153
+ '-NonInteractive',
154
+ '-Command',
155
+ script
156
+ ]);
157
+ let output = '';
158
+ let errorOutput = '';
159
+ ps.stdout.on('data', (data) => {
160
+ output += data.toString();
161
+ });
162
+ ps.stderr.on('data', (data) => {
163
+ errorOutput += data.toString();
164
+ });
165
+ ps.on('close', (code) => {
166
+ if (code === 0 && output.trim()) {
167
+ resolve(output.trim());
168
+ }
169
+ else {
170
+ reject(new Error(`PowerShell error: ${errorOutput || 'Unknown error'}`));
171
+ }
172
+ });
173
+ ps.on('error', (err) => {
174
+ reject(err);
175
+ });
176
+ });
177
+ }
178
+ /**
179
+ * Escapes string for use in PowerShell
180
+ */
181
+ function escapePowerShellString(str) {
182
+ return str.replace(/["'`$]/g, '`$&');
183
+ }
package/lib/types.d.ts ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Information about a printer
3
+ */
4
+ export interface PrinterInfo {
5
+ name: string;
6
+ isDefault: boolean;
7
+ status: string;
8
+ defaultPageSize?: string;
9
+ defaultTray?: string;
10
+ }
11
+ /**
12
+ * Options for printing a document
13
+ */
14
+ export interface PrintOptions {
15
+ /** Name of the printer to use */
16
+ printerName: string;
17
+ /** Path to PDF file to print */
18
+ filePath: string;
19
+ /**
20
+ * Paper size (optional - defaults to printer's default)
21
+ * Examples: "A4", "A5", "A6", "Letter", "Legal", "Tabloid"
22
+ */
23
+ pageSize?: string;
24
+ /**
25
+ * Tray/bin selection (optional - defaults to printer's default)
26
+ * Can be tray number (1, 2, 3...) or tray name
27
+ */
28
+ tray?: string | number;
29
+ /**
30
+ * Document/job name for tracking (optional - auto-generated if not provided)
31
+ */
32
+ jobName?: string;
33
+ /** Number of copies (optional - defaults to 1) */
34
+ copies?: number;
35
+ /** Page orientation (optional) */
36
+ orientation?: 'portrait' | 'landscape';
37
+ /** Duplex printing mode (optional) */
38
+ duplex?: 'simplex' | 'duplex';
39
+ /** Print in monochrome/black & white (optional) */
40
+ monochrome?: boolean;
41
+ /** Print specific pages (optional, e.g., "1-3,5") */
42
+ pages?: string;
43
+ /** Print only odd or even pages (optional) */
44
+ subset?: 'odd' | 'even';
45
+ }
46
+ /**
47
+ * Result of a print operation
48
+ */
49
+ export interface PrintResult {
50
+ /** Whether the print was successful */
51
+ success: boolean;
52
+ /** Job ID from Windows print spooler (may be undefined if retrieval failed) */
53
+ jobId?: number;
54
+ /** Document/job name used for tracking */
55
+ jobName: string;
56
+ /** Error message if print failed */
57
+ error?: string;
58
+ }
59
+ /**
60
+ * Information about a print job
61
+ */
62
+ export interface JobInfo {
63
+ /** Job ID in the print queue */
64
+ jobId: number;
65
+ /** Document name */
66
+ jobName: string;
67
+ /** Name of the printer */
68
+ printerName: string;
69
+ /** Current status of the job */
70
+ status: string;
71
+ /** Number of pages */
72
+ pages: number;
73
+ /** Size in bytes */
74
+ size?: number;
75
+ }
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "enhanced-printer",
3
+ "version": "1.0.0",
4
+ "description": "Advanced PDF printing library with job tracking, custom page sizes, and tray selection for Node.js and Electron",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "files": [
8
+ "lib/**/*",
9
+ "README.md",
10
+ "LICENSE"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "watch": "tsc --watch",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "printer",
19
+ "print",
20
+ "printing",
21
+ "pdf",
22
+ "pdf-printer",
23
+ "electron",
24
+ "windows",
25
+ "job-tracking",
26
+ "print-spooler",
27
+ "tray-selection",
28
+ "page-size",
29
+ "typescript"
30
+ ],
31
+ "engines": {
32
+ "node": ">=20.0.0"
33
+ },
34
+ "os": [
35
+ "win32"
36
+ ],
37
+ "dependencies": {
38
+ "pdf-to-printer": "^5.6.1",
39
+ "uuid": "^10.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.17.10",
43
+ "@types/uuid": "^10.0.0",
44
+ "typescript": "^5.7.3"
45
+ },
46
+ "author": "Akshay Malaviya",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/akshaymalaviya/enhanced-printer.git"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/akshaymalaviya/enhanced-printer/issues"
54
+ },
55
+ "homepage": "https://github.com/akshaymalaviya/enhanced-printer#readme"
56
+ }