kassza 0.13.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 +152 -22
- package/agents/README.md +6 -1
- package/agents/api.md +64 -12
- package/agents/pitfalls.md +12 -1
- package/agents/recipes.md +67 -8
- package/agents/skills/kassza/SKILL.md +3 -0
- 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 +105 -14
- package/dist/cli.js +104 -13
- package/dist/{client-C-PdfL_P.cjs → client-CLFvJCVW.cjs} +358 -181
- package/dist/{client-CfaS1-Jx.js → client-Cvf-hTz_.js} +311 -152
- package/dist/{client-6MkeuFqD.d.ts → client-DeWWQ-RZ.d.ts} +99 -26
- package/dist/{client-B5FryKxJ.d.cts → client-SVZu25MB.d.cts} +99 -26
- package/dist/{context-DXNbTPwz.d.cts → context-CFNKzStE.d.cts} +82 -58
- package/dist/{context-BxQlIlug.d.ts → context-kb33TgzE.d.ts} +82 -58
- 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-DgMtKKcG.cjs → create-once-9yxR_Er_.cjs} +285 -33
- package/dist/create-once-Bh6fOWkW.d.cts +20 -0
- package/dist/{create-once-Cz621l8r.js → create-once-Ca2gMk1h.js} +250 -34
- package/dist/create-once-VKp0tVow.d.ts +20 -0
- package/dist/data-link/index.cjs +4 -4
- package/dist/data-link/index.d.cts +2 -52
- package/dist/data-link/index.d.ts +2 -52
- package/dist/data-link/index.js +4 -4
- package/dist/delegation/index.cjs +4 -4
- package/dist/delegation/index.d.cts +2 -2
- package/dist/delegation/index.d.ts +2 -2
- package/dist/delegation/index.js +4 -4
- package/dist/{errors-DLrb0g64.js → errors-DtN4g5Z9.js} +9 -1
- package/dist/{errors-DxeuTslP.cjs → errors-EE96_6D_.cjs} +20 -0
- package/dist/{get-Csm2n0rZ.cjs → get-BdMTseh4.cjs} +9 -183
- package/dist/{get-DT3JEgQ6.js → get-CZEShCcj.js} +4 -124
- 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 +10 -20
- package/dist/index.d.ts +10 -20
- 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-AGRohSm7.cjs → issue-Bin4tKD_.cjs} +416 -342
- package/dist/{issue-DtSLpVdJ.js → issue-DMA1Nbr1.js} +394 -266
- 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 +1 -1
- package/dist/mcp/index.d.cts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- 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-t7uy1n91.js → money-Cw457SD6.js} +95 -3
- package/dist/{money-BxytJW6f.cjs → money-K9j0wPit.cjs} +99 -1
- package/dist/nav/index.cjs +2 -2
- package/dist/nav/index.d.cts +1 -1
- package/dist/nav/index.d.ts +1 -1
- package/dist/nav/index.js +2 -2
- package/dist/{nav-BEwcX7-N.cjs → nav-BNbc8U0R.cjs} +1 -1
- package/dist/{nav-CK1WgYo7.js → nav-BcCerwWS.js} +1 -1
- 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-C608ehqM.js → parse-Cr7yQ3_z.js} +2 -2
- package/dist/{parse-BJj-aqKy.cjs → parse-DOA2XQ3e.cjs} +2 -2
- 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 +16 -2
- package/dist/payments/revolut.d.cts +2 -2
- package/dist/payments/revolut.d.ts +2 -2
- package/dist/payments/revolut.js +16 -2
- package/dist/payments/simplepay.cjs +36 -4
- package/dist/payments/simplepay.d.cts +2 -2
- package/dist/payments/simplepay.d.ts +2 -2
- package/dist/payments/simplepay.js +36 -4
- package/dist/payments/stripe.cjs +19 -2
- package/dist/payments/stripe.d.cts +2 -2
- package/dist/payments/stripe.d.ts +2 -2
- package/dist/payments/stripe.js +19 -2
- 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 +1 -1
- package/dist/reports/index.d.cts +1 -1
- package/dist/reports/index.d.ts +1 -1
- package/dist/reports/index.js +1 -1
- package/dist/{serialize-DSE_o9RK.js → serialize-B2eFh3D-.js} +5 -1
- package/dist/{serialize-BXOww1Uq.cjs → serialize-CquIsxA-.cjs} +5 -1
- package/dist/{server-Cd8HB661.js → server-BrJUbXs7.js} +8 -7
- package/dist/{server-C6PoNkdD.cjs → server-Dw9j8Mnd.cjs} +17 -16
- 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 +28 -16
- package/dist/testing/index.d.cts +6 -3
- package/dist/testing/index.d.ts +6 -3
- package/dist/testing/index.js +26 -14
- package/dist/{types-BVeR7KyU.d.ts → types-B1A8mUIE.d.cts} +13 -1
- package/dist/{types-BVeR7KyU.d.cts → types-ByAEvGsZ.d.ts} +13 -1
- 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-CrEGohbg.js → webhook-CQVShAfI.js} +44 -1
- package/dist/{webhook-81giRMdQ.cjs → webhook-Ckj-_hPD.cjs} +67 -0
- package/dist/webhook-CmdhGiH5.d.cts +11 -0
- package/dist/webhook-D6lEejob.d.ts +11 -0
- package/llms.txt +4 -3
- package/package.json +92 -4
- package/dist/session-Dm_45x8K.d.cts +0 -11
- package/dist/session-Dm_45x8K.d.ts +0 -11
- package/dist/webhook-CpCMHhn2.d.ts +0 -6
- package/dist/webhook-CpMJuP6c.d.cts +0 -6
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
const require_binary = require("./binary-B89HM03_.cjs");
|
|
2
|
+
const require_session = require("./session-DeM5vjvC.cjs");
|
|
3
|
+
//#region src/cookie-stores/resilient.ts
|
|
4
|
+
function warnCookieStoreError(event) {
|
|
5
|
+
const continuation = ATOMIC_OPERATIONS.has(event.operation) ? "a hibát a kassza kapja meg és kezeli." : "a kérés session nélkül folytatódik.";
|
|
6
|
+
console.warn(`[szamlazz] A tároló "${event.operation}" művelete sikertelen, ${continuation}`, event.error);
|
|
7
|
+
}
|
|
8
|
+
const ATOMIC_OPERATIONS = /* @__PURE__ */ new Set([
|
|
9
|
+
"setIfAbsent",
|
|
10
|
+
"increment",
|
|
11
|
+
"deleteIfEquals"
|
|
12
|
+
]);
|
|
13
|
+
function withTimeout(promise, timeoutMs, operation) {
|
|
14
|
+
if (timeoutMs === void 0) return promise;
|
|
15
|
+
let timer;
|
|
16
|
+
const timeout = new Promise((_, reject) => {
|
|
17
|
+
timer = setTimeout(() => {
|
|
18
|
+
reject(/* @__PURE__ */ new Error(`A session cookie store "${operation}" művelete nem fejeződött be ${timeoutMs} ms alatt.`));
|
|
19
|
+
}, timeoutMs);
|
|
20
|
+
});
|
|
21
|
+
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
22
|
+
}
|
|
23
|
+
function resilientCookieStore(store, options = {}) {
|
|
24
|
+
const onError = options.onError ?? warnCookieStoreError;
|
|
25
|
+
if (options.timeoutMs !== void 0 && !(options.timeoutMs > 0)) throw new RangeError(`A timeoutMs pozitív szám legyen, kapott: ${options.timeoutMs}`);
|
|
26
|
+
function report(operation, key, error) {
|
|
27
|
+
try {
|
|
28
|
+
onError({
|
|
29
|
+
operation,
|
|
30
|
+
key,
|
|
31
|
+
error
|
|
32
|
+
});
|
|
33
|
+
} catch {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function run(operation, key, call) {
|
|
38
|
+
try {
|
|
39
|
+
return await withTimeout(Promise.resolve().then(call), options.timeoutMs, operation);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
report(operation, key, error);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function strict(operation, key, call) {
|
|
46
|
+
try {
|
|
47
|
+
return await withTimeout(Promise.resolve().then(call), options.timeoutMs, operation);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
report(operation, key, error);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const setIfAbsent = store.setIfAbsent?.bind(store);
|
|
54
|
+
const increment = store.increment?.bind(store);
|
|
55
|
+
const deleteIfEquals = store.deleteIfEquals?.bind(store);
|
|
56
|
+
return {
|
|
57
|
+
async get(key) {
|
|
58
|
+
return await run("get", key, () => store.get(key)) ?? void 0;
|
|
59
|
+
},
|
|
60
|
+
async set(key, value, ttlSeconds) {
|
|
61
|
+
await run("set", key, () => store.set(key, value, ttlSeconds));
|
|
62
|
+
},
|
|
63
|
+
async delete(key) {
|
|
64
|
+
await run("delete", key, () => store.delete(key));
|
|
65
|
+
},
|
|
66
|
+
...setIfAbsent && { setIfAbsent: (key, value, ttlSeconds) => strict("setIfAbsent", key, () => setIfAbsent(key, value, ttlSeconds)) },
|
|
67
|
+
...increment && { increment: (key, ttlSeconds) => strict("increment", key, () => increment(key, ttlSeconds)) },
|
|
68
|
+
...deleteIfEquals && { deleteIfEquals: (key, value) => strict("deleteIfEquals", key, () => deleteIfEquals(key, value)) }
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/cookie-stores/shared.ts
|
|
73
|
+
function prefixKey(options, key) {
|
|
74
|
+
const prefix = options?.prefix;
|
|
75
|
+
return prefix ? `${prefix}${key}` : key;
|
|
76
|
+
}
|
|
77
|
+
function finalizeCookieStore(store, options) {
|
|
78
|
+
if (options?.resilient === false) return store;
|
|
79
|
+
return resilientCookieStore(store, {
|
|
80
|
+
onError: options?.onError,
|
|
81
|
+
timeoutMs: options?.timeoutMs
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function readCookieValue(value) {
|
|
85
|
+
if (typeof value === "string") return value === "" ? void 0 : value;
|
|
86
|
+
if (value instanceof Uint8Array) return readCookieValue(require_binary.decodeUtf8(value));
|
|
87
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
88
|
+
}
|
|
89
|
+
function wholeSeconds(ttlSeconds, minimum) {
|
|
90
|
+
if (!Number.isFinite(ttlSeconds)) return minimum;
|
|
91
|
+
return Math.max(minimum, Math.ceil(ttlSeconds));
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/cookie-stores/cloudflare-kv.ts
|
|
95
|
+
const CLOUDFLARE_KV_MIN_TTL_SECONDS = 60;
|
|
96
|
+
function cloudflareKvCookieStore(namespace, options) {
|
|
97
|
+
return finalizeCookieStore({
|
|
98
|
+
async get(key) {
|
|
99
|
+
return readCookieValue(await namespace.get(prefixKey(options, key)));
|
|
100
|
+
},
|
|
101
|
+
async set(key, value, ttlSeconds) {
|
|
102
|
+
await namespace.put(prefixKey(options, key), value, { expirationTtl: wholeSeconds(ttlSeconds, 60) });
|
|
103
|
+
},
|
|
104
|
+
async delete(key) {
|
|
105
|
+
await namespace.delete(prefixKey(options, key));
|
|
106
|
+
}
|
|
107
|
+
}, options);
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/cookie-stores/custom.ts
|
|
111
|
+
function customCookieStore(store, options) {
|
|
112
|
+
const prefixed = (key) => prefixKey(options, key);
|
|
113
|
+
const wrapped = {
|
|
114
|
+
get: (key) => store.get(prefixed(key)),
|
|
115
|
+
set: (key, value, ttlSeconds) => store.set(prefixed(key), value, ttlSeconds),
|
|
116
|
+
delete: (key) => store.delete(prefixed(key))
|
|
117
|
+
};
|
|
118
|
+
const setIfAbsent = store.setIfAbsent?.bind(store);
|
|
119
|
+
const increment = store.increment?.bind(store);
|
|
120
|
+
const deleteIfEquals = store.deleteIfEquals?.bind(store);
|
|
121
|
+
return finalizeCookieStore({
|
|
122
|
+
...wrapped,
|
|
123
|
+
...setIfAbsent && { setIfAbsent: (key, value, ttlSeconds) => setIfAbsent(prefixed(key), value, ttlSeconds) },
|
|
124
|
+
...increment && { increment: (key, ttlSeconds) => increment(prefixed(key), ttlSeconds) },
|
|
125
|
+
...deleteIfEquals && { deleteIfEquals: (key, value) => deleteIfEquals(prefixed(key), value) }
|
|
126
|
+
}, options);
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/cookie-stores/scripts.ts
|
|
130
|
+
const SET_IF_ABSENT_SCRIPT = "if redis.call('SET', KEYS[1], ARGV[1], 'NX', 'EX', ARGV[2]) then return 1 else return 0 end";
|
|
131
|
+
const INCREMENT_SCRIPT = "local value = redis.call('INCR', KEYS[1]) redis.call('EXPIRE', KEYS[1], ARGV[1]) return value";
|
|
132
|
+
const DELETE_IF_EQUALS_SCRIPT = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end";
|
|
133
|
+
function scriptNumber(value) {
|
|
134
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
135
|
+
if (!Number.isFinite(parsed)) throw new TypeError(`A Redis szkript nem számot adott vissza: ${String(value)}`);
|
|
136
|
+
return parsed;
|
|
137
|
+
}
|
|
138
|
+
function atomicOperations(run, prefixed, seconds) {
|
|
139
|
+
return {
|
|
140
|
+
async setIfAbsent(key, value, ttlSeconds) {
|
|
141
|
+
return scriptNumber(await run(SET_IF_ABSENT_SCRIPT, prefixed(key), [value, String(seconds(ttlSeconds))])) === 1;
|
|
142
|
+
},
|
|
143
|
+
async increment(key, ttlSeconds) {
|
|
144
|
+
return scriptNumber(await run(INCREMENT_SCRIPT, prefixed(key), [String(seconds(ttlSeconds))]));
|
|
145
|
+
},
|
|
146
|
+
async deleteIfEquals(key, value) {
|
|
147
|
+
return scriptNumber(await run(DELETE_IF_EQUALS_SCRIPT, prefixed(key), [value])) > 0;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/cookie-stores/ioredis.ts
|
|
153
|
+
function ioredisCookieStore(redis, options) {
|
|
154
|
+
const base = {
|
|
155
|
+
async get(key) {
|
|
156
|
+
return readCookieValue(await redis.get(prefixKey(options, key)));
|
|
157
|
+
},
|
|
158
|
+
async set(key, value, ttlSeconds) {
|
|
159
|
+
await redis.set(prefixKey(options, key), value, "EX", wholeSeconds(ttlSeconds, 1));
|
|
160
|
+
},
|
|
161
|
+
async delete(key) {
|
|
162
|
+
await redis.del(prefixKey(options, key));
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const evaluate = redis.eval?.bind(redis);
|
|
166
|
+
if (!evaluate) return finalizeCookieStore(base, options);
|
|
167
|
+
const atomic = atomicOperations((script, key, args) => evaluate(script, 1, key, ...args), (key) => prefixKey(options, key), (ttlSeconds) => wholeSeconds(ttlSeconds, 1));
|
|
168
|
+
return finalizeCookieStore({
|
|
169
|
+
...base,
|
|
170
|
+
...atomic
|
|
171
|
+
}, options);
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/cookie-stores/node-redis.ts
|
|
175
|
+
function nodeRedisCookieStore(client, options) {
|
|
176
|
+
const base = {
|
|
177
|
+
async get(key) {
|
|
178
|
+
return readCookieValue(await client.get(prefixKey(options, key)));
|
|
179
|
+
},
|
|
180
|
+
async set(key, value, ttlSeconds) {
|
|
181
|
+
await client.set(prefixKey(options, key), value, { EX: wholeSeconds(ttlSeconds, 1) });
|
|
182
|
+
},
|
|
183
|
+
async delete(key) {
|
|
184
|
+
await client.del(prefixKey(options, key));
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const evaluate = client.eval?.bind(client);
|
|
188
|
+
if (!evaluate) return finalizeCookieStore(base, options);
|
|
189
|
+
const atomic = atomicOperations((script, key, args) => evaluate(script, {
|
|
190
|
+
keys: [key],
|
|
191
|
+
arguments: args
|
|
192
|
+
}), (key) => prefixKey(options, key), (ttlSeconds) => wholeSeconds(ttlSeconds, 1));
|
|
193
|
+
return finalizeCookieStore({
|
|
194
|
+
...base,
|
|
195
|
+
...atomic
|
|
196
|
+
}, options);
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region src/cookie-stores/upstash.ts
|
|
200
|
+
function upstashRedisCookieStore(redis, options) {
|
|
201
|
+
const base = {
|
|
202
|
+
async get(key) {
|
|
203
|
+
return readCookieValue(await redis.get(prefixKey(options, key)));
|
|
204
|
+
},
|
|
205
|
+
async set(key, value, ttlSeconds) {
|
|
206
|
+
await redis.set(prefixKey(options, key), value, { ex: wholeSeconds(ttlSeconds, 1) });
|
|
207
|
+
},
|
|
208
|
+
async delete(key) {
|
|
209
|
+
await redis.del(prefixKey(options, key));
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
const evaluate = redis.eval?.bind(redis);
|
|
213
|
+
if (!evaluate) return finalizeCookieStore(base, options);
|
|
214
|
+
const atomic = atomicOperations((script, key, args) => evaluate(script, [key], args), (key) => prefixKey(options, key), (ttlSeconds) => wholeSeconds(ttlSeconds, 1));
|
|
215
|
+
return finalizeCookieStore({
|
|
216
|
+
...base,
|
|
217
|
+
...atomic
|
|
218
|
+
}, options);
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/stores/diagnose.ts
|
|
222
|
+
function randomSuffix() {
|
|
223
|
+
return Array.from(crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(8)), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
224
|
+
}
|
|
225
|
+
function messageOf(error) {
|
|
226
|
+
return error instanceof Error ? error.message : String(error);
|
|
227
|
+
}
|
|
228
|
+
async function diagnoseStore(store, options = {}) {
|
|
229
|
+
const now = options.now ?? (() => Date.now());
|
|
230
|
+
const key = `${options.keyPrefix ?? "szamlazz:diagnose:"}${randomSuffix()}`;
|
|
231
|
+
const capabilities = require_session.storeCapabilities(store);
|
|
232
|
+
const problems = [];
|
|
233
|
+
const started = now();
|
|
234
|
+
const step = async (label, run) => {
|
|
235
|
+
try {
|
|
236
|
+
await run();
|
|
237
|
+
return true;
|
|
238
|
+
} catch (error) {
|
|
239
|
+
problems.push(`${label}: ${messageOf(error)}`);
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const basic = await step("írás és olvasás", async () => {
|
|
244
|
+
await store.set(key, "kassza", 60);
|
|
245
|
+
const read = await store.get(key);
|
|
246
|
+
if (read !== "kassza") throw new Error(`a visszaolvasott érték: ${String(read)}`);
|
|
247
|
+
await store.delete(key);
|
|
248
|
+
const deleted = await store.get(key);
|
|
249
|
+
if (deleted !== void 0 && deleted !== null) throw new Error("a törölt kulcs még olvasható");
|
|
250
|
+
});
|
|
251
|
+
const lock = capabilities.setIfAbsent && await step("setIfAbsent", async () => {
|
|
252
|
+
if (await store.setIfAbsent?.(key, "a", 60) !== true) throw new Error("az üres kulcsra false");
|
|
253
|
+
if (await store.setIfAbsent?.(key, "b", 60) !== false) throw new Error("a foglalt kulcsra true");
|
|
254
|
+
if (capabilities.deleteIfEquals) {
|
|
255
|
+
if (await store.deleteIfEquals?.(key, "b") !== false) throw new Error("deleteIfEquals idegen tokenre törölt");
|
|
256
|
+
if (await store.deleteIfEquals?.(key, "a") !== true) throw new Error("deleteIfEquals a saját tokenre nem törölt");
|
|
257
|
+
} else await store.delete(key);
|
|
258
|
+
});
|
|
259
|
+
const counter = capabilities.increment && await step("increment", async () => {
|
|
260
|
+
const first = await store.increment?.(key, 60);
|
|
261
|
+
const second = await store.increment?.(key, 60);
|
|
262
|
+
if (first !== 1 || second !== 2) throw new Error(`a számláló értékei: ${first}, ${second}`);
|
|
263
|
+
await store.delete(key);
|
|
264
|
+
});
|
|
265
|
+
await Promise.resolve(store.delete(key)).catch(() => void 0);
|
|
266
|
+
if (!capabilities.setIfAbsent) problems.push("Nincs setIfAbsent: createOnce zárnak nem alkalmas (például Cloudflare KV).");
|
|
267
|
+
if (!capabilities.increment) problems.push("Nincs increment: naplónak nem alkalmas, a próbálkozás-napló nem atomikus.");
|
|
268
|
+
return {
|
|
269
|
+
ok: basic && lock === true && counter === true,
|
|
270
|
+
capabilities,
|
|
271
|
+
suitableFor: {
|
|
272
|
+
session: basic,
|
|
273
|
+
attemptLedger: basic,
|
|
274
|
+
createOnceLock: basic && lock === true,
|
|
275
|
+
journal: basic && counter === true,
|
|
276
|
+
webhookDedupe: basic
|
|
277
|
+
},
|
|
278
|
+
latencyMs: Math.max(0, now() - started),
|
|
279
|
+
problems
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/stores/durable-object.ts
|
|
284
|
+
const OPERATIONS = /* @__PURE__ */ new Set([
|
|
285
|
+
"get",
|
|
286
|
+
"set",
|
|
287
|
+
"delete",
|
|
288
|
+
"setIfAbsent",
|
|
289
|
+
"increment",
|
|
290
|
+
"deleteIfEquals"
|
|
291
|
+
]);
|
|
292
|
+
const DURABLE_OBJECT_STORE_URL = "https://kassza-store.internal/";
|
|
293
|
+
function isEntry(value) {
|
|
294
|
+
if (typeof value !== "object" || value === null) return false;
|
|
295
|
+
const entry = value;
|
|
296
|
+
return typeof entry.value === "string" && typeof entry.expiresAt === "number";
|
|
297
|
+
}
|
|
298
|
+
async function readLive(storage, key, now) {
|
|
299
|
+
const stored = await storage.get(key);
|
|
300
|
+
if (!isEntry(stored)) return void 0;
|
|
301
|
+
if (stored.expiresAt <= now) {
|
|
302
|
+
await storage.delete(key);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
return stored.value;
|
|
306
|
+
}
|
|
307
|
+
function expiresAt(ttlSeconds, now) {
|
|
308
|
+
return now + Math.max(1, Math.ceil(ttlSeconds !== void 0 && Number.isFinite(ttlSeconds) ? ttlSeconds : 1)) * 1e3;
|
|
309
|
+
}
|
|
310
|
+
function parseCommand(body) {
|
|
311
|
+
if (typeof body !== "object" || body === null) return void 0;
|
|
312
|
+
const command = body;
|
|
313
|
+
if (typeof command.op !== "string" || !OPERATIONS.has(command.op)) return void 0;
|
|
314
|
+
if (typeof command.key !== "string" || command.key === "") return void 0;
|
|
315
|
+
if (command.value !== void 0 && typeof command.value !== "string") return void 0;
|
|
316
|
+
if (command.ttlSeconds !== void 0 && typeof command.ttlSeconds !== "number") return void 0;
|
|
317
|
+
return command;
|
|
318
|
+
}
|
|
319
|
+
function requireValue(command) {
|
|
320
|
+
if (command.value === void 0) throw new TypeError(`A(z) ${command.op} művelethez érték kell.`);
|
|
321
|
+
return command.value;
|
|
322
|
+
}
|
|
323
|
+
async function runCommand(storage, command, now) {
|
|
324
|
+
const { key } = command;
|
|
325
|
+
switch (command.op) {
|
|
326
|
+
case "get": return await readLive(storage, key, now) ?? null;
|
|
327
|
+
case "set":
|
|
328
|
+
await storage.put(key, {
|
|
329
|
+
value: requireValue(command),
|
|
330
|
+
expiresAt: expiresAt(command.ttlSeconds, now)
|
|
331
|
+
});
|
|
332
|
+
return null;
|
|
333
|
+
case "delete":
|
|
334
|
+
await storage.delete(key);
|
|
335
|
+
return null;
|
|
336
|
+
case "setIfAbsent": {
|
|
337
|
+
const value = requireValue(command);
|
|
338
|
+
if (await readLive(storage, key, now) !== void 0) return false;
|
|
339
|
+
await storage.put(key, {
|
|
340
|
+
value,
|
|
341
|
+
expiresAt: expiresAt(command.ttlSeconds, now)
|
|
342
|
+
});
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
case "increment": {
|
|
346
|
+
const current = Number.parseInt(await readLive(storage, key, now) ?? "0", 10);
|
|
347
|
+
const next = (Number.isInteger(current) ? current : 0) + 1;
|
|
348
|
+
await storage.put(key, {
|
|
349
|
+
value: String(next),
|
|
350
|
+
expiresAt: expiresAt(command.ttlSeconds, now)
|
|
351
|
+
});
|
|
352
|
+
return next;
|
|
353
|
+
}
|
|
354
|
+
case "deleteIfEquals":
|
|
355
|
+
if (await readLive(storage, key, now) !== requireValue(command)) return false;
|
|
356
|
+
await storage.delete(key);
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function jsonResponse(body, status = 200) {
|
|
361
|
+
return new Response(JSON.stringify(body), {
|
|
362
|
+
status,
|
|
363
|
+
headers: { "content-type": "application/json" }
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
async function handleDurableObjectStoreRequest(storage, request) {
|
|
367
|
+
if (request.method !== "POST") return jsonResponse({ error: "Csak POST kérés engedélyezett." }, 405);
|
|
368
|
+
let command;
|
|
369
|
+
try {
|
|
370
|
+
command = parseCommand(await request.json());
|
|
371
|
+
} catch {
|
|
372
|
+
command = void 0;
|
|
373
|
+
}
|
|
374
|
+
if (!command) return jsonResponse({ error: "Érvénytelen tároló-parancs." }, 400);
|
|
375
|
+
try {
|
|
376
|
+
return jsonResponse({ result: await runCommand(storage, command, Date.now()) });
|
|
377
|
+
} catch (error) {
|
|
378
|
+
return jsonResponse({ error: error instanceof Error ? error.message : String(error) }, 400);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async function call(stub, command) {
|
|
382
|
+
const response = await stub.fetch(DURABLE_OBJECT_STORE_URL, {
|
|
383
|
+
method: "POST",
|
|
384
|
+
headers: { "content-type": "application/json" },
|
|
385
|
+
body: JSON.stringify(command)
|
|
386
|
+
});
|
|
387
|
+
const body = await response.json().catch(() => ({}));
|
|
388
|
+
if (!response.ok) throw new Error(`A Durable Object tároló ${command.op} művelete sikertelen (HTTP ${response.status}): ${body.error ?? "ismeretlen hiba"}`);
|
|
389
|
+
return body.result ?? null;
|
|
390
|
+
}
|
|
391
|
+
function durableObjectStore(stub) {
|
|
392
|
+
return {
|
|
393
|
+
async get(key) {
|
|
394
|
+
const result = await call(stub, {
|
|
395
|
+
op: "get",
|
|
396
|
+
key
|
|
397
|
+
});
|
|
398
|
+
return typeof result === "string" ? result : void 0;
|
|
399
|
+
},
|
|
400
|
+
async set(key, value, ttlSeconds) {
|
|
401
|
+
await call(stub, {
|
|
402
|
+
op: "set",
|
|
403
|
+
key,
|
|
404
|
+
value,
|
|
405
|
+
ttlSeconds
|
|
406
|
+
});
|
|
407
|
+
},
|
|
408
|
+
async delete(key) {
|
|
409
|
+
await call(stub, {
|
|
410
|
+
op: "delete",
|
|
411
|
+
key
|
|
412
|
+
});
|
|
413
|
+
},
|
|
414
|
+
async setIfAbsent(key, value, ttlSeconds) {
|
|
415
|
+
return await call(stub, {
|
|
416
|
+
op: "setIfAbsent",
|
|
417
|
+
key,
|
|
418
|
+
value,
|
|
419
|
+
ttlSeconds
|
|
420
|
+
}) === true;
|
|
421
|
+
},
|
|
422
|
+
async increment(key, ttlSeconds) {
|
|
423
|
+
const result = await call(stub, {
|
|
424
|
+
op: "increment",
|
|
425
|
+
key,
|
|
426
|
+
ttlSeconds
|
|
427
|
+
});
|
|
428
|
+
if (typeof result !== "number") throw new TypeError(`A Durable Object tároló nem számot adott vissza: ${String(result)}`);
|
|
429
|
+
return result;
|
|
430
|
+
},
|
|
431
|
+
async deleteIfEquals(key, value) {
|
|
432
|
+
return await call(stub, {
|
|
433
|
+
op: "deleteIfEquals",
|
|
434
|
+
key,
|
|
435
|
+
value
|
|
436
|
+
}) === true;
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
//#endregion
|
|
441
|
+
Object.defineProperty(exports, "CLOUDFLARE_KV_MIN_TTL_SECONDS", {
|
|
442
|
+
enumerable: true,
|
|
443
|
+
get: function() {
|
|
444
|
+
return CLOUDFLARE_KV_MIN_TTL_SECONDS;
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
Object.defineProperty(exports, "DURABLE_OBJECT_STORE_URL", {
|
|
448
|
+
enumerable: true,
|
|
449
|
+
get: function() {
|
|
450
|
+
return DURABLE_OBJECT_STORE_URL;
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
Object.defineProperty(exports, "cloudflareKvCookieStore", {
|
|
454
|
+
enumerable: true,
|
|
455
|
+
get: function() {
|
|
456
|
+
return cloudflareKvCookieStore;
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
Object.defineProperty(exports, "customCookieStore", {
|
|
460
|
+
enumerable: true,
|
|
461
|
+
get: function() {
|
|
462
|
+
return customCookieStore;
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
Object.defineProperty(exports, "diagnoseStore", {
|
|
466
|
+
enumerable: true,
|
|
467
|
+
get: function() {
|
|
468
|
+
return diagnoseStore;
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
Object.defineProperty(exports, "durableObjectStore", {
|
|
472
|
+
enumerable: true,
|
|
473
|
+
get: function() {
|
|
474
|
+
return durableObjectStore;
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
Object.defineProperty(exports, "handleDurableObjectStoreRequest", {
|
|
478
|
+
enumerable: true,
|
|
479
|
+
get: function() {
|
|
480
|
+
return handleDurableObjectStoreRequest;
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
Object.defineProperty(exports, "ioredisCookieStore", {
|
|
484
|
+
enumerable: true,
|
|
485
|
+
get: function() {
|
|
486
|
+
return ioredisCookieStore;
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
Object.defineProperty(exports, "nodeRedisCookieStore", {
|
|
490
|
+
enumerable: true,
|
|
491
|
+
get: function() {
|
|
492
|
+
return nodeRedisCookieStore;
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
Object.defineProperty(exports, "resilientCookieStore", {
|
|
496
|
+
enumerable: true,
|
|
497
|
+
get: function() {
|
|
498
|
+
return resilientCookieStore;
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
Object.defineProperty(exports, "upstashRedisCookieStore", {
|
|
502
|
+
enumerable: true,
|
|
503
|
+
get: function() {
|
|
504
|
+
return upstashRedisCookieStore;
|
|
505
|
+
}
|
|
506
|
+
});
|