uqr 0.1.2 → 0.1.3
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 +4 -2
- package/dist/index.cjs +31 -32
- package/dist/index.d.cts +35 -6
- package/dist/index.d.mts +35 -6
- package/dist/index.d.ts +35 -6
- package/dist/index.mjs +31 -32
- package/package.json +27 -29
package/README.md
CHANGED
|
@@ -111,6 +111,10 @@ import { renderSVG } from 'uqr'
|
|
|
111
111
|
const string = renderSVG(text, options)
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
+
## Alternatives
|
|
115
|
+
|
|
116
|
+
- [etiket](https://github.com/productdevbook/etiket) — Zero-dependency barcode & QR code SVG generator. 20+ formats (1D barcodes, QR, Data Matrix, PDF417, Aztec), styled QR codes with dot types/gradients/logos, tree-shakeable, CLI tool.
|
|
117
|
+
|
|
114
118
|
## Credits
|
|
115
119
|
|
|
116
120
|
QR Code generation algorithm is modified from [nayuki/QR-Code-generator](https://github.com/nayuki/QR-Code-generator/blob/master/typescript-javascript/qrcodegen.ts) by Project Nayuki.
|
|
@@ -128,8 +132,6 @@ CLI renders are inspired by [qrcode-terminal](https://github.com/gtanner/qrcode-
|
|
|
128
132
|
[npm-version-href]: https://npmjs.com/package/uqr
|
|
129
133
|
[npm-downloads-src]: https://img.shields.io/npm/dm/uqr?style=flat&colorA=18181B&colorB=F0DB4F
|
|
130
134
|
[npm-downloads-href]: https://npmjs.com/package/uqr
|
|
131
|
-
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/uqr/main?style=flat&colorA=18181B&colorB=F0DB4F
|
|
132
|
-
[codecov-href]: https://codecov.io/gh/unjs/uqr
|
|
133
135
|
[bundle-src]: https://img.shields.io/bundlephobia/minzip/uqr?style=flat&colorA=18181B&colorB=F0DB4F
|
|
134
136
|
[bundle-href]: https://bundlephobia.com/result?p=uqr
|
|
135
137
|
[license-src]: https://img.shields.io/github/license/unjs/uqr.svg?style=flat&colorA=18181B&colorB=F0DB4F
|
package/dist/index.cjs
CHANGED
|
@@ -10,12 +10,6 @@ var QrCodeDataType = /* @__PURE__ */ ((QrCodeDataType2) => {
|
|
|
10
10
|
return QrCodeDataType2;
|
|
11
11
|
})(QrCodeDataType || {});
|
|
12
12
|
|
|
13
|
-
var __defProp = Object.defineProperty;
|
|
14
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
15
|
-
var __publicField = (obj, key, value) => {
|
|
16
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
17
|
-
return value;
|
|
18
|
-
};
|
|
19
13
|
const LOW = [0, 1];
|
|
20
14
|
const MEDIUM = [1, 0];
|
|
21
15
|
const QUARTILE = [2, 3];
|
|
@@ -26,8 +20,8 @@ const EccMap = {
|
|
|
26
20
|
Q: QUARTILE,
|
|
27
21
|
H: HIGH
|
|
28
22
|
};
|
|
29
|
-
const NUMERIC_REGEX =
|
|
30
|
-
const ALPHANUMERIC_REGEX = /^[A-Z0-9
|
|
23
|
+
const NUMERIC_REGEX = /^\d*$/;
|
|
24
|
+
const ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+./:-]*$/;
|
|
31
25
|
const ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
|
32
26
|
const MIN_VERSION = 1;
|
|
33
27
|
const MAX_VERSION = 40;
|
|
@@ -68,24 +62,12 @@ class QrCode {
|
|
|
68
62
|
constructor(version, ecc, dataCodewords, msk) {
|
|
69
63
|
this.version = version;
|
|
70
64
|
this.ecc = ecc;
|
|
71
|
-
/* -- Fields -- */
|
|
72
|
-
// The width and height of this QR Code, measured in modules, between
|
|
73
|
-
// 21 and 177 (inclusive). This is equal to version * 4 + 17.
|
|
74
|
-
__publicField(this, "size");
|
|
75
|
-
// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
|
|
76
|
-
// Even if a QR Code is created with automatic masking requested (mask = -1),
|
|
77
|
-
// the resulting object still has a mask value between 0 and 7.
|
|
78
|
-
__publicField(this, "mask");
|
|
79
|
-
// The modules of this QR Code (false = light, true = dark).
|
|
80
|
-
// Immutable after constructor finishes. Accessed through getModule().
|
|
81
|
-
__publicField(this, "modules", []);
|
|
82
|
-
__publicField(this, "types", []);
|
|
83
65
|
if (version < MIN_VERSION || version > MAX_VERSION)
|
|
84
66
|
throw new RangeError("Version value out of range");
|
|
85
67
|
if (msk < -1 || msk > 7)
|
|
86
68
|
throw new RangeError("Mask value out of range");
|
|
87
69
|
this.size = version * 4 + 17;
|
|
88
|
-
const row = Array.from({ length: this.size }
|
|
70
|
+
const row = Array.from({ length: this.size }).fill(false);
|
|
89
71
|
for (let i = 0; i < this.size; i++) {
|
|
90
72
|
this.modules.push(row.slice());
|
|
91
73
|
this.types.push(row.map(() => 0));
|
|
@@ -110,6 +92,18 @@ class QrCode {
|
|
|
110
92
|
this.applyMask(msk);
|
|
111
93
|
this.drawFormatBits(msk);
|
|
112
94
|
}
|
|
95
|
+
/* -- Fields -- */
|
|
96
|
+
// The width and height of this QR Code, measured in modules, between
|
|
97
|
+
// 21 and 177 (inclusive). This is equal to version * 4 + 17.
|
|
98
|
+
size;
|
|
99
|
+
// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
|
|
100
|
+
// Even if a QR Code is created with automatic masking requested (mask = -1),
|
|
101
|
+
// the resulting object still has a mask value between 0 and 7.
|
|
102
|
+
mask;
|
|
103
|
+
// The modules of this QR Code (false = light, true = dark).
|
|
104
|
+
// Immutable after constructor finishes. Accessed through getModule().
|
|
105
|
+
modules = [];
|
|
106
|
+
types = [];
|
|
113
107
|
/* -- Accessor methods -- */
|
|
114
108
|
// Returns the color of the module (pixel) at the given coordinates, which is false
|
|
115
109
|
// for light or true for dark. The top left corner has the coordinates (x=0, y=0).
|
|
@@ -356,8 +350,9 @@ class QrCode {
|
|
|
356
350
|
for (let y = 0; y < this.size - 1; y++) {
|
|
357
351
|
for (let x = 0; x < this.size - 1; x++) {
|
|
358
352
|
const color = this.modules[y][x];
|
|
359
|
-
if (color === this.modules[y][x + 1] && color === this.modules[y + 1][x] && color === this.modules[y + 1][x + 1])
|
|
353
|
+
if (color === this.modules[y][x + 1] && color === this.modules[y + 1][x] && color === this.modules[y + 1][x + 1]) {
|
|
360
354
|
result += PENALTY_N2;
|
|
355
|
+
}
|
|
361
356
|
}
|
|
362
357
|
}
|
|
363
358
|
let dark = 0;
|
|
@@ -565,8 +560,9 @@ function reedSolomonMultiply(x, y) {
|
|
|
565
560
|
return z;
|
|
566
561
|
}
|
|
567
562
|
function encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
|
|
568
|
-
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
|
|
563
|
+
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) {
|
|
569
564
|
throw new RangeError("Invalid value");
|
|
565
|
+
}
|
|
570
566
|
let version;
|
|
571
567
|
let dataUsedBits;
|
|
572
568
|
for (version = minVersion; ; version++) {
|
|
@@ -685,7 +681,7 @@ function renderANSI(data, options = {}) {
|
|
|
685
681
|
});
|
|
686
682
|
}
|
|
687
683
|
function renderUnicodeCompact(data, options = {}) {
|
|
688
|
-
const
|
|
684
|
+
const palette = {
|
|
689
685
|
WHITE_ALL: "\u2588",
|
|
690
686
|
WHITE_BLACK: "\u2580",
|
|
691
687
|
BLACK_WHITE: "\u2584",
|
|
@@ -700,13 +696,13 @@ function renderUnicodeCompact(data, options = {}) {
|
|
|
700
696
|
for (let row = 0; row < result.size; row += 2) {
|
|
701
697
|
for (let col = 0; col < result.size; col++) {
|
|
702
698
|
if (at(col, row) === WHITE && at(col, row + 1) === WHITE)
|
|
703
|
-
line +=
|
|
699
|
+
line += palette.WHITE_ALL;
|
|
704
700
|
else if (at(col, row) === WHITE && at(col, row + 1) === BLACK)
|
|
705
|
-
line +=
|
|
701
|
+
line += palette.WHITE_BLACK;
|
|
706
702
|
else if (at(col, row) === BLACK && at(col, row + 1) === WHITE)
|
|
707
|
-
line +=
|
|
703
|
+
line += palette.BLACK_WHITE;
|
|
708
704
|
else
|
|
709
|
-
line +=
|
|
705
|
+
line += palette.BLACK_ALL;
|
|
710
706
|
}
|
|
711
707
|
lines.push(line);
|
|
712
708
|
line = "";
|
|
@@ -714,6 +710,9 @@ function renderUnicodeCompact(data, options = {}) {
|
|
|
714
710
|
return lines.join("\n");
|
|
715
711
|
}
|
|
716
712
|
|
|
713
|
+
function escapeAttr(value) {
|
|
714
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
715
|
+
}
|
|
717
716
|
function renderSVG(data, options = {}) {
|
|
718
717
|
const result = encode(data, options);
|
|
719
718
|
const {
|
|
@@ -724,17 +723,17 @@ function renderSVG(data, options = {}) {
|
|
|
724
723
|
const height = result.size * pixelSize;
|
|
725
724
|
const width = result.size * pixelSize;
|
|
726
725
|
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}">`;
|
|
727
|
-
const
|
|
726
|
+
const paths = [];
|
|
728
727
|
for (let row = 0; row < result.size; row++) {
|
|
729
728
|
for (let col = 0; col < result.size; col++) {
|
|
730
729
|
const x = col * pixelSize;
|
|
731
730
|
const y = row * pixelSize;
|
|
732
731
|
if (result.data[row][col])
|
|
733
|
-
|
|
732
|
+
paths.push(`M${x},${y}h${pixelSize}v${pixelSize}h-${pixelSize}z`);
|
|
734
733
|
}
|
|
735
734
|
}
|
|
736
|
-
svg += `<rect fill="${whiteColor}" width="${width}" height="${height}"/>`;
|
|
737
|
-
svg += `<path fill="${blackColor}" d="${
|
|
735
|
+
svg += `<rect fill="${escapeAttr(whiteColor)}" width="${width}" height="${height}"/>`;
|
|
736
|
+
svg += `<path fill="${escapeAttr(blackColor)}" d="${paths.join("")}"/>`;
|
|
738
737
|
svg += "</svg>";
|
|
739
738
|
return svg;
|
|
740
739
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -82,17 +82,26 @@ interface QrCodeGenerateResult {
|
|
|
82
82
|
types: QrCodeDataType[][];
|
|
83
83
|
}
|
|
84
84
|
interface QrCodeGenerateInvertableOptions extends QrCodeGenerateOptions {
|
|
85
|
+
/**
|
|
86
|
+
* Adds the option to invert the colour scheme of the QR code in addition to the standard options.
|
|
87
|
+
*/
|
|
85
88
|
invert?: boolean;
|
|
86
89
|
}
|
|
87
90
|
interface QrCodeGenerateUnicodeOptions extends QrCodeGenerateInvertableOptions {
|
|
91
|
+
/**
|
|
92
|
+
* Character used to represent white modules in the QR code.
|
|
93
|
+
*/
|
|
88
94
|
whiteChar?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Character used to represent black modules in the QR code.
|
|
97
|
+
*/
|
|
89
98
|
blackChar?: string;
|
|
90
99
|
}
|
|
91
100
|
interface QrCodeGenerateSvgOptions extends QrCodeGenerateOptions {
|
|
92
101
|
/**
|
|
93
102
|
* Size of each pixel
|
|
94
103
|
*
|
|
95
|
-
* @default
|
|
104
|
+
* @default 10
|
|
96
105
|
*/
|
|
97
106
|
pixelSize?: number;
|
|
98
107
|
/**
|
|
@@ -109,24 +118,44 @@ interface QrCodeGenerateSvgOptions extends QrCodeGenerateOptions {
|
|
|
109
118
|
blackColor?: string;
|
|
110
119
|
}
|
|
111
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Encodes the given data into a QR code format according to the given options.
|
|
123
|
+
* @param {QrCodeGenerateData} data - The data to encode, either as a string or an array of bytes. See {@link QrCodeGenerateData}.
|
|
124
|
+
* @param {QrCodeGenerateOptions} [options] - QR Code generation configuration options. Optional. See {@link QrCodeGenerateOptions}.
|
|
125
|
+
* @returns {QrCodeGenerateResult} The result of the QR code generation, including the QR code matrix. See {@link QrCodeGenerateResult}.
|
|
126
|
+
*/
|
|
112
127
|
declare function encode(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): QrCodeGenerateResult;
|
|
113
128
|
|
|
114
129
|
/**
|
|
115
|
-
*
|
|
130
|
+
* Renders a QR code as a string using the specified Unicode characters for dark(`█`) and light(`░`) modules.
|
|
131
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
132
|
+
* @param {QrCodeGenerateUnicodeOptions} [options] - Rendering options, including characters for white and black modules. optional. See {@link QrCodeGenerateUnicodeOptions}.
|
|
133
|
+
* Returns {string} A string representing the QR code, with each module replaced by the specified Unicode character.
|
|
116
134
|
*/
|
|
117
135
|
declare function renderUnicode(data: QrCodeGenerateData, options?: QrCodeGenerateUnicodeOptions): string;
|
|
118
136
|
/**
|
|
119
|
-
*
|
|
137
|
+
* Renders a QR code as a string suitable for display on terminals using ANSI background colours.
|
|
138
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
139
|
+
* @param {QrCodeGenerateOptions} [options] - Options to render the QR code. optional. See {@link QrCodeGenerateOptions}.
|
|
140
|
+
* @returns {string} A string representing the QR code using ANSI colours, formatted for terminal display.
|
|
120
141
|
*/
|
|
121
142
|
declare function renderANSI(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): string;
|
|
122
143
|
/**
|
|
123
|
-
*
|
|
144
|
+
* Renders a QR code as a compact string using a combination of top half block(`▀`), bottom half block(`▄`), full block(`█`) and spaces to represent two lines in a single line.
|
|
145
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
146
|
+
* @param {QrCodeGenerateOptions} [options] - Options to render the QR code in a compact form. optional. See {@link QrCodeGenerateOptions}.
|
|
147
|
+
* @returns {string} A string representing the QR code in a compact format, using Unicode block characters to combine two lines per line.
|
|
124
148
|
*/
|
|
125
149
|
declare function renderUnicodeCompact(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): string;
|
|
126
150
|
|
|
127
151
|
/**
|
|
128
|
-
*
|
|
152
|
+
* Renders a QR code as an SVG string.
|
|
153
|
+
* The function converts the input data into a QR code and then generates an SVG representation using the specified colours and pixel sizes.
|
|
154
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
155
|
+
* @param {QrCodeGenerateSvgOptions} [options] - Options to render the QR code in SVG format, including pixel size and colours for modules. optional. See {@link QrCodeGenerateSvgOptions}.
|
|
156
|
+
* @returns {string} An SVG string representing the QR code.
|
|
129
157
|
*/
|
|
130
158
|
declare function renderSVG(data: QrCodeGenerateData, options?: QrCodeGenerateSvgOptions): string;
|
|
131
159
|
|
|
132
|
-
export { QrCodeDataType,
|
|
160
|
+
export { QrCodeDataType, encode, renderANSI, renderSVG, renderUnicode, renderUnicodeCompact };
|
|
161
|
+
export type { QrCodeGenerateData, QrCodeGenerateInvertableOptions, QrCodeGenerateOptions, QrCodeGenerateResult, QrCodeGenerateSvgOptions, QrCodeGenerateUnicodeOptions };
|
package/dist/index.d.mts
CHANGED
|
@@ -82,17 +82,26 @@ interface QrCodeGenerateResult {
|
|
|
82
82
|
types: QrCodeDataType[][];
|
|
83
83
|
}
|
|
84
84
|
interface QrCodeGenerateInvertableOptions extends QrCodeGenerateOptions {
|
|
85
|
+
/**
|
|
86
|
+
* Adds the option to invert the colour scheme of the QR code in addition to the standard options.
|
|
87
|
+
*/
|
|
85
88
|
invert?: boolean;
|
|
86
89
|
}
|
|
87
90
|
interface QrCodeGenerateUnicodeOptions extends QrCodeGenerateInvertableOptions {
|
|
91
|
+
/**
|
|
92
|
+
* Character used to represent white modules in the QR code.
|
|
93
|
+
*/
|
|
88
94
|
whiteChar?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Character used to represent black modules in the QR code.
|
|
97
|
+
*/
|
|
89
98
|
blackChar?: string;
|
|
90
99
|
}
|
|
91
100
|
interface QrCodeGenerateSvgOptions extends QrCodeGenerateOptions {
|
|
92
101
|
/**
|
|
93
102
|
* Size of each pixel
|
|
94
103
|
*
|
|
95
|
-
* @default
|
|
104
|
+
* @default 10
|
|
96
105
|
*/
|
|
97
106
|
pixelSize?: number;
|
|
98
107
|
/**
|
|
@@ -109,24 +118,44 @@ interface QrCodeGenerateSvgOptions extends QrCodeGenerateOptions {
|
|
|
109
118
|
blackColor?: string;
|
|
110
119
|
}
|
|
111
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Encodes the given data into a QR code format according to the given options.
|
|
123
|
+
* @param {QrCodeGenerateData} data - The data to encode, either as a string or an array of bytes. See {@link QrCodeGenerateData}.
|
|
124
|
+
* @param {QrCodeGenerateOptions} [options] - QR Code generation configuration options. Optional. See {@link QrCodeGenerateOptions}.
|
|
125
|
+
* @returns {QrCodeGenerateResult} The result of the QR code generation, including the QR code matrix. See {@link QrCodeGenerateResult}.
|
|
126
|
+
*/
|
|
112
127
|
declare function encode(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): QrCodeGenerateResult;
|
|
113
128
|
|
|
114
129
|
/**
|
|
115
|
-
*
|
|
130
|
+
* Renders a QR code as a string using the specified Unicode characters for dark(`█`) and light(`░`) modules.
|
|
131
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
132
|
+
* @param {QrCodeGenerateUnicodeOptions} [options] - Rendering options, including characters for white and black modules. optional. See {@link QrCodeGenerateUnicodeOptions}.
|
|
133
|
+
* Returns {string} A string representing the QR code, with each module replaced by the specified Unicode character.
|
|
116
134
|
*/
|
|
117
135
|
declare function renderUnicode(data: QrCodeGenerateData, options?: QrCodeGenerateUnicodeOptions): string;
|
|
118
136
|
/**
|
|
119
|
-
*
|
|
137
|
+
* Renders a QR code as a string suitable for display on terminals using ANSI background colours.
|
|
138
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
139
|
+
* @param {QrCodeGenerateOptions} [options] - Options to render the QR code. optional. See {@link QrCodeGenerateOptions}.
|
|
140
|
+
* @returns {string} A string representing the QR code using ANSI colours, formatted for terminal display.
|
|
120
141
|
*/
|
|
121
142
|
declare function renderANSI(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): string;
|
|
122
143
|
/**
|
|
123
|
-
*
|
|
144
|
+
* Renders a QR code as a compact string using a combination of top half block(`▀`), bottom half block(`▄`), full block(`█`) and spaces to represent two lines in a single line.
|
|
145
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
146
|
+
* @param {QrCodeGenerateOptions} [options] - Options to render the QR code in a compact form. optional. See {@link QrCodeGenerateOptions}.
|
|
147
|
+
* @returns {string} A string representing the QR code in a compact format, using Unicode block characters to combine two lines per line.
|
|
124
148
|
*/
|
|
125
149
|
declare function renderUnicodeCompact(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): string;
|
|
126
150
|
|
|
127
151
|
/**
|
|
128
|
-
*
|
|
152
|
+
* Renders a QR code as an SVG string.
|
|
153
|
+
* The function converts the input data into a QR code and then generates an SVG representation using the specified colours and pixel sizes.
|
|
154
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
155
|
+
* @param {QrCodeGenerateSvgOptions} [options] - Options to render the QR code in SVG format, including pixel size and colours for modules. optional. See {@link QrCodeGenerateSvgOptions}.
|
|
156
|
+
* @returns {string} An SVG string representing the QR code.
|
|
129
157
|
*/
|
|
130
158
|
declare function renderSVG(data: QrCodeGenerateData, options?: QrCodeGenerateSvgOptions): string;
|
|
131
159
|
|
|
132
|
-
export { QrCodeDataType,
|
|
160
|
+
export { QrCodeDataType, encode, renderANSI, renderSVG, renderUnicode, renderUnicodeCompact };
|
|
161
|
+
export type { QrCodeGenerateData, QrCodeGenerateInvertableOptions, QrCodeGenerateOptions, QrCodeGenerateResult, QrCodeGenerateSvgOptions, QrCodeGenerateUnicodeOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -82,17 +82,26 @@ interface QrCodeGenerateResult {
|
|
|
82
82
|
types: QrCodeDataType[][];
|
|
83
83
|
}
|
|
84
84
|
interface QrCodeGenerateInvertableOptions extends QrCodeGenerateOptions {
|
|
85
|
+
/**
|
|
86
|
+
* Adds the option to invert the colour scheme of the QR code in addition to the standard options.
|
|
87
|
+
*/
|
|
85
88
|
invert?: boolean;
|
|
86
89
|
}
|
|
87
90
|
interface QrCodeGenerateUnicodeOptions extends QrCodeGenerateInvertableOptions {
|
|
91
|
+
/**
|
|
92
|
+
* Character used to represent white modules in the QR code.
|
|
93
|
+
*/
|
|
88
94
|
whiteChar?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Character used to represent black modules in the QR code.
|
|
97
|
+
*/
|
|
89
98
|
blackChar?: string;
|
|
90
99
|
}
|
|
91
100
|
interface QrCodeGenerateSvgOptions extends QrCodeGenerateOptions {
|
|
92
101
|
/**
|
|
93
102
|
* Size of each pixel
|
|
94
103
|
*
|
|
95
|
-
* @default
|
|
104
|
+
* @default 10
|
|
96
105
|
*/
|
|
97
106
|
pixelSize?: number;
|
|
98
107
|
/**
|
|
@@ -109,24 +118,44 @@ interface QrCodeGenerateSvgOptions extends QrCodeGenerateOptions {
|
|
|
109
118
|
blackColor?: string;
|
|
110
119
|
}
|
|
111
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Encodes the given data into a QR code format according to the given options.
|
|
123
|
+
* @param {QrCodeGenerateData} data - The data to encode, either as a string or an array of bytes. See {@link QrCodeGenerateData}.
|
|
124
|
+
* @param {QrCodeGenerateOptions} [options] - QR Code generation configuration options. Optional. See {@link QrCodeGenerateOptions}.
|
|
125
|
+
* @returns {QrCodeGenerateResult} The result of the QR code generation, including the QR code matrix. See {@link QrCodeGenerateResult}.
|
|
126
|
+
*/
|
|
112
127
|
declare function encode(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): QrCodeGenerateResult;
|
|
113
128
|
|
|
114
129
|
/**
|
|
115
|
-
*
|
|
130
|
+
* Renders a QR code as a string using the specified Unicode characters for dark(`█`) and light(`░`) modules.
|
|
131
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
132
|
+
* @param {QrCodeGenerateUnicodeOptions} [options] - Rendering options, including characters for white and black modules. optional. See {@link QrCodeGenerateUnicodeOptions}.
|
|
133
|
+
* Returns {string} A string representing the QR code, with each module replaced by the specified Unicode character.
|
|
116
134
|
*/
|
|
117
135
|
declare function renderUnicode(data: QrCodeGenerateData, options?: QrCodeGenerateUnicodeOptions): string;
|
|
118
136
|
/**
|
|
119
|
-
*
|
|
137
|
+
* Renders a QR code as a string suitable for display on terminals using ANSI background colours.
|
|
138
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
139
|
+
* @param {QrCodeGenerateOptions} [options] - Options to render the QR code. optional. See {@link QrCodeGenerateOptions}.
|
|
140
|
+
* @returns {string} A string representing the QR code using ANSI colours, formatted for terminal display.
|
|
120
141
|
*/
|
|
121
142
|
declare function renderANSI(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): string;
|
|
122
143
|
/**
|
|
123
|
-
*
|
|
144
|
+
* Renders a QR code as a compact string using a combination of top half block(`▀`), bottom half block(`▄`), full block(`█`) and spaces to represent two lines in a single line.
|
|
145
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
146
|
+
* @param {QrCodeGenerateOptions} [options] - Options to render the QR code in a compact form. optional. See {@link QrCodeGenerateOptions}.
|
|
147
|
+
* @returns {string} A string representing the QR code in a compact format, using Unicode block characters to combine two lines per line.
|
|
124
148
|
*/
|
|
125
149
|
declare function renderUnicodeCompact(data: QrCodeGenerateData, options?: QrCodeGenerateOptions): string;
|
|
126
150
|
|
|
127
151
|
/**
|
|
128
|
-
*
|
|
152
|
+
* Renders a QR code as an SVG string.
|
|
153
|
+
* The function converts the input data into a QR code and then generates an SVG representation using the specified colours and pixel sizes.
|
|
154
|
+
* @param {QrCodeGenerateData} data - The data to encode into the QR code. See {@link QrCodeGenerateData}.
|
|
155
|
+
* @param {QrCodeGenerateSvgOptions} [options] - Options to render the QR code in SVG format, including pixel size and colours for modules. optional. See {@link QrCodeGenerateSvgOptions}.
|
|
156
|
+
* @returns {string} An SVG string representing the QR code.
|
|
129
157
|
*/
|
|
130
158
|
declare function renderSVG(data: QrCodeGenerateData, options?: QrCodeGenerateSvgOptions): string;
|
|
131
159
|
|
|
132
|
-
export { QrCodeDataType,
|
|
160
|
+
export { QrCodeDataType, encode, renderANSI, renderSVG, renderUnicode, renderUnicodeCompact };
|
|
161
|
+
export type { QrCodeGenerateData, QrCodeGenerateInvertableOptions, QrCodeGenerateOptions, QrCodeGenerateResult, QrCodeGenerateSvgOptions, QrCodeGenerateUnicodeOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -8,12 +8,6 @@ var QrCodeDataType = /* @__PURE__ */ ((QrCodeDataType2) => {
|
|
|
8
8
|
return QrCodeDataType2;
|
|
9
9
|
})(QrCodeDataType || {});
|
|
10
10
|
|
|
11
|
-
var __defProp = Object.defineProperty;
|
|
12
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
-
var __publicField = (obj, key, value) => {
|
|
14
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
15
|
-
return value;
|
|
16
|
-
};
|
|
17
11
|
const LOW = [0, 1];
|
|
18
12
|
const MEDIUM = [1, 0];
|
|
19
13
|
const QUARTILE = [2, 3];
|
|
@@ -24,8 +18,8 @@ const EccMap = {
|
|
|
24
18
|
Q: QUARTILE,
|
|
25
19
|
H: HIGH
|
|
26
20
|
};
|
|
27
|
-
const NUMERIC_REGEX =
|
|
28
|
-
const ALPHANUMERIC_REGEX = /^[A-Z0-9
|
|
21
|
+
const NUMERIC_REGEX = /^\d*$/;
|
|
22
|
+
const ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+./:-]*$/;
|
|
29
23
|
const ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
|
30
24
|
const MIN_VERSION = 1;
|
|
31
25
|
const MAX_VERSION = 40;
|
|
@@ -66,24 +60,12 @@ class QrCode {
|
|
|
66
60
|
constructor(version, ecc, dataCodewords, msk) {
|
|
67
61
|
this.version = version;
|
|
68
62
|
this.ecc = ecc;
|
|
69
|
-
/* -- Fields -- */
|
|
70
|
-
// The width and height of this QR Code, measured in modules, between
|
|
71
|
-
// 21 and 177 (inclusive). This is equal to version * 4 + 17.
|
|
72
|
-
__publicField(this, "size");
|
|
73
|
-
// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
|
|
74
|
-
// Even if a QR Code is created with automatic masking requested (mask = -1),
|
|
75
|
-
// the resulting object still has a mask value between 0 and 7.
|
|
76
|
-
__publicField(this, "mask");
|
|
77
|
-
// The modules of this QR Code (false = light, true = dark).
|
|
78
|
-
// Immutable after constructor finishes. Accessed through getModule().
|
|
79
|
-
__publicField(this, "modules", []);
|
|
80
|
-
__publicField(this, "types", []);
|
|
81
63
|
if (version < MIN_VERSION || version > MAX_VERSION)
|
|
82
64
|
throw new RangeError("Version value out of range");
|
|
83
65
|
if (msk < -1 || msk > 7)
|
|
84
66
|
throw new RangeError("Mask value out of range");
|
|
85
67
|
this.size = version * 4 + 17;
|
|
86
|
-
const row = Array.from({ length: this.size }
|
|
68
|
+
const row = Array.from({ length: this.size }).fill(false);
|
|
87
69
|
for (let i = 0; i < this.size; i++) {
|
|
88
70
|
this.modules.push(row.slice());
|
|
89
71
|
this.types.push(row.map(() => 0));
|
|
@@ -108,6 +90,18 @@ class QrCode {
|
|
|
108
90
|
this.applyMask(msk);
|
|
109
91
|
this.drawFormatBits(msk);
|
|
110
92
|
}
|
|
93
|
+
/* -- Fields -- */
|
|
94
|
+
// The width and height of this QR Code, measured in modules, between
|
|
95
|
+
// 21 and 177 (inclusive). This is equal to version * 4 + 17.
|
|
96
|
+
size;
|
|
97
|
+
// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
|
|
98
|
+
// Even if a QR Code is created with automatic masking requested (mask = -1),
|
|
99
|
+
// the resulting object still has a mask value between 0 and 7.
|
|
100
|
+
mask;
|
|
101
|
+
// The modules of this QR Code (false = light, true = dark).
|
|
102
|
+
// Immutable after constructor finishes. Accessed through getModule().
|
|
103
|
+
modules = [];
|
|
104
|
+
types = [];
|
|
111
105
|
/* -- Accessor methods -- */
|
|
112
106
|
// Returns the color of the module (pixel) at the given coordinates, which is false
|
|
113
107
|
// for light or true for dark. The top left corner has the coordinates (x=0, y=0).
|
|
@@ -354,8 +348,9 @@ class QrCode {
|
|
|
354
348
|
for (let y = 0; y < this.size - 1; y++) {
|
|
355
349
|
for (let x = 0; x < this.size - 1; x++) {
|
|
356
350
|
const color = this.modules[y][x];
|
|
357
|
-
if (color === this.modules[y][x + 1] && color === this.modules[y + 1][x] && color === this.modules[y + 1][x + 1])
|
|
351
|
+
if (color === this.modules[y][x + 1] && color === this.modules[y + 1][x] && color === this.modules[y + 1][x + 1]) {
|
|
358
352
|
result += PENALTY_N2;
|
|
353
|
+
}
|
|
359
354
|
}
|
|
360
355
|
}
|
|
361
356
|
let dark = 0;
|
|
@@ -563,8 +558,9 @@ function reedSolomonMultiply(x, y) {
|
|
|
563
558
|
return z;
|
|
564
559
|
}
|
|
565
560
|
function encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
|
|
566
|
-
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
|
|
561
|
+
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) {
|
|
567
562
|
throw new RangeError("Invalid value");
|
|
563
|
+
}
|
|
568
564
|
let version;
|
|
569
565
|
let dataUsedBits;
|
|
570
566
|
for (version = minVersion; ; version++) {
|
|
@@ -683,7 +679,7 @@ function renderANSI(data, options = {}) {
|
|
|
683
679
|
});
|
|
684
680
|
}
|
|
685
681
|
function renderUnicodeCompact(data, options = {}) {
|
|
686
|
-
const
|
|
682
|
+
const palette = {
|
|
687
683
|
WHITE_ALL: "\u2588",
|
|
688
684
|
WHITE_BLACK: "\u2580",
|
|
689
685
|
BLACK_WHITE: "\u2584",
|
|
@@ -698,13 +694,13 @@ function renderUnicodeCompact(data, options = {}) {
|
|
|
698
694
|
for (let row = 0; row < result.size; row += 2) {
|
|
699
695
|
for (let col = 0; col < result.size; col++) {
|
|
700
696
|
if (at(col, row) === WHITE && at(col, row + 1) === WHITE)
|
|
701
|
-
line +=
|
|
697
|
+
line += palette.WHITE_ALL;
|
|
702
698
|
else if (at(col, row) === WHITE && at(col, row + 1) === BLACK)
|
|
703
|
-
line +=
|
|
699
|
+
line += palette.WHITE_BLACK;
|
|
704
700
|
else if (at(col, row) === BLACK && at(col, row + 1) === WHITE)
|
|
705
|
-
line +=
|
|
701
|
+
line += palette.BLACK_WHITE;
|
|
706
702
|
else
|
|
707
|
-
line +=
|
|
703
|
+
line += palette.BLACK_ALL;
|
|
708
704
|
}
|
|
709
705
|
lines.push(line);
|
|
710
706
|
line = "";
|
|
@@ -712,6 +708,9 @@ function renderUnicodeCompact(data, options = {}) {
|
|
|
712
708
|
return lines.join("\n");
|
|
713
709
|
}
|
|
714
710
|
|
|
711
|
+
function escapeAttr(value) {
|
|
712
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
713
|
+
}
|
|
715
714
|
function renderSVG(data, options = {}) {
|
|
716
715
|
const result = encode(data, options);
|
|
717
716
|
const {
|
|
@@ -722,17 +721,17 @@ function renderSVG(data, options = {}) {
|
|
|
722
721
|
const height = result.size * pixelSize;
|
|
723
722
|
const width = result.size * pixelSize;
|
|
724
723
|
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}">`;
|
|
725
|
-
const
|
|
724
|
+
const paths = [];
|
|
726
725
|
for (let row = 0; row < result.size; row++) {
|
|
727
726
|
for (let col = 0; col < result.size; col++) {
|
|
728
727
|
const x = col * pixelSize;
|
|
729
728
|
const y = row * pixelSize;
|
|
730
729
|
if (result.data[row][col])
|
|
731
|
-
|
|
730
|
+
paths.push(`M${x},${y}h${pixelSize}v${pixelSize}h-${pixelSize}z`);
|
|
732
731
|
}
|
|
733
732
|
}
|
|
734
|
-
svg += `<rect fill="${whiteColor}" width="${width}" height="${height}"/>`;
|
|
735
|
-
svg += `<path fill="${blackColor}" d="${
|
|
733
|
+
svg += `<rect fill="${escapeAttr(whiteColor)}" width="${width}" height="${height}"/>`;
|
|
734
|
+
svg += `<path fill="${escapeAttr(blackColor)}" d="${paths.join("")}"/>`;
|
|
736
735
|
svg += "</svg>";
|
|
737
736
|
return svg;
|
|
738
737
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uqr",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
5
|
-
"packageManager": "pnpm@8.6.12",
|
|
4
|
+
"version": "0.1.3",
|
|
6
5
|
"description": "Generate QR Code universally, in any runtime, to ANSI, Unicode or SVG.",
|
|
7
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
8
7
|
"license": "MIT",
|
|
@@ -34,38 +33,37 @@
|
|
|
34
33
|
"files": [
|
|
35
34
|
"dist"
|
|
36
35
|
],
|
|
37
|
-
"scripts": {
|
|
38
|
-
"build": "unbuild",
|
|
39
|
-
"dev": "unbuild --stub",
|
|
40
|
-
"lint": "eslint .",
|
|
41
|
-
"prepublishOnly": "nr build",
|
|
42
|
-
"release": "bumpp && npm publish",
|
|
43
|
-
"play": "esno play/run.ts",
|
|
44
|
-
"test": "vitest",
|
|
45
|
-
"typecheck": "tsc --noEmit"
|
|
46
|
-
},
|
|
47
36
|
"devDependencies": {
|
|
48
|
-
"@antfu/eslint-config": "^0.
|
|
49
|
-
"@antfu/ni": "^0.
|
|
50
|
-
"@antfu/utils": "^
|
|
51
|
-
"@types/node": "^
|
|
52
|
-
"bumpp": "^
|
|
53
|
-
"eslint": "^
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"typescript": "^
|
|
61
|
-
"unbuild": "^
|
|
62
|
-
"vite": "^
|
|
63
|
-
"vitest": "^
|
|
37
|
+
"@antfu/eslint-config": "^8.0.0",
|
|
38
|
+
"@antfu/ni": "^30.0.0",
|
|
39
|
+
"@antfu/utils": "^9.3.0",
|
|
40
|
+
"@types/node": "^25.5.0",
|
|
41
|
+
"bumpp": "^11.0.1",
|
|
42
|
+
"eslint": "^10.1.0",
|
|
43
|
+
"lint-staged": "^16.4.0",
|
|
44
|
+
"pnpm": "^10.33.0",
|
|
45
|
+
"rimraf": "^6.1.3",
|
|
46
|
+
"rollup": "^4.60.1",
|
|
47
|
+
"simple-git-hooks": "^2.13.1",
|
|
48
|
+
"tsx": "^4.21.0",
|
|
49
|
+
"typescript": "^6.0.2",
|
|
50
|
+
"unbuild": "^3.6.1",
|
|
51
|
+
"vite": "^8.0.3",
|
|
52
|
+
"vitest": "^4.1.2"
|
|
64
53
|
},
|
|
65
54
|
"simple-git-hooks": {
|
|
66
55
|
"pre-commit": "pnpm lint-staged"
|
|
67
56
|
},
|
|
68
57
|
"lint-staged": {
|
|
69
58
|
"*": "eslint --fix"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "unbuild",
|
|
62
|
+
"dev": "unbuild --stub",
|
|
63
|
+
"lint": "eslint .",
|
|
64
|
+
"release": "bumpp && npm publish",
|
|
65
|
+
"play": "tsx play/run.ts",
|
|
66
|
+
"test": "vitest",
|
|
67
|
+
"typecheck": "tsc --noEmit"
|
|
70
68
|
}
|
|
71
|
-
}
|
|
69
|
+
}
|