dovmikesoul-codigo-barras-js 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 +21 -0
- package/README.md +45 -0
- package/package.json +18 -0
- package/src/index.js +108 -0
- package/test/test.js +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Miguel Angel Pérez Díaz
|
|
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,45 @@
|
|
|
1
|
+
# dovmikesoul-codigo-barras-js
|
|
2
|
+
|
|
3
|
+
Una biblioteca ligera, rápida y sin dependencias para generar códigos de barras (Code 39) en formato SVG en JavaScript.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install dovmikesoul-codigo-barras-js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Uso
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
const { generateCode39SVG } = require('dovmikesoul-codigo-barras-js');
|
|
15
|
+
|
|
16
|
+
// Generar el código de barras (devuelve un string SVG)
|
|
17
|
+
const svgString = generateCode39SVG('NPM 123');
|
|
18
|
+
|
|
19
|
+
console.log(svgString); // Imprime el contenido <svg>...</svg>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Opciones de personalización
|
|
23
|
+
|
|
24
|
+
Puedes pasar un segundo argumento de configuración a la función:
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
const svgString = generateCode39SVG('PERSONALIZADO', {
|
|
28
|
+
width: 2, // Ancho base de las barras (px)
|
|
29
|
+
height: 80, // Alto de las barras (px)
|
|
30
|
+
color: '#000000', // Color del código de barras
|
|
31
|
+
background: '#ffffff', // Color de fondo (usa 'transparent' para omitirlo)
|
|
32
|
+
showText: true, // Mostrar texto en la base
|
|
33
|
+
padding: 15 // Espacio exterior de seguridad
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Caracteres soportados (Code 39)
|
|
38
|
+
- Letras MAYÚSCULAS: `A-Z`
|
|
39
|
+
- Números: `0-9`
|
|
40
|
+
- Caracteres especiales: `-`, `.`, ` `, `$`, `/`, `+`, `%`
|
|
41
|
+
|
|
42
|
+
## Licencia
|
|
43
|
+
|
|
44
|
+
MIT
|
|
45
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dovmikesoul-codigo-barras-js",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Biblioteca en JavaScript para generar códigos de barras (Code 39) en formato SVG.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node test/test.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"barcode",
|
|
11
|
+
"svg",
|
|
12
|
+
"codigo-barras",
|
|
13
|
+
"code39",
|
|
14
|
+
"javascript"
|
|
15
|
+
],
|
|
16
|
+
"author": "DovMikeSoul",
|
|
17
|
+
"license": "MIT"
|
|
18
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const code39Map = {
|
|
2
|
+
'0': '000110100', '1': '100100001', '2': '001100001', '3': '101100000',
|
|
3
|
+
'4': '000110001', '5': '100110000', '6': '001110000', '7': '000100101',
|
|
4
|
+
'8': '100100100', '9': '001100100', 'A': '100001001', 'B': '001001001',
|
|
5
|
+
'C': '101001000', 'D': '000011001', 'E': '100011000', 'F': '001011000',
|
|
6
|
+
'G': '000001101', 'H': '100001100', 'I': '001001100', 'J': '000011100',
|
|
7
|
+
'K': '100000011', 'L': '001000011', 'M': '101000010', 'N': '000010011',
|
|
8
|
+
'O': '100010010', 'P': '001010010', 'Q': '000000111', 'R': '100000110',
|
|
9
|
+
'S': '001000110', 'T': '000010110', 'U': '110000001', 'V': '011000001',
|
|
10
|
+
'W': '111000000', 'X': '010010001', 'Y': '110010000', 'Z': '011010000',
|
|
11
|
+
'-': '010000101', '.': '110000100', ' ': '011000100', '*': '010010100',
|
|
12
|
+
'$': '010101000', '/': '010100010', '+': '010001010', '%': '000101010'
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Genera un código de barras Code 39 en formato SVG.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} text - El texto a codificar.
|
|
19
|
+
* @param {Object} options - Opciones de configuración.
|
|
20
|
+
* @param {number} options.width - Ancho de la barra estrecha (por defecto: 2).
|
|
21
|
+
* @param {number} options.height - Alto de las barras (por defecto: 100).
|
|
22
|
+
* @param {string} options.color - Color de las barras (por defecto: '#000000').
|
|
23
|
+
* @param {string} options.background - Color de fondo (por defecto: '#ffffff').
|
|
24
|
+
* @param {boolean} options.showText - Si se debe mostrar el texto debajo del código (por defecto: true).
|
|
25
|
+
* @param {number} options.padding - Espaciado interno (por defecto: 10).
|
|
26
|
+
* @returns {string} Código SVG generado.
|
|
27
|
+
*/
|
|
28
|
+
function generateCode39SVG(text, options = {}) {
|
|
29
|
+
if (!text) throw new Error("El texto no puede estar vacío");
|
|
30
|
+
|
|
31
|
+
const width = options.width || 2;
|
|
32
|
+
const height = options.height || 100;
|
|
33
|
+
const color = options.color || '#000000';
|
|
34
|
+
const background = options.background || '#ffffff';
|
|
35
|
+
const showText = options.showText !== undefined ? options.showText : true;
|
|
36
|
+
const padding = options.padding !== undefined ? options.padding : 10;
|
|
37
|
+
|
|
38
|
+
const wideWidth = width * 3;
|
|
39
|
+
|
|
40
|
+
// Asegurar que el texto tiene caracteres de inicio y fin '*'
|
|
41
|
+
let formattedText = text.toUpperCase();
|
|
42
|
+
if (!formattedText.startsWith('*')) formattedText = '*' + formattedText;
|
|
43
|
+
if (!formattedText.endsWith('*')) formattedText = formattedText + '*';
|
|
44
|
+
|
|
45
|
+
// Validar caracteres
|
|
46
|
+
for (let i = 0; i < formattedText.length; i++) {
|
|
47
|
+
if (!code39Map[formattedText[i]]) {
|
|
48
|
+
throw new Error(`Carácter no válido para Code 39: ${formattedText[i]}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let currentX = padding;
|
|
53
|
+
let svgElements = [];
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < formattedText.length; i++) {
|
|
56
|
+
const char = formattedText[i];
|
|
57
|
+
const pattern = code39Map[char];
|
|
58
|
+
|
|
59
|
+
for (let j = 0; j < pattern.length; j++) {
|
|
60
|
+
const isBar = j % 2 === 0;
|
|
61
|
+
const isWide = pattern[j] === '1';
|
|
62
|
+
const elementWidth = isWide ? wideWidth : width;
|
|
63
|
+
|
|
64
|
+
if (isBar) {
|
|
65
|
+
svgElements.push(`<rect x="${currentX}" y="${padding}" width="${elementWidth}" height="${height}" fill="${color}" />`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
currentX += elementWidth;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Espacio entre caracteres (espacio estrecho)
|
|
72
|
+
if (i < formattedText.length - 1) {
|
|
73
|
+
currentX += width;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const totalWidth = currentX + padding;
|
|
78
|
+
const textHeight = showText ? 24 : 0;
|
|
79
|
+
const totalHeight = height + (padding * 2) + textHeight;
|
|
80
|
+
|
|
81
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="${totalHeight}" viewBox="0 0 ${totalWidth} ${totalHeight}">
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
if (background !== 'transparent') {
|
|
85
|
+
svg += ` <rect width="100%" height="100%" fill="${background}" />
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
svg += ` <g>
|
|
90
|
+
${svgElements.join('\n ')}
|
|
91
|
+
</g>
|
|
92
|
+
`;
|
|
93
|
+
|
|
94
|
+
if (showText) {
|
|
95
|
+
// Mostrar el texto original sin los asteriscos de formato si no venían en el texto
|
|
96
|
+
const displayText = text.toUpperCase();
|
|
97
|
+
svg += ` <text x="${totalWidth / 2}" y="${totalHeight - padding}" font-family="monospace" font-size="16" fill="${color}" text-anchor="middle">${displayText}</text>
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
svg += `</svg>`;
|
|
102
|
+
|
|
103
|
+
return svg;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
generateCode39SVG
|
|
108
|
+
};
|
package/test/test.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const { generateCode39SVG } = require('../src/index.js');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
// 1. Probar generación con texto válido
|
|
7
|
+
const svg = generateCode39SVG('HOLA 123');
|
|
8
|
+
if (!svg.includes('<svg')) {
|
|
9
|
+
throw new Error("El SVG no se generó correctamente.");
|
|
10
|
+
}
|
|
11
|
+
if (!svg.includes('HOLA 123')) {
|
|
12
|
+
throw new Error("El texto no está presente en el SVG.");
|
|
13
|
+
}
|
|
14
|
+
console.log('✅ Prueba 1: Generación exitosa de SVG.');
|
|
15
|
+
|
|
16
|
+
// Guardar para inspección visual
|
|
17
|
+
const testOutputPath = path.join(__dirname, 'test_output.svg');
|
|
18
|
+
fs.writeFileSync(testOutputPath, svg);
|
|
19
|
+
console.log(`SVG de prueba guardado en: ${testOutputPath}`);
|
|
20
|
+
|
|
21
|
+
// 2. Probar manejo de errores
|
|
22
|
+
try {
|
|
23
|
+
generateCode39SVG('hola_mundo!');
|
|
24
|
+
throw new Error("Debería haber fallado por caracteres inválidos.");
|
|
25
|
+
} catch (e) {
|
|
26
|
+
if (e.message.includes('Carácter no válido')) {
|
|
27
|
+
console.log('✅ Prueba 2: Detección correcta de caracteres inválidos.');
|
|
28
|
+
} else {
|
|
29
|
+
throw e;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 3. Probar opciones
|
|
34
|
+
const customSvg = generateCode39SVG('TEST', {
|
|
35
|
+
color: '#FF0000',
|
|
36
|
+
background: 'transparent',
|
|
37
|
+
showText: false
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (customSvg.includes('#FF0000') && !customSvg.includes('TEST</text>')) {
|
|
41
|
+
console.log('✅ Prueba 3: Opciones personalizadas aplicadas correctamente.');
|
|
42
|
+
} else {
|
|
43
|
+
throw new Error("Opciones no aplicadas correctamente.");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log('\n¡Todas las pruebas pasaron satisfactoriamente!');
|
|
47
|
+
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('❌ Error en las pruebas:', error);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|