bysquare 2.10.0 → 2.12.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 -49
- package/dist/base32hex.d.ts +2 -0
- package/dist/base32hex.js +53 -0
- package/dist/crc32.d.ts +1 -0
- package/dist/crc32.js +63 -0
- package/dist/decode.d.ts +23 -7
- package/dist/decode.js +90 -97
- package/dist/encode.d.ts +35 -0
- package/dist/encode.js +66 -18
- package/dist/helpers.d.ts +16 -0
- package/dist/helpers.js +52 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/test_assets.d.ts +43 -0
- package/dist/test_assets.js +123 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/validations.js +1 -1
- package/package.json +6 -8
package/README.md
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
# bysquare
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
"PAY by square" is a national standard for QR code payments that was adopted by
|
|
4
|
+
the Slovak Banking Association in 2013. It is incorporated into a variety of
|
|
5
|
+
invoices, reminders and other payment regulations.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
## What it is
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
reminders and other payment regulations.
|
|
9
|
+
- Simple JavaScript library to encode and decode "PAY by square" string.
|
|
10
|
+
- Aim to support simpe programming interface to encode and decode data for QR.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
## What it is not
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
[examples](./docs/examples/).
|
|
16
|
-
|
|
17
|
-
## Features
|
|
18
|
-
|
|
19
|
-
- Encode data to qr string
|
|
20
|
-
- Decode data to json
|
|
21
|
-
- Detect bysquare from qr string
|
|
14
|
+
- Generating QR code images.
|
|
15
|
+
- Parsing QR code images.
|
|
22
16
|
|
|
23
17
|
## Installation
|
|
24
18
|
|
|
@@ -63,59 +57,58 @@ import {
|
|
|
63
57
|
|
|
64
58
|
## Usage
|
|
65
59
|
|
|
66
|
-
###
|
|
60
|
+
### Basic Usage
|
|
61
|
+
|
|
62
|
+
Simple helper functions to wrap encoding for most common use cases.
|
|
63
|
+
|
|
64
|
+
- `simplePayment` - Encode simple payment data.
|
|
65
|
+
- `directDebit` - Encode direct debit data.
|
|
66
|
+
- `standingOrder` - Encode standing order data.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { simplePayment } from "bysquare";
|
|
70
|
+
|
|
71
|
+
const qrstring = simplePayment({
|
|
72
|
+
amount: 100,
|
|
73
|
+
variableSymbol: "123456",
|
|
74
|
+
currencyCode: CurrencyCode.EUR,
|
|
75
|
+
iban: "SK9611000000002918599669",
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Adavanced usage
|
|
80
|
+
|
|
81
|
+
For more complex data use `encode` and `decode` functions:
|
|
67
82
|
|
|
68
83
|
```ts
|
|
69
84
|
import {
|
|
70
85
|
CurrencyCode,
|
|
71
86
|
DataModel,
|
|
87
|
+
decode,
|
|
72
88
|
encode,
|
|
73
89
|
PaymentOptions,
|
|
74
90
|
} from "bysquare";
|
|
75
91
|
|
|
76
|
-
|
|
77
|
-
const qrString = encode({
|
|
92
|
+
const data = {
|
|
78
93
|
invoiceId: "random-id",
|
|
79
94
|
payments: [
|
|
80
95
|
{
|
|
81
96
|
type: PaymentOptions.PaymentOrder,
|
|
82
|
-
amount: 100.0,
|
|
83
|
-
bankAccounts: [
|
|
84
|
-
{
|
|
85
|
-
iban: "SK9611000000002918599669",
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
97
|
currencyCode: CurrencyCode.EUR,
|
|
98
|
+
amount: 100.0,
|
|
89
99
|
variableSymbol: "123",
|
|
100
|
+
paymentNote: "hello world",
|
|
101
|
+
bankAccounts: [{ iban: "SK9611000000002918599669" }],
|
|
102
|
+
// ...more fields
|
|
90
103
|
},
|
|
91
104
|
],
|
|
92
|
-
}
|
|
93
|
-
```
|
|
105
|
+
} satisfies DataModel;
|
|
94
106
|
|
|
95
|
-
|
|
107
|
+
// Encode data to a QR string
|
|
108
|
+
const qrstring = encode(data);
|
|
96
109
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const model = decode(
|
|
101
|
-
"0405QH8090IFU27IV0J6HGGLIOTIBVHNQQJQ6LAVGNBT363HR13JC6CB54HSI0KH9FCRASHNQBSKAQD2LJ4AU400UVKDNDPFRKLOBEVVVU0QJ000",
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
// {
|
|
105
|
-
// invoiceId: "random-id",
|
|
106
|
-
// payments: [
|
|
107
|
-
// {
|
|
108
|
-
// type: 1,
|
|
109
|
-
// amount: 100.0,
|
|
110
|
-
// bankAccounts: [
|
|
111
|
-
// { iban: "SK9611000000002918599669" },
|
|
112
|
-
// ],
|
|
113
|
-
// currencyCode: "EUR",
|
|
114
|
-
// variableSymbol: "123",
|
|
115
|
-
// }
|
|
116
|
-
// ]
|
|
117
|
-
// }
|
|
118
|
-
//
|
|
110
|
+
// Decode QR string back to the original data model
|
|
111
|
+
const model = decode(qrstring);
|
|
119
112
|
```
|
|
120
113
|
|
|
121
114
|
## CLI
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const base32Hex = {
|
|
2
|
+
chars: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
|
|
3
|
+
bits: 5,
|
|
4
|
+
mask: 0b11111, // Mask to extract 5 bits
|
|
5
|
+
};
|
|
6
|
+
export function encode(input, addPadding = true) {
|
|
7
|
+
const output = Array();
|
|
8
|
+
let buffer = 0;
|
|
9
|
+
let bitsLeft = 0;
|
|
10
|
+
for (let i = 0; i < input.length; i++) {
|
|
11
|
+
buffer = (buffer << 8) | input[i];
|
|
12
|
+
bitsLeft += 8;
|
|
13
|
+
while (bitsLeft >= base32Hex.bits) {
|
|
14
|
+
bitsLeft -= base32Hex.bits;
|
|
15
|
+
const index = (buffer >> bitsLeft) & base32Hex.mask;
|
|
16
|
+
output.push(base32Hex.chars[index]);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (bitsLeft > 0) {
|
|
20
|
+
const maskedValue = (buffer << (base32Hex.bits - bitsLeft)) & base32Hex.mask;
|
|
21
|
+
output.push(base32Hex.chars[maskedValue]);
|
|
22
|
+
}
|
|
23
|
+
let base32hex = output.join("");
|
|
24
|
+
if (addPadding) {
|
|
25
|
+
const paddedLength = Math.ceil(base32hex.length / 8) * 8;
|
|
26
|
+
base32hex = base32hex.padEnd(paddedLength, "=");
|
|
27
|
+
}
|
|
28
|
+
return base32hex;
|
|
29
|
+
}
|
|
30
|
+
export function decode(input, isLoose = false) {
|
|
31
|
+
if (isLoose) {
|
|
32
|
+
input = input.toUpperCase();
|
|
33
|
+
const paddingNeeded = (8 - (input.length % 8)) % 8;
|
|
34
|
+
input += "=".repeat(paddingNeeded);
|
|
35
|
+
}
|
|
36
|
+
input = input.replace(/=+$/, "");
|
|
37
|
+
const output = Array();
|
|
38
|
+
let buffer = 0;
|
|
39
|
+
let bitsLeft = 0;
|
|
40
|
+
for (let i = 0; i < input.length; i++) {
|
|
41
|
+
const index = base32Hex.chars.indexOf(input[i]);
|
|
42
|
+
if (index === -1) {
|
|
43
|
+
throw new Error("Invalid base32hex string");
|
|
44
|
+
}
|
|
45
|
+
buffer = (buffer << base32Hex.bits) | index;
|
|
46
|
+
bitsLeft += base32Hex.bits;
|
|
47
|
+
if (bitsLeft >= 8) {
|
|
48
|
+
bitsLeft -= 8;
|
|
49
|
+
output.push((buffer >> bitsLeft) & 0xFF);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Uint8Array.from(output);
|
|
53
|
+
}
|
package/dist/crc32.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function crc32(data: string): number;
|
package/dist/crc32.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Computed CRC32 lookup table
|
|
2
|
+
// const CRC32_TABLE = new Uint32Array(256);
|
|
3
|
+
// for (let i = 0; i < CRC32_TABLE.length; i++) {
|
|
4
|
+
// let crc = i;
|
|
5
|
+
// for (let j = 0; j < 8; j++) {
|
|
6
|
+
// crc = (crc >>> 1) ^ (0xEDB88320 * (crc & 1));
|
|
7
|
+
// }
|
|
8
|
+
// CRC32_TABLE[i] = crc;
|
|
9
|
+
// }
|
|
10
|
+
// dprint-ignore
|
|
11
|
+
const CRC32_TABLE = [
|
|
12
|
+
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
|
13
|
+
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
|
14
|
+
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
|
15
|
+
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
|
16
|
+
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
|
17
|
+
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
|
18
|
+
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
|
19
|
+
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
|
20
|
+
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
|
21
|
+
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
|
22
|
+
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
|
23
|
+
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
|
24
|
+
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
|
25
|
+
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
|
26
|
+
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
|
27
|
+
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
|
28
|
+
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
|
29
|
+
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
|
30
|
+
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
|
31
|
+
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
|
32
|
+
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
|
33
|
+
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
|
34
|
+
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
|
35
|
+
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
|
36
|
+
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
|
37
|
+
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
|
38
|
+
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
|
39
|
+
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
|
40
|
+
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
|
41
|
+
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
|
42
|
+
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
|
43
|
+
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
|
44
|
+
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
|
45
|
+
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
|
46
|
+
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
|
47
|
+
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
|
48
|
+
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
|
49
|
+
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
|
50
|
+
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
|
51
|
+
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
|
52
|
+
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
|
53
|
+
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
|
54
|
+
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
|
55
|
+
];
|
|
56
|
+
export function crc32(data) {
|
|
57
|
+
let crc = 0 ^ (-1);
|
|
58
|
+
const encoded = new TextEncoder().encode(data);
|
|
59
|
+
for (let i = 0; i < encoded.length; i++) {
|
|
60
|
+
crc = (crc >>> 8) ^ CRC32_TABLE[(crc ^ encoded[i]) & 0xFF];
|
|
61
|
+
}
|
|
62
|
+
return (crc ^ (-1)) >>> 0;
|
|
63
|
+
}
|
package/dist/decode.d.ts
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import { DataModel } from "./index.js";
|
|
2
|
+
export declare enum DecodeErrorMessage {
|
|
3
|
+
MissingIBAN = "IBAN is missing",
|
|
4
|
+
/**
|
|
5
|
+
* @description - find original LZMA error in extensions
|
|
6
|
+
*/
|
|
7
|
+
LZMADecompressionFailed = "LZMA decompression failed",
|
|
8
|
+
/**
|
|
9
|
+
* @description - find found version in extensions
|
|
10
|
+
* @see {@link ./types#Version} for valid ranges
|
|
11
|
+
*/
|
|
12
|
+
UnsupportedVersion = "Unsupported version"
|
|
13
|
+
}
|
|
14
|
+
export declare class DecodeError extends Error {
|
|
15
|
+
name: string;
|
|
16
|
+
extensions?: {
|
|
17
|
+
[name: string]: any;
|
|
18
|
+
};
|
|
19
|
+
constructor(message: DecodeErrorMessage, extensions?: {
|
|
20
|
+
[name: string]: any;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
2
23
|
/**
|
|
3
24
|
* Generating by square Code
|
|
4
25
|
*
|
|
5
26
|
* @see 3.14.
|
|
6
27
|
*/
|
|
7
28
|
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
|
-
}
|
|
13
29
|
/** @deprecated */
|
|
14
30
|
export declare const parse: typeof decode;
|
|
15
31
|
/**
|
|
@@ -21,7 +37,7 @@ export declare function decode(qr: string): DataModel;
|
|
|
21
37
|
/**
|
|
22
38
|
* Detect if qr string contains bysquare header.
|
|
23
39
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
40
|
+
* There is not magic header in the bysquare specification.
|
|
41
|
+
* Version is just 4 bites, so it is possible to have false positives.
|
|
26
42
|
*/
|
|
27
43
|
export declare function detect(qr: string): boolean;
|
package/dist/decode.js
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import { decompress } from "lzma1";
|
|
2
|
-
import
|
|
2
|
+
import * as base32hex from "./base32hex.js";
|
|
3
3
|
import { CurrencyCode, PaymentOptions, Version, } from "./index.js";
|
|
4
|
+
export var DecodeErrorMessage;
|
|
5
|
+
(function (DecodeErrorMessage) {
|
|
6
|
+
DecodeErrorMessage["MissingIBAN"] = "IBAN is missing";
|
|
7
|
+
/**
|
|
8
|
+
* @description - find original LZMA error in extensions
|
|
9
|
+
*/
|
|
10
|
+
DecodeErrorMessage["LZMADecompressionFailed"] = "LZMA decompression failed";
|
|
11
|
+
/**
|
|
12
|
+
* @description - find found version in extensions
|
|
13
|
+
* @see {@link ./types#Version} for valid ranges
|
|
14
|
+
*/
|
|
15
|
+
DecodeErrorMessage["UnsupportedVersion"] = "Unsupported version";
|
|
16
|
+
})(DecodeErrorMessage || (DecodeErrorMessage = {}));
|
|
17
|
+
export class DecodeError extends Error {
|
|
18
|
+
name = "DecodeError";
|
|
19
|
+
extensions;
|
|
20
|
+
constructor(message, extensions) {
|
|
21
|
+
super(message);
|
|
22
|
+
if (extensions) {
|
|
23
|
+
this.extensions = extensions;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
4
27
|
function cleanUndefined(obj) {
|
|
5
28
|
Object.keys(obj).forEach((key) => {
|
|
6
29
|
if (typeof obj[key] === "undefined") {
|
|
@@ -8,6 +31,12 @@ function cleanUndefined(obj) {
|
|
|
8
31
|
}
|
|
9
32
|
});
|
|
10
33
|
}
|
|
34
|
+
function decodeNumber(value) {
|
|
35
|
+
return value?.length ? Number(value) : undefined;
|
|
36
|
+
}
|
|
37
|
+
function decodeString(value) {
|
|
38
|
+
return value?.length ? value : undefined;
|
|
39
|
+
}
|
|
11
40
|
/**
|
|
12
41
|
* Generating by square Code
|
|
13
42
|
*
|
|
@@ -26,82 +55,62 @@ export function deserialize(qr) {
|
|
|
26
55
|
const ammount = data.shift();
|
|
27
56
|
const currency = data.shift();
|
|
28
57
|
const dueDate = data.shift();
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
58
|
+
const variableSymbol = data.shift();
|
|
59
|
+
const constantSymbol = data.shift();
|
|
60
|
+
const specificSymbol = data.shift();
|
|
32
61
|
const originatorRefInfo = data.shift();
|
|
33
62
|
const paymentNote = data.shift();
|
|
34
63
|
let payment = {
|
|
35
64
|
bankAccounts: [],
|
|
36
65
|
type: Number(paymentOptions),
|
|
37
66
|
currencyCode: currency ?? CurrencyCode.EUR,
|
|
38
|
-
amount: ammount
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
? variables
|
|
46
|
-
: undefined,
|
|
47
|
-
constantSymbol: constants?.length
|
|
48
|
-
? constants
|
|
49
|
-
: undefined,
|
|
50
|
-
specificSymbol: specifics?.length
|
|
51
|
-
? specifics
|
|
52
|
-
: undefined,
|
|
53
|
-
originatorsReferenceInformation: originatorRefInfo?.length
|
|
54
|
-
? originatorRefInfo
|
|
55
|
-
: undefined,
|
|
56
|
-
paymentNote: paymentNote?.length
|
|
57
|
-
? paymentNote
|
|
58
|
-
: undefined,
|
|
67
|
+
amount: Number(ammount),
|
|
68
|
+
paymentDueDate: dueDate || undefined,
|
|
69
|
+
variableSymbol: variableSymbol || undefined,
|
|
70
|
+
constantSymbol: constantSymbol || undefined,
|
|
71
|
+
specificSymbol: specificSymbol || undefined,
|
|
72
|
+
originatorsReferenceInformation: originatorRefInfo || undefined,
|
|
73
|
+
paymentNote: paymentNote || undefined,
|
|
59
74
|
};
|
|
60
|
-
const
|
|
61
|
-
for (let j = 0; j <
|
|
75
|
+
const numberOfAccounts = Number(data.shift());
|
|
76
|
+
for (let j = 0; j < numberOfAccounts; j++) {
|
|
62
77
|
const iban = data.shift();
|
|
63
78
|
if (iban === undefined || iban.length === 0) {
|
|
64
|
-
throw new
|
|
79
|
+
throw new DecodeError(DecodeErrorMessage.MissingIBAN);
|
|
65
80
|
}
|
|
66
81
|
const bic = data.shift();
|
|
67
82
|
const account = {
|
|
68
83
|
iban: iban,
|
|
69
|
-
bic: bic
|
|
70
|
-
? bic
|
|
71
|
-
: undefined,
|
|
84
|
+
bic: bic || undefined,
|
|
72
85
|
};
|
|
73
86
|
cleanUndefined(account);
|
|
74
87
|
payment.bankAccounts.push(account);
|
|
75
88
|
}
|
|
76
|
-
data.shift();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
};
|
|
102
|
-
break;
|
|
103
|
-
default:
|
|
104
|
-
break;
|
|
89
|
+
const standingOrderExt = data.shift();
|
|
90
|
+
if (standingOrderExt === "1" && payment.type === PaymentOptions.StandingOrder) {
|
|
91
|
+
payment = {
|
|
92
|
+
...payment,
|
|
93
|
+
day: decodeNumber(data.shift()),
|
|
94
|
+
month: decodeNumber(data.shift()),
|
|
95
|
+
periodicity: decodeString(data.shift()),
|
|
96
|
+
lastDate: decodeString(data.shift()),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const directDebitExt = data.shift();
|
|
100
|
+
if (directDebitExt === "1" && payment.type === PaymentOptions.DirectDebit) {
|
|
101
|
+
payment = {
|
|
102
|
+
...payment,
|
|
103
|
+
directDebitScheme: decodeNumber(data.shift()),
|
|
104
|
+
directDebitType: decodeNumber(data.shift()),
|
|
105
|
+
variableSymbol: decodeString(data.shift()),
|
|
106
|
+
specificSymbol: decodeString(data.shift()),
|
|
107
|
+
originatorsReferenceInformation: decodeString(data.shift()),
|
|
108
|
+
mandateId: decodeString(data.shift()),
|
|
109
|
+
creditorId: decodeString(data.shift()),
|
|
110
|
+
contractId: decodeString(data.shift()),
|
|
111
|
+
maxAmount: decodeNumber(data.shift()),
|
|
112
|
+
validTillDate: decodeString(data.shift()),
|
|
113
|
+
};
|
|
105
114
|
}
|
|
106
115
|
cleanUndefined(payment);
|
|
107
116
|
output.payments.push(payment);
|
|
@@ -112,15 +121,9 @@ export function deserialize(qr) {
|
|
|
112
121
|
const addressLine2 = data.shift();
|
|
113
122
|
if (Boolean(name) || Boolean(addressLine1) || Boolean(addressLine2)) {
|
|
114
123
|
const beneficiary = {
|
|
115
|
-
name: name
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
street: addressLine1?.length
|
|
119
|
-
? addressLine1
|
|
120
|
-
: undefined,
|
|
121
|
-
city: addressLine2?.length
|
|
122
|
-
? addressLine2
|
|
123
|
-
: undefined,
|
|
124
|
+
name: name || undefined,
|
|
125
|
+
street: addressLine1 || undefined,
|
|
126
|
+
city: addressLine2 || undefined,
|
|
124
127
|
};
|
|
125
128
|
cleanUndefined(beneficiary);
|
|
126
129
|
output.payments[i].beneficiary = beneficiary;
|
|
@@ -148,14 +151,6 @@ function bysquareHeaderDecoder(header) {
|
|
|
148
151
|
reserved,
|
|
149
152
|
};
|
|
150
153
|
}
|
|
151
|
-
export class DecodeError extends Error {
|
|
152
|
-
cause;
|
|
153
|
-
name = "DecodeError";
|
|
154
|
-
constructor(cause, msg) {
|
|
155
|
-
super(msg);
|
|
156
|
-
this.cause = cause;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
154
|
/** @deprecated */
|
|
160
155
|
export const parse = decode;
|
|
161
156
|
/**
|
|
@@ -164,17 +159,13 @@ export const parse = decode;
|
|
|
164
159
|
* @see 3.16.
|
|
165
160
|
*/
|
|
166
161
|
export function decode(qr) {
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
bytes = base32hex.parse(qr, { loose: true });
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
throw new DecodeError(error, "Unable to decode QR string base32hex encoding");
|
|
173
|
-
}
|
|
162
|
+
const bytes = base32hex.decode(qr);
|
|
174
163
|
const bysquareHeader = bytes.slice(0, 2);
|
|
175
164
|
const decodedBysquareHeader = bysquareHeaderDecoder(bysquareHeader);
|
|
176
165
|
if ((decodedBysquareHeader.version > Version["1.1.0"])) {
|
|
177
|
-
throw new
|
|
166
|
+
throw new DecodeError(DecodeErrorMessage.UnsupportedVersion, {
|
|
167
|
+
version: decodedBysquareHeader.version,
|
|
168
|
+
});
|
|
178
169
|
}
|
|
179
170
|
/**
|
|
180
171
|
* The process of decompressing data requires the addition of an LZMA header
|
|
@@ -182,11 +173,13 @@ export function decode(qr) {
|
|
|
182
173
|
* algorithm to properly interpret and extract the original uncompressed
|
|
183
174
|
* data. Bysquare only store properties
|
|
184
175
|
*
|
|
185
|
-
*
|
|
176
|
+
* @see https://docs.fileformat.com/compression/lzma/
|
|
186
177
|
*
|
|
187
|
-
*
|
|
188
|
-
* |
|
|
189
|
-
*
|
|
178
|
+
* +---------------+---------------------------+-------------------+
|
|
179
|
+
* | 1B | 4B | 8B |
|
|
180
|
+
* +---------------+---------------------------+-------------------+
|
|
181
|
+
* | Properties | Dictionary Size | Uncompressed Size |
|
|
182
|
+
* +---------------+---------------------------+-------------------+
|
|
190
183
|
*/
|
|
191
184
|
const defaultProperties = [0x5D]; // lc=3, lp=0, pb=2
|
|
192
185
|
const defaultDictionarySize = [0x00, 0x02, 0x00, 0x00]; // 2^17
|
|
@@ -207,7 +200,7 @@ export function decode(qr) {
|
|
|
207
200
|
decompressed = decompress(body);
|
|
208
201
|
}
|
|
209
202
|
catch (error) {
|
|
210
|
-
throw new DecodeError(
|
|
203
|
+
throw new DecodeError(DecodeErrorMessage.LZMADecompressionFailed, { error });
|
|
211
204
|
}
|
|
212
205
|
if (typeof decompressed === "string") {
|
|
213
206
|
return deserialize(decompressed);
|
|
@@ -220,21 +213,21 @@ export function decode(qr) {
|
|
|
220
213
|
/**
|
|
221
214
|
* Detect if qr string contains bysquare header.
|
|
222
215
|
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
216
|
+
* There is not magic header in the bysquare specification.
|
|
217
|
+
* Version is just 4 bites, so it is possible to have false positives.
|
|
225
218
|
*/
|
|
226
219
|
export function detect(qr) {
|
|
227
|
-
let
|
|
220
|
+
let decoded;
|
|
228
221
|
try {
|
|
229
|
-
|
|
222
|
+
decoded = base32hex.decode(qr, true);
|
|
230
223
|
}
|
|
231
|
-
catch {
|
|
224
|
+
catch (error) {
|
|
232
225
|
return false;
|
|
233
226
|
}
|
|
234
|
-
if (
|
|
227
|
+
if (decoded.byteLength < 2) {
|
|
235
228
|
return false;
|
|
236
229
|
}
|
|
237
|
-
const bysquareHeader =
|
|
230
|
+
const bysquareHeader = decoded.subarray(0, 2);
|
|
238
231
|
const header = bysquareHeaderDecoder(bysquareHeader);
|
|
239
232
|
const isValid = [
|
|
240
233
|
header.bysquareType,
|
package/dist/encode.d.ts
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
import { DataModel } from "./types.js";
|
|
2
|
+
export declare enum EncodeErrorMessage {
|
|
3
|
+
/**
|
|
4
|
+
* @description - find invalid value in extensions
|
|
5
|
+
*/
|
|
6
|
+
BySquareType = "Invalid BySquareType value in header, valid range <0,15>",
|
|
7
|
+
/**
|
|
8
|
+
* @description - find invalid value in extensions
|
|
9
|
+
* @see {@link ./types#Version} for valid ranges
|
|
10
|
+
*/
|
|
11
|
+
Version = "Invalid Version value in header",
|
|
12
|
+
/**
|
|
13
|
+
* @description - find invalid value in extensions
|
|
14
|
+
*/
|
|
15
|
+
DocumentType = "Invalid DocumentType value in header, valid range <0,15>",
|
|
16
|
+
/**
|
|
17
|
+
* @description - find invalid value in extensions
|
|
18
|
+
*/
|
|
19
|
+
Reserved = "Invalid Reserved value in header, valid range <0,15>",
|
|
20
|
+
/**
|
|
21
|
+
* @description - find actual size of header in extensions
|
|
22
|
+
* @see MAX_COMPRESSED_SIZE
|
|
23
|
+
*/
|
|
24
|
+
HeaderDataSize = "Allowed header data size exceeded"
|
|
25
|
+
}
|
|
26
|
+
export declare class EncodeError extends Error {
|
|
27
|
+
name: string;
|
|
28
|
+
extensions?: {
|
|
29
|
+
[name: string]: any;
|
|
30
|
+
};
|
|
31
|
+
constructor(message: EncodeErrorMessage, extensions?: {
|
|
32
|
+
[name: string]: any;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export declare const MAX_COMPRESSED_SIZE = 131072;
|
|
2
36
|
/**
|
|
3
37
|
* Returns a 2 byte buffer that represents the header of the bysquare
|
|
4
38
|
* specification
|
|
@@ -40,6 +74,7 @@ export declare function addChecksum(serialized: string): Uint8Array;
|
|
|
40
74
|
* @see Table 15.
|
|
41
75
|
*/
|
|
42
76
|
export declare function serialize(data: DataModel): string;
|
|
77
|
+
export declare function removeDiacritics(model: DataModel): void;
|
|
43
78
|
type Options = {
|
|
44
79
|
/**
|
|
45
80
|
* Many banking apps do not support diacritics, which results in errors when
|
package/dist/encode.js
CHANGED
|
@@ -1,10 +1,45 @@
|
|
|
1
|
-
import crc32 from "crc-32";
|
|
2
1
|
import { compress } from "lzma1";
|
|
3
|
-
import
|
|
2
|
+
import * as base32hex from "./base32hex.js";
|
|
3
|
+
import { crc32 } from "./crc32.js";
|
|
4
4
|
import { deburr } from "./deburr.js";
|
|
5
5
|
import { PaymentOptions, Version, } from "./types.js";
|
|
6
6
|
import { validateDataModel } from "./validations.js";
|
|
7
|
-
|
|
7
|
+
export var EncodeErrorMessage;
|
|
8
|
+
(function (EncodeErrorMessage) {
|
|
9
|
+
/**
|
|
10
|
+
* @description - find invalid value in extensions
|
|
11
|
+
*/
|
|
12
|
+
EncodeErrorMessage["BySquareType"] = "Invalid BySquareType value in header, valid range <0,15>";
|
|
13
|
+
/**
|
|
14
|
+
* @description - find invalid value in extensions
|
|
15
|
+
* @see {@link ./types#Version} for valid ranges
|
|
16
|
+
*/
|
|
17
|
+
EncodeErrorMessage["Version"] = "Invalid Version value in header";
|
|
18
|
+
/**
|
|
19
|
+
* @description - find invalid value in extensions
|
|
20
|
+
*/
|
|
21
|
+
EncodeErrorMessage["DocumentType"] = "Invalid DocumentType value in header, valid range <0,15>";
|
|
22
|
+
/**
|
|
23
|
+
* @description - find invalid value in extensions
|
|
24
|
+
*/
|
|
25
|
+
EncodeErrorMessage["Reserved"] = "Invalid Reserved value in header, valid range <0,15>";
|
|
26
|
+
/**
|
|
27
|
+
* @description - find actual size of header in extensions
|
|
28
|
+
* @see MAX_COMPRESSED_SIZE
|
|
29
|
+
*/
|
|
30
|
+
EncodeErrorMessage["HeaderDataSize"] = "Allowed header data size exceeded";
|
|
31
|
+
})(EncodeErrorMessage || (EncodeErrorMessage = {}));
|
|
32
|
+
export class EncodeError extends Error {
|
|
33
|
+
name = "EncodeError";
|
|
34
|
+
extensions;
|
|
35
|
+
constructor(message, extensions) {
|
|
36
|
+
super(message);
|
|
37
|
+
if (extensions) {
|
|
38
|
+
this.extensions = extensions;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export const MAX_COMPRESSED_SIZE = 131_072; // 2^17
|
|
8
43
|
/**
|
|
9
44
|
* Returns a 2 byte buffer that represents the header of the bysquare
|
|
10
45
|
* specification
|
|
@@ -27,16 +62,16 @@ header = [
|
|
|
27
62
|
0x00, 0x00
|
|
28
63
|
]) {
|
|
29
64
|
if (header[0] < 0 || header[0] > 15) {
|
|
30
|
-
throw new
|
|
65
|
+
throw new EncodeError(EncodeErrorMessage.BySquareType, { invalidValue: header[0] });
|
|
31
66
|
}
|
|
32
67
|
if (header[1] < 0 || header[1] > 15) {
|
|
33
|
-
throw new
|
|
68
|
+
throw new EncodeError(EncodeErrorMessage.Version, { invalidValue: header[1] });
|
|
34
69
|
}
|
|
35
70
|
if (header[2] < 0 || header[2] > 15) {
|
|
36
|
-
throw new
|
|
71
|
+
throw new EncodeError(EncodeErrorMessage.DocumentType, { invalidValue: header[2] });
|
|
37
72
|
}
|
|
38
73
|
if (header[3] < 0 || header[3] > 15) {
|
|
39
|
-
throw new
|
|
74
|
+
throw new EncodeError(EncodeErrorMessage.Reserved, { invalidValue: header[3] });
|
|
40
75
|
}
|
|
41
76
|
const [bySquareType, version, documentType, reserved,] = header;
|
|
42
77
|
// Combine 4-nibbles to 2-bytes
|
|
@@ -52,7 +87,10 @@ header = [
|
|
|
52
87
|
*/
|
|
53
88
|
export function headerDataLength(length) {
|
|
54
89
|
if (length >= MAX_COMPRESSED_SIZE) {
|
|
55
|
-
throw new
|
|
90
|
+
throw new EncodeError(EncodeErrorMessage.HeaderDataSize, {
|
|
91
|
+
actualSize: length,
|
|
92
|
+
allowedSize: MAX_COMPRESSED_SIZE,
|
|
93
|
+
});
|
|
56
94
|
}
|
|
57
95
|
const header = new ArrayBuffer(2);
|
|
58
96
|
new DataView(header).setUint16(0, length, true);
|
|
@@ -65,7 +103,7 @@ export function headerDataLength(length) {
|
|
|
65
103
|
*/
|
|
66
104
|
export function addChecksum(serialized) {
|
|
67
105
|
const checksum = new ArrayBuffer(4);
|
|
68
|
-
new DataView(checksum).setUint32(0, crc32
|
|
106
|
+
new DataView(checksum).setUint32(0, crc32(serialized), true);
|
|
69
107
|
const byteArray = new TextEncoder().encode(serialized);
|
|
70
108
|
return Uint8Array.from([
|
|
71
109
|
...new Uint8Array(checksum),
|
|
@@ -131,7 +169,7 @@ export function serialize(data) {
|
|
|
131
169
|
}
|
|
132
170
|
return serialized.join("\t");
|
|
133
171
|
}
|
|
134
|
-
function removeDiacritics(model) {
|
|
172
|
+
export function removeDiacritics(model) {
|
|
135
173
|
for (const payment of model.payments) {
|
|
136
174
|
if (payment.paymentNote) {
|
|
137
175
|
payment.paymentNote = deburr(payment.paymentNote);
|
|
@@ -161,19 +199,29 @@ export function encode(model, options) {
|
|
|
161
199
|
validateDataModel(model);
|
|
162
200
|
}
|
|
163
201
|
const payload = serialize(model);
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
202
|
+
const payloadChecked = addChecksum(payload);
|
|
203
|
+
const payloadCompressed = Uint8Array.from(compress(payloadChecked));
|
|
204
|
+
/**
|
|
205
|
+
* The LZMA files has a 13-byte header that is followed by the LZMA
|
|
206
|
+
* compressed data.
|
|
207
|
+
*
|
|
208
|
+
* @see https://docs.fileformat.com/compression/lzma/
|
|
209
|
+
*
|
|
210
|
+
* +---------------+---------------------------+-------------------+
|
|
211
|
+
* | 1B | 4B | 8B |
|
|
212
|
+
* +---------------+---------------------------+-------------------+
|
|
213
|
+
* | Properties | Dictionary Size | Uncompressed Size |
|
|
214
|
+
* +---------------+---------------------------+-------------------+
|
|
215
|
+
*/
|
|
216
|
+
const _lzmaHeader = Uint8Array.from(payloadCompressed.subarray(0, 13));
|
|
217
|
+
const lzmaBody = Uint8Array.from(payloadCompressed.subarray(13));
|
|
168
218
|
const output = Uint8Array.from([
|
|
169
219
|
// NOTE: Newer version 1.1.0 is not supported by all apps (e.g., TatraBanka).
|
|
170
220
|
// We recommend using version "1.0.0" for better compatibility.
|
|
171
221
|
// ...headerBysquare([0x00, Version["1.1.0"], 0x00, 0x00]),
|
|
172
222
|
...headerBysquare([0x00, Version["1.0.0"], 0x00, 0x00]),
|
|
173
|
-
...headerDataLength(
|
|
223
|
+
...headerDataLength(payloadChecked.byteLength),
|
|
174
224
|
...lzmaBody,
|
|
175
225
|
]);
|
|
176
|
-
return base32hex.
|
|
177
|
-
pad: false,
|
|
178
|
-
});
|
|
226
|
+
return base32hex.encode(output, false);
|
|
179
227
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type BankAccount, SimplePayment, type StandingOrder } from "./types.js";
|
|
2
|
+
type PaymentInput = Pick<BankAccount, "iban"> & Pick<SimplePayment, "amount" | "currencyCode" | "variableSymbol">;
|
|
3
|
+
/**
|
|
4
|
+
* Vytvorí QR pre jednorázovú platbu
|
|
5
|
+
*/
|
|
6
|
+
export declare function simplePayment(input: PaymentInput): string;
|
|
7
|
+
/**
|
|
8
|
+
* Vytvorí QR pre inkaso
|
|
9
|
+
*/
|
|
10
|
+
export declare function directDebit(input: PaymentInput): string;
|
|
11
|
+
type StandingInput = PaymentInput & Pick<StandingOrder, "day" | "periodicity">;
|
|
12
|
+
/**
|
|
13
|
+
* Vytvorí QR pre trvalý príkaz
|
|
14
|
+
*/
|
|
15
|
+
export declare function standingOrder(input: StandingInput): string;
|
|
16
|
+
export {};
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { encode } from "./encode.js";
|
|
2
|
+
import { CurrencyCode, PaymentOptions, } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Vytvorí QR pre jednorázovú platbu
|
|
5
|
+
*/
|
|
6
|
+
export function simplePayment(input) {
|
|
7
|
+
return encode({
|
|
8
|
+
payments: [
|
|
9
|
+
{
|
|
10
|
+
type: PaymentOptions.PaymentOrder,
|
|
11
|
+
amount: input.amount,
|
|
12
|
+
variableSymbol: input.variableSymbol,
|
|
13
|
+
currencyCode: CurrencyCode.EUR,
|
|
14
|
+
bankAccounts: [{ iban: input.iban }],
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Vytvorí QR pre inkaso
|
|
21
|
+
*/
|
|
22
|
+
export function directDebit(input) {
|
|
23
|
+
return encode({
|
|
24
|
+
payments: [
|
|
25
|
+
{
|
|
26
|
+
type: PaymentOptions.DirectDebit,
|
|
27
|
+
amount: input.amount,
|
|
28
|
+
variableSymbol: input.variableSymbol,
|
|
29
|
+
currencyCode: CurrencyCode.EUR,
|
|
30
|
+
bankAccounts: [{ iban: input.iban }],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Vytvorí QR pre trvalý príkaz
|
|
37
|
+
*/
|
|
38
|
+
export function standingOrder(input) {
|
|
39
|
+
return encode({
|
|
40
|
+
payments: [
|
|
41
|
+
{
|
|
42
|
+
type: PaymentOptions.StandingOrder,
|
|
43
|
+
day: input.day,
|
|
44
|
+
periodicity: input.periodicity,
|
|
45
|
+
amount: input.amount,
|
|
46
|
+
variableSymbol: input.variableSymbol,
|
|
47
|
+
currencyCode: CurrencyCode.EUR,
|
|
48
|
+
bankAccounts: [{ iban: input.iban }],
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CurrencyCode, PaymentOptions, Periodicity } from "./types.js";
|
|
2
|
+
export declare const payloadWithPaymentOrder: {
|
|
3
|
+
invoiceId: string;
|
|
4
|
+
payments: {
|
|
5
|
+
type: PaymentOptions.PaymentOrder;
|
|
6
|
+
amount: number;
|
|
7
|
+
bankAccounts: {
|
|
8
|
+
iban: string;
|
|
9
|
+
}[];
|
|
10
|
+
currencyCode: CurrencyCode;
|
|
11
|
+
variableSymbol: string;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
export declare const serializedPaymentOrder: string;
|
|
15
|
+
export declare const payloadWithStandingOrder: {
|
|
16
|
+
invoiceId: string;
|
|
17
|
+
payments: {
|
|
18
|
+
type: PaymentOptions.StandingOrder;
|
|
19
|
+
amount: number;
|
|
20
|
+
bankAccounts: {
|
|
21
|
+
iban: string;
|
|
22
|
+
}[];
|
|
23
|
+
periodicity: Periodicity.Monthly;
|
|
24
|
+
currencyCode: CurrencyCode;
|
|
25
|
+
variableSymbol: string;
|
|
26
|
+
lastDate: string;
|
|
27
|
+
day: number;
|
|
28
|
+
}[];
|
|
29
|
+
};
|
|
30
|
+
export declare const serializedStandingOrder: string;
|
|
31
|
+
export declare const payloadWithDirectDebit: {
|
|
32
|
+
invoiceId: string;
|
|
33
|
+
payments: {
|
|
34
|
+
type: PaymentOptions.DirectDebit;
|
|
35
|
+
amount: number;
|
|
36
|
+
bankAccounts: {
|
|
37
|
+
iban: string;
|
|
38
|
+
}[];
|
|
39
|
+
currencyCode: CurrencyCode;
|
|
40
|
+
variableSymbol: string;
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
43
|
+
export declare const serializedDirectDebit: string;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { CurrencyCode, PaymentOptions, Periodicity, } from "./types.js";
|
|
2
|
+
export const payloadWithPaymentOrder = {
|
|
3
|
+
invoiceId: "random-id",
|
|
4
|
+
payments: [
|
|
5
|
+
{
|
|
6
|
+
type: PaymentOptions.PaymentOrder,
|
|
7
|
+
amount: 100.0,
|
|
8
|
+
bankAccounts: [
|
|
9
|
+
{ iban: "SK9611000000002918599669" },
|
|
10
|
+
],
|
|
11
|
+
currencyCode: CurrencyCode.EUR,
|
|
12
|
+
variableSymbol: "123",
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
export const serializedPaymentOrder = /** dprint-ignore */ [
|
|
17
|
+
"random-id",
|
|
18
|
+
"\t", "1",
|
|
19
|
+
"\t", "1",
|
|
20
|
+
"\t", "100",
|
|
21
|
+
"\t", "EUR",
|
|
22
|
+
"\t",
|
|
23
|
+
"\t", "123",
|
|
24
|
+
"\t",
|
|
25
|
+
"\t",
|
|
26
|
+
"\t",
|
|
27
|
+
"\t",
|
|
28
|
+
"\t", "1",
|
|
29
|
+
"\t", "SK9611000000002918599669",
|
|
30
|
+
"\t",
|
|
31
|
+
"\t", "0",
|
|
32
|
+
"\t", "0",
|
|
33
|
+
"\t",
|
|
34
|
+
"\t",
|
|
35
|
+
"\t",
|
|
36
|
+
].join("");
|
|
37
|
+
export const payloadWithStandingOrder = {
|
|
38
|
+
invoiceId: "random-id",
|
|
39
|
+
payments: [
|
|
40
|
+
{
|
|
41
|
+
type: PaymentOptions.StandingOrder,
|
|
42
|
+
amount: 100.0,
|
|
43
|
+
bankAccounts: [
|
|
44
|
+
{ iban: "SK9611000000002918599669" },
|
|
45
|
+
],
|
|
46
|
+
periodicity: Periodicity.Monthly,
|
|
47
|
+
currencyCode: CurrencyCode.EUR,
|
|
48
|
+
variableSymbol: "123",
|
|
49
|
+
lastDate: "20241011",
|
|
50
|
+
day: 1,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
export const serializedStandingOrder = /** dprint-ignore */ [
|
|
55
|
+
"random-id",
|
|
56
|
+
"\t", "1",
|
|
57
|
+
"\t", "2",
|
|
58
|
+
"\t", "100",
|
|
59
|
+
"\t", "EUR",
|
|
60
|
+
"\t",
|
|
61
|
+
"\t", "123",
|
|
62
|
+
"\t",
|
|
63
|
+
"\t",
|
|
64
|
+
"\t",
|
|
65
|
+
"\t",
|
|
66
|
+
"\t", "1",
|
|
67
|
+
"\t", "SK9611000000002918599669",
|
|
68
|
+
"\t",
|
|
69
|
+
"\t", "1",
|
|
70
|
+
"\t", "1",
|
|
71
|
+
"\t",
|
|
72
|
+
"\t", "m",
|
|
73
|
+
"\t", "20241011",
|
|
74
|
+
"\t", "0",
|
|
75
|
+
"\t",
|
|
76
|
+
"\t",
|
|
77
|
+
"\t",
|
|
78
|
+
].join("");
|
|
79
|
+
export const payloadWithDirectDebit = {
|
|
80
|
+
invoiceId: "random-id",
|
|
81
|
+
payments: [
|
|
82
|
+
{
|
|
83
|
+
type: PaymentOptions.DirectDebit,
|
|
84
|
+
amount: 100.0,
|
|
85
|
+
bankAccounts: [
|
|
86
|
+
{ iban: "SK9611000000002918599669" },
|
|
87
|
+
],
|
|
88
|
+
currencyCode: CurrencyCode.EUR,
|
|
89
|
+
variableSymbol: "123",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
export const serializedDirectDebit = /** dprint-ignore */ [
|
|
94
|
+
"random-id",
|
|
95
|
+
"\t", "1",
|
|
96
|
+
"\t", "4",
|
|
97
|
+
"\t", "100",
|
|
98
|
+
"\t", "EUR",
|
|
99
|
+
"\t",
|
|
100
|
+
"\t", "123",
|
|
101
|
+
"\t",
|
|
102
|
+
"\t",
|
|
103
|
+
"\t",
|
|
104
|
+
"\t",
|
|
105
|
+
"\t", "1",
|
|
106
|
+
"\t", "SK9611000000002918599669",
|
|
107
|
+
"\t",
|
|
108
|
+
"\t", "0",
|
|
109
|
+
"\t", "1",
|
|
110
|
+
"\t",
|
|
111
|
+
"\t",
|
|
112
|
+
"\t", "123",
|
|
113
|
+
"\t",
|
|
114
|
+
"\t",
|
|
115
|
+
"\t",
|
|
116
|
+
"\t",
|
|
117
|
+
"\t",
|
|
118
|
+
"\t",
|
|
119
|
+
"\t",
|
|
120
|
+
"\t",
|
|
121
|
+
"\t",
|
|
122
|
+
"\t",
|
|
123
|
+
].join("");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/base32hex.test.ts","../src/base32hex.ts","../src/cli.ts","../src/crc32.test.ts","../src/crc32.ts","../src/deburr.test.ts","../src/deburr.ts","../src/decode.test.ts","../src/decode.ts","../src/encode.test.ts","../src/encode.ts","../src/helper.test.ts","../src/helpers.ts","../src/index.ts","../src/test_assets.ts","../src/types.ts","../src/validations.test.ts","../src/validations.ts"],"version":"5.6.2"}
|
package/dist/types.d.ts
CHANGED
package/dist/validations.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.
|
|
4
|
+
"version": "2.12.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"funding": "https://github.com/sponsors/xseman",
|
|
7
7
|
"homepage": "https://github.com/xseman/bysquare#readme",
|
|
@@ -24,21 +24,19 @@
|
|
|
24
24
|
"typecheck": "tsc --noEmit",
|
|
25
25
|
"version": "git checkout develop && npm test",
|
|
26
26
|
"postversion": "echo 'Now run npm run build && npm publish'",
|
|
27
|
-
"test": "TS_NODE_TRANSPILE_ONLY=true node --test --loader=ts-node/esm --no-warnings src/*.test.ts",
|
|
27
|
+
"test": "TS_NODE_TRANSPILE_ONLY=true node --test --experimental-test-coverage --loader=ts-node/esm --no-warnings src/*.test.ts",
|
|
28
28
|
"test:watch": "TS_NODE_TRANSPILE_ONLY=true node --test --watch --loader=ts-node/esm --no-warnings src/*.test.ts"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"
|
|
32
|
-
"lzma1": "0.0.2",
|
|
33
|
-
"rfc4648": "~1.5.0",
|
|
31
|
+
"lzma1": "0.0.3",
|
|
34
32
|
"validator": "^13.12.0"
|
|
35
33
|
},
|
|
36
34
|
"devDependencies": {
|
|
37
|
-
"@types/node": "
|
|
35
|
+
"@types/node": "^22.7.0",
|
|
38
36
|
"@types/validator": "^13.12.0",
|
|
39
37
|
"dprint": "~0.47.0",
|
|
40
38
|
"ts-node": "~10.9.0",
|
|
41
|
-
"typescript": "~5.
|
|
39
|
+
"typescript": "~5.6.0"
|
|
42
40
|
},
|
|
43
41
|
"type": "module",
|
|
44
42
|
"bin": "./dist/cli.js",
|
|
@@ -54,7 +52,7 @@
|
|
|
54
52
|
"!dist/*.test.*"
|
|
55
53
|
],
|
|
56
54
|
"engines": {
|
|
57
|
-
"node": ">=
|
|
55
|
+
"node": ">=16",
|
|
58
56
|
"npm": ">=7"
|
|
59
57
|
}
|
|
60
58
|
}
|