bysquare 2.0.0 → 2.1.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 +42 -44
- package/lib/{cli.d.ts → cjs/cli.d.ts} +0 -0
- package/lib/cjs/cli.js +90 -0
- package/lib/cjs/generate.d.ts +54 -0
- package/lib/cjs/generate.js +185 -0
- package/lib/{index.d.ts → cjs/index.d.ts} +0 -0
- package/lib/cjs/index.js +23 -0
- package/lib/cjs/package.json +71 -0
- package/lib/{parse.d.ts → cjs/parse.d.ts} +2 -2
- package/lib/cjs/parse.js +234 -0
- package/lib/{types.d.ts → cjs/types.d.ts} +0 -0
- package/lib/cjs/types.js +246 -0
- package/lib/mjs/cli.d.ts +2 -0
- package/lib/{cli.js → mjs/cli.js} +18 -35
- package/lib/{generate.d.ts → mjs/generate.d.ts} +10 -4
- package/lib/{generate.js → mjs/generate.js} +35 -57
- package/lib/{index.js → mjs/index.d.ts} +0 -0
- package/lib/mjs/index.js +3 -0
- package/lib/mjs/package.json +71 -0
- package/lib/mjs/parse.d.ts +16 -0
- package/lib/{parse.js → mjs/parse.js} +79 -28
- package/lib/mjs/types.d.ts +379 -0
- package/lib/{types.js → mjs/types.js} +0 -0
- package/package.json +15 -8
package/README.md
CHANGED
|
@@ -15,45 +15,50 @@ other payment regulations.
|
|
|
15
15
|
This library is un-opinionated. Image generation from qr-code string depends on
|
|
16
16
|
your implementation. See [examples](examples).
|
|
17
17
|
|
|
18
|
-
## How it works
|
|
19
|
-
|
|
20
|
-

|
|
21
|
-
|
|
22
18
|
## Install
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
**npm registry**
|
|
25
21
|
|
|
26
22
|
```sh
|
|
27
|
-
npm install
|
|
28
|
-
npm install xseman/bysquare#develop
|
|
23
|
+
npm install bysquare
|
|
29
24
|
```
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
**GitHub**
|
|
32
27
|
|
|
33
28
|
```sh
|
|
34
|
-
npm
|
|
29
|
+
# same as latest released npm registry version
|
|
30
|
+
npm install xseman/bysquare#master
|
|
31
|
+
|
|
32
|
+
# latest unreleased changes
|
|
33
|
+
npm install xseman/bysquare#develop
|
|
35
34
|
```
|
|
36
35
|
|
|
37
|
-
CLI
|
|
36
|
+
**CLI**
|
|
38
37
|
|
|
39
38
|
```sh
|
|
40
39
|
npm install --global bysquare
|
|
41
40
|
```
|
|
42
41
|
|
|
42
|
+
## How it works
|
|
43
|
+
|
|
44
|
+
### Encoding sequence
|
|
45
|
+
|
|
46
|
+

|
|
47
|
+
|
|
43
48
|
## API
|
|
44
49
|
|
|
45
50
|
```ts
|
|
46
|
-
generate(model: DataModel):
|
|
47
|
-
parse(qr: string):
|
|
51
|
+
generate(model: DataModel, options?: Options): string
|
|
52
|
+
parse(qr: string): DataModel
|
|
48
53
|
detect(qr: string): Boolean
|
|
49
54
|
```
|
|
50
55
|
|
|
51
|
-
**generate(model: DataModel):
|
|
56
|
+
**generate(model: DataModel, options?: Options): string**
|
|
52
57
|
|
|
53
58
|
```ts
|
|
54
59
|
import { generate, DataModel, parse, PaymentOptions } from "bysquare"
|
|
55
60
|
|
|
56
|
-
const model
|
|
61
|
+
const model {
|
|
57
62
|
invoiceId: "random-id",
|
|
58
63
|
payments: [
|
|
59
64
|
{
|
|
@@ -66,22 +71,18 @@ const model: DataModel = {
|
|
|
66
71
|
variableSymbol: "123",
|
|
67
72
|
}
|
|
68
73
|
]
|
|
69
|
-
}
|
|
74
|
+
} satisfies DataModel
|
|
70
75
|
|
|
71
|
-
generate(model)
|
|
72
|
-
// your logic...
|
|
73
|
-
})
|
|
76
|
+
const qr = generate(model)
|
|
74
77
|
```
|
|
75
78
|
|
|
76
|
-
**parse(qr: string):
|
|
79
|
+
**parse(qr: string): DataModel**
|
|
77
80
|
|
|
78
81
|
```ts
|
|
79
|
-
import { parse
|
|
82
|
+
import { parse } from "bysquare"
|
|
80
83
|
|
|
81
|
-
const qr = "
|
|
82
|
-
parse(qr)
|
|
83
|
-
// your logic...
|
|
84
|
-
});
|
|
84
|
+
const qr = "0004A00090IFU27IV0J6HGGLIOTIBVHNQQJQ6LAVGNBT363HR13JC6CB54HSI0KH9FCRASHNQBSKAQD2LJ4AU400UVKDNDPFRKLOBEVVVU0QJ000"
|
|
85
|
+
const model = parse(qr)
|
|
85
86
|
```
|
|
86
87
|
|
|
87
88
|
**detect(qr: string): Boolean**
|
|
@@ -89,7 +90,7 @@ parse(qr).then((model: DataModel) => {
|
|
|
89
90
|
```ts
|
|
90
91
|
import { detect } from "bysquare"
|
|
91
92
|
|
|
92
|
-
const qr = "
|
|
93
|
+
const qr = "0004A00090IFU27IV0J6HGGLIOTIBVHNQQJQ6LAVGNBT363HR13JC6CB54HSI0KH9FCRASHNQBSKAQD2LJ4AU400UVKDNDPFRKLOBEVVVU0QJ000"
|
|
93
94
|
const isBysquare = detect(qr)
|
|
94
95
|
```
|
|
95
96
|
|
|
@@ -105,9 +106,7 @@ You can use json file with valid model to generate qr-string.
|
|
|
105
106
|
# {
|
|
106
107
|
# "type": 1,
|
|
107
108
|
# "amount": 100.0,
|
|
108
|
-
# "bankAccounts": [
|
|
109
|
-
# { "iban": "SK9611000000002918599669" }
|
|
110
|
-
# ],
|
|
109
|
+
# "bankAccounts": [{ "iban": "SK9611000000002918599669" }],
|
|
111
110
|
# "currencyCode": "EUR",
|
|
112
111
|
# "variableSymbol": "123"
|
|
113
112
|
# }
|
|
@@ -115,27 +114,26 @@ You can use json file with valid model to generate qr-string.
|
|
|
115
114
|
# }
|
|
116
115
|
|
|
117
116
|
$ npx bysquare ./example.json
|
|
118
|
-
$
|
|
117
|
+
$ 0004A00090IFU27IV0J6HGGLIOTIBVHNQQJQ6LAVGNBT363HR13JC6CB54HSI0KH9FCRASHNQBSKAQD2LJ4AU400UVKDNDPFRKLOBEVVVU0QJ000
|
|
119
118
|
```
|
|
120
119
|
|
|
121
120
|
You can also use stdin.
|
|
122
121
|
|
|
123
122
|
```sh
|
|
124
|
-
$ bysquare <<< '{
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
]
|
|
123
|
+
$ npx bysquare <<< '{
|
|
124
|
+
"invoiceId": "random-id",
|
|
125
|
+
"payments": [
|
|
126
|
+
{
|
|
127
|
+
"type": 1,
|
|
128
|
+
"amount": 100.0,
|
|
129
|
+
"bankAccounts": [{ "iban": "SK9611000000002918599669" }],
|
|
130
|
+
"currencyCode": "EUR",
|
|
131
|
+
"variableSymbol": "123"
|
|
132
|
+
}
|
|
133
|
+
]
|
|
137
134
|
}'
|
|
138
|
-
|
|
135
|
+
|
|
136
|
+
$ 0004A00090IFU27IV0J6HGGLIOTIBVHNQQJQ6LAVGNBT363HR13JC6CB54HSI0KH9FCRASHNQBSKAQD2LJ4AU400UVKDNDPFRKLOBEVVVU0QJ000
|
|
139
137
|
```
|
|
140
138
|
|
|
141
139
|
## Related
|
|
@@ -157,9 +155,9 @@ https://github.com/dherges/npm-version-git-flow
|
|
|
157
155
|
- Run `npm test`
|
|
158
156
|
- Run `npm version <patch, minor, major>`
|
|
159
157
|
- Commit and push
|
|
160
|
-
- Run `npm version`
|
|
161
158
|
- Follow git-flow instructions
|
|
162
159
|
- Checkout to master
|
|
160
|
+
- Build artefacts
|
|
163
161
|
- Push commits and tag, git push && git push --tags
|
|
164
162
|
- Validate with `npm publish --dry-run`
|
|
165
163
|
- Publish to npm, `npm publish`
|
|
File without changes
|
package/lib/cjs/cli.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_readline_1 = require("node:readline");
|
|
10
|
+
const generate_js_1 = require("./generate.js");
|
|
11
|
+
if (process.stdin.isTTY) {
|
|
12
|
+
// bysquare "file"
|
|
13
|
+
handleInput(process.argv[2]);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
// echo "data" | bysquare
|
|
17
|
+
;
|
|
18
|
+
(async () => {
|
|
19
|
+
const stdin = await handleStdin();
|
|
20
|
+
console.log(fromJsonString(stdin));
|
|
21
|
+
process.exit(0);
|
|
22
|
+
})();
|
|
23
|
+
}
|
|
24
|
+
function handleInput(input) {
|
|
25
|
+
if (input === undefined || input === "-h" || input === "--help") {
|
|
26
|
+
console.log(help());
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
if ((0, node_fs_1.existsSync)(process.argv[2])) {
|
|
30
|
+
const file = (0, node_fs_1.readFileSync)(process.argv[2], "utf8");
|
|
31
|
+
console.log(fromJsonString(file));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.error(`File ${process.argv[2]} doesn't exists`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function fromJsonString(stdin) {
|
|
39
|
+
const data = JSON.parse(stdin);
|
|
40
|
+
return (0, generate_js_1.generate)(data);
|
|
41
|
+
}
|
|
42
|
+
async function handleStdin() {
|
|
43
|
+
const readline = (0, node_readline_1.createInterface)({
|
|
44
|
+
input: process.stdin,
|
|
45
|
+
output: process.stdout,
|
|
46
|
+
terminal: false
|
|
47
|
+
});
|
|
48
|
+
const lines = [];
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
readline
|
|
51
|
+
.on("line", (line) => {
|
|
52
|
+
lines.push(line);
|
|
53
|
+
})
|
|
54
|
+
.on("close", () => {
|
|
55
|
+
resolve(lines.join(""));
|
|
56
|
+
})
|
|
57
|
+
.on("SIGINT", /* CTRL+C */ reject);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function help() {
|
|
61
|
+
const exe = node_path_1.default.basename(process.argv[1]);
|
|
62
|
+
return [
|
|
63
|
+
"Simple Node.js library to generate 'PAY by square' QR string.",
|
|
64
|
+
"",
|
|
65
|
+
"Usage:",
|
|
66
|
+
` ${exe} file`,
|
|
67
|
+
"",
|
|
68
|
+
"File:",
|
|
69
|
+
" Valid json file",
|
|
70
|
+
"",
|
|
71
|
+
"Flags:",
|
|
72
|
+
" -h, --help display this help and exit",
|
|
73
|
+
"",
|
|
74
|
+
"If <file> is omitted, reads from stdin.",
|
|
75
|
+
"",
|
|
76
|
+
"Examples:",
|
|
77
|
+
" bysquare <<< \"{",
|
|
78
|
+
" \"invoiceId\": \"random-id\",",
|
|
79
|
+
" \"payments\": [",
|
|
80
|
+
" {",
|
|
81
|
+
" \"type\": 1,",
|
|
82
|
+
" \"amount\": 100.0,",
|
|
83
|
+
" \"bankAccounts\": [{ \"iban\": \"SK9611000000002918599669\" }],",
|
|
84
|
+
" \"currencyCode\": \"EUR\",",
|
|
85
|
+
" \"variableSymbol\": \"123\"",
|
|
86
|
+
" }",
|
|
87
|
+
" ]",
|
|
88
|
+
" }\"",
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { DataModel } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Returns a 2 byte buffer that represents the header of the bysquare
|
|
5
|
+
* specification
|
|
6
|
+
*
|
|
7
|
+
* ```
|
|
8
|
+
* | Attribute | Number of bits | Possible values | Note
|
|
9
|
+
* --------------------------------------------------------------------------------------------
|
|
10
|
+
* | BySquareType | 4 | 0-15 | by square type
|
|
11
|
+
* | Version | 4 | 0-15 | version of the by square type
|
|
12
|
+
* | DocumentType | 4 | 0-15 | document type within given by square type
|
|
13
|
+
* | Reserved | 4 | 0-15 | bits reserved for future needs
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @see 3.5. by square header
|
|
17
|
+
*/
|
|
18
|
+
export declare function bysquareHeader(header?: [
|
|
19
|
+
bySquareType: number,
|
|
20
|
+
version: number,
|
|
21
|
+
documentType: number,
|
|
22
|
+
reserved: number
|
|
23
|
+
]): Uint8Array;
|
|
24
|
+
/**
|
|
25
|
+
* @see 3.10 Appending CRC32 checksum
|
|
26
|
+
*/
|
|
27
|
+
export declare function checksum(intermediate: string): Buffer;
|
|
28
|
+
/**
|
|
29
|
+
* Transfer object to a tabbed string and append a CRC32 checksum
|
|
30
|
+
*
|
|
31
|
+
* @see 3.10. Appending CRC32 checksum
|
|
32
|
+
*/
|
|
33
|
+
export declare function addChecksum(model: DataModel): Uint8Array;
|
|
34
|
+
/**
|
|
35
|
+
* Transform data to ordered tab-separated intermediate representation ready for
|
|
36
|
+
* encoding
|
|
37
|
+
*
|
|
38
|
+
* @see Table 15 PAY by square sequence data model
|
|
39
|
+
*/
|
|
40
|
+
export declare function deserialize(data: DataModel): string;
|
|
41
|
+
type Options = {
|
|
42
|
+
/**
|
|
43
|
+
* Many banking apps do not support diacritics, which results in errors when
|
|
44
|
+
* serializing data from QR codes.
|
|
45
|
+
*
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
deburr: boolean;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Generate QR string ready for encoding into text QR code
|
|
52
|
+
*/
|
|
53
|
+
export declare function generate(model: DataModel, options?: Options): string;
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generate = exports.deserialize = exports.addChecksum = exports.checksum = exports.bysquareHeader = void 0;
|
|
7
|
+
const crc_32_1 = __importDefault(require("crc-32"));
|
|
8
|
+
const lodash_deburr_1 = __importDefault(require("lodash.deburr"));
|
|
9
|
+
const rfc4648_1 = require("rfc4648");
|
|
10
|
+
const types_js_1 = require("./types.js");
|
|
11
|
+
// @ts-ignore: missing types
|
|
12
|
+
const lzma_1 = __importDefault(require("lzma"));
|
|
13
|
+
/**
|
|
14
|
+
* Returns a 2 byte buffer that represents the header of the bysquare
|
|
15
|
+
* specification
|
|
16
|
+
*
|
|
17
|
+
* ```
|
|
18
|
+
* | Attribute | Number of bits | Possible values | Note
|
|
19
|
+
* --------------------------------------------------------------------------------------------
|
|
20
|
+
* | BySquareType | 4 | 0-15 | by square type
|
|
21
|
+
* | Version | 4 | 0-15 | version of the by square type
|
|
22
|
+
* | DocumentType | 4 | 0-15 | document type within given by square type
|
|
23
|
+
* | Reserved | 4 | 0-15 | bits reserved for future needs
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @see 3.5. by square header
|
|
27
|
+
*/
|
|
28
|
+
function bysquareHeader(header = [
|
|
29
|
+
0, 0,
|
|
30
|
+
0, 0
|
|
31
|
+
]) {
|
|
32
|
+
const isValid = header.every((nibble) => 0 <= nibble && nibble <= 15);
|
|
33
|
+
if (!isValid) {
|
|
34
|
+
throw new Error(`Invalid header byte value, valid range <0,15>`);
|
|
35
|
+
}
|
|
36
|
+
const [bySquareType, version, documentType, reserved] = header;
|
|
37
|
+
// Combine 4-nibbles to 2-bytes
|
|
38
|
+
const mergedNibbles = Uint8Array.from([
|
|
39
|
+
(bySquareType << 4) | (version << 0),
|
|
40
|
+
(documentType << 4) | (reserved << 0),
|
|
41
|
+
]);
|
|
42
|
+
return mergedNibbles;
|
|
43
|
+
}
|
|
44
|
+
exports.bysquareHeader = bysquareHeader;
|
|
45
|
+
/**
|
|
46
|
+
* Allocates a new buffer of a 2 bytes that represents LZMA header which
|
|
47
|
+
* contains 16-bit unsigned integer (word, little-endian), which is the size of
|
|
48
|
+
* the decompressed data. Therefore the maximum size of compressed data is
|
|
49
|
+
* limited to 65535
|
|
50
|
+
*
|
|
51
|
+
* @see 3.11. LZMA Compression
|
|
52
|
+
*/
|
|
53
|
+
function datasizeHeader(data) {
|
|
54
|
+
if (data.byteLength >= 2 ** 16) {
|
|
55
|
+
throw new Error("The maximum compressed data size has been reached");
|
|
56
|
+
}
|
|
57
|
+
const header = new Uint8Array(2);
|
|
58
|
+
header.set(Uint16Array.from([data.byteLength]));
|
|
59
|
+
return header;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @see 3.10 Appending CRC32 checksum
|
|
63
|
+
*/
|
|
64
|
+
function checksum(intermediate) {
|
|
65
|
+
const data = crc_32_1.default.str(intermediate);
|
|
66
|
+
const checksum = Buffer.alloc(4);
|
|
67
|
+
checksum.writeUInt32LE(data);
|
|
68
|
+
return checksum;
|
|
69
|
+
}
|
|
70
|
+
exports.checksum = checksum;
|
|
71
|
+
/**
|
|
72
|
+
* Transfer object to a tabbed string and append a CRC32 checksum
|
|
73
|
+
*
|
|
74
|
+
* @see 3.10. Appending CRC32 checksum
|
|
75
|
+
*/
|
|
76
|
+
function addChecksum(model) {
|
|
77
|
+
const intermediate = deserialize(model);
|
|
78
|
+
const checksum = Uint32Array.from([crc_32_1.default.str(intermediate)]);
|
|
79
|
+
const byearray = [...intermediate].map(char => char.charCodeAt(0));
|
|
80
|
+
return Uint8Array.from([
|
|
81
|
+
...new Uint8Array(checksum.buffer),
|
|
82
|
+
...Uint8Array.from(byearray)
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
exports.addChecksum = addChecksum;
|
|
86
|
+
/**
|
|
87
|
+
* Transform data to ordered tab-separated intermediate representation ready for
|
|
88
|
+
* encoding
|
|
89
|
+
*
|
|
90
|
+
* @see Table 15 PAY by square sequence data model
|
|
91
|
+
*/
|
|
92
|
+
function deserialize(data) {
|
|
93
|
+
const intermediate = new Array();
|
|
94
|
+
intermediate.push(data.invoiceId?.toString());
|
|
95
|
+
intermediate.push(data.payments.length.toString());
|
|
96
|
+
for (const p of data.payments) {
|
|
97
|
+
intermediate.push(p.type.toString());
|
|
98
|
+
intermediate.push(p.amount?.toString());
|
|
99
|
+
intermediate.push(p.currencyCode);
|
|
100
|
+
intermediate.push(p.paymentDueDate);
|
|
101
|
+
intermediate.push(p.variableSymbol);
|
|
102
|
+
intermediate.push(p.constantSymbol);
|
|
103
|
+
intermediate.push(p.specificSymbol);
|
|
104
|
+
intermediate.push(p.originatorRefInfo);
|
|
105
|
+
intermediate.push(p.paymentNote);
|
|
106
|
+
intermediate.push(p.bankAccounts.length.toString());
|
|
107
|
+
for (const ba of p.bankAccounts) {
|
|
108
|
+
intermediate.push(ba.iban);
|
|
109
|
+
intermediate.push(ba.bic);
|
|
110
|
+
}
|
|
111
|
+
if (p.type === types_js_1.PaymentOptions.StandingOrder) {
|
|
112
|
+
intermediate.push('1');
|
|
113
|
+
intermediate.push(p.day?.toString());
|
|
114
|
+
intermediate.push(p.month?.toString());
|
|
115
|
+
intermediate.push(p.periodicity);
|
|
116
|
+
intermediate.push(p.lastDate);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
intermediate.push('0');
|
|
120
|
+
}
|
|
121
|
+
if (p.type === types_js_1.PaymentOptions.DirectDebit) {
|
|
122
|
+
intermediate.push('1');
|
|
123
|
+
intermediate.push(p.directDebitScheme?.toString());
|
|
124
|
+
intermediate.push(p.directDebitType?.toString());
|
|
125
|
+
intermediate.push(p.variableSymbol?.toString());
|
|
126
|
+
intermediate.push(p.specificSymbol?.toString());
|
|
127
|
+
intermediate.push(p.originatorRefInfo?.toString());
|
|
128
|
+
intermediate.push(p.mandateId?.toString());
|
|
129
|
+
intermediate.push(p.creditorId?.toString());
|
|
130
|
+
intermediate.push(p.contractId?.toString());
|
|
131
|
+
intermediate.push(p.maxAmount?.toString());
|
|
132
|
+
intermediate.push(p.validTillDate?.toString());
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
intermediate.push('0');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
for (const p of data.payments) {
|
|
139
|
+
intermediate.push(p.beneficiary?.name);
|
|
140
|
+
intermediate.push(p.beneficiary?.street);
|
|
141
|
+
intermediate.push(p.beneficiary?.city);
|
|
142
|
+
}
|
|
143
|
+
return intermediate.join('\t');
|
|
144
|
+
}
|
|
145
|
+
exports.deserialize = deserialize;
|
|
146
|
+
function removeDiacritics(model) {
|
|
147
|
+
for (const payment of model.payments) {
|
|
148
|
+
if (payment.paymentNote) {
|
|
149
|
+
payment.paymentNote = (0, lodash_deburr_1.default)(payment.paymentNote);
|
|
150
|
+
}
|
|
151
|
+
if (payment.beneficiary?.name) {
|
|
152
|
+
payment.beneficiary.name = (0, lodash_deburr_1.default)(payment.beneficiary.name);
|
|
153
|
+
}
|
|
154
|
+
if (payment.beneficiary?.city) {
|
|
155
|
+
payment.beneficiary.city = (0, lodash_deburr_1.default)(payment.beneficiary.city);
|
|
156
|
+
}
|
|
157
|
+
if (payment.beneficiary?.street) {
|
|
158
|
+
payment.beneficiary.street = (0, lodash_deburr_1.default)(payment.beneficiary.street);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Generate QR string ready for encoding into text QR code
|
|
164
|
+
*/
|
|
165
|
+
function generate(model, options = { deburr: true }) {
|
|
166
|
+
if (options.deburr) {
|
|
167
|
+
removeDiacritics(model);
|
|
168
|
+
}
|
|
169
|
+
const payload = addChecksum(model);
|
|
170
|
+
const compressed = Uint8Array.from(lzma_1.default.compress(payload));
|
|
171
|
+
/**
|
|
172
|
+
* @see https://docs.fileformat.com/compression/lzma/#lzma-header
|
|
173
|
+
*/
|
|
174
|
+
const _header = Uint8Array.from(compressed.subarray(0, 13));
|
|
175
|
+
const data = Uint8Array.from(compressed.subarray(13));
|
|
176
|
+
const output = Uint8Array.from([
|
|
177
|
+
...bysquareHeader(),
|
|
178
|
+
...datasizeHeader(payload),
|
|
179
|
+
...data
|
|
180
|
+
]);
|
|
181
|
+
return rfc4648_1.base32hex.stringify(output, {
|
|
182
|
+
pad: false
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
exports.generate = generate;
|
|
File without changes
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.parse = exports.detect = exports.generate = void 0;
|
|
18
|
+
var generate_js_1 = require("./generate.js");
|
|
19
|
+
Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_js_1.generate; } });
|
|
20
|
+
var parse_js_1 = require("./parse.js");
|
|
21
|
+
Object.defineProperty(exports, "detect", { enumerable: true, get: function () { return parse_js_1.detect; } });
|
|
22
|
+
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_js_1.parse; } });
|
|
23
|
+
__exportStar(require("./types.js"), exports);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bysquare",
|
|
3
|
+
"description": "It's a national standard for payment QR codes adopted by Slovak Banking Association (SBA)",
|
|
4
|
+
"version": "2.1.0",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"funding": "https://github.com/sponsors/xseman",
|
|
8
|
+
"homepage": "https://github.com/xseman/bysquare#readme",
|
|
9
|
+
"author": {
|
|
10
|
+
"name": "Filip Seman",
|
|
11
|
+
"email": "filip.seman@protonmail.com"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"prebuild": "rm -rf ./lib || :",
|
|
15
|
+
"build": "tsc --project ./tsconfig.json && tsc --project ./tsconfig.cjs.json",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"postbuild": "bash -c 'chmod +x ./lib/{cjs,mjs}/cli.js' && cp package.json ./lib/mjs/ && jq '.type=\"commonjs\"' package.json > lib/cjs/package.json",
|
|
18
|
+
"test": "xv --loader=tsx ./src",
|
|
19
|
+
"test:watch": "find ./src/*.ts | entr xv --loader=tsx ./src",
|
|
20
|
+
"cli:local": "npm run build && npm link bysquare",
|
|
21
|
+
"version": "git flow release start v$npm_package_version",
|
|
22
|
+
"prepare": "",
|
|
23
|
+
"prepublishOnly": "npm run build",
|
|
24
|
+
"preversion": "git checkout develop",
|
|
25
|
+
"postversion": ""
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"crc-32": "~1.2.0",
|
|
29
|
+
"lodash.deburr": "~4.1.0",
|
|
30
|
+
"lzma": "~2.3.0",
|
|
31
|
+
"rfc4648": "~1.5.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/lodash.deburr": "~4.1.0",
|
|
35
|
+
"@types/lzma-native": "^4.0.1",
|
|
36
|
+
"@types/node": "~18.11.0",
|
|
37
|
+
"tsx": "~3.12.0",
|
|
38
|
+
"typescript": "~4.9.0",
|
|
39
|
+
"xv": "~2.1.0"
|
|
40
|
+
},
|
|
41
|
+
"bin": "lib/mjs/cli.js",
|
|
42
|
+
"types": "lib/mjs/index.d.ts",
|
|
43
|
+
"exports": {
|
|
44
|
+
".": {
|
|
45
|
+
"require": "./lib/cjs/index.js",
|
|
46
|
+
"import": "./lib/mjs/index.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"lib",
|
|
51
|
+
"!lib/*.test.*"
|
|
52
|
+
],
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=16.0",
|
|
55
|
+
"npm": ">=7.0"
|
|
56
|
+
},
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/xseman/bysquare.git"
|
|
60
|
+
},
|
|
61
|
+
"keywords": [
|
|
62
|
+
"pay by square",
|
|
63
|
+
"by square",
|
|
64
|
+
"paybysquare",
|
|
65
|
+
"bysquare",
|
|
66
|
+
"payments",
|
|
67
|
+
"qr-string",
|
|
68
|
+
"qr",
|
|
69
|
+
"cli"
|
|
70
|
+
]
|
|
71
|
+
}
|
|
@@ -2,11 +2,11 @@ import { DataModel } from "./index.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* @see 3.14. Generating by square Code
|
|
4
4
|
*/
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function serialize(qr: string): DataModel;
|
|
6
6
|
/**
|
|
7
7
|
* @see 3.16. Decoding client data from QR Code 2005 symbol
|
|
8
8
|
*/
|
|
9
|
-
export declare function parse(qr: string):
|
|
9
|
+
export declare function parse(qr: string): DataModel;
|
|
10
10
|
/**
|
|
11
11
|
* Detect if qr string contains bysquare header.
|
|
12
12
|
*
|