bysquare 2.13.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts ADDED
@@ -0,0 +1,604 @@
1
+ /**
2
+ * Mapping semantic version to encoded version number, header 4-bit.
3
+ * It's a bit silly to limit the version number to 4-bit, if they keep
4
+ * increasing the version number, the latest possible mapped value is 16
5
+ */
6
+ export const Version = {
7
+ /**
8
+ * Created this document from original by square specifications.
9
+ *
10
+ * **Released Date:** 2013-02-22
11
+ */
12
+ "1.0.0": 0x00,
13
+
14
+ /**
15
+ * Added fields for beneficiary name and address
16
+ *
17
+ * **Released Date:** 2015-06-24
18
+ */
19
+ "1.1.0": 0x01,
20
+ } as const;
21
+
22
+ // Add type for enum-like usage
23
+ export type Version = typeof Version[keyof typeof Version];
24
+
25
+ /**
26
+ * Calendar month.
27
+ *
28
+ * @dprint-ignore
29
+ */
30
+ export const Month = {
31
+ January: 0b00000000000001,
32
+ February: 0b00000000000010,
33
+ March: 0b00000000000100,
34
+ April: 0b00000000001000,
35
+ May: 0b00000000010000,
36
+ June: 0b00000000100000,
37
+ July: 0b00000001000000,
38
+ August: 0b00000010000000,
39
+ September: 0b00000100000000,
40
+ October: 0b00001000000000,
41
+ November: 0b00010000000000,
42
+ December: 0b00100000000000,
43
+ } as const;
44
+
45
+ // Add type for enum-like usage
46
+ export type Month = typeof Month[keyof typeof Month];
47
+
48
+ /**
49
+ * Payment day derived from the periodicity. Day of the month is a number
50
+ * between 1 and 31. Day of the week is a number between 1 and 7 (1 = Monday,
51
+ * 2 = Tuesday, …, 7 = Sunday).
52
+ *
53
+ * @dprint-ignore
54
+ */
55
+ export const Periodicity = {
56
+ Daily: "d",
57
+ Weekly: "w",
58
+ Biweekly: "b",
59
+ Monthly: "m",
60
+ Bimonthly: "B",
61
+ Quarterly: "q",
62
+ Semiannually: "s",
63
+ Annually: "a",
64
+ } as const;
65
+
66
+ // Add type for enum-like usage
67
+ export type Periodicity = typeof Periodicity[keyof typeof Periodicity];
68
+
69
+ /**
70
+ * This is the payment day. It's meaning depends on the periodicity, meaning
71
+ * either day of the month (number between 1 and 31) or day of the week
72
+ * (1=Monday,2=Tuesday, …, 7=Sunday).
73
+ *
74
+ * @description Payment day value range from 1 to 31
75
+ * @minimum 1
76
+ * @maximum 31
77
+ */
78
+ export type Day =
79
+ | 1
80
+ | 2
81
+ | 3
82
+ | 4
83
+ | 5
84
+ | 6
85
+ | 7
86
+ | 8
87
+ | 9
88
+ | 10
89
+ | 11
90
+ | 12
91
+ | 13
92
+ | 14
93
+ | 15
94
+ | 16
95
+ | 17
96
+ | 18
97
+ | 19
98
+ | 20
99
+ | 21
100
+ | 22
101
+ | 23
102
+ | 24
103
+ | 25
104
+ | 26
105
+ | 27
106
+ | 28
107
+ | 29
108
+ | 30
109
+ | 31;
110
+
111
+ /**
112
+ * Payment options can be combined. At least one option must be specified:
113
+ *
114
+ * - `PaymentOrder`: Single payment order
115
+ * - `StandingOrder`: Standing order (recurring payment), details in StandingOrderExt
116
+ * - `DirectDebit`: Direct debit, details in DirectDebitExt
117
+ */
118
+ export const PaymentOptions = {
119
+ /**
120
+ * Single payment order
121
+ */
122
+ PaymentOrder: 0b00000001,
123
+
124
+ /**
125
+ * Standing order (recurring payment), details filled in StandingOrderExt
126
+ */
127
+ StandingOrder: 0b00000010,
128
+
129
+ /**
130
+ * Direct debit, details filled in DirectDebitExt
131
+ */
132
+ DirectDebit: 0b00000100,
133
+ } as const;
134
+
135
+ // Add type for enum-like usage
136
+ export type PaymentOptions = typeof PaymentOptions[keyof typeof PaymentOptions];
137
+
138
+ /**
139
+ * Bank account data of the payment recipient.
140
+ */
141
+ export type BankAccount = {
142
+ /**
143
+ * International Bank Account Number in IBAN format.
144
+ *
145
+ * @example "SK8209000000000011424060"
146
+ * @pattern [A-Z]{2}[0-9]{2}[A-Z0-9]{0,30}
147
+ * @minLength 15
148
+ * @maxLength 34
149
+ */
150
+ iban: string;
151
+
152
+ /**
153
+ * Bank Identification Code (BIC) in ISO 9362 format (SWIFT).
154
+ *
155
+ * @example "TATRSKBX"
156
+ * @pattern [A-Z]{4}[A-Z]{2}[A-Z\d]{2}([A-Z\d]{3})?
157
+ * @minLength 8
158
+ * @maxLength 11
159
+ */
160
+ bic?: string;
161
+ };
162
+
163
+ /**
164
+ * Direct debit scheme. One of the following options:
165
+ *
166
+ * - SEPA - Direct debit follows the SEPA scheme
167
+ * - Other - Other scheme
168
+ */
169
+ export const DirectDebitScheme = {
170
+ /**
171
+ * Other scheme
172
+ */
173
+ Other: 0x00,
174
+
175
+ /**
176
+ * SEPA - Direct debit follows the SEPA scheme
177
+ */
178
+ Sepa: 0x01,
179
+ } as const;
180
+
181
+ // Add type for enum-like usage
182
+ export type DirectDebitScheme = typeof DirectDebitScheme[keyof typeof DirectDebitScheme];
183
+
184
+ /**
185
+ * Direct debit type. One of the following options:
186
+ *
187
+ * @maximum 1
188
+ *
189
+ * - one-off: One-time direct debit
190
+ * - recurrent: Recurring direct debit
191
+ */
192
+ export const DirectDebitType = {
193
+ /**
194
+ * One-time direct debit
195
+ */
196
+ OneOff: 0x00,
197
+
198
+ /**
199
+ * Recurring direct debit
200
+ */
201
+ Recurrent: 0x01,
202
+ } as const;
203
+
204
+ // Add type for enum-like usage
205
+ export type DirectDebitType = typeof DirectDebitType[keyof typeof DirectDebitType];
206
+
207
+ export type Beneficiary = {
208
+ /**
209
+ * Beneficiary name.
210
+ *
211
+ * @maxLength 70
212
+ */
213
+ name?: string;
214
+
215
+ /**
216
+ * Beneficiary street address.
217
+ *
218
+ * @maxLength 70
219
+ */
220
+ street?: string;
221
+
222
+ /**
223
+ * Beneficiary city.
224
+ *
225
+ * @maxLength 70
226
+ */
227
+ city?: string;
228
+ };
229
+
230
+ export type SimplePayment = {
231
+ /**
232
+ * Payment amount. Only positive values are allowed. The decimal part is
233
+ * separated by a dot. Can be left empty, e.g., for voluntary donations.
234
+ *
235
+ * @example 1000
236
+ * @example 1.99
237
+ * @example 10.5
238
+ * @example 0.08
239
+ * @minimum 0
240
+ * @maximum 999999999999999
241
+ */
242
+ amount?: number;
243
+
244
+ /**
245
+ * Currency code in [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format (3 letters).
246
+ *
247
+ * @example "EUR"
248
+ * @pattern [A-Z]{3}
249
+ * @minLength 3
250
+ * @maxLength 3
251
+ */
252
+ currencyCode: string | keyof typeof CurrencyCode;
253
+
254
+ /**
255
+ * Payment due date.
256
+ *
257
+ * For standing orders, this indicates the first payment date.
258
+ * The date will be converted to YYYYMMDD format during encoding per specification section 3.7.
259
+ *
260
+ * @format date
261
+ * @example "2024-12-31"
262
+ * @pattern \d{4}-\d{2}-\d{2}
263
+ */
264
+ paymentDueDate?: string;
265
+
266
+ /**
267
+ * Variable symbol, up to 10 digits.
268
+ *
269
+ * @pattern [0-9]{0,10}
270
+ * @maxLength 10
271
+ */
272
+ variableSymbol?: string;
273
+
274
+ /**
275
+ * Constant symbol, a 4-digit payment identifier defined by NBS (National Bank of Slovakia).
276
+ *
277
+ * @pattern [0-9]{0,4}
278
+ * @maxLength 4
279
+ */
280
+ constantSymbol?: string;
281
+
282
+ /**
283
+ * Specific symbol, up to 10 digits.
284
+ *
285
+ * @pattern [0-9]{0,10}
286
+ * @maxLength 10
287
+ */
288
+ specificSymbol?: string;
289
+
290
+ /**
291
+ * Originator's reference information according to SEPA.
292
+ *
293
+ * @maxLength 35
294
+ */
295
+ originatorsReferenceInformation?: string;
296
+
297
+ /**
298
+ * Payment note for the recipient. Contains payment details that help the
299
+ * recipient identify the payment.
300
+ *
301
+ * @maxLength 140
302
+ */
303
+ paymentNote?: string;
304
+
305
+ /**
306
+ * List of bank accounts.
307
+ *
308
+ * @minItems 1
309
+ */
310
+ bankAccounts: BankAccount[];
311
+ beneficiary?: Beneficiary;
312
+ };
313
+
314
+ export type PaymentOrder = SimplePayment & {
315
+ type: typeof PaymentOptions.PaymentOrder;
316
+ };
317
+
318
+ /**
319
+ * Extension of payment data with standing order (recurring payment) settings.
320
+ */
321
+ export type StandingOrder = SimplePayment & {
322
+ type: typeof PaymentOptions.StandingOrder;
323
+ /**
324
+ * Specifies the day on which the standing order will be processed in the
325
+ * specified months.
326
+ *
327
+ * @minimum 1
328
+ * @maximum 31
329
+ */
330
+ day?: number | Day;
331
+
332
+ /**
333
+ * Specifies the months in which the standing order payment should be
334
+ * executed.
335
+ *
336
+ * @example Month.January
337
+ * @example Month.January | Month.July | Month.October
338
+ * @example 577
339
+ */
340
+ month?: keyof typeof Month | number;
341
+
342
+ /**
343
+ * Periodicity (frequency) of the standing order.
344
+ */
345
+ periodicity: keyof typeof Periodicity | string;
346
+
347
+ /**
348
+ * Last payment date within the standing order.
349
+ *
350
+ * @format date
351
+ * @pattern \d{8}
352
+ * @example "20241231"
353
+ */
354
+ lastDate?: string;
355
+ };
356
+
357
+ /**
358
+ * Extension of payment data with direct debit settings and identification.
359
+ */
360
+ export type DirectDebit = SimplePayment & {
361
+ type: typeof PaymentOptions.DirectDebit;
362
+
363
+ /**
364
+ * Direct debit scheme.
365
+ *
366
+ * @example DirectDebitScheme.Sepa
367
+ */
368
+ directDebitScheme?: keyof typeof DirectDebitScheme | number;
369
+
370
+ /**
371
+ * Direct debit type.
372
+ *
373
+ * @example DirectDebitType.Recurrent
374
+ */
375
+ directDebitType?: keyof typeof DirectDebitType | number;
376
+
377
+ /**
378
+ * Mandate identification between creditor and debtor according to SEPA.
379
+ *
380
+ * @maxLength 35
381
+ */
382
+ mandateId?: string;
383
+
384
+ /**
385
+ * Creditor identification according to SEPA.
386
+ *
387
+ * @maxLength 35
388
+ */
389
+ creditorId?: string;
390
+
391
+ /**
392
+ * Contract identification between creditor and debtor according to SEPA.
393
+ *
394
+ * @maxLength 35
395
+ */
396
+ contractId?: string;
397
+
398
+ /**
399
+ * Maximum direct debit amount.
400
+ *
401
+ * @minimum 0
402
+ * @maximum 999999999999999
403
+ */
404
+ maxAmount?: number;
405
+
406
+ /**
407
+ * Direct debit validity date. The direct debit expires on this date.
408
+ *
409
+ * @format date
410
+ * @pattern \d{8}
411
+ * @maxLength 8
412
+ * @example "20241231"
413
+ */
414
+ validTillDate?: string;
415
+ };
416
+
417
+ /**
418
+ * Data for a single payment order.
419
+ */
420
+ export type Payment = PaymentOrder | StandingOrder | DirectDebit;
421
+
422
+ export type DataModel = {
423
+ /**
424
+ * Invoice number if the data is part of an invoice, or an identifier for
425
+ * the issuer's internal purposes.
426
+ *
427
+ * @maxLength 10
428
+ */
429
+ invoiceId?: string;
430
+
431
+ /**
432
+ * List of one or more payments for batch payment orders.
433
+ * The main (preferred) payment should be listed first.
434
+ *
435
+ * @minItems 1
436
+ */
437
+ payments: Payment[];
438
+ };
439
+
440
+ /**
441
+ * [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217)
442
+ */
443
+ export const CurrencyCode = {
444
+ AED: "AED",
445
+ AFN: "AFN",
446
+ ALL: "ALL",
447
+ AMD: "AMD",
448
+ ANG: "ANG",
449
+ AOA: "AOA",
450
+ ARS: "ARS",
451
+ AUD: "AUD",
452
+ AWG: "AWG",
453
+ AZN: "AZN",
454
+ BAM: "BAM",
455
+ BBD: "BBD",
456
+ BDT: "BDT",
457
+ BGN: "BGN",
458
+ BHD: "BHD",
459
+ BIF: "BIF",
460
+ BMD: "BMD",
461
+ BND: "BND",
462
+ BOB: "BOB",
463
+ BRL: "BRL",
464
+ BSD: "BSD",
465
+ BTN: "BTN",
466
+ BWP: "BWP",
467
+ BYN: "BYN",
468
+ BZD: "BZD",
469
+ CAD: "CAD",
470
+ CDF: "CDF",
471
+ CHF: "CHF",
472
+ CLP: "CLP",
473
+ CNY: "CNY",
474
+ COP: "COP",
475
+ CRC: "CRC",
476
+ CUC: "CUC",
477
+ CUP: "CUP",
478
+ CVE: "CVE",
479
+ CZK: "CZK",
480
+ DJF: "DJF",
481
+ DKK: "DKK",
482
+ DOP: "DOP",
483
+ DZD: "DZD",
484
+ EGP: "EGP",
485
+ ERN: "ERN",
486
+ ETB: "ETB",
487
+ EUR: "EUR",
488
+ FJD: "FJD",
489
+ FKP: "FKP",
490
+ GBP: "GBP",
491
+ GEL: "GEL",
492
+ GHS: "GHS",
493
+ GIP: "GIP",
494
+ GMD: "GMD",
495
+ GNF: "GNF",
496
+ GTQ: "GTQ",
497
+ GYD: "GYD",
498
+ HKD: "HKD",
499
+ HNL: "HNL",
500
+ HRK: "HRK",
501
+ HTG: "HTG",
502
+ HUF: "HUF",
503
+ IDR: "IDR",
504
+ ILS: "ILS",
505
+ INR: "INR",
506
+ IQD: "IQD",
507
+ IRR: "IRR",
508
+ ISK: "ISK",
509
+ JMD: "JMD",
510
+ JOD: "JOD",
511
+ JPY: "JPY",
512
+ KES: "KES",
513
+ KGS: "KGS",
514
+ KHR: "KHR",
515
+ KMF: "KMF",
516
+ KPW: "KPW",
517
+ KRW: "KRW",
518
+ KWD: "KWD",
519
+ KYD: "KYD",
520
+ KZT: "KZT",
521
+ LAK: "LAK",
522
+ LBP: "LBP",
523
+ LKR: "LKR",
524
+ LRD: "LRD",
525
+ LSL: "LSL",
526
+ LYD: "LYD",
527
+ MAD: "MAD",
528
+ MDL: "MDL",
529
+ MGA: "MGA",
530
+ MKD: "MKD",
531
+ MMK: "MMK",
532
+ MNT: "MNT",
533
+ MOP: "MOP",
534
+ MRU: "MRU",
535
+ MUR: "MUR",
536
+ MVR: "MVR",
537
+ MWK: "MWK",
538
+ MXN: "MXN",
539
+ MYR: "MYR",
540
+ MZN: "MZN",
541
+ NAD: "NAD",
542
+ NGN: "NGN",
543
+ NIO: "NIO",
544
+ NOK: "NOK",
545
+ NPR: "NPR",
546
+ NZD: "NZD",
547
+ OMR: "OMR",
548
+ PAB: "PAB",
549
+ PEN: "PEN",
550
+ PGK: "PGK",
551
+ PHP: "PHP",
552
+ PKR: "PKR",
553
+ PLN: "PLN",
554
+ PYG: "PYG",
555
+ QAR: "QAR",
556
+ RON: "RON",
557
+ RSD: "RSD",
558
+ RUB: "RUB",
559
+ RWF: "RWF",
560
+ SAR: "SAR",
561
+ SBD: "SBD",
562
+ SCR: "SCR",
563
+ SDG: "SDG",
564
+ SEK: "SEK",
565
+ SGD: "SGD",
566
+ SHP: "SHP",
567
+ SLL: "SLL",
568
+ SOS: "SOS",
569
+ SRD: "SRD",
570
+ SSP: "SSP",
571
+ STN: "STN",
572
+ SVC: "SVC",
573
+ SYP: "SYP",
574
+ SZL: "SZL",
575
+ THB: "THB",
576
+ TJS: "TJS",
577
+ TMT: "TMT",
578
+ TND: "TND",
579
+ TOP: "TOP",
580
+ TRY: "TRY",
581
+ TTD: "TTD",
582
+ TWD: "TWD",
583
+ TZS: "TZS",
584
+ UAH: "UAH",
585
+ UGX: "UGX",
586
+ USD: "USD",
587
+ UYU: "UYU",
588
+ UZS: "UZS",
589
+ VES: "VES",
590
+ VND: "VND",
591
+ VUV: "VUV",
592
+ WST: "WST",
593
+ XAF: "XAF",
594
+ XCD: "XCD",
595
+ XOF: "XOF",
596
+ XPF: "XPF",
597
+ YER: "YER",
598
+ ZAR: "ZAR",
599
+ ZMW: "ZMW",
600
+ ZWL: "ZWL",
601
+ } as const;
602
+
603
+ // Add type for enum-like usage
604
+ export type CurrencyCode = typeof CurrencyCode[keyof typeof CurrencyCode];
@@ -0,0 +1,97 @@
1
+ import validator from "validator";
2
+
3
+ import {
4
+ BankAccount,
5
+ DataModel,
6
+ SimplePayment,
7
+ } from "./types.js";
8
+
9
+ const ErrorMessages = {
10
+ IBAN: "Invalid IBAN. Make sure ISO 13616 format is used.",
11
+ BIC: "Invalid BIC. Make sure ISO 9362 format is used.",
12
+ CurrencyCode: "Invalid currency code. Make sure ISO 4217 format is used.",
13
+ Date: "Invalid date. Make sure ISO 8601 format is used.",
14
+ } as const;
15
+
16
+ /**
17
+ * This error will be thrown in case of a validation issue. It provides message with error description and specific path to issue in dataModel object.
18
+ */
19
+ export class ValidationError extends Error {
20
+ public path: string;
21
+
22
+ /**
23
+ * @param message - explains, what is wrong on the specific field
24
+ * @param path - navigates to the specific field in DataModel, where error occurred
25
+ */
26
+ constructor(
27
+ message: string,
28
+ path: string,
29
+ ) {
30
+ super(message);
31
+ this.name = this.constructor.name;
32
+ this.path = path;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * validates bankAccount fields:
38
+ * - iban (ISO 13616)
39
+ * - bic (ISO 9362)
40
+ */
41
+ export function validateBankAccount(
42
+ bankAccount: BankAccount,
43
+ path: string,
44
+ ): void {
45
+ if (!validator.isIBAN(bankAccount.iban)) {
46
+ throw new ValidationError(ErrorMessages.IBAN, `${path}.iban`);
47
+ }
48
+
49
+ if (bankAccount.bic && !validator.isBIC(bankAccount.bic)) {
50
+ throw new ValidationError(ErrorMessages.BIC, `${path}.bic`);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * validate simple payment fields:
56
+ * - currencyCode (ISO 4217)
57
+ * - paymentDueDate (ISO 8601)
58
+ * - bankAccounts
59
+ *
60
+ * @see validateBankAccount
61
+ */
62
+ export function validateSimplePayment(
63
+ simplePayment: SimplePayment,
64
+ path: string,
65
+ ): void {
66
+ for (const [index, bankAccount] of simplePayment.bankAccounts.entries()) {
67
+ validateBankAccount(bankAccount, `${path}.bankAccounts[${index}]`);
68
+ }
69
+
70
+ if (simplePayment.currencyCode && !validator.isISO4217(simplePayment.currencyCode)) {
71
+ throw new ValidationError(
72
+ ErrorMessages.CurrencyCode,
73
+ `${path}.currencyCode`,
74
+ );
75
+ }
76
+
77
+ if (simplePayment.paymentDueDate && !validator.isDate(simplePayment.paymentDueDate)) {
78
+ throw new ValidationError(
79
+ ErrorMessages.Date,
80
+ `${path}.paymentDueDate`,
81
+ );
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Validate `payments` field of dataModel.
87
+ *
88
+ * @see validateSimplePayment
89
+ * @see ValidationError
90
+ */
91
+ export function validateDataModel(dataModel: DataModel): DataModel {
92
+ for (const [index, payment] of dataModel.payments.entries()) {
93
+ validateSimplePayment(payment, `payments[${index}]`);
94
+ }
95
+
96
+ return dataModel;
97
+ }
package/lib/helpers.d.ts DELETED
@@ -1,34 +0,0 @@
1
- import { type BankAccount, SimplePayment, type StandingOrder } from "./types.js";
2
- type PaymentInput = Pick<BankAccount, "iban"> & Pick<SimplePayment, "amount" | "currencyCode" | "variableSymbol">;
3
- /**
4
- * @deprecated Will be removed as of v3.
5
- * This was intended to simplify the main API, but it has complicated it
6
- * instead, serving only as a limited wrapper. The main goal should be to
7
- * enhance documentation for the main API, enabling users to create their own
8
- * wrappers.
9
- *
10
- * Vytvorí QR pre jednorázovú platbu
11
- */
12
- export declare function simplePayment(input: PaymentInput): string;
13
- /**
14
- * @deprecated Will be removed as of v3.
15
- * This was intended to simplify the main API, but it has complicated it
16
- * instead, serving only as a limited wrapper. The main goal should be to
17
- * enhance documentation for the main API, enabling users to create their own
18
- * wrappers.
19
- *
20
- * Vytvorí QR pre inkaso
21
- */
22
- export declare function directDebit(input: PaymentInput): string;
23
- type StandingInput = PaymentInput & Pick<StandingOrder, "day" | "periodicity">;
24
- /**
25
- * @deprecated Will be removed as of v3.
26
- * This was intended to simplify the main API, but it has complicated it
27
- * instead, serving only as a limited wrapper. The main goal should be to
28
- * enhance documentation for the main API, enabling users to create their own
29
- * wrappers.
30
- *
31
- * Vytvorí QR pre trvalý príkaz
32
- */
33
- export declare function standingOrder(input: StandingInput): string;
34
- export {};