isahaq-barcode 1.9.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,338 +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
46
-
47
- ## ๐ŸŒ Universal Compatibility
41
+ Requires Node.js 18 or newer.
48
42
 
49
- > **Great News:** This package now works in **both Node.js and browser environments**!
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.
50
47
 
51
- ### โœ… Server-Side (Node.js)
48
+ ```bash
49
+ npm install canvas # only if you need QR logos/labels/watermarks
50
+ ```
52
51
 
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
52
+ ## Quick start
57
53
 
58
- ### โœ… Client-Side (Browser)
54
+ ```javascript
55
+ const fs = require('fs/promises');
56
+ const BarcodeGenerator = require('isahaq-barcode');
59
57
 
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
58
+ // PNG (returns a Promise<Buffer>)
59
+ await fs.writeFile(
60
+ 'code128.png',
61
+ await BarcodeGenerator.png('1234567890', 'code128')
62
+ );
64
63
 
65
- ### Recommended Usage Patterns
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');
66
67
 
67
- **โœ… Server-Side (Recommended):**
68
+ // HTML fragment with an inline SVG
69
+ const html = BarcodeGenerator.htmlSync('1234567890', 'code128');
68
70
 
69
- ```javascript
70
- // Node.js/Express.js server
71
- const BarcodeGenerator = require('isahaq-barcode');
71
+ // PDF
72
+ await fs.writeFile(
73
+ 'label.pdf',
74
+ await BarcodeGenerator.pdf('1234567890', 'code128', { fitToBarcode: true })
75
+ );
72
76
 
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:**
82
-
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
- ```
86
+ ## Upgrading from 1.x
93
87
 
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
- ### Webpack Configuration
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
- If you're using webpack and encountering module resolution issues, add this to your webpack config:
108
+ ## Supported barcode types
110
109
 
111
- ```javascript
112
- module.exports = {
113
- resolve: {
114
- fallback: {
115
- fs: false,
116
- path: false,
117
- os: false,
118
- canvas: false,
119
- pdfkit: false,
120
- chalk: false,
121
- ora: false,
122
- commander: false,
123
- },
124
- },
125
- };
126
- ```
110
+ 45 types across six categories. `BarcodeGenerator.getBarcodeTypeInfo(type)`
111
+ returns the metadata for any of them.
127
112
 
128
- ### Next.js Configuration
129
-
130
- For Next.js projects, add this to your `next.config.js`:
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` |
131
121
 
132
122
  ```javascript
133
- module.exports = {
134
- webpack: config => {
135
- config.resolve.fallback = {
136
- ...config.resolve.fallback,
137
- fs: false,
138
- path: false,
139
- os: false,
140
- canvas: false,
141
- pdfkit: false,
142
- chalk: false,
143
- ora: false,
144
- commander: false,
145
- };
146
- return config;
147
- },
148
- };
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
+ // }
149
133
  ```
150
134
 
151
- **Global CLI Installation:**
135
+ ## Output formats
152
136
 
153
- ```bash
154
- npm install -g isahaq-barcode
155
- ```
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>` |
156
143
 
157
- ---
158
-
159
- ## ๐Ÿš€ Quick Start
144
+ `generate()` takes the format as an argument:
160
145
 
161
146
  ```javascript
162
- const BarcodeGenerator = require('isahaq-barcode');
163
-
164
- // Generate PNG barcode
165
- const pngBuffer = BarcodeGenerator.png('1234567890', 'code128');
166
-
167
- // Generate SVG barcode
168
- const svgString = BarcodeGenerator.svg('1234567890', 'ean13');
169
-
170
- // Generate QR code with logo
171
- const qrCode = BarcodeGenerator.modernQr({
172
- data: 'https://example.com',
173
- size: 300,
174
- logoPath: 'path/to/logo.png',
175
- label: 'Scan me!',
147
+ const output = await BarcodeGenerator.generate('1234567890', 'code128', 'pdf', {
148
+ pageSize: 'A4',
176
149
  });
177
-
178
- await qrCode.saveToFile('qr-code.png');
179
150
  ```
180
151
 
181
- ---
182
-
183
- ## ๐Ÿ“Š Supported Barcode Types
184
-
185
- ### Linear Barcodes (1D)
186
-
187
- | Type | Variants | Use Case |
188
- | -------------- | ---------------------------------- | ----------------------------- |
189
- | **Code 128** | A, B, C, Auto | General purpose, high density |
190
- | **Code 39** | Standard, Extended, Checksum, Auto | Alphanumeric, automotive |
191
- | **Code 93** | - | Compact alphanumeric |
192
- | **EAN Family** | EAN-13, EAN-8, EAN-2, EAN-5 | Retail products (Europe) |
193
- | **UPC Family** | UPC-A, UPC-E | Retail products (USA) |
194
- | **Code 25** | Standard, Interleaved, Auto | Industrial, logistics |
195
- | **ITF-14** | - | Shipping containers |
196
- | **MSI** | Standard, Checksum, Auto | Inventory management |
197
- | **Codabar** | - | Libraries, blood banks |
198
- | **Code 11** | - | Telecommunications |
152
+ ## Render options
199
153
 
200
- ### 2D Barcodes
201
-
202
- | Type | Data Capacity | Use Case |
203
- | --------------- | ----------------- | ----------------------- |
204
- | **QR Code** | Up to 4,296 chars | URLs, payments, general |
205
- | **Data Matrix** | Up to 2,335 chars | Small item marking |
206
- | **Aztec** | Up to 3,832 chars | Transport tickets |
207
- | **PDF417** | Up to 1,850 chars | IDs, boarding passes |
208
- | **Micro QR** | Up to 35 chars | Compact applications |
209
- | **MaxiCode** | Up to 93 chars | Package tracking |
210
-
211
- ### Postal Barcodes
212
-
213
- **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
+ ```
214
172
 
215
- ### 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.
216
177
 
217
- **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.
218
181
 
219
- ---
182
+ PDF-only options: `pageWidth`, `pageHeight`, `pageSize` (for example `'A4'`),
183
+ `fitToBarcode` (size the page to the barcode plus its margins) and `title`.
220
184
 
221
- ## ๐Ÿ’ป Usage Examples
185
+ HTML-only options: `id`, `className`, `includeStyles`.
222
186
 
223
- ### Basic Generation
187
+ Anything the encoder itself understands can be passed straight through:
224
188
 
225
189
  ```javascript
226
- const BarcodeGenerator = require('isahaq-barcode');
227
-
228
- // PNG with custom options
229
- const barcode = BarcodeGenerator.png('1234567890', 'code128', {
230
- width: 3,
231
- height: 150,
232
- displayValue: true,
233
- foregroundColor: '#000000',
234
- backgroundColor: '#FFFFFF',
235
- margin: 10,
190
+ await BarcodeGenerator.png('1234567890', 'code128', {
191
+ bwipOptions: { alttext: 'custom caption' },
236
192
  });
237
-
238
- // Convert to Base64 for web display
239
- const base64Image = barcode.toString('base64');
240
- console.log(`<img src="data:image/png;base64,${base64Image}" alt="Barcode" />`);
241
193
  ```
242
194
 
243
- ### Advanced QR Code with Logo
195
+ ## QR codes with logos, labels and watermarks
244
196
 
245
- ```javascript
246
- const qrCode = BarcodeGenerator.modernQr({
247
- data: 'https://example.com',
248
- size: 300,
249
- margin: 10,
250
-
251
- // Logo configuration
252
- logoPath: 'path/to/logo.png',
253
- logoSize: 60, // Percentage
254
-
255
- // Text elements
256
- label: 'Scan me!',
257
- watermark: 'Company Name',
258
- watermarkPosition: 'bottom-center',
259
-
260
- // Colors
261
- foregroundColor: [0, 0, 0],
262
- backgroundColor: [255, 255, 255],
197
+ `qrCode()` / `modernQr()` return a chainable builder. Plain codes need no extra
198
+ dependencies; a logo, label or watermark requires the optional `canvas` package.
263
199
 
264
- // Error correction (H recommended for logos)
200
+ ```javascript
201
+ const buffer = await BarcodeGenerator.qrCode('https://example.com', {
202
+ size: 400,
265
203
  errorCorrectionLevel: 'H',
266
- });
204
+ }).generate();
267
205
 
268
- // Save to file
269
- await qrCode.saveToFile('qr-code.png');
206
+ // Or with the builder API
207
+ const QrCodeBuilder = BarcodeGenerator.QrCodeBuilder;
270
208
 
271
- // Get as data URI
272
- 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();
273
228
  ```
274
229
 
275
- ### 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()`).
276
233
 
277
- ```javascript
278
- 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.
279
236
 
280
- const qrCode = QrCodeBuilder.create()
281
- .data('https://example.com')
282
- .size(300)
283
- .margin(10)
284
- .foregroundColor([0, 0, 0])
285
- .backgroundColor([255, 255, 255])
286
- .logoPath('path/to/logo.png')
287
- .logoSize(60)
288
- .label('Scan me!')
289
- .watermark('Watermark Text', 'center')
290
- .format('png')
291
- .build();
292
-
293
- await qrCode.saveToFile('qr-code.png');
294
- ```
237
+ ## Validation
295
238
 
296
- ### Batch Generation
239
+ Validation runs automatically before generation, and is also available directly:
297
240
 
298
241
  ```javascript
299
- const items = [
300
- { data: '1234567890', type: 'code128', format: 'png' },
301
- { data: '9876543210', type: 'code39', format: 'svg' },
302
- { data: 'https://example.com', type: 'qrcode', format: 'png' },
303
- ];
242
+ BarcodeGenerator.validate('5901234123457', 'ean13');
243
+ // { valid: true, data: '5901234123457', type: 'ean13', length: 13, charset: 'Numeric' }
304
244
 
305
- const results = BarcodeGenerator.batch(items);
245
+ BarcodeGenerator.validate('1234567890123', 'ean13');
246
+ // { valid: false, error: 'Invalid EAN-13 check digit (expected 8)' }
306
247
 
307
- results.forEach((result, index) => {
308
- if (result.success) {
309
- console.log(`โœ“ Barcode ${index} generated`);
310
- // result.data contains the generated barcode
311
- } else {
312
- console.error(`โœ— Barcode ${index} failed: ${result.error}`);
313
- }
314
- });
248
+ BarcodeGenerator.validate('123', 'ean13');
249
+ // { valid: false, error: 'Data too short. Minimum length: 12' }
315
250
  ```
316
251
 
317
- ### 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.
318
254
 
319
- ```javascript
320
- const validation = BarcodeGenerator.validate('1234567890', 'code128');
321
-
322
- if (validation.valid) {
323
- console.log('โœ“ Valid data');
324
- console.log(` Length: ${validation.length}`);
325
- console.log(` Charset: ${validation.charset}`);
326
- } else {
327
- console.error(`โœ— Invalid: ${validation.error}`);
328
- }
329
- ```
255
+ ## Batch generation
330
256
 
331
- ---
257
+ Per-item failures are reported in the result rather than rejecting the batch:
332
258
 
333
- ## ๐ŸŒ 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
+ ```
334
277
 
335
- ### Basic Route Implementation
278
+ ## Express.js integration
336
279
 
337
280
  ```javascript
338
281
  const express = require('express');
@@ -340,361 +283,182 @@ const BarcodeGenerator = require('isahaq-barcode');
340
283
 
341
284
  const app = express();
342
285
 
343
- // Barcode endpoint
344
- app.get('/barcode/:data', (req, res) => {
345
- const { data } = req.params;
286
+ app.get('/barcode/:data', async (req, res) => {
346
287
  const { type = 'code128', format = 'png' } = req.query;
347
288
 
348
289
  try {
349
- let result, contentType;
350
-
351
- switch (format) {
352
- case 'png':
353
- result = BarcodeGenerator.png(data, type);
354
- contentType = 'image/png';
355
- break;
356
- case 'svg':
357
- result = BarcodeGenerator.svg(data, type);
358
- contentType = 'image/svg+xml';
359
- break;
360
- case 'html':
361
- result = BarcodeGenerator.html(data, type);
362
- contentType = 'text/html';
363
- break;
364
- default:
365
- return res.status(400).json({ error: 'Invalid format' });
366
- }
367
-
368
- 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
+ );
369
299
  res.send(result);
370
300
  } catch (error) {
371
301
  res.status(400).json({ error: error.message });
372
302
  }
373
303
  });
374
304
 
375
- // QR code endpoint
376
- app.get('/qr/:data', async (req, res) => {
377
- const { data } = req.params;
378
- const { size = 300, logo, label } = req.query;
379
-
380
- try {
381
- const qrCode = BarcodeGenerator.modernQr({
382
- data: decodeURIComponent(data),
383
- size: parseInt(size),
384
- logoPath: logo,
385
- label: label,
386
- });
387
-
388
- const result = await qrCode.generate();
389
- res.set('Content-Type', 'image/png');
390
- res.send(result);
391
- } catch (error) {
392
- res.status(400).json({ error: error.message });
393
- }
394
- });
395
-
396
- app.listen(3000, () => {
397
- 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'));
398
308
  });
399
309
  ```
400
310
 
401
- ### Middleware Pattern
311
+ A complete server, including QR and batch endpoints, is in
312
+ [examples/express-server.js](examples/express-server.js).
402
313
 
403
- ```javascript
404
- const express = require('express');
405
- const BarcodeGenerator = require('isahaq-barcode');
314
+ ## Browser usage
406
315
 
407
- 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.
408
319
 
409
- // Barcode middleware
410
- app.use('/api/barcode', (req, res, next) => {
411
- req.generateBarcode = (
412
- data,
413
- type = 'code128',
414
- format = 'png',
415
- options = {}
416
- ) => {
417
- try {
418
- switch (format) {
419
- case 'png':
420
- return BarcodeGenerator.png(data, type, options);
421
- case 'svg':
422
- return BarcodeGenerator.svg(data, type, options);
423
- case 'html':
424
- return BarcodeGenerator.html(data, type, options);
425
- default:
426
- throw new Error(`Unsupported format: ${format}`);
427
- }
428
- } catch (error) {
429
- throw new Error(`Generation failed: ${error.message}`);
430
- }
431
- };
432
- next();
433
- });
320
+ ```javascript
321
+ import BarcodeGenerator from 'isahaq-barcode';
434
322
 
435
- // Route using middleware
436
- app.get('/api/barcode/:data', (req, res) => {
437
- const { data } = req.params;
438
- const { type, format = 'png', width, height } = req.query;
323
+ // Synchronous SVG - no DOM required
324
+ element.innerHTML = BarcodeGenerator.svg('1234567890', 'code128');
439
325
 
440
- const options = {};
441
- if (width) options.width = parseInt(width);
442
- if (height) options.height = parseInt(height);
326
+ // Canvas rendering
327
+ BarcodeGenerator.toCanvas(
328
+ document.querySelector('canvas'),
329
+ '1234567890',
330
+ 'code128'
331
+ );
443
332
 
444
- try {
445
- const result = req.generateBarcode(data, type, format, options);
446
- const mimeTypes = {
447
- png: 'image/png',
448
- svg: 'image/svg+xml',
449
- html: 'text/html',
450
- };
451
-
452
- res.set('Content-Type', mimeTypes[format] || 'image/png');
453
- res.send(result);
454
- } catch (error) {
455
- res.status(400).json({ error: error.message });
456
- }
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,
457
337
  });
458
338
  ```
459
339
 
460
- ---
461
-
462
- ## ๐Ÿ–ฅ๏ธ CLI Usage
463
-
464
- ### Generate Barcodes
340
+ ## CLI
465
341
 
466
342
  ```bash
467
- # Basic PNG barcode
468
- barcode-generate barcode -d "1234567890" -t code128 -f png -o barcode.png
469
-
470
- # SVG with custom dimensions
471
- barcode-generate barcode -d "1234567890" -t ean13 -f svg -w 3 -h 150 -o barcode.svg
472
-
473
- # Custom colors
474
- barcode-generate barcode -d "1234567890" -t code128 \
475
- --foreground "#FF0000" --background "#FFFFFF" -o red-barcode.png
343
+ npx barcode-generate --help
476
344
  ```
477
345
 
478
- ### Generate QR Codes
479
-
480
346
  ```bash
481
- # Basic QR code
482
- barcode-generate qr -d "https://example.com" -s 300 -o qr.png
483
-
484
- # QR code with logo
485
- barcode-generate qr -d "https://example.com" -s 300 \
486
- --logo "path/to/logo.png" --logo-size 60 -o qr-logo.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
487
353
 
488
- # QR code with watermark
489
- barcode-generate qr -d "https://example.com" -s 300 \
490
- --watermark "Company Name" --watermark-position bottom-center -o qr-watermark.png
491
- ```
354
+ # QR codes with extras
355
+ barcode-generate qr -d "https://example.com" -s 400 -e H --label "Scan me" -o qr.png
492
356
 
493
- ### Batch Operations
357
+ # Batch generation from a JSON file
358
+ barcode-generate batch -i examples/batch-example.json -o ./output
494
359
 
495
- ```bash
496
- # Create batch configuration file
497
- cat > batch.json << EOF
498
- [
499
- {"data": "1234567890", "type": "code128", "format": "png"},
500
- {"data": "9876543210", "type": "code39", "format": "svg"},
501
- {"data": "https://example.com", "type": "qrcode", "format": "png"}
502
- ]
503
- EOF
504
-
505
- # Generate batch
506
- barcode-generate batch -i batch.json -o ./output
507
- ```
508
-
509
- ### Utility Commands
510
-
511
- ```bash
512
- # List supported barcode types
360
+ # Discovery and validation
513
361
  barcode-generate types
514
-
515
- # List output formats
362
+ barcode-generate types -c matrix_2d
516
363
  barcode-generate formats
517
-
518
- # Validate data for specific type
519
- barcode-generate validate -d "1234567890" -t code128
364
+ barcode-generate validate -d 5901234123457 -t ean13
520
365
  ```
521
366
 
522
- ---
523
-
524
- ## ๐Ÿ“š API Reference
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`.
525
369
 
526
- ### BarcodeGenerator (Static Methods)
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`).
527
374
 
528
- #### Generation Methods
375
+ Install globally with `npm install -g isahaq-barcode` to drop the `npx` prefix.
529
376
 
530
- ```javascript
531
- BarcodeGenerator.png(data, type, options?)
532
- // Returns: Buffer
377
+ ## TypeScript
533
378
 
534
- BarcodeGenerator.svg(data, type, options?)
535
- // Returns: String
379
+ Type declarations ship with the package - no `@types` install needed.
536
380
 
537
- BarcodeGenerator.html(data, type, options?)
538
- // Returns: String
381
+ ```typescript
382
+ import BarcodeGenerator = require('isahaq-barcode');
383
+ // or, with esModuleInterop: import BarcodeGenerator from 'isahaq-barcode';
539
384
 
540
- BarcodeGenerator.pdf(data, type, options?)
541
- // Returns: Promise<Buffer>
385
+ const options: BarcodeGenerator.RenderOptions = { width: 3, height: 140 };
386
+ const png: Buffer = await BarcodeGenerator.png(
387
+ '1234567890',
388
+ 'code128',
389
+ options
390
+ );
542
391
 
543
- BarcodeGenerator.modernQr(options)
544
- // Returns: QrCodeInstance
392
+ const result = BarcodeGenerator.validate('5901234123457', 'ean13');
393
+ if (result.valid) {
394
+ console.log(result.charset); // narrowed to the success shape
395
+ }
545
396
  ```
546
397
 
547
- #### Utility Methods
398
+ ## API reference
548
399
 
549
- ```javascript
550
- BarcodeGenerator.validate(data, type);
551
- // Returns: { valid: boolean, error?: string, length?: number, charset?: string }
552
-
553
- BarcodeGenerator.batch(items);
554
- // Returns: Array<{ success: boolean, data?: Buffer|String, error?: string }>
400
+ ### Generation
555
401
 
556
- BarcodeGenerator.getBarcodeTypes();
557
- // Returns: Array<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` |
558
414
 
559
- BarcodeGenerator.getRenderFormats();
560
- // Returns: Array<string>
415
+ `type` defaults to `code128`, `format` to `png`.
561
416
 
562
- BarcodeGenerator.getWatermarkPositions();
563
- // Returns: Array<string>
564
- ```
417
+ ### Metadata
565
418
 
566
- ### Options Object
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` |
567
430
 
568
- ```javascript
569
- {
570
- // Dimensions
571
- width: 3, // Bar width
572
- height: 150, // Bar height
573
-
574
- // Display
575
- displayValue: true, // Show text below barcode
576
- fontSize: 20, // Text font size
577
- textAlign: 'center', // 'left' | 'center' | 'right'
578
- textPosition: 'bottom', // 'top' | 'bottom'
579
- textMargin: 2, // Space between bars and text
580
-
581
- // Colors
582
- background: '#ffffff', // Background color
583
- lineColor: '#000000', // Bar color (alias: foregroundColor)
584
-
585
- // Margins
586
- margin: 10, // All sides
587
- marginTop: 10, // Individual sides
588
- marginBottom: 10,
589
- marginLeft: 10,
590
- marginRight: 10
591
- }
592
- ```
431
+ ### Building blocks
593
432
 
594
- ### QrCodeBuilder Methods
433
+ Attached to the default export for advanced use: `QrCodeBuilder`,
434
+ `BarcodeService`, `BarcodeEncoder`, `BarcodeTypes`, `RenderFormats`, `Validator`.
595
435
 
596
436
  ```javascript
597
- QrCodeBuilder.create(options?)
598
- .data(string) // Set data to encode
599
- .size(number) // QR code size in pixels
600
- .margin(number) // Margin size
601
- .errorCorrectionLevel(level) // 'L' | 'M' | 'Q' | 'H'
602
- .foregroundColor(rgb) // [R, G, B]
603
- .backgroundColor(rgb) // [R, G, B]
604
- .logoPath(string) // Path to logo image
605
- .logoSize(number) // Logo size percentage
606
- .label(string) // Label text
607
- .watermark(text, position) // Watermark text and position
608
- .format(format) // 'png' | 'svg'
609
- .build() // Build QR code instance
610
-
611
- // QR Code Instance Methods
612
- qrCode.generate() // Returns: Promise<Buffer>
613
- qrCode.saveToFile(path) // Returns: Promise<void>
614
- qrCode.getDataUri() // Returns: Promise<string>
615
- qrCode.getString() // Returns: Promise<string>
616
- ```
437
+ const { BarcodeEncoder, BarcodeTypes } = require('isahaq-barcode');
617
438
 
618
- ### 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
619
444
 
620
- ```javascript
621
- ('top-left',
622
- 'top-center',
623
- 'top-right',
624
- 'left-center',
625
- 'center',
626
- 'right-center',
627
- 'bottom-left',
628
- 'bottom-center',
629
- 'bottom-right');
445
+ BarcodeTypes.getSymbology('aztec'); // 'azteccode'
630
446
  ```
631
447
 
632
- ---
633
-
634
- ## ๐Ÿงช Testing
448
+ ## Development
635
449
 
636
450
  ```bash
637
- # Run all tests
638
- npm test
639
-
640
- # Run with coverage report
641
- npm run test:coverage
642
-
643
- # Watch mode for development
644
- 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
645
460
  ```
646
461
 
647
- ---
648
-
649
- ## ๐Ÿค Contributing
650
-
651
- We welcome contributions! Please follow these steps:
652
-
653
- 1. **Fork** the repository
654
- 2. **Create** a feature branch: `git checkout -b feature/amazing-feature`
655
- 3. **Commit** your changes: `git commit -m 'Add amazing feature'`
656
- 4. **Push** to the branch: `git push origin feature/amazing-feature`
657
- 5. **Open** a Pull Request
658
-
659
- Please ensure your code:
660
-
661
- - Follows the existing code style
662
- - Includes tests for new features
663
- - Updates documentation as needed
664
-
665
- ---
666
-
667
- ## ๐Ÿ“„ License
668
-
669
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
670
-
671
- ---
672
-
673
- ## ๐Ÿ™ Acknowledgments
674
-
675
- Built with these excellent libraries:
676
-
677
- - [JsBarcode](https://github.com/lindell/JsBarcode) - Barcode generation
678
- - [node-qrcode](https://github.com/soldair/node-qrcode) - QR code generation
679
- - [node-canvas](https://github.com/Automattic/node-canvas) - Canvas implementation
680
- - [PDFKit](https://github.com/foliojs/pdfkit) - PDF generation
681
-
682
- ---
683
-
684
- ## ๐Ÿ“ž Support
685
-
686
- Need help? Here's how to get support:
687
-
688
- 1. ๐Ÿ“– Check the [documentation](README.md)
689
- 2. ๐Ÿ” Search [existing issues](https://github.com/isahaq1//npm-barcodegeneratop/issues)
690
- 3. ๐Ÿ’ฌ Create a [new issue](https://github.com/isahaq1//npm-barcodegeneratop/issues/new)
691
-
692
- ---
693
-
694
- <div align="center">
695
-
696
- **Made with โค๏ธ by [Isahaq](https://github.com/isahaq1)**
697
-
698
- [โญ 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
699
463
 
700
- </div>
464
+ MIT - see [LICENSE](LICENSE).