isahaq-barcode 1.8.0 โ†’ 2.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/README.md CHANGED
@@ -1,302 +1,281 @@
1
1
  # Isahaq Barcode Generator
2
2
 
3
- > A comprehensive Node.js barcode generation library supporting 32+ barcode types with Express.js integration and CLI tools
3
+ > Barcode and QR code generation for Node.js and the browser. 45 symbologies, PNG / SVG / HTML / PDF output, a CLI, and a builder for QR codes with logos and watermarks.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/isahaq-barcode.svg)](https://www.npmjs.com/package/isahaq-barcode)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
- ---
9
-
10
- ## Table of Contents
11
-
12
- - [Features](#-features)
13
- - [Installation](#-installation)
14
- - [Quick Start](#-quick-start)
15
- - [Supported Barcode Types](#-supported-barcode-types)
16
- - [Usage Examples](#-usage-examples)
17
- - [Express.js Integration](#-expressjs-integration)
18
- - [CLI Usage](#-cli-usage)
19
- - [API Reference](#-api-reference)
20
- - [Contributing](#-contributing)
8
+ Encoding is done by [bwip-js](https://github.com/metafloor/bwip-js) (a port of the
9
+ BWIPP reference implementation), so every advertised type and output format
10
+ produces a real, scannable symbology. `npm run verify:scan` proves it by decoding
11
+ generated barcodes with ZXing.
21
12
 
22
13
  ---
23
14
 
24
- ## โœจ Features
25
-
26
- | Feature | Description |
27
- | --------------------- | -------------------------------------------------------- |
28
- | **32+ Barcode Types** | Linear, 2D, postal, stacked, and auto-detection variants |
29
- | **Multiple Formats** | PNG, SVG, HTML, JPG, PDF output support |
30
- | **Framework Ready** | Express.js middleware and route helpers included |
31
- | **CLI Tool** | Generate barcodes directly from terminal |
32
- | **Advanced QR Codes** | Logos, watermarks, labels, and customization |
33
- | **Validation** | Built-in data validation for all barcode types |
34
- | **Batch Processing** | Generate multiple barcodes simultaneously |
35
- | **High Performance** | Optimized for enterprise-scale generation |
15
+ ## Contents
16
+
17
+ - [Installation](#installation)
18
+ - [Quick start](#quick-start)
19
+ - [Upgrading from 1.x](#upgrading-from-1x)
20
+ - [Supported barcode types](#supported-barcode-types)
21
+ - [Output formats](#output-formats)
22
+ - [Render options](#render-options)
23
+ - [QR codes with logos, labels and watermarks](#qr-codes-with-logos-labels-and-watermarks)
24
+ - [Validation](#validation)
25
+ - [Batch generation](#batch-generation)
26
+ - [Express.js integration](#expressjs-integration)
27
+ - [Browser usage](#browser-usage)
28
+ - [CLI](#cli)
29
+ - [TypeScript](#typescript)
30
+ - [API reference](#api-reference)
31
+ - [Development](#development)
36
32
 
37
33
  ---
38
34
 
39
- ## ๐Ÿ“ฆ Installation
35
+ ## Installation
40
36
 
41
37
  ```bash
42
38
  npm install isahaq-barcode
43
39
  ```
44
40
 
45
- **Requirements:** Node.js 18.0 or higher
41
+ Requires Node.js 18 or newer.
46
42
 
47
- ## ๐ŸŒ Universal Compatibility
43
+ `canvas` is an **optional** dependency. It is only needed for QR codes that
44
+ composite a logo, label or watermark. Everything else - all barcode types, all
45
+ output formats, plain QR codes - works without it, so installs never fail on a
46
+ missing native toolchain.
48
47
 
49
- > **Great News:** This package now works in **both Node.js and browser environments**!
48
+ ```bash
49
+ npm install canvas # only if you need QR logos/labels/watermarks
50
+ ```
50
51
 
51
- ### โœ… Server-Side (Node.js)
52
+ ## Quick start
52
53
 
53
- - **Full Features**: All barcode types, formats, and advanced features
54
- - **Canvas Support**: High-quality image generation with Node.js canvas
55
- - **File Operations**: Save files directly to filesystem
56
- - **CLI Tools**: Command-line interface available
54
+ ```javascript
55
+ const fs = require('fs/promises');
56
+ const BarcodeGenerator = require('isahaq-barcode');
57
57
 
58
- ### โœ… Client-Side (Browser)
58
+ // PNG (returns a Promise<Buffer>)
59
+ await fs.writeFile(
60
+ 'code128.png',
61
+ await BarcodeGenerator.png('1234567890', 'code128')
62
+ );
59
63
 
60
- - **Core Features**: PNG, SVG, HTML generation
61
- - **QR Codes**: Full QR code generation with customization
62
- - **Barcode Types**: Code128, Code39, EAN13, UPC, and more
63
- - **No Dependencies**: Works with just jsbarcode and qrcode
64
+ // SVG - async or sync, whichever suits the call site
65
+ const svg = await BarcodeGenerator.svg('5901234123457', 'ean13');
66
+ const svgNow = BarcodeGenerator.svgSync('5901234123457', 'ean13');
64
67
 
65
- ### Recommended Usage Patterns
68
+ // HTML fragment with an inline SVG
69
+ const html = BarcodeGenerator.htmlSync('1234567890', 'code128');
66
70
 
67
- **โœ… Server-Side (Recommended):**
71
+ // PDF
72
+ await fs.writeFile(
73
+ 'label.pdf',
74
+ await BarcodeGenerator.pdf('1234567890', 'code128', { fitToBarcode: true })
75
+ );
68
76
 
69
- ```javascript
70
- // Node.js/Express.js server
71
- const BarcodeGenerator = require('isahaq-barcode');
72
-
73
- // Generate barcode on server
74
- app.get('/barcode/:data', (req, res) => {
75
- const barcode = BarcodeGenerator.png(req.params.data, 'code128');
76
- res.set('Content-Type', 'image/png');
77
- res.send(barcode);
77
+ // 2D symbologies - size them in pixels
78
+ const qr = await BarcodeGenerator.png('https://example.com', 'qrcode', {
79
+ size: 400,
80
+ });
81
+ const dm = await BarcodeGenerator.svg('SHIPMENT-000123', 'datamatrix', {
82
+ size: 200,
78
83
  });
79
84
  ```
80
85
 
81
- **โœ… Next.js API Routes:**
86
+ ## Upgrading from 1.x
82
87
 
83
- ```javascript
84
- // pages/api/barcode.js or app/api/barcode/route.js
85
- import BarcodeGenerator from 'isahaq-barcode';
86
-
87
- export default function handler(req, res) {
88
- const barcode = BarcodeGenerator.png(req.query.data, 'code128');
89
- res.setHeader('Content-Type', 'image/png');
90
- res.send(barcode);
91
- }
92
- ```
93
-
94
- **โœ… Client-Side (Browser/React/Vue):**
88
+ Version 2 rewrote the rendering core. In 1.x only PNG output was a real barcode:
89
+ SVG, HTML and PDF drew decorative bars from character codes, and unsupported
90
+ types silently produced a Code 128. Fixing that required two API changes:
95
91
 
96
92
  ```javascript
97
- // Browser/React/Vue components
98
- import BarcodeGenerator from 'isahaq-barcode';
93
+ // 1.x - synchronous
94
+ const buffer = BarcodeGenerator.png('1234567890', 'code128');
95
+ const svg = BarcodeGenerator.svg('1234567890', 'code128');
96
+ const results = BarcodeGenerator.batch(items);
99
97
 
100
- // Generate barcode in browser
101
- const generateBarcode = async () => {
102
- const barcode = await BarcodeGenerator.png('123456789', 'code128');
103
- // Use the barcode buffer
104
- };
98
+ // 2.x - promises, with sync variants for the text formats
99
+ const buffer = await BarcodeGenerator.png('1234567890', 'code128');
100
+ const svg = BarcodeGenerator.svgSync('1234567890', 'code128'); // or await .svg(...)
101
+ const results = await BarcodeGenerator.batch(items);
105
102
  ```
106
103
 
107
- ### Alternative for Client-Side
104
+ See the [CHANGELOG](CHANGELOG.md) for the full list, including the removal of the
105
+ `jpg`/`jpeg` render formats (they never worked) and the corrected EAN-8 / UPC-A
106
+ check digit validation.
108
107
 
109
- For browser-based barcode generation, consider:
108
+ ## Supported barcode types
110
109
 
111
- - **jsbarcode** - Client-side barcode generation
112
- - **qrcode** - Client-side QR code generation
113
- - **Server-side API** - Use this package on your backend
110
+ 45 types across six categories. `BarcodeGenerator.getBarcodeTypeInfo(type)`
111
+ returns the metadata for any of them.
114
112
 
115
- **Global CLI Installation:**
113
+ | Category | Types |
114
+ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115
+ | **Linear** | `code128`, `code128a`, `code128b`, `code128c`, `code128auto`, `code39`, `code39extended`, `code39checksum`, `code39auto`, `code93`, `code25`, `code25auto`, `code32`, `standard25`, `standard25checksum`, `interleaved25`, `interleaved25checksum`, `interleaved25auto`, `msi`, `msichecksum`, `msiauto` |
116
+ | **EAN / UPC** | `ean13`, `ean8`, `ean2`, `ean5`, `upca`, `upce`, `itf14` |
117
+ | **Postal** | `postnet`, `planet`, `rms4cc`, `kix`, `imb` |
118
+ | **Specialized** | `codabar`, `code11`, `pharmacode`, `pharmacodetwotracks` |
119
+ | **2D matrix** | `qrcode`, `datamatrix`, `aztec`, `pdf417`, `microqr`, `maxicode` |
120
+ | **Stacked** | `code16k`, `code49` |
116
121
 
117
- ```bash
118
- npm install -g isahaq-barcode
122
+ ```javascript
123
+ BarcodeGenerator.getBarcodeTypes(); // all 45 ids
124
+ BarcodeGenerator.getBarcodeCategories(); // ['LINEAR', 'EAN_UPC', ...]
125
+ BarcodeGenerator.getBarcodeTypesByCategory('matrix_2d'); // ['qrcode', 'datamatrix', ...]
126
+
127
+ BarcodeGenerator.getBarcodeTypeInfo('ean13');
128
+ // {
129
+ // type: 'ean13', name: 'EAN-13', category: 'EAN_UPC', symbology: 'ean13',
130
+ // description: 'EAN-13 - European Article Number',
131
+ // minLength: 12, maxLength: 13, charset: 'Numeric'
132
+ // }
119
133
  ```
120
134
 
121
- ---
135
+ ## Output formats
122
136
 
123
- ## ๐Ÿš€ Quick Start
137
+ | Format | Method | Returns |
138
+ | ------ | ----------------------- | ---------------------------- |
139
+ | `png` | `png()` | `Promise<Buffer>` |
140
+ | `svg` | `svg()` / `svgSync()` | `Promise<string>` / `string` |
141
+ | `html` | `html()` / `htmlSync()` | `Promise<string>` / `string` |
142
+ | `pdf` | `pdf()` | `Promise<Buffer>` |
124
143
 
125
- ```javascript
126
- const BarcodeGenerator = require('isahaq-barcode');
127
-
128
- // Generate PNG barcode
129
- const pngBuffer = BarcodeGenerator.png('1234567890', 'code128');
144
+ `generate()` takes the format as an argument:
130
145
 
131
- // Generate SVG barcode
132
- const svgString = BarcodeGenerator.svg('1234567890', 'ean13');
133
-
134
- // Generate QR code with logo
135
- const qrCode = BarcodeGenerator.modernQr({
136
- data: 'https://example.com',
137
- size: 300,
138
- logoPath: 'path/to/logo.png',
139
- label: 'Scan me!',
146
+ ```javascript
147
+ const output = await BarcodeGenerator.generate('1234567890', 'code128', 'pdf', {
148
+ pageSize: 'A4',
140
149
  });
141
-
142
- await qrCode.saveToFile('qr-code.png');
143
150
  ```
144
151
 
145
- ---
146
-
147
- ## ๐Ÿ“Š Supported Barcode Types
148
-
149
- ### Linear Barcodes (1D)
150
-
151
- | Type | Variants | Use Case |
152
- | -------------- | ---------------------------------- | ----------------------------- |
153
- | **Code 128** | A, B, C, Auto | General purpose, high density |
154
- | **Code 39** | Standard, Extended, Checksum, Auto | Alphanumeric, automotive |
155
- | **Code 93** | - | Compact alphanumeric |
156
- | **EAN Family** | EAN-13, EAN-8, EAN-2, EAN-5 | Retail products (Europe) |
157
- | **UPC Family** | UPC-A, UPC-E | Retail products (USA) |
158
- | **Code 25** | Standard, Interleaved, Auto | Industrial, logistics |
159
- | **ITF-14** | - | Shipping containers |
160
- | **MSI** | Standard, Checksum, Auto | Inventory management |
161
- | **Codabar** | - | Libraries, blood banks |
162
- | **Code 11** | - | Telecommunications |
163
-
164
- ### 2D Barcodes
165
-
166
- | Type | Data Capacity | Use Case |
167
- | --------------- | ----------------- | ----------------------- |
168
- | **QR Code** | Up to 4,296 chars | URLs, payments, general |
169
- | **Data Matrix** | Up to 2,335 chars | Small item marking |
170
- | **Aztec** | Up to 3,832 chars | Transport tickets |
171
- | **PDF417** | Up to 1,850 chars | IDs, boarding passes |
172
- | **Micro QR** | Up to 35 chars | Compact applications |
173
- | **MaxiCode** | Up to 93 chars | Package tracking |
174
-
175
- ### Postal Barcodes
152
+ ## Render options
176
153
 
177
- **POSTNET** โ€ข **PLANET** โ€ข **RMS4CC** โ€ข **KIX** โ€ข **IMB**
154
+ ```javascript
155
+ await BarcodeGenerator.png('1234567890', 'code128', {
156
+ width: 3, // module (narrow bar) width in px default 2
157
+ height: 140, // bar height in px, 1D only default 100
158
+ size: 400, // target size in px, 2D/stacked only
159
+ displayValue: true, // print the human readable text default true
160
+ fontSize: 24, // text size in px default 20
161
+ textAlign: 'center', // center | left | right | justify
162
+ textMargin: 2, // gap between bars and text in px
163
+ textColor: '#1d3557', // defaults to lineColor
164
+ lineColor: '#1d3557', // bar colour default #000000
165
+ background: '#f1faee', // background colour default #ffffff
166
+ margin: 24, // quiet zone in px, or use quietZone
167
+ marginTop: 10, // per-side overrides
168
+ quietZone: 10, // quiet zone in modules default 10
169
+ rotate: 'N', // N | R | L | I
170
+ });
171
+ ```
178
172
 
179
- ### Specialized
173
+ **Quiet zone:** when no `margin` is given, the quiet zone is `quietZone` modules
174
+ (10 by default) rather than a fixed pixel count. Most specifications require at
175
+ least 10 narrow modules of clear space, and scanners reject codes with less. Pass
176
+ `margin` in pixels when you need an exact figure, or `margin: 0` for none.
180
177
 
181
- **Code 32** (Italian Pharmacode) โ€ข **PharmaCode** โ€ข **PharmaCodeTwoTracks** โ€ข **Code 16K** โ€ข **Code 49**
178
+ **2D symbologies** keep their own aspect ratio: `height` does not apply, and
179
+ `size` is honoured by scaling the module size to the nearest whole number, so the
180
+ result lands close to - not exactly on - the requested pixel size.
182
181
 
183
- ---
182
+ PDF-only options: `pageWidth`, `pageHeight`, `pageSize` (for example `'A4'`),
183
+ `fitToBarcode` (size the page to the barcode plus its margins) and `title`.
184
184
 
185
- ## ๐Ÿ’ป Usage Examples
185
+ HTML-only options: `id`, `className`, `includeStyles`.
186
186
 
187
- ### Basic Generation
187
+ Anything the encoder itself understands can be passed straight through:
188
188
 
189
189
  ```javascript
190
- const BarcodeGenerator = require('isahaq-barcode');
191
-
192
- // PNG with custom options
193
- const barcode = BarcodeGenerator.png('1234567890', 'code128', {
194
- width: 3,
195
- height: 150,
196
- displayValue: true,
197
- foregroundColor: '#000000',
198
- backgroundColor: '#FFFFFF',
199
- margin: 10,
190
+ await BarcodeGenerator.png('1234567890', 'code128', {
191
+ bwipOptions: { alttext: 'custom caption' },
200
192
  });
201
-
202
- // Convert to Base64 for web display
203
- const base64Image = barcode.toString('base64');
204
- console.log(`<img src="data:image/png;base64,${base64Image}" alt="Barcode" />`);
205
193
  ```
206
194
 
207
- ### Advanced QR Code with Logo
208
-
209
- ```javascript
210
- const qrCode = BarcodeGenerator.modernQr({
211
- data: 'https://example.com',
212
- size: 300,
213
- margin: 10,
195
+ ## QR codes with logos, labels and watermarks
214
196
 
215
- // Logo configuration
216
- logoPath: 'path/to/logo.png',
217
- logoSize: 60, // Percentage
197
+ `qrCode()` / `modernQr()` return a chainable builder. Plain codes need no extra
198
+ dependencies; a logo, label or watermark requires the optional `canvas` package.
218
199
 
219
- // Text elements
220
- label: 'Scan me!',
221
- watermark: 'Company Name',
222
- watermarkPosition: 'bottom-center',
223
-
224
- // Colors
225
- foregroundColor: [0, 0, 0],
226
- backgroundColor: [255, 255, 255],
227
-
228
- // Error correction (H recommended for logos)
200
+ ```javascript
201
+ const buffer = await BarcodeGenerator.qrCode('https://example.com', {
202
+ size: 400,
229
203
  errorCorrectionLevel: 'H',
230
- });
204
+ }).generate();
231
205
 
232
- // Save to file
233
- await qrCode.saveToFile('qr-code.png');
206
+ // Or with the builder API
207
+ const QrCodeBuilder = BarcodeGenerator.QrCodeBuilder;
234
208
 
235
- // Get as data URI
236
- const dataUri = await qrCode.getDataUri();
209
+ await QrCodeBuilder.create()
210
+ .data('https://example.com')
211
+ .size(400)
212
+ .margin(12)
213
+ .errorCorrectionLevel('H')
214
+ .foregroundColor([29, 53, 87]) // RGB array or '#1d3557'
215
+ .backgroundColor('#ffffff')
216
+ .logoPath('./logo.png') // path, URL or data URI
217
+ .logoSize(20) // percent of the QR code
218
+ .label('Scan me!')
219
+ .watermark('DRAFT', 'center')
220
+ .saveToFile('qr.png');
221
+
222
+ // Other outputs
223
+ const svg = await BarcodeGenerator.modernQr({
224
+ data: 'x',
225
+ format: 'svg',
226
+ }).generate();
227
+ const uri = await BarcodeGenerator.modernQr({ data: 'x' }).getDataUri();
237
228
  ```
238
229
 
239
- ### QR Code Builder Pattern
230
+ Watermark positions: `top-left`, `top-center`, `top-right`, `left-center`,
231
+ `center`, `right-center`, `bottom-left`, `bottom-center`, `bottom-right`
232
+ (`getWatermarkPositions()`).
240
233
 
241
- ```javascript
242
- const { QrCodeBuilder } = require('isahaq-barcode');
234
+ Keep `logoSize` at or below roughly 25%. A larger logo covers too many modules
235
+ for the error correction to recover, and the code stops scanning.
243
236
 
244
- const qrCode = QrCodeBuilder.create()
245
- .data('https://example.com')
246
- .size(300)
247
- .margin(10)
248
- .foregroundColor([0, 0, 0])
249
- .backgroundColor([255, 255, 255])
250
- .logoPath('path/to/logo.png')
251
- .logoSize(60)
252
- .label('Scan me!')
253
- .watermark('Watermark Text', 'center')
254
- .format('png')
255
- .build();
237
+ ## Validation
256
238
 
257
- await qrCode.saveToFile('qr-code.png');
258
- ```
259
-
260
- ### Batch Generation
239
+ Validation runs automatically before generation, and is also available directly:
261
240
 
262
241
  ```javascript
263
- const items = [
264
- { data: '1234567890', type: 'code128', format: 'png' },
265
- { data: '9876543210', type: 'code39', format: 'svg' },
266
- { data: 'https://example.com', type: 'qrcode', format: 'png' },
267
- ];
242
+ BarcodeGenerator.validate('5901234123457', 'ean13');
243
+ // { valid: true, data: '5901234123457', type: 'ean13', length: 13, charset: 'Numeric' }
268
244
 
269
- const results = BarcodeGenerator.batch(items);
245
+ BarcodeGenerator.validate('1234567890123', 'ean13');
246
+ // { valid: false, error: 'Invalid EAN-13 check digit (expected 8)' }
270
247
 
271
- results.forEach((result, index) => {
272
- if (result.success) {
273
- console.log(`โœ“ Barcode ${index} generated`);
274
- // result.data contains the generated barcode
275
- } else {
276
- console.error(`โœ— Barcode ${index} failed: ${result.error}`);
277
- }
278
- });
248
+ BarcodeGenerator.validate('123', 'ean13');
249
+ // { valid: false, error: 'Data too short. Minimum length: 12' }
279
250
  ```
280
251
 
281
- ### Data Validation
252
+ EAN-13, EAN-8, UPC-A and ITF-14 accept the code with or without its trailing
253
+ check digit; when one is supplied it is verified.
282
254
 
283
- ```javascript
284
- const validation = BarcodeGenerator.validate('1234567890', 'code128');
285
-
286
- if (validation.valid) {
287
- console.log('โœ“ Valid data');
288
- console.log(` Length: ${validation.length}`);
289
- console.log(` Charset: ${validation.charset}`);
290
- } else {
291
- console.error(`โœ— Invalid: ${validation.error}`);
292
- }
293
- ```
255
+ ## Batch generation
294
256
 
295
- ---
257
+ Per-item failures are reported in the result rather than rejecting the batch:
296
258
 
297
- ## ๐ŸŒ Express.js Integration
259
+ ```javascript
260
+ const results = await BarcodeGenerator.batch([
261
+ { data: '1234567890', type: 'code128', format: 'png' },
262
+ {
263
+ data: '5901234123457',
264
+ type: 'ean13',
265
+ format: 'svg',
266
+ options: { width: 3 },
267
+ },
268
+ { data: 'nope', type: 'ean13', format: 'png' },
269
+ ]);
270
+
271
+ // [
272
+ // { index: 0, success: true, result: <Buffer ...>, data: '1234567890', type: 'code128', format: 'png' },
273
+ // { index: 1, success: true, result: '<svg ...', data: '5901234123457', type: 'ean13', format: 'svg' },
274
+ // { index: 2, success: false, error: 'Invalid data for ean13: Data too short. Minimum length: 12', ... }
275
+ // ]
276
+ ```
298
277
 
299
- ### Basic Route Implementation
278
+ ## Express.js integration
300
279
 
301
280
  ```javascript
302
281
  const express = require('express');
@@ -304,361 +283,182 @@ const BarcodeGenerator = require('isahaq-barcode');
304
283
 
305
284
  const app = express();
306
285
 
307
- // Barcode endpoint
308
- app.get('/barcode/:data', (req, res) => {
309
- const { data } = req.params;
286
+ app.get('/barcode/:data', async (req, res) => {
310
287
  const { type = 'code128', format = 'png' } = req.query;
311
288
 
312
289
  try {
313
- let result, contentType;
314
-
315
- switch (format) {
316
- case 'png':
317
- result = BarcodeGenerator.png(data, type);
318
- contentType = 'image/png';
319
- break;
320
- case 'svg':
321
- result = BarcodeGenerator.svg(data, type);
322
- contentType = 'image/svg+xml';
323
- break;
324
- case 'html':
325
- result = BarcodeGenerator.html(data, type);
326
- contentType = 'text/html';
327
- break;
328
- default:
329
- return res.status(400).json({ error: 'Invalid format' });
330
- }
331
-
332
- res.set('Content-Type', contentType);
290
+ const result = await BarcodeGenerator.generate(
291
+ req.params.data,
292
+ type,
293
+ format
294
+ );
295
+ res.set(
296
+ 'Content-Type',
297
+ BarcodeGenerator.getRenderFormatInfo(format).mimeType
298
+ );
333
299
  res.send(result);
334
300
  } catch (error) {
335
301
  res.status(400).json({ error: error.message });
336
302
  }
337
303
  });
338
304
 
339
- // QR code endpoint
340
- app.get('/qr/:data', async (req, res) => {
341
- const { data } = req.params;
342
- const { size = 300, logo, label } = req.query;
343
-
344
- try {
345
- const qrCode = BarcodeGenerator.modernQr({
346
- data: decodeURIComponent(data),
347
- size: parseInt(size),
348
- logoPath: logo,
349
- label: label,
350
- });
351
-
352
- const result = await qrCode.generate();
353
- res.set('Content-Type', 'image/png');
354
- res.send(result);
355
- } catch (error) {
356
- res.status(400).json({ error: error.message });
357
- }
358
- });
359
-
360
- app.listen(3000, () => {
361
- console.log('๐Ÿš€ Barcode server running on port 3000');
305
+ // Inline SVG needs no await
306
+ app.get('/inline/:data', (req, res) => {
307
+ res.type('svg').send(BarcodeGenerator.svgSync(req.params.data, 'code128'));
362
308
  });
363
309
  ```
364
310
 
365
- ### Middleware Pattern
311
+ A complete server, including QR and batch endpoints, is in
312
+ [examples/express-server.js](examples/express-server.js).
366
313
 
367
- ```javascript
368
- const express = require('express');
369
- const BarcodeGenerator = require('isahaq-barcode');
314
+ ## Browser usage
370
315
 
371
- const app = express();
316
+ Bundlers resolve the package to the browser build automatically through the
317
+ `browser` field. It shares the encoder and type registry with the Node build, so
318
+ output is identical; PDF generation and file writing are Node-only.
372
319
 
373
- // Barcode middleware
374
- app.use('/api/barcode', (req, res, next) => {
375
- req.generateBarcode = (
376
- data,
377
- type = 'code128',
378
- format = 'png',
379
- options = {}
380
- ) => {
381
- try {
382
- switch (format) {
383
- case 'png':
384
- return BarcodeGenerator.png(data, type, options);
385
- case 'svg':
386
- return BarcodeGenerator.svg(data, type, options);
387
- case 'html':
388
- return BarcodeGenerator.html(data, type, options);
389
- default:
390
- throw new Error(`Unsupported format: ${format}`);
391
- }
392
- } catch (error) {
393
- throw new Error(`Generation failed: ${error.message}`);
394
- }
395
- };
396
- next();
397
- });
320
+ ```javascript
321
+ import BarcodeGenerator from 'isahaq-barcode';
398
322
 
399
- // Route using middleware
400
- app.get('/api/barcode/:data', (req, res) => {
401
- const { data } = req.params;
402
- const { type, format = 'png', width, height } = req.query;
323
+ // Synchronous SVG - no DOM required
324
+ element.innerHTML = BarcodeGenerator.svg('1234567890', 'code128');
403
325
 
404
- const options = {};
405
- if (width) options.width = parseInt(width);
406
- if (height) options.height = parseInt(height);
326
+ // Canvas rendering
327
+ BarcodeGenerator.toCanvas(
328
+ document.querySelector('canvas'),
329
+ '1234567890',
330
+ 'code128'
331
+ );
407
332
 
408
- try {
409
- const result = req.generateBarcode(data, type, format, options);
410
- const mimeTypes = {
411
- png: 'image/png',
412
- svg: 'image/svg+xml',
413
- html: 'text/html',
414
- };
415
-
416
- res.set('Content-Type', mimeTypes[format] || 'image/png');
417
- res.send(result);
418
- } catch (error) {
419
- res.status(400).json({ error: error.message });
420
- }
333
+ const dataUrl = BarcodeGenerator.dataUrl('1234567890', 'code128');
334
+ const blob = await BarcodeGenerator.png('1234567890', 'code128'); // Blob, not Buffer
335
+ const qrDataUrl = await BarcodeGenerator.qrCode('https://example.com', {
336
+ size: 300,
421
337
  });
422
338
  ```
423
339
 
424
- ---
425
-
426
- ## ๐Ÿ–ฅ๏ธ CLI Usage
427
-
428
- ### Generate Barcodes
340
+ ## CLI
429
341
 
430
342
  ```bash
431
- # Basic PNG barcode
432
- barcode-generate barcode -d "1234567890" -t code128 -f png -o barcode.png
433
-
434
- # SVG with custom dimensions
435
- barcode-generate barcode -d "1234567890" -t ean13 -f svg -w 3 -h 150 -o barcode.svg
436
-
437
- # Custom colors
438
- barcode-generate barcode -d "1234567890" -t code128 \
439
- --foreground "#FF0000" --background "#FFFFFF" -o red-barcode.png
343
+ npx barcode-generate --help
440
344
  ```
441
345
 
442
- ### Generate QR Codes
443
-
444
346
  ```bash
445
- # Basic QR code
446
- barcode-generate qr -d "https://example.com" -s 300 -o qr.png
347
+ # Barcodes
348
+ barcode-generate barcode -d 1234567890 -t code128 -f png -o barcode.png
349
+ barcode-generate barcode -d 5901234123457 -t ean13 -f pdf -o label.pdf
350
+ barcode-generate barcode -d "https://example.com" -t qrcode -s 400 -o qr.png
351
+ barcode-generate barcode -d 1234567890 -f svg # writes SVG to stdout
352
+ barcode-generate barcode -d 1234567890 --no-text --width 3 --height 140 -o bars.png
447
353
 
448
- # QR code with logo
449
- barcode-generate qr -d "https://example.com" -s 300 \
450
- --logo "path/to/logo.png" --logo-size 60 -o qr-logo.png
451
-
452
- # QR code with watermark
453
- barcode-generate qr -d "https://example.com" -s 300 \
454
- --watermark "Company Name" --watermark-position bottom-center -o qr-watermark.png
455
- ```
456
-
457
- ### Batch Operations
458
-
459
- ```bash
460
- # Create batch configuration file
461
- cat > batch.json << EOF
462
- [
463
- {"data": "1234567890", "type": "code128", "format": "png"},
464
- {"data": "9876543210", "type": "code39", "format": "svg"},
465
- {"data": "https://example.com", "type": "qrcode", "format": "png"}
466
- ]
467
- EOF
468
-
469
- # Generate batch
470
- barcode-generate batch -i batch.json -o ./output
471
- ```
354
+ # QR codes with extras
355
+ barcode-generate qr -d "https://example.com" -s 400 -e H --label "Scan me" -o qr.png
472
356
 
473
- ### Utility Commands
357
+ # Batch generation from a JSON file
358
+ barcode-generate batch -i examples/batch-example.json -o ./output
474
359
 
475
- ```bash
476
- # List supported barcode types
360
+ # Discovery and validation
477
361
  barcode-generate types
478
-
479
- # List output formats
362
+ barcode-generate types -c matrix_2d
480
363
  barcode-generate formats
481
-
482
- # Validate data for specific type
483
- barcode-generate validate -d "1234567890" -t code128
364
+ barcode-generate validate -d 5901234123457 -t ean13
484
365
  ```
485
366
 
486
- ---
367
+ Data goes to stdout and diagnostics to stderr, so the CLI pipes cleanly. Without
368
+ `-o`, binary formats are printed as base64. Colour output honours `NO_COLOR`.
487
369
 
488
- ## ๐Ÿ“š API Reference
370
+ Sizing flags mirror the render options: `-w/--width` (module width in px),
371
+ `-h/--height` (bar height in px), `-s/--size` (2D target size in px),
372
+ `-q/--quiet-zone` (quiet zone in modules, default 10) and `-m/--margin` (quiet
373
+ zone in px, overrides `--quiet-zone`).
489
374
 
490
- ### BarcodeGenerator (Static Methods)
375
+ Install globally with `npm install -g isahaq-barcode` to drop the `npx` prefix.
491
376
 
492
- #### Generation Methods
377
+ ## TypeScript
493
378
 
494
- ```javascript
495
- BarcodeGenerator.png(data, type, options?)
496
- // Returns: Buffer
379
+ Type declarations ship with the package - no `@types` install needed.
497
380
 
498
- BarcodeGenerator.svg(data, type, options?)
499
- // Returns: String
381
+ ```typescript
382
+ import BarcodeGenerator = require('isahaq-barcode');
383
+ // or, with esModuleInterop: import BarcodeGenerator from 'isahaq-barcode';
500
384
 
501
- BarcodeGenerator.html(data, type, options?)
502
- // Returns: String
385
+ const options: BarcodeGenerator.RenderOptions = { width: 3, height: 140 };
386
+ const png: Buffer = await BarcodeGenerator.png(
387
+ '1234567890',
388
+ 'code128',
389
+ options
390
+ );
503
391
 
504
- BarcodeGenerator.pdf(data, type, options?)
505
- // Returns: Promise<Buffer>
506
-
507
- BarcodeGenerator.modernQr(options)
508
- // Returns: QrCodeInstance
392
+ const result = BarcodeGenerator.validate('5901234123457', 'ean13');
393
+ if (result.valid) {
394
+ console.log(result.charset); // narrowed to the success shape
395
+ }
509
396
  ```
510
397
 
511
- #### Utility Methods
398
+ ## API reference
512
399
 
513
- ```javascript
514
- BarcodeGenerator.validate(data, type);
515
- // Returns: { valid: boolean, error?: string, length?: number, charset?: string }
400
+ ### Generation
516
401
 
517
- BarcodeGenerator.batch(items);
518
- // Returns: Array<{ success: boolean, data?: Buffer|String, error?: string }>
402
+ | Method | Returns |
403
+ | --------------------------------------- | --------------------------- |
404
+ | `generate(data, type?, format?, opts?)` | `Promise<Buffer \| string>` |
405
+ | `png(data, type?, opts?)` | `Promise<Buffer>` |
406
+ | `svg(data, type?, opts?)` | `Promise<string>` |
407
+ | `svgSync(data, type?, opts?)` | `string` |
408
+ | `html(data, type?, opts?)` | `Promise<string>` |
409
+ | `htmlSync(data, type?, opts?)` | `string` |
410
+ | `pdf(data, type?, opts?)` | `Promise<Buffer>` |
411
+ | `batch(items)` | `Promise<BatchResult[]>` |
412
+ | `qrCode(data, opts?)` | `QrCodeBuilder` |
413
+ | `modernQr(opts?)` | `QrCodeBuilder` |
519
414
 
520
- BarcodeGenerator.getBarcodeTypes();
521
- // Returns: Array<string>
415
+ `type` defaults to `code128`, `format` to `png`.
522
416
 
523
- BarcodeGenerator.getRenderFormats();
524
- // Returns: Array<string>
417
+ ### Metadata
525
418
 
526
- BarcodeGenerator.getWatermarkPositions();
527
- // Returns: Array<string>
528
- ```
419
+ | Method | Returns |
420
+ | -------------------------------- | -------------------------- |
421
+ | `validate(data, type)` | `ValidationResult` |
422
+ | `getBarcodeTypes()` | `string[]` |
423
+ | `getBarcodeCategories()` | `string[]` |
424
+ | `getBarcodeTypesByCategory(cat)` | `string[]` |
425
+ | `getBarcodeTypeInfo(type)` | `BarcodeTypeInfo \| null` |
426
+ | `getRenderFormats()` | `string[]` |
427
+ | `getRenderFormatInfo(format)` | `RenderFormatInfo \| null` |
428
+ | `getWatermarkPositions()` | `string[]` |
429
+ | `getDefaultOptions()` | `RenderOptions` |
529
430
 
530
- ### Options Object
431
+ ### Building blocks
531
432
 
532
- ```javascript
533
- {
534
- // Dimensions
535
- width: 3, // Bar width
536
- height: 150, // Bar height
537
-
538
- // Display
539
- displayValue: true, // Show text below barcode
540
- fontSize: 20, // Text font size
541
- textAlign: 'center', // 'left' | 'center' | 'right'
542
- textPosition: 'bottom', // 'top' | 'bottom'
543
- textMargin: 2, // Space between bars and text
544
-
545
- // Colors
546
- background: '#ffffff', // Background color
547
- lineColor: '#000000', // Bar color (alias: foregroundColor)
548
-
549
- // Margins
550
- margin: 10, // All sides
551
- marginTop: 10, // Individual sides
552
- marginBottom: 10,
553
- marginLeft: 10,
554
- marginRight: 10
555
- }
556
- ```
557
-
558
- ### QrCodeBuilder Methods
433
+ Attached to the default export for advanced use: `QrCodeBuilder`,
434
+ `BarcodeService`, `BarcodeEncoder`, `BarcodeTypes`, `RenderFormats`, `Validator`.
559
435
 
560
436
  ```javascript
561
- QrCodeBuilder.create(options?)
562
- .data(string) // Set data to encode
563
- .size(number) // QR code size in pixels
564
- .margin(number) // Margin size
565
- .errorCorrectionLevel(level) // 'L' | 'M' | 'Q' | 'H'
566
- .foregroundColor(rgb) // [R, G, B]
567
- .backgroundColor(rgb) // [R, G, B]
568
- .logoPath(string) // Path to logo image
569
- .logoSize(number) // Logo size percentage
570
- .label(string) // Label text
571
- .watermark(text, position) // Watermark text and position
572
- .format(format) // 'png' | 'svg'
573
- .build() // Build QR code instance
574
-
575
- // QR Code Instance Methods
576
- qrCode.generate() // Returns: Promise<Buffer>
577
- qrCode.saveToFile(path) // Returns: Promise<void>
578
- qrCode.getDataUri() // Returns: Promise<string>
579
- qrCode.getString() // Returns: Promise<string>
580
- ```
437
+ const { BarcodeEncoder, BarcodeTypes } = require('isahaq-barcode');
581
438
 
582
- ### Watermark Positions
439
+ BarcodeEncoder.getDimensions('1234567890', 'code128', {
440
+ width: 2,
441
+ height: 100,
442
+ });
443
+ // { width: 220, height: 153 } bars + human readable text + quiet zone
583
444
 
584
- ```javascript
585
- ('top-left',
586
- 'top-center',
587
- 'top-right',
588
- 'left-center',
589
- 'center',
590
- 'right-center',
591
- 'bottom-left',
592
- 'bottom-center',
593
- 'bottom-right');
445
+ BarcodeTypes.getSymbology('aztec'); // 'azteccode'
594
446
  ```
595
447
 
596
- ---
597
-
598
- ## ๐Ÿงช Testing
448
+ ## Development
599
449
 
600
450
  ```bash
601
- # Run all tests
602
- npm test
603
-
604
- # Run with coverage report
605
- npm run test:coverage
606
-
607
- # Watch mode for development
608
- npm run test:watch
451
+ npm install
452
+ npm test # jest
453
+ npm run lint # eslint
454
+ npm run format # prettier --write
455
+ npm run typecheck # tsc against index.d.ts
456
+ npm run verify:scan # generate barcodes and decode them with ZXing
457
+ npm run build # lint + format:check + typecheck + test
458
+ node examples/basic-usage.js
459
+ npm run dev # express example on :3000
609
460
  ```
610
461
 
611
- ---
612
-
613
- ## ๐Ÿค Contributing
614
-
615
- We welcome contributions! Please follow these steps:
616
-
617
- 1. **Fork** the repository
618
- 2. **Create** a feature branch: `git checkout -b feature/amazing-feature`
619
- 3. **Commit** your changes: `git commit -m 'Add amazing feature'`
620
- 4. **Push** to the branch: `git push origin feature/amazing-feature`
621
- 5. **Open** a Pull Request
622
-
623
- Please ensure your code:
624
-
625
- - Follows the existing code style
626
- - Includes tests for new features
627
- - Updates documentation as needed
628
-
629
- ---
630
-
631
- ## ๐Ÿ“„ License
632
-
633
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
634
-
635
- ---
636
-
637
- ## ๐Ÿ™ Acknowledgments
638
-
639
- Built with these excellent libraries:
640
-
641
- - [JsBarcode](https://github.com/lindell/JsBarcode) - Barcode generation
642
- - [node-qrcode](https://github.com/soldair/node-qrcode) - QR code generation
643
- - [node-canvas](https://github.com/Automattic/node-canvas) - Canvas implementation
644
- - [PDFKit](https://github.com/foliojs/pdfkit) - PDF generation
645
-
646
- ---
647
-
648
- ## ๐Ÿ“ž Support
649
-
650
- Need help? Here's how to get support:
651
-
652
- 1. ๐Ÿ“– Check the [documentation](README.md)
653
- 2. ๐Ÿ” Search [existing issues](https://github.com/isahaq1//npm-barcodegeneratop/issues)
654
- 3. ๐Ÿ’ฌ Create a [new issue](https://github.com/isahaq1//npm-barcodegeneratop/issues/new)
655
-
656
- ---
657
-
658
- <div align="center">
659
-
660
- **Made with โค๏ธ by [Isahaq](https://github.com/isahaq1)**
661
-
662
- [โญ Star this repo](https://github.com/isahaq1//npm-barcodegeneratop) โ€ข [๐Ÿ› Report Bug](https://github.com/isahaq1//npm-barcodegeneratop/issues) โ€ข [โœจ Request Feature](https://github.com/isahaq1//npm-barcodegeneratop/issues)
462
+ ## License
663
463
 
664
- </div>
464
+ MIT - see [LICENSE](LICENSE).