bysquare 2.0.1 → 2.2.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 +84 -55
- package/lib/cjs/cli.js +20 -39
- package/lib/cjs/generate.d.ts +19 -11
- package/lib/cjs/generate.js +122 -116
- package/lib/cjs/package.json +25 -26
- package/lib/cjs/parse.d.ts +13 -4
- package/lib/cjs/parse.js +201 -89
- package/lib/cjs/types.d.ts +18 -0
- package/lib/mjs/cli.js +20 -39
- package/lib/mjs/generate.d.ts +19 -11
- package/lib/mjs/generate.js +94 -111
- package/lib/mjs/package.json +25 -26
- package/lib/mjs/parse.d.ts +13 -4
- package/lib/mjs/parse.js +176 -85
- package/lib/mjs/types.d.ts +18 -0
- package/package.json +25 -26
package/lib/cjs/generate.js
CHANGED
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.generate = exports.
|
|
29
|
+
exports.generate = exports.serialize = exports.addChecksum = exports.headerDataLength = exports.headerBysquare = void 0;
|
|
30
|
+
const crc_32_1 = __importDefault(require("crc-32"));
|
|
7
31
|
const lodash_deburr_1 = __importDefault(require("lodash.deburr"));
|
|
8
|
-
const
|
|
32
|
+
const lzma = __importStar(require("lzma1"));
|
|
9
33
|
const rfc4648_1 = require("rfc4648");
|
|
10
34
|
const types_js_1 = require("./types.js");
|
|
11
|
-
// echo "Hello" | xz --format=raw --lzma1=lc=3,lp=0,pb=2,dict=32KiB --stdout | hexdump -C
|
|
12
35
|
/**
|
|
13
36
|
* Returns a 2 byte buffer that represents the header of the bysquare
|
|
14
37
|
* specification
|
|
@@ -22,129 +45,132 @@ const types_js_1 = require("./types.js");
|
|
|
22
45
|
* | Reserved | 4 | 0-15 | bits reserved for future needs
|
|
23
46
|
* ```
|
|
24
47
|
*
|
|
25
|
-
* @see 3.5.
|
|
48
|
+
* @see 3.5.
|
|
26
49
|
*/
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
50
|
+
function headerBysquare(
|
|
51
|
+
/** dprint-ignore */
|
|
52
|
+
header = [
|
|
53
|
+
0x00, 0x00,
|
|
54
|
+
0x00, 0x00
|
|
30
55
|
]) {
|
|
31
56
|
const isValid = header.every((nibble) => 0 <= nibble && nibble <= 15);
|
|
32
57
|
if (!isValid) {
|
|
33
|
-
throw new Error(
|
|
58
|
+
throw new Error("Invalid header byte value, valid range <0,15>");
|
|
34
59
|
}
|
|
35
60
|
const [bySquareType, version, documentType, reserved] = header;
|
|
36
61
|
// Combine 4-nibbles to 2-bytes
|
|
37
|
-
const mergedNibbles =
|
|
62
|
+
const mergedNibbles = Uint8Array.from([
|
|
38
63
|
(bySquareType << 4) | (version << 0),
|
|
39
|
-
(documentType << 4) | (reserved << 0)
|
|
64
|
+
(documentType << 4) | (reserved << 0)
|
|
40
65
|
]);
|
|
41
66
|
return mergedNibbles;
|
|
42
67
|
}
|
|
43
|
-
exports.
|
|
68
|
+
exports.headerBysquare = headerBysquare;
|
|
44
69
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
70
|
+
* The function first sets default values for the lc, lp, and pb properties,
|
|
71
|
+
* which represent the number of literal context bits, literal position bits,
|
|
72
|
+
* and position bits, respectively. These values are then used to calculate the
|
|
73
|
+
* properties value, which is a single byte that encodes all three properties.
|
|
49
74
|
*
|
|
50
|
-
* @see 3.11.
|
|
75
|
+
* @see 3.11.
|
|
51
76
|
*/
|
|
52
|
-
function
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
return
|
|
77
|
+
function headerLzmaProps() {
|
|
78
|
+
const lc = 3;
|
|
79
|
+
const lp = 0;
|
|
80
|
+
const pb = 2;
|
|
81
|
+
const properties = (((pb * 5) + lp) * 9) + lc;
|
|
82
|
+
const header = new ArrayBuffer(1);
|
|
83
|
+
new DataView(header).setUint8(0, properties);
|
|
84
|
+
return new Uint8Array(header);
|
|
60
85
|
}
|
|
61
86
|
/**
|
|
62
|
-
*
|
|
87
|
+
* Creates a one-byte array that represents the length of compressed data in
|
|
88
|
+
* combination with CRC32 in bytes.
|
|
63
89
|
*/
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
function headerDataLength(length) {
|
|
91
|
+
if (length >= 2 ** 16) {
|
|
92
|
+
throw new Error("The maximum compressed data size has been reached");
|
|
93
|
+
}
|
|
94
|
+
const header = new ArrayBuffer(1);
|
|
95
|
+
new DataView(header).setUint8(0, length);
|
|
96
|
+
return new Uint8Array(header);
|
|
70
97
|
}
|
|
71
|
-
exports.
|
|
98
|
+
exports.headerDataLength = headerDataLength;
|
|
72
99
|
/**
|
|
73
100
|
* Transfer object to a tabbed string and append a CRC32 checksum
|
|
74
101
|
*
|
|
75
|
-
* @see 3.10.
|
|
102
|
+
* @see 3.10.
|
|
76
103
|
*/
|
|
77
|
-
function
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
104
|
+
function addChecksum(serialized) {
|
|
105
|
+
const checksum = new ArrayBuffer(4);
|
|
106
|
+
new DataView(checksum).setUint32(0, crc_32_1.default.str(serialized), true);
|
|
107
|
+
const byteArray = new TextEncoder().encode(serialized);
|
|
108
|
+
return Uint8Array.from([
|
|
109
|
+
...new Uint8Array(checksum),
|
|
110
|
+
...Uint8Array.from(byteArray)
|
|
82
111
|
]);
|
|
83
112
|
}
|
|
84
|
-
exports.
|
|
113
|
+
exports.addChecksum = addChecksum;
|
|
85
114
|
/**
|
|
86
115
|
* Transform data to ordered tab-separated intermediate representation ready for
|
|
87
116
|
* encoding
|
|
88
117
|
*
|
|
89
|
-
* @see Table 15
|
|
118
|
+
* @see Table 15.
|
|
90
119
|
*/
|
|
91
|
-
function
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
120
|
+
function serialize(data) {
|
|
121
|
+
const serialized = new Array();
|
|
122
|
+
serialized.push(data.invoiceId?.toString());
|
|
123
|
+
serialized.push(data.payments.length.toString());
|
|
95
124
|
for (const p of data.payments) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
serialized.push(p.type.toString());
|
|
126
|
+
serialized.push(p.amount?.toString());
|
|
127
|
+
serialized.push(p.currencyCode);
|
|
128
|
+
serialized.push(p.paymentDueDate);
|
|
129
|
+
serialized.push(p.variableSymbol);
|
|
130
|
+
serialized.push(p.constantSymbol);
|
|
131
|
+
serialized.push(p.specificSymbol);
|
|
132
|
+
serialized.push(p.originatorRefInfo);
|
|
133
|
+
serialized.push(p.paymentNote);
|
|
134
|
+
serialized.push(p.bankAccounts.length.toString());
|
|
106
135
|
for (const ba of p.bankAccounts) {
|
|
107
|
-
|
|
108
|
-
|
|
136
|
+
serialized.push(ba.iban);
|
|
137
|
+
serialized.push(ba.bic);
|
|
109
138
|
}
|
|
110
139
|
if (p.type === types_js_1.PaymentOptions.StandingOrder) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
140
|
+
serialized.push("1");
|
|
141
|
+
serialized.push(p.day?.toString());
|
|
142
|
+
serialized.push(p.month?.toString());
|
|
143
|
+
serialized.push(p.periodicity);
|
|
144
|
+
serialized.push(p.lastDate);
|
|
116
145
|
}
|
|
117
146
|
else {
|
|
118
|
-
|
|
147
|
+
serialized.push("0");
|
|
119
148
|
}
|
|
120
149
|
if (p.type === types_js_1.PaymentOptions.DirectDebit) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
serialized.push("1");
|
|
151
|
+
serialized.push(p.directDebitScheme?.toString());
|
|
152
|
+
serialized.push(p.directDebitType?.toString());
|
|
153
|
+
serialized.push(p.variableSymbol?.toString());
|
|
154
|
+
serialized.push(p.specificSymbol?.toString());
|
|
155
|
+
serialized.push(p.originatorRefInfo?.toString());
|
|
156
|
+
serialized.push(p.mandateId?.toString());
|
|
157
|
+
serialized.push(p.creditorId?.toString());
|
|
158
|
+
serialized.push(p.contractId?.toString());
|
|
159
|
+
serialized.push(p.maxAmount?.toString());
|
|
160
|
+
serialized.push(p.validTillDate?.toString());
|
|
132
161
|
}
|
|
133
162
|
else {
|
|
134
|
-
|
|
163
|
+
serialized.push("0");
|
|
135
164
|
}
|
|
136
165
|
}
|
|
137
166
|
for (const p of data.payments) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
serialized.push(p.beneficiary?.name);
|
|
168
|
+
serialized.push(p.beneficiary?.street);
|
|
169
|
+
serialized.push(p.beneficiary?.city);
|
|
141
170
|
}
|
|
142
|
-
return
|
|
171
|
+
return serialized.join("\t");
|
|
143
172
|
}
|
|
144
|
-
exports.
|
|
145
|
-
/**
|
|
146
|
-
* Transfer diacritics to basic latin letters
|
|
147
|
-
*/
|
|
173
|
+
exports.serialize = serialize;
|
|
148
174
|
function removeDiacritics(model) {
|
|
149
175
|
for (const payment of model.payments) {
|
|
150
176
|
if (payment.paymentNote) {
|
|
@@ -168,40 +194,20 @@ function generate(model, options = { deburr: true }) {
|
|
|
168
194
|
if (options.deburr) {
|
|
169
195
|
removeDiacritics(model);
|
|
170
196
|
}
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
},
|
|
186
|
-
],
|
|
187
|
-
});
|
|
188
|
-
encoder
|
|
189
|
-
.on("end", () => {
|
|
190
|
-
const output = Buffer.concat([
|
|
191
|
-
bysquareHeader(),
|
|
192
|
-
lzmaHeader(data),
|
|
193
|
-
...compressedData
|
|
194
|
-
]);
|
|
195
|
-
resolve(rfc4648_1.base32hex.stringify(output, { pad: false }));
|
|
196
|
-
})
|
|
197
|
-
.on("data", (chunk) => {
|
|
198
|
-
compressedData.push(chunk);
|
|
199
|
-
})
|
|
200
|
-
.on("error", reject)
|
|
201
|
-
.write(data, (error) => {
|
|
202
|
-
error && reject(error);
|
|
203
|
-
encoder.end();
|
|
204
|
-
});
|
|
197
|
+
const payload = serialize(model);
|
|
198
|
+
const withChecksum = addChecksum(payload);
|
|
199
|
+
const compressed = Uint8Array.from(lzma.compress(withChecksum));
|
|
200
|
+
/** Exclude the LZMA header and retain raw compressed data */
|
|
201
|
+
const _headerLzma = Uint8Array.from(compressed.subarray(0, 13));
|
|
202
|
+
const compressedPayload = Uint8Array.from(compressed.subarray(13));
|
|
203
|
+
const output = Uint8Array.from([
|
|
204
|
+
...headerBysquare([0x00, 1 /* Version["1.1.0"] */, 0x00, 0x00]),
|
|
205
|
+
...headerLzmaProps(),
|
|
206
|
+
...headerDataLength(withChecksum.byteLength),
|
|
207
|
+
...compressedPayload
|
|
208
|
+
]);
|
|
209
|
+
return rfc4648_1.base32hex.stringify(output, {
|
|
210
|
+
pad: false
|
|
205
211
|
});
|
|
206
212
|
}
|
|
207
213
|
exports.generate = generate;
|
package/lib/cjs/package.json
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bysquare",
|
|
3
3
|
"description": "It's a national standard for payment QR codes adopted by Slovak Banking Association (SBA)",
|
|
4
|
-
"version": "2.0
|
|
4
|
+
"version": "2.2.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
|
-
"type": "commonjs",
|
|
7
6
|
"funding": "https://github.com/sponsors/xseman",
|
|
8
7
|
"homepage": "https://github.com/xseman/bysquare#readme",
|
|
9
|
-
"author":
|
|
10
|
-
|
|
11
|
-
"
|
|
8
|
+
"author": "Filip Seman <filip.seman@pm.me>",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"pay by square",
|
|
11
|
+
"by square",
|
|
12
|
+
"paybysquare",
|
|
13
|
+
"bysquare",
|
|
14
|
+
"payments",
|
|
15
|
+
"qr-string",
|
|
16
|
+
"generate",
|
|
17
|
+
"parse"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/xseman/bysquare.git"
|
|
12
22
|
},
|
|
13
23
|
"scripts": {
|
|
14
24
|
"prebuild": "rm -rf ./lib || :",
|
|
15
25
|
"build": "tsc --project ./tsconfig.json && tsc --project ./tsconfig.cjs.json",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
16
27
|
"postbuild": "bash -c 'chmod +x ./lib/{cjs,mjs}/cli.js' && cp package.json ./lib/mjs/ && jq '.type=\"commonjs\"' package.json > lib/cjs/package.json",
|
|
17
28
|
"test": "xv --loader=tsx ./src",
|
|
18
29
|
"test:watch": "find ./src/*.ts | entr xv --loader=tsx ./src",
|
|
@@ -24,18 +35,20 @@
|
|
|
24
35
|
"postversion": ""
|
|
25
36
|
},
|
|
26
37
|
"dependencies": {
|
|
38
|
+
"crc-32": "~1.2.0",
|
|
27
39
|
"lodash.deburr": "~4.1.0",
|
|
28
|
-
"
|
|
29
|
-
"rfc4648": "1.5.
|
|
40
|
+
"lzma1": "~0.0.1",
|
|
41
|
+
"rfc4648": "~1.5.0"
|
|
30
42
|
},
|
|
31
43
|
"devDependencies": {
|
|
32
44
|
"@types/lodash.deburr": "~4.1.0",
|
|
33
|
-
"@types/
|
|
34
|
-
"
|
|
45
|
+
"@types/node": ">=16.14",
|
|
46
|
+
"dprint": "~0.35.0",
|
|
35
47
|
"tsx": "~3.12.0",
|
|
36
|
-
"typescript": "~
|
|
48
|
+
"typescript": "~5.0.0",
|
|
37
49
|
"xv": "~2.1.0"
|
|
38
50
|
},
|
|
51
|
+
"type": "commonjs",
|
|
39
52
|
"bin": "lib/mjs/cli.js",
|
|
40
53
|
"types": "lib/mjs/index.d.ts",
|
|
41
54
|
"exports": {
|
|
@@ -49,21 +62,7 @@
|
|
|
49
62
|
"!lib/*.test.*"
|
|
50
63
|
],
|
|
51
64
|
"engines": {
|
|
52
|
-
"node": ">=16.
|
|
65
|
+
"node": ">=16.14",
|
|
53
66
|
"npm": ">=7.0"
|
|
54
|
-
}
|
|
55
|
-
"repository": {
|
|
56
|
-
"type": "git",
|
|
57
|
-
"url": "git+https://github.com/xseman/bysquare.git"
|
|
58
|
-
},
|
|
59
|
-
"keywords": [
|
|
60
|
-
"pay by square",
|
|
61
|
-
"by square",
|
|
62
|
-
"paybysquare",
|
|
63
|
-
"bysquare",
|
|
64
|
-
"payments",
|
|
65
|
-
"qr-string",
|
|
66
|
-
"qr",
|
|
67
|
-
"cli"
|
|
68
|
-
]
|
|
67
|
+
}
|
|
69
68
|
}
|
package/lib/cjs/parse.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { DataModel } from "./index.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Generating by square Code
|
|
4
|
+
*
|
|
5
|
+
* @see 3.14.
|
|
4
6
|
*/
|
|
5
|
-
export declare function
|
|
7
|
+
export declare function deserialize(qr: string): DataModel;
|
|
8
|
+
export declare class DecodeError extends Error {
|
|
9
|
+
cause: Error;
|
|
10
|
+
name: string;
|
|
11
|
+
constructor(cause: Error, msg?: string);
|
|
12
|
+
}
|
|
6
13
|
/**
|
|
7
|
-
*
|
|
14
|
+
* Decoding client data from QR Code 2005 symbol
|
|
15
|
+
*
|
|
16
|
+
* @see 3.16.
|
|
8
17
|
*/
|
|
9
|
-
export declare function parse(qr: string):
|
|
18
|
+
export declare function parse(qr: string): DataModel;
|
|
10
19
|
/**
|
|
11
20
|
* Detect if qr string contains bysquare header.
|
|
12
21
|
*
|