kassza 0.12.0 → 0.14.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.en.md +48 -0
- package/README.md +427 -32
- package/agents/README.md +26 -6
- package/agents/api.md +218 -3
- package/agents/pitfalls.md +27 -3
- package/agents/recipes.md +280 -51
- package/agents/skills/kassza/SKILL.md +14 -8
- package/agents/skills/migrate-from-szamlazz-js/SKILL.md +39 -0
- package/dist/batch/index.cjs +346 -0
- package/dist/batch/index.d.cts +91 -0
- package/dist/batch/index.d.ts +91 -0
- package/dist/batch/index.js +339 -0
- package/dist/cli.cjs +643 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +643 -0
- package/dist/client-CLFvJCVW.cjs +1452 -0
- package/dist/{client-CL3fuH6A.js → client-Cvf-hTz_.js} +306 -515
- package/dist/client-DeWWQ-RZ.d.ts +341 -0
- package/dist/client-SVZu25MB.d.cts +341 -0
- package/dist/context-CFNKzStE.d.cts +449 -0
- package/dist/context-kb33TgzE.d.ts +449 -0
- package/dist/cookie-stores/index.cjs +21 -150
- package/dist/cookie-stores/index.d.cts +4 -63
- package/dist/cookie-stores/index.d.ts +4 -63
- package/dist/cookie-stores/index.js +3 -144
- package/dist/create-CflXrPip.js +204 -0
- package/dist/create-CvUvLUaT.cjs +257 -0
- package/dist/{create-once-D0pwuenl.cjs → create-once-9yxR_Er_.cjs} +291 -33
- package/dist/create-once-Bh6fOWkW.d.cts +20 -0
- package/dist/{create-once-CqdYmQD8.js → create-once-Ca2gMk1h.js} +250 -34
- package/dist/create-once-VKp0tVow.d.ts +20 -0
- package/dist/{crypto-B8lERvR1.cjs → crypto-Dpn4FHQ6.cjs} +9 -0
- package/dist/{crypto-DK_osBVy.js → crypto-usDg8L2K.js} +4 -1
- package/dist/data-link/index.cjs +232 -0
- package/dist/data-link/index.d.cts +29 -0
- package/dist/data-link/index.d.ts +29 -0
- package/dist/data-link/index.js +224 -0
- package/dist/delegation/index.cjs +35 -34
- package/dist/delegation/index.d.cts +2 -1
- package/dist/delegation/index.d.ts +2 -1
- package/dist/delegation/index.js +4 -3
- package/dist/{errors-DLrb0g64.js → errors-DtN4g5Z9.js} +9 -1
- package/dist/{errors-DxeuTslP.cjs → errors-EE96_6D_.cjs} +20 -0
- package/dist/get-BdMTseh4.cjs +271 -0
- package/dist/get-Byc9T5WO.d.cts +151 -0
- package/dist/get-Byc9T5WO.d.ts +151 -0
- package/dist/get-CZEShCcj.js +260 -0
- package/dist/index-BhUPY_EH.d.cts +109 -0
- package/dist/index-BqGgQ4t3.d.ts +109 -0
- package/dist/{index-CYAGCdKJ.d.cts → index-C-7yWV7L.d.cts} +24 -1
- package/dist/{index-CYAGCdKJ.d.ts → index-C-7yWV7L.d.ts} +24 -1
- package/dist/index.cjs +19 -5
- package/dist/index.d.cts +11 -19
- package/dist/index.d.ts +11 -19
- package/dist/index.js +6 -6
- package/dist/ipn/index.cjs +26 -5
- package/dist/ipn/index.d.cts +12 -1
- package/dist/ipn/index.d.ts +12 -1
- package/dist/ipn/index.js +26 -6
- package/dist/issue-Bin4tKD_.cjs +988 -0
- package/dist/issue-DMA1Nbr1.js +905 -0
- package/dist/journal/index.cjs +454 -0
- package/dist/journal/index.d.cts +18 -0
- package/dist/journal/index.d.ts +18 -0
- package/dist/journal/index.js +445 -0
- package/dist/journal-DvI81Kt7.d.cts +114 -0
- package/dist/journal-Y9qrIB8G.d.ts +114 -0
- package/dist/mcp/index.cjs +10 -0
- package/dist/mcp/index.d.cts +71 -0
- package/dist/mcp/index.d.ts +71 -0
- package/dist/mcp/index.js +2 -0
- package/dist/money/index.cjs +2 -1
- package/dist/money/index.d.cts +2 -2
- package/dist/money/index.d.ts +2 -2
- package/dist/money/index.js +2 -2
- package/dist/{money-DAA7OwiO.js → money-Cw457SD6.js} +120 -12
- package/dist/{money-DrhGkWHW.cjs → money-K9j0wPit.cjs} +124 -10
- package/dist/nav/index.cjs +1046 -0
- package/dist/nav/index.d.cts +247 -0
- package/dist/nav/index.d.ts +247 -0
- package/dist/nav/index.js +1012 -0
- package/dist/nav-BNbc8U0R.cjs +203 -0
- package/dist/nav-BcCerwWS.js +156 -0
- package/dist/node/index.cjs +124 -0
- package/dist/node/index.d.cts +35 -0
- package/dist/node/index.d.ts +35 -0
- package/dist/node/index.js +120 -0
- package/dist/observe/index.cjs +311 -0
- package/dist/observe/index.d.cts +53 -0
- package/dist/observe/index.d.ts +53 -0
- package/dist/observe/index.js +303 -0
- package/dist/once-BN_3B5OF.cjs +103 -0
- package/dist/once-CqqZxsXG.js +74 -0
- package/dist/parse-Cr7yQ3_z.js +291 -0
- package/dist/parse-DOA2XQ3e.cjs +380 -0
- package/dist/payments/barion.cjs +26 -2
- package/dist/payments/barion.d.cts +2 -2
- package/dist/payments/barion.d.ts +2 -2
- package/dist/payments/barion.js +26 -2
- package/dist/payments/index.cjs +7 -2
- package/dist/payments/index.d.cts +4 -4
- package/dist/payments/index.d.ts +4 -4
- package/dist/payments/index.js +3 -3
- package/dist/payments/paypal.cjs +16 -2
- package/dist/payments/paypal.d.cts +2 -2
- package/dist/payments/paypal.d.ts +2 -2
- package/dist/payments/paypal.js +16 -2
- package/dist/payments/revolut.cjs +17 -3
- package/dist/payments/revolut.d.cts +2 -2
- package/dist/payments/revolut.d.ts +2 -2
- package/dist/payments/revolut.js +17 -3
- package/dist/payments/simplepay.cjs +37 -5
- package/dist/payments/simplepay.d.cts +2 -2
- package/dist/payments/simplepay.d.ts +2 -2
- package/dist/payments/simplepay.js +37 -5
- package/dist/payments/stripe.cjs +20 -3
- package/dist/payments/stripe.d.cts +2 -2
- package/dist/payments/stripe.d.ts +2 -2
- package/dist/payments/stripe.js +20 -3
- package/dist/push-BXj0Sf0Z.d.ts +52 -0
- package/dist/push-D4nNbCNV.d.cts +52 -0
- package/dist/reference-B5TATqb5.js +124 -0
- package/dist/reference-BIdYMK0t.cjs +183 -0
- package/dist/reports/index.cjs +11 -164
- package/dist/reports/index.d.cts +1 -1
- package/dist/reports/index.d.ts +1 -1
- package/dist/reports/index.js +1 -154
- package/dist/request-body-CH6ZGOrq.cjs +34 -0
- package/dist/request-body-uZHMRlQr.js +29 -0
- package/dist/serialize-B2eFh3D-.js +219 -0
- package/dist/serialize-CquIsxA-.cjs +290 -0
- package/dist/server-BrJUbXs7.js +1505 -0
- package/dist/server-Dw9j8Mnd.cjs +1558 -0
- package/dist/session-Ckl5eJhV.d.ts +7 -0
- package/dist/{session-CKOuE6Jc.cjs → session-DeM5vjvC.cjs} +69 -13
- package/dist/{session-rMKaJcmq.js → session-SaEEXu2N.js} +58 -14
- package/dist/session-YbChChx7.d.cts +7 -0
- package/dist/storage/fs.cjs +1 -1
- package/dist/storage/fs.js +1 -1
- package/dist/storage/index.cjs +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/store-C1rHd9DB.d.cts +19 -0
- package/dist/store-C1rHd9DB.d.ts +19 -0
- package/dist/stores/index.cjs +24 -0
- package/dist/stores/index.d.cts +4 -0
- package/dist/stores/index.d.ts +4 -0
- package/dist/stores/index.js +3 -0
- package/dist/stores-BNrS0dWl.cjs +506 -0
- package/dist/stores-DhjGBrl_.js +441 -0
- package/dist/testing/index.cjs +1500 -15
- package/dist/testing/index.d.cts +198 -3
- package/dist/testing/index.d.ts +198 -3
- package/dist/testing/index.js +1498 -15
- package/dist/{types-COf1LAD-.d.ts → types-B1A8mUIE.d.cts} +14 -2
- package/dist/{types-COf1LAD-.d.cts → types-ByAEvGsZ.d.ts} +14 -2
- package/dist/{types-k--zHf4l.d.ts → types-D1zDOH_F.d.ts} +1 -1
- package/dist/{types-DH8QoNZK.d.cts → types-lnKkQdot.d.cts} +1 -1
- package/dist/warnings-B3DXnveC.d.cts +31 -0
- package/dist/warnings-B3DXnveC.d.ts +31 -0
- package/dist/warnings-DeIw5RFj.cjs +20 -0
- package/dist/warnings-DwTl5J-2.js +15 -0
- package/dist/{webhook-D4lvtex1.js → webhook-CQVShAfI.js} +47 -26
- package/dist/{webhook-C76bV-4R.cjs → webhook-Ckj-_hPD.cjs} +70 -25
- package/dist/webhook-CmdhGiH5.d.cts +11 -0
- package/dist/webhook-D6lEejob.d.ts +11 -0
- package/llms.txt +6 -5
- package/package.json +134 -4
- package/dist/client-CickRRFr.d.ts +0 -838
- package/dist/client-CsmGIFRS.cjs +0 -1637
- package/dist/client-DvWZoX_E.d.cts +0 -838
- package/dist/issue-BsyYdrIG.cjs +0 -1531
- package/dist/issue-C6Fcjvln.js +0 -1274
- package/dist/session-Dm_45x8K.d.cts +0 -11
- package/dist/session-Dm_45x8K.d.ts +0 -11
- package/dist/webhook-CfaDgcL0.d.cts +0 -6
- package/dist/webhook-q2OzNwd7.d.ts +0 -6
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
const require_errors = require("./errors-EE96_6D_.cjs");
|
|
2
|
+
const require_rounding = require("./rounding-TxoWy2ww.cjs");
|
|
3
|
+
const require_vat = require("./vat-g35srbNG.cjs");
|
|
4
|
+
//#region src/reports/vat-category.ts
|
|
5
|
+
const NAV_VAT_CATEGORIES = [
|
|
6
|
+
"0%",
|
|
7
|
+
"5%",
|
|
8
|
+
"18%",
|
|
9
|
+
"27%",
|
|
10
|
+
"Alanyi adómentes",
|
|
11
|
+
"Egyéb"
|
|
12
|
+
];
|
|
13
|
+
const NUMERIC_CATEGORIES = /* @__PURE__ */ new Map([
|
|
14
|
+
[0, "0%"],
|
|
15
|
+
[5, "5%"],
|
|
16
|
+
[18, "18%"],
|
|
17
|
+
[27, "27%"]
|
|
18
|
+
]);
|
|
19
|
+
function navVatCategory(vat) {
|
|
20
|
+
if (typeof vat === "number") return NUMERIC_CATEGORIES.get(vat) ?? "Egyéb";
|
|
21
|
+
if (vat === "AAM") return "Alanyi adómentes";
|
|
22
|
+
return "Egyéb";
|
|
23
|
+
}
|
|
24
|
+
function isNavVatCategory(value) {
|
|
25
|
+
return NAV_VAT_CATEGORIES.includes(value);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/reports/nav.ts
|
|
29
|
+
const SEQUENCE_PATTERN = /^(.*)-(\d+)$/;
|
|
30
|
+
function splitReceiptNumber(receiptNumber) {
|
|
31
|
+
const match = SEQUENCE_PATTERN.exec(receiptNumber.trim());
|
|
32
|
+
if (!match?.[1]) return {
|
|
33
|
+
series: receiptNumber.trim(),
|
|
34
|
+
sequence: void 0
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
series: match[1],
|
|
38
|
+
sequence: Number(match[2])
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function navCurrencyCode(currency) {
|
|
42
|
+
return require_vat.isHuf(currency) ? "HUF" : currency.trim().toUpperCase();
|
|
43
|
+
}
|
|
44
|
+
function compareReceiptNumbers(a, b) {
|
|
45
|
+
const left = splitReceiptNumber(a);
|
|
46
|
+
const right = splitReceiptNumber(b);
|
|
47
|
+
if (left.series === right.series && left.sequence !== void 0 && right.sequence !== void 0) return left.sequence - right.sequence;
|
|
48
|
+
return a.localeCompare(b, "hu");
|
|
49
|
+
}
|
|
50
|
+
function reportError(message) {
|
|
51
|
+
return new require_errors.SzamlazzError(message, { category: "validation" });
|
|
52
|
+
}
|
|
53
|
+
function exchangeRateOf(receipt, currency) {
|
|
54
|
+
if (currency === "HUF") return null;
|
|
55
|
+
const rate = receipt.exchangeRate;
|
|
56
|
+
if (rate === void 0 || !Number.isFinite(rate) || rate <= 0) throw reportError(`A(z) ${receipt.number} devizás (${currency}) nyugtán nincs érvényes árfolyam, ezért nem összesíthető.`);
|
|
57
|
+
return require_rounding.roundMoney(rate, 4);
|
|
58
|
+
}
|
|
59
|
+
function signedGross(item, receipt) {
|
|
60
|
+
return receipt.type === "reversal" ? -Math.abs(item.grossAmount) : item.grossAmount;
|
|
61
|
+
}
|
|
62
|
+
function bucketFor(buckets, receipt, series, currency, exchangeRate) {
|
|
63
|
+
const key = JSON.stringify([
|
|
64
|
+
receipt.issueDate,
|
|
65
|
+
series,
|
|
66
|
+
currency,
|
|
67
|
+
exchangeRate
|
|
68
|
+
]);
|
|
69
|
+
const existing = buckets.get(key);
|
|
70
|
+
if (existing) return existing;
|
|
71
|
+
const created = {
|
|
72
|
+
applicableDate: receipt.issueDate,
|
|
73
|
+
series,
|
|
74
|
+
currency,
|
|
75
|
+
exchangeRate,
|
|
76
|
+
categories: /* @__PURE__ */ new Map(),
|
|
77
|
+
numbers: [],
|
|
78
|
+
sales: 0,
|
|
79
|
+
modifying: 0
|
|
80
|
+
};
|
|
81
|
+
buckets.set(key, created);
|
|
82
|
+
return created;
|
|
83
|
+
}
|
|
84
|
+
function categoryOrder(name) {
|
|
85
|
+
const index = NAV_VAT_CATEGORIES.indexOf(name);
|
|
86
|
+
return index === -1 ? NAV_VAT_CATEGORIES.length : index;
|
|
87
|
+
}
|
|
88
|
+
function toReport(bucket) {
|
|
89
|
+
const vatCategories = [...bucket.categories.entries()].map(([vat, totals]) => ({
|
|
90
|
+
vat,
|
|
91
|
+
saleDocument: require_rounding.roundMoney(totals.sale, 2),
|
|
92
|
+
modifyingDocument: require_rounding.roundMoney(totals.modifying, 2)
|
|
93
|
+
})).sort((a, b) => categoryOrder(a.vat) - categoryOrder(b.vat) || a.vat.localeCompare(b.vat));
|
|
94
|
+
const total = require_rounding.roundMoney(vatCategories.reduce((sum, row) => sum + row.saleDocument + row.modifyingDocument, 0), 2);
|
|
95
|
+
const receiptNumbers = [...bucket.numbers].sort(compareReceiptNumbers);
|
|
96
|
+
return {
|
|
97
|
+
applicableDate: bucket.applicableDate,
|
|
98
|
+
series: bucket.series,
|
|
99
|
+
serialNumber: receiptNumbers[0] ?? "",
|
|
100
|
+
currency: bucket.currency,
|
|
101
|
+
exchangeRate: bucket.exchangeRate,
|
|
102
|
+
vatCategories,
|
|
103
|
+
total,
|
|
104
|
+
numberOfSaleDocument: bucket.sales,
|
|
105
|
+
numberOfModifyingDocument: bucket.modifying,
|
|
106
|
+
receiptNumbers
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function assertIssueDate(receipt) {
|
|
110
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(receipt.issueDate)) throw reportError(`A(z) ${receipt.number} nyugta kelte érvénytelen: "${receipt.issueDate}".`);
|
|
111
|
+
}
|
|
112
|
+
function navDailyReports(receipts, options = {}) {
|
|
113
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
114
|
+
const seen = /* @__PURE__ */ new Set();
|
|
115
|
+
const seriesOf = options.series ?? ((number) => splitReceiptNumber(number).series);
|
|
116
|
+
const categoryOf = options.vatCategory ?? ((item) => navVatCategory(item.vat));
|
|
117
|
+
for (const receipt of receipts) {
|
|
118
|
+
if (receipt.isTest && options.includeTest !== true) continue;
|
|
119
|
+
if (seen.has(receipt.number)) continue;
|
|
120
|
+
seen.add(receipt.number);
|
|
121
|
+
assertIssueDate(receipt);
|
|
122
|
+
const currency = navCurrencyCode(receipt.currency);
|
|
123
|
+
const bucket = bucketFor(buckets, receipt, seriesOf(receipt.number), currency, exchangeRateOf(receipt, currency));
|
|
124
|
+
bucket.numbers.push(receipt.number);
|
|
125
|
+
const isModifying = receipt.type === "reversal";
|
|
126
|
+
if (isModifying) bucket.modifying += 1;
|
|
127
|
+
else bucket.sales += 1;
|
|
128
|
+
for (const item of receipt.items) {
|
|
129
|
+
const name = categoryOf(item, receipt);
|
|
130
|
+
const totals = bucket.categories.get(name) ?? {
|
|
131
|
+
sale: 0,
|
|
132
|
+
modifying: 0
|
|
133
|
+
};
|
|
134
|
+
if (isModifying) totals.modifying += signedGross(item, receipt);
|
|
135
|
+
else totals.sale += signedGross(item, receipt);
|
|
136
|
+
bucket.categories.set(name, totals);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return [...buckets.values()].map(toReport).sort((a, b) => a.applicableDate.localeCompare(b.applicableDate) || a.series.localeCompare(b.series, "hu") || a.currency.localeCompare(b.currency) || (a.exchangeRate ?? 0) - (b.exchangeRate ?? 0));
|
|
140
|
+
}
|
|
141
|
+
const amountFormatter = new Intl.NumberFormat("hu-HU", {
|
|
142
|
+
minimumFractionDigits: 0,
|
|
143
|
+
maximumFractionDigits: 2
|
|
144
|
+
});
|
|
145
|
+
function describeNavReport(report) {
|
|
146
|
+
return [
|
|
147
|
+
`Tárgynap: ${report.applicableDate}`,
|
|
148
|
+
`Kezdő nyugtasorszám: ${report.serialNumber}`,
|
|
149
|
+
`Pénznem: ${report.currency}${report.exchangeRate === null ? "" : ` (árfolyam: ${report.exchangeRate})`}`,
|
|
150
|
+
...report.vatCategories.map((row) => `${row.vat}: értékesítés ${amountFormatter.format(row.saleDocument)}, módosító/érvénytelenítő ${amountFormatter.format(row.modifyingDocument)}`),
|
|
151
|
+
`Végösszeg: ${amountFormatter.format(report.total)}`,
|
|
152
|
+
`Nyugták száma: ${report.numberOfSaleDocument}, módosító/érvénytelenítő bizonylatok száma: ${report.numberOfModifyingDocument}`
|
|
153
|
+
].join("\n");
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
Object.defineProperty(exports, "NAV_VAT_CATEGORIES", {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
get: function() {
|
|
159
|
+
return NAV_VAT_CATEGORIES;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
Object.defineProperty(exports, "compareReceiptNumbers", {
|
|
163
|
+
enumerable: true,
|
|
164
|
+
get: function() {
|
|
165
|
+
return compareReceiptNumbers;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
Object.defineProperty(exports, "describeNavReport", {
|
|
169
|
+
enumerable: true,
|
|
170
|
+
get: function() {
|
|
171
|
+
return describeNavReport;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
Object.defineProperty(exports, "isNavVatCategory", {
|
|
175
|
+
enumerable: true,
|
|
176
|
+
get: function() {
|
|
177
|
+
return isNavVatCategory;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
Object.defineProperty(exports, "navCurrencyCode", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
get: function() {
|
|
183
|
+
return navCurrencyCode;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
Object.defineProperty(exports, "navDailyReports", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
get: function() {
|
|
189
|
+
return navDailyReports;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
Object.defineProperty(exports, "navVatCategory", {
|
|
193
|
+
enumerable: true,
|
|
194
|
+
get: function() {
|
|
195
|
+
return navVatCategory;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
Object.defineProperty(exports, "splitReceiptNumber", {
|
|
199
|
+
enumerable: true,
|
|
200
|
+
get: function() {
|
|
201
|
+
return splitReceiptNumber;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { r as SzamlazzError } from "./errors-DtN4g5Z9.js";
|
|
2
|
+
import { r as roundMoney } from "./rounding-BLyHjjI5.js";
|
|
3
|
+
import { i as isHuf } from "./vat-v_dcWCto.js";
|
|
4
|
+
//#region src/reports/vat-category.ts
|
|
5
|
+
const NAV_VAT_CATEGORIES = [
|
|
6
|
+
"0%",
|
|
7
|
+
"5%",
|
|
8
|
+
"18%",
|
|
9
|
+
"27%",
|
|
10
|
+
"Alanyi adómentes",
|
|
11
|
+
"Egyéb"
|
|
12
|
+
];
|
|
13
|
+
const NUMERIC_CATEGORIES = /* @__PURE__ */ new Map([
|
|
14
|
+
[0, "0%"],
|
|
15
|
+
[5, "5%"],
|
|
16
|
+
[18, "18%"],
|
|
17
|
+
[27, "27%"]
|
|
18
|
+
]);
|
|
19
|
+
function navVatCategory(vat) {
|
|
20
|
+
if (typeof vat === "number") return NUMERIC_CATEGORIES.get(vat) ?? "Egyéb";
|
|
21
|
+
if (vat === "AAM") return "Alanyi adómentes";
|
|
22
|
+
return "Egyéb";
|
|
23
|
+
}
|
|
24
|
+
function isNavVatCategory(value) {
|
|
25
|
+
return NAV_VAT_CATEGORIES.includes(value);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/reports/nav.ts
|
|
29
|
+
const SEQUENCE_PATTERN = /^(.*)-(\d+)$/;
|
|
30
|
+
function splitReceiptNumber(receiptNumber) {
|
|
31
|
+
const match = SEQUENCE_PATTERN.exec(receiptNumber.trim());
|
|
32
|
+
if (!match?.[1]) return {
|
|
33
|
+
series: receiptNumber.trim(),
|
|
34
|
+
sequence: void 0
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
series: match[1],
|
|
38
|
+
sequence: Number(match[2])
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function navCurrencyCode(currency) {
|
|
42
|
+
return isHuf(currency) ? "HUF" : currency.trim().toUpperCase();
|
|
43
|
+
}
|
|
44
|
+
function compareReceiptNumbers(a, b) {
|
|
45
|
+
const left = splitReceiptNumber(a);
|
|
46
|
+
const right = splitReceiptNumber(b);
|
|
47
|
+
if (left.series === right.series && left.sequence !== void 0 && right.sequence !== void 0) return left.sequence - right.sequence;
|
|
48
|
+
return a.localeCompare(b, "hu");
|
|
49
|
+
}
|
|
50
|
+
function reportError(message) {
|
|
51
|
+
return new SzamlazzError(message, { category: "validation" });
|
|
52
|
+
}
|
|
53
|
+
function exchangeRateOf(receipt, currency) {
|
|
54
|
+
if (currency === "HUF") return null;
|
|
55
|
+
const rate = receipt.exchangeRate;
|
|
56
|
+
if (rate === void 0 || !Number.isFinite(rate) || rate <= 0) throw reportError(`A(z) ${receipt.number} devizás (${currency}) nyugtán nincs érvényes árfolyam, ezért nem összesíthető.`);
|
|
57
|
+
return roundMoney(rate, 4);
|
|
58
|
+
}
|
|
59
|
+
function signedGross(item, receipt) {
|
|
60
|
+
return receipt.type === "reversal" ? -Math.abs(item.grossAmount) : item.grossAmount;
|
|
61
|
+
}
|
|
62
|
+
function bucketFor(buckets, receipt, series, currency, exchangeRate) {
|
|
63
|
+
const key = JSON.stringify([
|
|
64
|
+
receipt.issueDate,
|
|
65
|
+
series,
|
|
66
|
+
currency,
|
|
67
|
+
exchangeRate
|
|
68
|
+
]);
|
|
69
|
+
const existing = buckets.get(key);
|
|
70
|
+
if (existing) return existing;
|
|
71
|
+
const created = {
|
|
72
|
+
applicableDate: receipt.issueDate,
|
|
73
|
+
series,
|
|
74
|
+
currency,
|
|
75
|
+
exchangeRate,
|
|
76
|
+
categories: /* @__PURE__ */ new Map(),
|
|
77
|
+
numbers: [],
|
|
78
|
+
sales: 0,
|
|
79
|
+
modifying: 0
|
|
80
|
+
};
|
|
81
|
+
buckets.set(key, created);
|
|
82
|
+
return created;
|
|
83
|
+
}
|
|
84
|
+
function categoryOrder(name) {
|
|
85
|
+
const index = NAV_VAT_CATEGORIES.indexOf(name);
|
|
86
|
+
return index === -1 ? NAV_VAT_CATEGORIES.length : index;
|
|
87
|
+
}
|
|
88
|
+
function toReport(bucket) {
|
|
89
|
+
const vatCategories = [...bucket.categories.entries()].map(([vat, totals]) => ({
|
|
90
|
+
vat,
|
|
91
|
+
saleDocument: roundMoney(totals.sale, 2),
|
|
92
|
+
modifyingDocument: roundMoney(totals.modifying, 2)
|
|
93
|
+
})).sort((a, b) => categoryOrder(a.vat) - categoryOrder(b.vat) || a.vat.localeCompare(b.vat));
|
|
94
|
+
const total = roundMoney(vatCategories.reduce((sum, row) => sum + row.saleDocument + row.modifyingDocument, 0), 2);
|
|
95
|
+
const receiptNumbers = [...bucket.numbers].sort(compareReceiptNumbers);
|
|
96
|
+
return {
|
|
97
|
+
applicableDate: bucket.applicableDate,
|
|
98
|
+
series: bucket.series,
|
|
99
|
+
serialNumber: receiptNumbers[0] ?? "",
|
|
100
|
+
currency: bucket.currency,
|
|
101
|
+
exchangeRate: bucket.exchangeRate,
|
|
102
|
+
vatCategories,
|
|
103
|
+
total,
|
|
104
|
+
numberOfSaleDocument: bucket.sales,
|
|
105
|
+
numberOfModifyingDocument: bucket.modifying,
|
|
106
|
+
receiptNumbers
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function assertIssueDate(receipt) {
|
|
110
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(receipt.issueDate)) throw reportError(`A(z) ${receipt.number} nyugta kelte érvénytelen: "${receipt.issueDate}".`);
|
|
111
|
+
}
|
|
112
|
+
function navDailyReports(receipts, options = {}) {
|
|
113
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
114
|
+
const seen = /* @__PURE__ */ new Set();
|
|
115
|
+
const seriesOf = options.series ?? ((number) => splitReceiptNumber(number).series);
|
|
116
|
+
const categoryOf = options.vatCategory ?? ((item) => navVatCategory(item.vat));
|
|
117
|
+
for (const receipt of receipts) {
|
|
118
|
+
if (receipt.isTest && options.includeTest !== true) continue;
|
|
119
|
+
if (seen.has(receipt.number)) continue;
|
|
120
|
+
seen.add(receipt.number);
|
|
121
|
+
assertIssueDate(receipt);
|
|
122
|
+
const currency = navCurrencyCode(receipt.currency);
|
|
123
|
+
const bucket = bucketFor(buckets, receipt, seriesOf(receipt.number), currency, exchangeRateOf(receipt, currency));
|
|
124
|
+
bucket.numbers.push(receipt.number);
|
|
125
|
+
const isModifying = receipt.type === "reversal";
|
|
126
|
+
if (isModifying) bucket.modifying += 1;
|
|
127
|
+
else bucket.sales += 1;
|
|
128
|
+
for (const item of receipt.items) {
|
|
129
|
+
const name = categoryOf(item, receipt);
|
|
130
|
+
const totals = bucket.categories.get(name) ?? {
|
|
131
|
+
sale: 0,
|
|
132
|
+
modifying: 0
|
|
133
|
+
};
|
|
134
|
+
if (isModifying) totals.modifying += signedGross(item, receipt);
|
|
135
|
+
else totals.sale += signedGross(item, receipt);
|
|
136
|
+
bucket.categories.set(name, totals);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return [...buckets.values()].map(toReport).sort((a, b) => a.applicableDate.localeCompare(b.applicableDate) || a.series.localeCompare(b.series, "hu") || a.currency.localeCompare(b.currency) || (a.exchangeRate ?? 0) - (b.exchangeRate ?? 0));
|
|
140
|
+
}
|
|
141
|
+
const amountFormatter = new Intl.NumberFormat("hu-HU", {
|
|
142
|
+
minimumFractionDigits: 0,
|
|
143
|
+
maximumFractionDigits: 2
|
|
144
|
+
});
|
|
145
|
+
function describeNavReport(report) {
|
|
146
|
+
return [
|
|
147
|
+
`Tárgynap: ${report.applicableDate}`,
|
|
148
|
+
`Kezdő nyugtasorszám: ${report.serialNumber}`,
|
|
149
|
+
`Pénznem: ${report.currency}${report.exchangeRate === null ? "" : ` (árfolyam: ${report.exchangeRate})`}`,
|
|
150
|
+
...report.vatCategories.map((row) => `${row.vat}: értékesítés ${amountFormatter.format(row.saleDocument)}, módosító/érvénytelenítő ${amountFormatter.format(row.modifyingDocument)}`),
|
|
151
|
+
`Végösszeg: ${amountFormatter.format(report.total)}`,
|
|
152
|
+
`Nyugták száma: ${report.numberOfSaleDocument}, módosító/érvénytelenítő bizonylatok száma: ${report.numberOfModifyingDocument}`
|
|
153
|
+
].join("\n");
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
export { splitReceiptNumber as a, navVatCategory as c, navDailyReports as i, describeNavReport as n, NAV_VAT_CATEGORIES as o, navCurrencyCode as r, isNavVatCategory as s, compareReceiptNumbers as t };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/node/index.ts
|
|
3
|
+
const encoder = new TextEncoder();
|
|
4
|
+
var NodeBodyError = class extends Error {
|
|
5
|
+
name = "NodeBodyError";
|
|
6
|
+
};
|
|
7
|
+
function firstHeader(value) {
|
|
8
|
+
if (value === void 0) return void 0;
|
|
9
|
+
return typeof value === "string" ? value : value[0];
|
|
10
|
+
}
|
|
11
|
+
function requestUrl(request, trustProxy) {
|
|
12
|
+
const forwardedProto = trustProxy ? firstHeader(request.headers["x-forwarded-proto"])?.split(",")[0]?.trim() : void 0;
|
|
13
|
+
const forwardedHost = trustProxy ? firstHeader(request.headers["x-forwarded-host"])?.split(",")[0]?.trim() : void 0;
|
|
14
|
+
const protocol = forwardedProto || (request.socket?.encrypted ? "https" : "http");
|
|
15
|
+
const host = forwardedHost || firstHeader(request.headers.host) || firstHeader(request.headers[":authority"]) || "localhost";
|
|
16
|
+
const path = request.originalUrl ?? request.url ?? "/";
|
|
17
|
+
return `${protocol}://${host}${path.startsWith("/") ? path : `/${path}`}`;
|
|
18
|
+
}
|
|
19
|
+
function requestHeaders(request) {
|
|
20
|
+
const headers = new Headers();
|
|
21
|
+
for (const [name, value] of Object.entries(request.headers)) {
|
|
22
|
+
if (value === void 0 || name.startsWith(":")) continue;
|
|
23
|
+
if (typeof value === "string") headers.append(name, value);
|
|
24
|
+
else for (const item of value) headers.append(name, item);
|
|
25
|
+
}
|
|
26
|
+
return headers;
|
|
27
|
+
}
|
|
28
|
+
function streamOf(source) {
|
|
29
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
30
|
+
return new ReadableStream({
|
|
31
|
+
async pull(controller) {
|
|
32
|
+
const { value, done } = await iterator.next();
|
|
33
|
+
if (done) {
|
|
34
|
+
controller.close();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
controller.enqueue(typeof value === "string" ? encoder.encode(value) : value);
|
|
38
|
+
},
|
|
39
|
+
async cancel(reason) {
|
|
40
|
+
await iterator.return?.(reason);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function bytesOf(value) {
|
|
45
|
+
if (typeof value === "string") return value;
|
|
46
|
+
if (value instanceof Uint8Array) return value;
|
|
47
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
48
|
+
}
|
|
49
|
+
function isUnparsedPlaceholder(request) {
|
|
50
|
+
const { body } = request;
|
|
51
|
+
if (request.readableEnded || typeof body !== "object" || body === null) return false;
|
|
52
|
+
const prototype = Object.getPrototypeOf(body);
|
|
53
|
+
return (prototype === Object.prototype || prototype === null) && Object.keys(body).length === 0;
|
|
54
|
+
}
|
|
55
|
+
function requestBody(request) {
|
|
56
|
+
const method = (request.method ?? "GET").toUpperCase();
|
|
57
|
+
if (method === "GET" || method === "HEAD") return void 0;
|
|
58
|
+
const raw = bytesOf(request.rawBody);
|
|
59
|
+
if (raw !== void 0) return raw;
|
|
60
|
+
if (request.body !== void 0 && request.body !== null && !isUnparsedPlaceholder(request)) {
|
|
61
|
+
const body = bytesOf(request.body);
|
|
62
|
+
if (body !== void 0) return body;
|
|
63
|
+
throw new NodeBodyError("A kérés törzsét egy middleware (például az express.json()) már feldolgozta, így az aláírás nem ellenőrizhető. A webhook útvonalat az express.json() elé tedd, vagy használd rajta az express.raw({ type: \"*/*\" }) middleware-t. NestJS-ben kapcsold be a rawBody: true beállítást.");
|
|
64
|
+
}
|
|
65
|
+
if (request.readableEnded) throw new NodeBodyError("A kérés törzsét egy middleware már elolvasta, és nem adta tovább. A webhook útvonalra ne tegyél törzsolvasó middleware-t, vagy használd az express.raw({ type: \"*/*\" }) middleware-t.");
|
|
66
|
+
if (typeof request[Symbol.asyncIterator] !== "function") return void 0;
|
|
67
|
+
return streamOf(request);
|
|
68
|
+
}
|
|
69
|
+
function toWebRequest(request, options = {}) {
|
|
70
|
+
const node = request;
|
|
71
|
+
const body = requestBody(node);
|
|
72
|
+
const init = {
|
|
73
|
+
method: node.method ?? "GET",
|
|
74
|
+
headers: requestHeaders(node)
|
|
75
|
+
};
|
|
76
|
+
if (body !== void 0) {
|
|
77
|
+
init.body = body;
|
|
78
|
+
if (body instanceof ReadableStream) init.duplex = "half";
|
|
79
|
+
}
|
|
80
|
+
return new Request(requestUrl(node, options.trustProxy === true), init);
|
|
81
|
+
}
|
|
82
|
+
async function writeWebResponse(source, target) {
|
|
83
|
+
const response = target;
|
|
84
|
+
response.statusCode = source.status;
|
|
85
|
+
const setCookies = source.headers.getSetCookie();
|
|
86
|
+
source.headers.forEach((value, name) => {
|
|
87
|
+
if (name.toLowerCase() === "set-cookie") return;
|
|
88
|
+
response.setHeader(name, value);
|
|
89
|
+
});
|
|
90
|
+
if (setCookies.length > 0) response.setHeader("set-cookie", setCookies);
|
|
91
|
+
const body = new Uint8Array(await source.arrayBuffer());
|
|
92
|
+
response.end(body.byteLength > 0 ? body : void 0);
|
|
93
|
+
}
|
|
94
|
+
function reportError(options, error) {
|
|
95
|
+
try {
|
|
96
|
+
if (options.onError) options.onError(error);
|
|
97
|
+
else console.error("[kassza] A Node kérés kezelése nem sikerült.", error);
|
|
98
|
+
} catch {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function toNodeHandler(handler, options = {}) {
|
|
103
|
+
return async (request, response, next) => {
|
|
104
|
+
try {
|
|
105
|
+
await writeWebResponse(await handler(toWebRequest(request, options)), response);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (next) {
|
|
108
|
+
next(error);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
reportError(options, error);
|
|
112
|
+
const target = response;
|
|
113
|
+
if (target.headersSent) return;
|
|
114
|
+
target.statusCode = 500;
|
|
115
|
+
target.setHeader("content-type", "text/plain; charset=utf-8");
|
|
116
|
+
target.end(encoder.encode("A kérés feldolgozása nem sikerült."));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
exports.NodeBodyError = NodeBodyError;
|
|
122
|
+
exports.toNodeHandler = toNodeHandler;
|
|
123
|
+
exports.toWebRequest = toWebRequest;
|
|
124
|
+
exports.writeWebResponse = writeWebResponse;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
//#region src/node/index.d.ts
|
|
3
|
+
export type WebRequestHandler = (request: Request) => Response | Promise<Response>;
|
|
4
|
+
export interface NodeRequestLike {
|
|
5
|
+
[Symbol.asyncIterator]?(): AsyncIterator<Uint8Array | string>;
|
|
6
|
+
readonly method?: string | undefined;
|
|
7
|
+
readonly url?: string | undefined;
|
|
8
|
+
readonly headers: IncomingMessage["headers"];
|
|
9
|
+
readonly readableEnded?: boolean | undefined;
|
|
10
|
+
readonly socket?: {
|
|
11
|
+
readonly encrypted?: boolean | undefined;
|
|
12
|
+
} | undefined;
|
|
13
|
+
readonly originalUrl?: string | undefined;
|
|
14
|
+
readonly body?: unknown;
|
|
15
|
+
readonly rawBody?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface NodeResponseLike {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
setHeader(name: string, value: string | readonly string[]): unknown;
|
|
20
|
+
end(chunk?: Uint8Array): unknown;
|
|
21
|
+
readonly headersSent?: boolean | undefined;
|
|
22
|
+
}
|
|
23
|
+
export type NodeNext = (error?: unknown) => void;
|
|
24
|
+
export interface ToNodeHandlerOptions {
|
|
25
|
+
readonly trustProxy?: boolean | undefined;
|
|
26
|
+
readonly onError?: ((error: unknown) => void) | undefined;
|
|
27
|
+
}
|
|
28
|
+
export type NodeHandler = (request: IncomingMessage | NodeRequestLike, response: ServerResponse | NodeResponseLike, next?: NodeNext) => Promise<void>;
|
|
29
|
+
export declare class NodeBodyError extends Error {
|
|
30
|
+
override readonly name: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function toWebRequest(request: IncomingMessage | NodeRequestLike, options?: ToNodeHandlerOptions): Request;
|
|
33
|
+
export declare function writeWebResponse(source: Response, target: ServerResponse | NodeResponseLike): Promise<void>;
|
|
34
|
+
export declare function toNodeHandler(handler: WebRequestHandler, options?: ToNodeHandlerOptions): NodeHandler;
|
|
35
|
+
//#endregion
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
//#region src/node/index.d.ts
|
|
3
|
+
export type WebRequestHandler = (request: Request) => Response | Promise<Response>;
|
|
4
|
+
export interface NodeRequestLike {
|
|
5
|
+
[Symbol.asyncIterator]?(): AsyncIterator<Uint8Array | string>;
|
|
6
|
+
readonly method?: string | undefined;
|
|
7
|
+
readonly url?: string | undefined;
|
|
8
|
+
readonly headers: IncomingMessage["headers"];
|
|
9
|
+
readonly readableEnded?: boolean | undefined;
|
|
10
|
+
readonly socket?: {
|
|
11
|
+
readonly encrypted?: boolean | undefined;
|
|
12
|
+
} | undefined;
|
|
13
|
+
readonly originalUrl?: string | undefined;
|
|
14
|
+
readonly body?: unknown;
|
|
15
|
+
readonly rawBody?: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface NodeResponseLike {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
setHeader(name: string, value: string | readonly string[]): unknown;
|
|
20
|
+
end(chunk?: Uint8Array): unknown;
|
|
21
|
+
readonly headersSent?: boolean | undefined;
|
|
22
|
+
}
|
|
23
|
+
export type NodeNext = (error?: unknown) => void;
|
|
24
|
+
export interface ToNodeHandlerOptions {
|
|
25
|
+
readonly trustProxy?: boolean | undefined;
|
|
26
|
+
readonly onError?: ((error: unknown) => void) | undefined;
|
|
27
|
+
}
|
|
28
|
+
export type NodeHandler = (request: IncomingMessage | NodeRequestLike, response: ServerResponse | NodeResponseLike, next?: NodeNext) => Promise<void>;
|
|
29
|
+
export declare class NodeBodyError extends Error {
|
|
30
|
+
override readonly name: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function toWebRequest(request: IncomingMessage | NodeRequestLike, options?: ToNodeHandlerOptions): Request;
|
|
33
|
+
export declare function writeWebResponse(source: Response, target: ServerResponse | NodeResponseLike): Promise<void>;
|
|
34
|
+
export declare function toNodeHandler(handler: WebRequestHandler, options?: ToNodeHandlerOptions): NodeHandler;
|
|
35
|
+
//#endregion
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//#region src/node/index.ts
|
|
2
|
+
const encoder = new TextEncoder();
|
|
3
|
+
var NodeBodyError = class extends Error {
|
|
4
|
+
name = "NodeBodyError";
|
|
5
|
+
};
|
|
6
|
+
function firstHeader(value) {
|
|
7
|
+
if (value === void 0) return void 0;
|
|
8
|
+
return typeof value === "string" ? value : value[0];
|
|
9
|
+
}
|
|
10
|
+
function requestUrl(request, trustProxy) {
|
|
11
|
+
const forwardedProto = trustProxy ? firstHeader(request.headers["x-forwarded-proto"])?.split(",")[0]?.trim() : void 0;
|
|
12
|
+
const forwardedHost = trustProxy ? firstHeader(request.headers["x-forwarded-host"])?.split(",")[0]?.trim() : void 0;
|
|
13
|
+
const protocol = forwardedProto || (request.socket?.encrypted ? "https" : "http");
|
|
14
|
+
const host = forwardedHost || firstHeader(request.headers.host) || firstHeader(request.headers[":authority"]) || "localhost";
|
|
15
|
+
const path = request.originalUrl ?? request.url ?? "/";
|
|
16
|
+
return `${protocol}://${host}${path.startsWith("/") ? path : `/${path}`}`;
|
|
17
|
+
}
|
|
18
|
+
function requestHeaders(request) {
|
|
19
|
+
const headers = new Headers();
|
|
20
|
+
for (const [name, value] of Object.entries(request.headers)) {
|
|
21
|
+
if (value === void 0 || name.startsWith(":")) continue;
|
|
22
|
+
if (typeof value === "string") headers.append(name, value);
|
|
23
|
+
else for (const item of value) headers.append(name, item);
|
|
24
|
+
}
|
|
25
|
+
return headers;
|
|
26
|
+
}
|
|
27
|
+
function streamOf(source) {
|
|
28
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
29
|
+
return new ReadableStream({
|
|
30
|
+
async pull(controller) {
|
|
31
|
+
const { value, done } = await iterator.next();
|
|
32
|
+
if (done) {
|
|
33
|
+
controller.close();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
controller.enqueue(typeof value === "string" ? encoder.encode(value) : value);
|
|
37
|
+
},
|
|
38
|
+
async cancel(reason) {
|
|
39
|
+
await iterator.return?.(reason);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function bytesOf(value) {
|
|
44
|
+
if (typeof value === "string") return value;
|
|
45
|
+
if (value instanceof Uint8Array) return value;
|
|
46
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
47
|
+
}
|
|
48
|
+
function isUnparsedPlaceholder(request) {
|
|
49
|
+
const { body } = request;
|
|
50
|
+
if (request.readableEnded || typeof body !== "object" || body === null) return false;
|
|
51
|
+
const prototype = Object.getPrototypeOf(body);
|
|
52
|
+
return (prototype === Object.prototype || prototype === null) && Object.keys(body).length === 0;
|
|
53
|
+
}
|
|
54
|
+
function requestBody(request) {
|
|
55
|
+
const method = (request.method ?? "GET").toUpperCase();
|
|
56
|
+
if (method === "GET" || method === "HEAD") return void 0;
|
|
57
|
+
const raw = bytesOf(request.rawBody);
|
|
58
|
+
if (raw !== void 0) return raw;
|
|
59
|
+
if (request.body !== void 0 && request.body !== null && !isUnparsedPlaceholder(request)) {
|
|
60
|
+
const body = bytesOf(request.body);
|
|
61
|
+
if (body !== void 0) return body;
|
|
62
|
+
throw new NodeBodyError("A kérés törzsét egy middleware (például az express.json()) már feldolgozta, így az aláírás nem ellenőrizhető. A webhook útvonalat az express.json() elé tedd, vagy használd rajta az express.raw({ type: \"*/*\" }) middleware-t. NestJS-ben kapcsold be a rawBody: true beállítást.");
|
|
63
|
+
}
|
|
64
|
+
if (request.readableEnded) throw new NodeBodyError("A kérés törzsét egy middleware már elolvasta, és nem adta tovább. A webhook útvonalra ne tegyél törzsolvasó middleware-t, vagy használd az express.raw({ type: \"*/*\" }) middleware-t.");
|
|
65
|
+
if (typeof request[Symbol.asyncIterator] !== "function") return void 0;
|
|
66
|
+
return streamOf(request);
|
|
67
|
+
}
|
|
68
|
+
function toWebRequest(request, options = {}) {
|
|
69
|
+
const node = request;
|
|
70
|
+
const body = requestBody(node);
|
|
71
|
+
const init = {
|
|
72
|
+
method: node.method ?? "GET",
|
|
73
|
+
headers: requestHeaders(node)
|
|
74
|
+
};
|
|
75
|
+
if (body !== void 0) {
|
|
76
|
+
init.body = body;
|
|
77
|
+
if (body instanceof ReadableStream) init.duplex = "half";
|
|
78
|
+
}
|
|
79
|
+
return new Request(requestUrl(node, options.trustProxy === true), init);
|
|
80
|
+
}
|
|
81
|
+
async function writeWebResponse(source, target) {
|
|
82
|
+
const response = target;
|
|
83
|
+
response.statusCode = source.status;
|
|
84
|
+
const setCookies = source.headers.getSetCookie();
|
|
85
|
+
source.headers.forEach((value, name) => {
|
|
86
|
+
if (name.toLowerCase() === "set-cookie") return;
|
|
87
|
+
response.setHeader(name, value);
|
|
88
|
+
});
|
|
89
|
+
if (setCookies.length > 0) response.setHeader("set-cookie", setCookies);
|
|
90
|
+
const body = new Uint8Array(await source.arrayBuffer());
|
|
91
|
+
response.end(body.byteLength > 0 ? body : void 0);
|
|
92
|
+
}
|
|
93
|
+
function reportError(options, error) {
|
|
94
|
+
try {
|
|
95
|
+
if (options.onError) options.onError(error);
|
|
96
|
+
else console.error("[kassza] A Node kérés kezelése nem sikerült.", error);
|
|
97
|
+
} catch {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function toNodeHandler(handler, options = {}) {
|
|
102
|
+
return async (request, response, next) => {
|
|
103
|
+
try {
|
|
104
|
+
await writeWebResponse(await handler(toWebRequest(request, options)), response);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
if (next) {
|
|
107
|
+
next(error);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
reportError(options, error);
|
|
111
|
+
const target = response;
|
|
112
|
+
if (target.headersSent) return;
|
|
113
|
+
target.statusCode = 500;
|
|
114
|
+
target.setHeader("content-type", "text/plain; charset=utf-8");
|
|
115
|
+
target.end(encoder.encode("A kérés feldolgozása nem sikerült."));
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { NodeBodyError, toNodeHandler, toWebRequest, writeWebResponse };
|