kassza 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -0
  3. package/agents/README.md +59 -0
  4. package/agents/api.md +206 -0
  5. package/agents/pitfalls.md +52 -0
  6. package/agents/recipes.md +217 -0
  7. package/agents/skills/kassza/SKILL.md +29 -0
  8. package/assets/logo-wordmark.svg +25 -0
  9. package/assets/logo.svg +19 -0
  10. package/dist/binary-B89HM03_.cjs +63 -0
  11. package/dist/binary-D0M9U2MD.js +34 -0
  12. package/dist/client-B9kbKKBf.d.cts +748 -0
  13. package/dist/client-zv4enyq7.d.ts +748 -0
  14. package/dist/cookie-stores/index.cjs +153 -0
  15. package/dist/cookie-stores/index.d.cts +63 -0
  16. package/dist/cookie-stores/index.d.ts +63 -0
  17. package/dist/cookie-stores/index.js +144 -0
  18. package/dist/create-BZd6CUO7.cjs +1160 -0
  19. package/dist/create-DDZaNlOz.js +939 -0
  20. package/dist/dates-D2XebOIg.js +34 -0
  21. package/dist/dates-DtHzwNU6.d.cts +7 -0
  22. package/dist/dates-DtHzwNU6.d.ts +7 -0
  23. package/dist/dates-PPxH0n5H.cjs +57 -0
  24. package/dist/errors-B0QJhUW1.cjs +302 -0
  25. package/dist/errors-DapdV5DK.js +273 -0
  26. package/dist/index-CYAGCdKJ.d.cts +56 -0
  27. package/dist/index-CYAGCdKJ.d.ts +56 -0
  28. package/dist/index.cjs +1406 -0
  29. package/dist/index.d.cts +8 -0
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.js +1394 -0
  32. package/dist/ipn/index.cjs +108 -0
  33. package/dist/ipn/index.d.cts +32 -0
  34. package/dist/ipn/index.d.ts +32 -0
  35. package/dist/ipn/index.js +101 -0
  36. package/dist/money/index.cjs +15 -0
  37. package/dist/money/index.d.cts +2 -0
  38. package/dist/money/index.d.ts +2 -0
  39. package/dist/money/index.js +2 -0
  40. package/dist/money-C9j7nBNP.js +258 -0
  41. package/dist/money-DkiGukAw.cjs +335 -0
  42. package/dist/session-CRGOuz-R.cjs +100 -0
  43. package/dist/session-Dm_45x8K.d.cts +11 -0
  44. package/dist/session-Dm_45x8K.d.ts +11 -0
  45. package/dist/session-OJMLGufT.js +77 -0
  46. package/dist/shared-CrxlxI8n.cjs +207 -0
  47. package/dist/shared-D6DLa4b7.js +100 -0
  48. package/dist/storage/fs.cjs +88 -0
  49. package/dist/storage/fs.d.cts +13 -0
  50. package/dist/storage/fs.d.ts +13 -0
  51. package/dist/storage/fs.js +87 -0
  52. package/dist/storage/index.cjs +643 -0
  53. package/dist/storage/index.d.cts +288 -0
  54. package/dist/storage/index.d.ts +288 -0
  55. package/dist/storage/index.js +619 -0
  56. package/dist/testing/index.cjs +409 -0
  57. package/dist/testing/index.d.cts +35 -0
  58. package/dist/testing/index.d.ts +35 -0
  59. package/dist/testing/index.js +407 -0
  60. package/dist/types-DVRgwcqg.d.cts +26 -0
  61. package/dist/types-DVRgwcqg.d.ts +26 -0
  62. package/dist/validators/index.cjs +296 -0
  63. package/dist/validators/index.d.cts +51 -0
  64. package/dist/validators/index.d.ts +51 -0
  65. package/dist/validators/index.js +278 -0
  66. package/llms.txt +16 -0
  67. package/package.json +151 -0
@@ -0,0 +1,619 @@
1
+ import { n as SzamlazzError } from "../errors-DapdV5DK.js";
2
+ import { a as isPdf } from "../binary-D0M9U2MD.js";
3
+ import { i as todayInBudapest, n as toAgentDate } from "../dates-D2XebOIg.js";
4
+ import { _ as guardStorageCall, a as assertStorageKey, c as encodeRfc3986, d as normalizePrefix, f as resolveKey, g as describeError, h as StorageError, i as assertExpires, l as joinPublicUrl, m as unsupportedSignedUrl, n as PDF_CONTENT_TYPE, o as basename, p as toArrayBuffer, r as S3_MAX_PRESIGN_SECONDS, s as encodeKeyPath, u as missingPublicBaseUrl, v as isStorageError } from "../shared-D6DLa4b7.js";
5
+ //#region src/storage/keys.ts
6
+ const DEFAULT_INVOICE_KEY_PREFIX = "szamlak";
7
+ const DEFAULT_RECEIPT_KEY_PREFIX = "nyugtak";
8
+ const KIND_FOLDERS = {
9
+ invoice: void 0,
10
+ proforma: "dijbekero",
11
+ advance: "elolegszamla",
12
+ final: "vegszamla",
13
+ corrective: "helyesbito",
14
+ storno: "sztorno",
15
+ deliveryNote: "szallitolevel"
16
+ };
17
+ const COMBINING_MARKS = /\p{M}/gu;
18
+ function sanitizeKeySegment(value) {
19
+ return value.normalize("NFKD").replace(COMBINING_MARKS, "").replace(/[^A-Za-z0-9._-]+/g, "-").replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, "");
20
+ }
21
+ function datedPdfKey(prefix, folder, number, date) {
22
+ const fileName = sanitizeKeySegment(number);
23
+ if (fileName === "") throw new StorageError(`A bizonylatszámból nem képezhető fájlnév: ${JSON.stringify(number)}`, { operation: "key" });
24
+ const [year = "", month = ""] = (date === void 0 ? todayInBudapest() : toAgentDate(date)).split("-");
25
+ return [
26
+ ...prefix.split("/"),
27
+ folder ?? "",
28
+ year,
29
+ month
30
+ ].map(sanitizeKeySegment).filter((segment) => segment !== "").concat(`${fileName}.pdf`).join("/");
31
+ }
32
+ function invoicePdfKey(input) {
33
+ return datedPdfKey(input.prefix ?? "szamlak", KIND_FOLDERS[input.type ?? "invoice"], input.number, input.date);
34
+ }
35
+ function receiptPdfKey(input) {
36
+ return datedPdfKey(input.prefix ?? "nyugtak", void 0, input.number, input.date);
37
+ }
38
+ //#endregion
39
+ //#region src/storage/memory.ts
40
+ const MEMORY_BASE_URL = "memory://storage";
41
+ function memoryStorage(options = {}) {
42
+ const prefix = normalizePrefix(options.prefix);
43
+ const files = /* @__PURE__ */ new Map();
44
+ const urlFor = (fullKey) => joinPublicUrl(options.publicBaseUrl ?? MEMORY_BASE_URL, fullKey);
45
+ return {
46
+ files,
47
+ async put(key, body, putOptions) {
48
+ const fullKey = resolveKey(prefix, key);
49
+ files.set(fullKey, {
50
+ body: body.slice(),
51
+ contentType: putOptions.contentType
52
+ });
53
+ return {
54
+ key,
55
+ url: urlFor(fullKey),
56
+ size: body.byteLength,
57
+ contentType: putOptions.contentType
58
+ };
59
+ },
60
+ async get(key) {
61
+ return files.get(resolveKey(prefix, key))?.body.slice();
62
+ },
63
+ async delete(key) {
64
+ files.delete(resolveKey(prefix, key));
65
+ },
66
+ async getUrl(key) {
67
+ const fullKey = resolveKey(prefix, key);
68
+ if (!files.has(fullKey)) throw new StorageError(`Nincs ilyen fájl: ${key}`, {
69
+ operation: "getUrl",
70
+ key,
71
+ status: 404
72
+ });
73
+ return urlFor(fullKey);
74
+ },
75
+ clear() {
76
+ files.clear();
77
+ }
78
+ };
79
+ }
80
+ //#endregion
81
+ //#region src/storage/r2-binding.ts
82
+ function r2BindingStorage(bucket, options = {}) {
83
+ const prefix = normalizePrefix(options.prefix);
84
+ return {
85
+ async put(key, body, putOptions) {
86
+ const fullKey = resolveKey(prefix, key);
87
+ const object = await guardStorageCall("R2", "put", key, () => bucket.put(fullKey, body, { httpMetadata: { contentType: putOptions.contentType } }));
88
+ if (!object) throw new StorageError("Az R2 nem mentette el a fájlt (a put null-t adott vissza).", {
89
+ operation: "put",
90
+ key
91
+ });
92
+ return {
93
+ key,
94
+ url: options.publicBaseUrl ? joinPublicUrl(options.publicBaseUrl, fullKey) : void 0,
95
+ size: object.size,
96
+ contentType: putOptions.contentType
97
+ };
98
+ },
99
+ async get(key) {
100
+ const fullKey = resolveKey(prefix, key);
101
+ const object = await guardStorageCall("R2", "get", key, () => bucket.get(fullKey));
102
+ if (!object) return void 0;
103
+ return new Uint8Array(await guardStorageCall("R2", "get", key, () => object.arrayBuffer()));
104
+ },
105
+ async delete(key) {
106
+ const fullKey = resolveKey(prefix, key);
107
+ await guardStorageCall("R2", "delete", key, () => bucket.delete(fullKey));
108
+ },
109
+ async getUrl(key, urlOptions = {}) {
110
+ const fullKey = resolveKey(prefix, key);
111
+ if (urlOptions.expiresInSeconds !== void 0) throw unsupportedSignedUrl("r2BindingStorage", key);
112
+ if (!options.publicBaseUrl) throw missingPublicBaseUrl("r2BindingStorage", key);
113
+ return joinPublicUrl(options.publicBaseUrl, fullKey);
114
+ }
115
+ };
116
+ }
117
+ //#endregion
118
+ //#region src/storage/s3.ts
119
+ function statusOf(error) {
120
+ const status = error?.$metadata?.httpStatusCode;
121
+ return typeof status === "number" ? status : void 0;
122
+ }
123
+ function isNotFound$1(error) {
124
+ const name = error?.name;
125
+ return name === "NoSuchKey" || name === "NotFound" || statusOf(error) === 404;
126
+ }
127
+ function wrap(operation, key, error) {
128
+ return new StorageError(`S3 hiba (${operation}): ${describeError(error)}`, {
129
+ operation,
130
+ key,
131
+ status: statusOf(error),
132
+ cause: error
133
+ });
134
+ }
135
+ function missingCommand(name, key, operation) {
136
+ return new StorageError(`Ehhez a művelethez add meg a commands.${name} osztályt.`, {
137
+ operation,
138
+ key
139
+ });
140
+ }
141
+ async function readBody(output) {
142
+ const body = output?.Body;
143
+ if (!body || typeof body.transformToByteArray !== "function") throw new Error("A GetObject válasza nem tartalmaz olvasható Body-t.");
144
+ return await body.transformToByteArray();
145
+ }
146
+ function s3Storage(options) {
147
+ const prefix = normalizePrefix(options.prefix);
148
+ const { client, bucket, commands } = options;
149
+ return {
150
+ async put(key, body, putOptions) {
151
+ const fullKey = resolveKey(prefix, key);
152
+ try {
153
+ await client.send(new commands.PutObjectCommand({
154
+ Bucket: bucket,
155
+ Key: fullKey,
156
+ Body: body,
157
+ ContentType: putOptions.contentType,
158
+ ContentLength: body.byteLength
159
+ }));
160
+ } catch (error) {
161
+ throw wrap("put", key, error);
162
+ }
163
+ return {
164
+ key,
165
+ url: options.publicBaseUrl ? joinPublicUrl(options.publicBaseUrl, fullKey) : void 0,
166
+ size: body.byteLength,
167
+ contentType: putOptions.contentType
168
+ };
169
+ },
170
+ async get(key) {
171
+ const fullKey = resolveKey(prefix, key);
172
+ if (!commands.GetObjectCommand) throw missingCommand("GetObjectCommand", key, "get");
173
+ try {
174
+ return await readBody(await client.send(new commands.GetObjectCommand({
175
+ Bucket: bucket,
176
+ Key: fullKey
177
+ })));
178
+ } catch (error) {
179
+ if (isNotFound$1(error)) return void 0;
180
+ throw wrap("get", key, error);
181
+ }
182
+ },
183
+ async delete(key) {
184
+ const fullKey = resolveKey(prefix, key);
185
+ if (!commands.DeleteObjectCommand) throw missingCommand("DeleteObjectCommand", key, "delete");
186
+ try {
187
+ await client.send(new commands.DeleteObjectCommand({
188
+ Bucket: bucket,
189
+ Key: fullKey
190
+ }));
191
+ } catch (error) {
192
+ throw wrap("delete", key, error);
193
+ }
194
+ },
195
+ async getUrl(key, urlOptions = {}) {
196
+ const fullKey = resolveKey(prefix, key);
197
+ if (urlOptions.expiresInSeconds === void 0 && options.publicBaseUrl) return joinPublicUrl(options.publicBaseUrl, fullKey);
198
+ if (!options.getSignedUrl || !commands.GetObjectCommand) throw new StorageError("URL készítéséhez add meg a publicBaseUrl opciót, vagy aláírt URL-hez a getSignedUrl függvényt (@aws-sdk/s3-request-presigner) és a commands.GetObjectCommand osztályt.", {
199
+ operation: "getUrl",
200
+ key
201
+ });
202
+ const expiresIn = assertExpires(urlOptions.expiresInSeconds ?? 3600, S3_MAX_PRESIGN_SECONDS, key);
203
+ try {
204
+ return await options.getSignedUrl(client, new commands.GetObjectCommand({
205
+ Bucket: bucket,
206
+ Key: fullKey
207
+ }), { expiresIn });
208
+ } catch (error) {
209
+ throw wrap("getUrl", key, error);
210
+ }
211
+ }
212
+ };
213
+ }
214
+ //#endregion
215
+ //#region src/storage/sigv4.ts
216
+ const AWS_SIGV4_ALGORITHM = "AWS4-HMAC-SHA256";
217
+ const UNSIGNED_PAYLOAD = "UNSIGNED-PAYLOAD";
218
+ const encoder = new TextEncoder();
219
+ function toHex(buffer) {
220
+ return Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, "0")).join("");
221
+ }
222
+ function toBuffer(data) {
223
+ return typeof data === "string" ? toArrayBuffer(encoder.encode(data)) : toArrayBuffer(data);
224
+ }
225
+ async function sha256Hex(data) {
226
+ return toHex(await crypto.subtle.digest("SHA-256", toBuffer(data)));
227
+ }
228
+ async function hmac(key, data) {
229
+ const cryptoKey = await crypto.subtle.importKey("raw", key, {
230
+ name: "HMAC",
231
+ hash: "SHA-256"
232
+ }, false, ["sign"]);
233
+ return crypto.subtle.sign("HMAC", cryptoKey, toBuffer(data));
234
+ }
235
+ function toAmzDate(date) {
236
+ return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
237
+ }
238
+ function canonicalPath(url) {
239
+ return url.pathname.split("/").map((segment) => encodeRfc3986(decodeURIComponent(segment))).join("/");
240
+ }
241
+ function canonicalQuery(params) {
242
+ return [...params].map(([name, value]) => [encodeRfc3986(name), encodeRfc3986(value)]).sort(([nameA, valueA], [nameB, valueB]) => nameA === nameB ? valueA < valueB ? -1 : 1 : nameA < nameB ? -1 : 1).map(([name, value]) => `${name}=${value}`).join("&");
243
+ }
244
+ function normalizeHeaders(headers) {
245
+ const normalized = /* @__PURE__ */ new Map();
246
+ for (const [name, value] of Object.entries(headers)) normalized.set(name.toLowerCase(), value.trim().replace(/\s+/g, " "));
247
+ return new Map([...normalized].sort(([a], [b]) => a < b ? -1 : 1));
248
+ }
249
+ function canonicalRequest(input) {
250
+ const signedHeaders = [...input.headers.keys()].join(";");
251
+ const headerLines = [...input.headers].map(([name, value]) => `${name}:${value}\n`).join("");
252
+ return {
253
+ request: [
254
+ input.method.toUpperCase(),
255
+ canonicalPath(input.url),
256
+ canonicalQuery(input.url.searchParams),
257
+ headerLines,
258
+ signedHeaders,
259
+ input.payloadHash
260
+ ].join("\n"),
261
+ signedHeaders
262
+ };
263
+ }
264
+ async function signCanonical(scope, amzDate, request) {
265
+ const day = amzDate.slice(0, 8);
266
+ const credentialScope = `${day}/${scope.region}/${scope.service}/aws4_request`;
267
+ const stringToSign = [
268
+ AWS_SIGV4_ALGORITHM,
269
+ amzDate,
270
+ credentialScope,
271
+ await sha256Hex(request)
272
+ ].join("\n");
273
+ return {
274
+ signature: toHex(await hmac(await hmac(await hmac(await hmac(await hmac(toBuffer(`AWS4${scope.credentials.secretAccessKey}`), day), scope.region), scope.service), "aws4_request"), stringToSign)),
275
+ credentialScope
276
+ };
277
+ }
278
+ async function signAwsRequest(input) {
279
+ const url = new URL(input.url);
280
+ const amzDate = toAmzDate(input.date ?? /* @__PURE__ */ new Date());
281
+ const payloadHash = input.payloadHash ?? await sha256Hex(input.body ?? "");
282
+ const extra = {
283
+ host: url.host,
284
+ "x-amz-date": amzDate
285
+ };
286
+ if (input.service === "s3") extra["x-amz-content-sha256"] = payloadHash;
287
+ if (input.credentials.sessionToken) extra["x-amz-security-token"] = input.credentials.sessionToken;
288
+ const headers = normalizeHeaders({
289
+ ...input.headers,
290
+ ...extra
291
+ });
292
+ const { request, signedHeaders } = canonicalRequest({
293
+ method: input.method,
294
+ url,
295
+ headers,
296
+ payloadHash
297
+ });
298
+ const { signature, credentialScope } = await signCanonical(input, amzDate, request);
299
+ const result = {};
300
+ for (const [name, value] of headers) if (name !== "host") result[name] = value;
301
+ result.authorization = `${AWS_SIGV4_ALGORITHM} Credential=${input.credentials.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
302
+ return result;
303
+ }
304
+ async function presignAwsUrl(input) {
305
+ const url = new URL(input.url);
306
+ const amzDate = toAmzDate(input.date ?? /* @__PURE__ */ new Date());
307
+ const credentialScope = `${amzDate.slice(0, 8)}/${input.region}/${input.service}/aws4_request`;
308
+ url.searchParams.set("X-Amz-Algorithm", AWS_SIGV4_ALGORITHM);
309
+ url.searchParams.set("X-Amz-Credential", `${input.credentials.accessKeyId}/${credentialScope}`);
310
+ url.searchParams.set("X-Amz-Date", amzDate);
311
+ url.searchParams.set("X-Amz-Expires", String(input.expiresInSeconds));
312
+ if (input.credentials.sessionToken) url.searchParams.set("X-Amz-Security-Token", input.credentials.sessionToken);
313
+ url.searchParams.set("X-Amz-SignedHeaders", "host");
314
+ const { request } = canonicalRequest({
315
+ method: input.method,
316
+ url,
317
+ headers: /* @__PURE__ */ new Map([["host", url.host]]),
318
+ payloadHash: UNSIGNED_PAYLOAD
319
+ });
320
+ const { signature } = await signCanonical(input, amzDate, request);
321
+ const query = `${canonicalQuery(url.searchParams)}&X-Amz-Signature=${signature}`;
322
+ return `${url.origin}${canonicalPath(url)}?${query}`;
323
+ }
324
+ //#endregion
325
+ //#region src/storage/s3-fetch.ts
326
+ function requireOption(value, name) {
327
+ if (typeof value !== "string" || value.trim() === "") throw new SzamlazzError(`Az s3FetchStorage ${name} opciója kötelező.`, { category: "configuration" });
328
+ return value;
329
+ }
330
+ function bucketBaseUrl(options) {
331
+ const bucket = options.bucket;
332
+ if (options.endpoint === void 0) return options.forcePathStyle ?? bucket.includes(".") ? `https://s3.${options.region}.amazonaws.com/${bucket}` : `https://${bucket}.s3.${options.region}.amazonaws.com`;
333
+ let endpoint;
334
+ try {
335
+ endpoint = new URL(options.endpoint);
336
+ } catch (error) {
337
+ throw new SzamlazzError(`Érvénytelen S3 endpoint: ${options.endpoint}`, {
338
+ category: "configuration",
339
+ cause: error
340
+ });
341
+ }
342
+ const basePath = endpoint.pathname.replace(/\/+$/, "");
343
+ if (options.forcePathStyle ?? true) return `${endpoint.origin}${basePath}/${bucket}`;
344
+ return `${endpoint.protocol}//${bucket}.${endpoint.host}${basePath}`;
345
+ }
346
+ function readS3ErrorCode(body) {
347
+ const code = /<Code>([^<]*)<\/Code>/.exec(body)?.[1];
348
+ const message = /<Message>([^<]*)<\/Message>/.exec(body)?.[1];
349
+ if (!code) return void 0;
350
+ return message ? `${code}: ${message}` : code;
351
+ }
352
+ function s3FetchStorage(options) {
353
+ requireOption(options.bucket, "bucket");
354
+ requireOption(options.region, "region");
355
+ const credentials = {
356
+ accessKeyId: requireOption(options.accessKeyId, "accessKeyId"),
357
+ secretAccessKey: requireOption(options.secretAccessKey, "secretAccessKey"),
358
+ sessionToken: options.sessionToken
359
+ };
360
+ const baseUrl = bucketBaseUrl(options);
361
+ const prefix = normalizePrefix(options.prefix);
362
+ const scope = {
363
+ credentials,
364
+ region: options.region,
365
+ service: "s3"
366
+ };
367
+ const objectUrl = (fullKey) => `${baseUrl}/${encodeKeyPath(fullKey)}`;
368
+ async function send(operation, key, init) {
369
+ const doFetch = options.fetch ?? globalThis.fetch;
370
+ try {
371
+ return await doFetch(init.url, {
372
+ method: init.method,
373
+ headers: init.headers,
374
+ ...init.body === void 0 ? {} : { body: init.body }
375
+ });
376
+ } catch (error) {
377
+ throw new StorageError(`S3 hálózati hiba (${operation}): ${describeError(error)}`, {
378
+ operation,
379
+ key,
380
+ cause: error
381
+ });
382
+ }
383
+ }
384
+ async function failure(operation, key, response) {
385
+ const detail = readS3ErrorCode(await response.text().catch(() => "")) ?? response.statusText;
386
+ return new StorageError(`S3 hiba (${operation}, HTTP ${response.status})${detail ? `: ${detail}` : ""}`, {
387
+ operation,
388
+ key,
389
+ status: response.status
390
+ });
391
+ }
392
+ return {
393
+ async put(key, body, putOptions) {
394
+ const fullKey = resolveKey(prefix, key);
395
+ const url = objectUrl(fullKey);
396
+ const response = await send("put", key, {
397
+ method: "PUT",
398
+ url,
399
+ headers: await signAwsRequest({
400
+ ...scope,
401
+ method: "PUT",
402
+ url,
403
+ headers: { "content-type": putOptions.contentType },
404
+ payloadHash: await sha256Hex(body)
405
+ }),
406
+ body: toArrayBuffer(body)
407
+ });
408
+ if (!response.ok) throw await failure("put", key, response);
409
+ return {
410
+ key,
411
+ url: options.publicBaseUrl ? joinPublicUrl(options.publicBaseUrl, fullKey) : void 0,
412
+ size: body.byteLength,
413
+ contentType: putOptions.contentType
414
+ };
415
+ },
416
+ async get(key) {
417
+ const url = objectUrl(resolveKey(prefix, key));
418
+ const response = await send("get", key, {
419
+ method: "GET",
420
+ url,
421
+ headers: await signAwsRequest({
422
+ ...scope,
423
+ method: "GET",
424
+ url
425
+ })
426
+ });
427
+ if (response.status === 404) return void 0;
428
+ if (!response.ok) throw await failure("get", key, response);
429
+ return new Uint8Array(await response.arrayBuffer());
430
+ },
431
+ async delete(key) {
432
+ const url = objectUrl(resolveKey(prefix, key));
433
+ const response = await send("delete", key, {
434
+ method: "DELETE",
435
+ url,
436
+ headers: await signAwsRequest({
437
+ ...scope,
438
+ method: "DELETE",
439
+ url
440
+ })
441
+ });
442
+ if (!response.ok && response.status !== 404) throw await failure("delete", key, response);
443
+ },
444
+ async getUrl(key, urlOptions = {}) {
445
+ const fullKey = resolveKey(prefix, key);
446
+ if (urlOptions.expiresInSeconds === void 0 && options.publicBaseUrl) return joinPublicUrl(options.publicBaseUrl, fullKey);
447
+ return presignAwsUrl({
448
+ ...scope,
449
+ method: "GET",
450
+ url: objectUrl(fullKey),
451
+ expiresInSeconds: assertExpires(urlOptions.expiresInSeconds ?? 3600, S3_MAX_PRESIGN_SECONDS, key)
452
+ });
453
+ }
454
+ };
455
+ }
456
+ //#endregion
457
+ //#region src/storage/store-pdf.ts
458
+ async function storePdf(storage, key, pdf) {
459
+ if (!isPdf(pdf)) throw new StorageError("A tárolandó tartalom nem PDF (hiányzik a %PDF fejléc).", {
460
+ operation: "put",
461
+ key
462
+ });
463
+ return storage.put(key, pdf, { contentType: PDF_CONTENT_TYPE });
464
+ }
465
+ //#endregion
466
+ //#region src/storage/supabase.ts
467
+ const SUPABASE_MAX_SIGNED_URL_SECONDS = 31536e3;
468
+ function isNotFound(error) {
469
+ return error.status === 404 || error.statusCode === "404" || /not[\s_-]?found/i.test(error.message);
470
+ }
471
+ const run = (operation, key, call) => guardStorageCall("Supabase Storage", operation, key, call);
472
+ function failure(operation, key, error) {
473
+ return new StorageError(`Supabase Storage hiba (${operation}): ${error?.message ?? "üres válasz"}`, {
474
+ operation,
475
+ key,
476
+ status: error?.status,
477
+ cause: error ?? void 0
478
+ });
479
+ }
480
+ function supabaseStorage(options) {
481
+ const prefix = normalizePrefix(options.prefix);
482
+ const bucket = () => options.client.storage.from(options.bucket);
483
+ return {
484
+ async put(key, body, putOptions) {
485
+ const path = resolveKey(prefix, key);
486
+ const uploadOptions = {
487
+ contentType: putOptions.contentType,
488
+ upsert: options.upsert ?? true,
489
+ ...options.cacheControl === void 0 ? {} : { cacheControl: options.cacheControl }
490
+ };
491
+ const result = await run("put", key, () => bucket().upload(path, body, uploadOptions));
492
+ if (!result.data) throw failure("put", key, result.error);
493
+ return {
494
+ key,
495
+ url: options.public ? bucket().getPublicUrl(path).data.publicUrl : void 0,
496
+ size: body.byteLength,
497
+ contentType: putOptions.contentType
498
+ };
499
+ },
500
+ async get(key) {
501
+ const path = resolveKey(prefix, key);
502
+ const result = await run("get", key, () => bucket().download(path));
503
+ if (!result.data) {
504
+ if (result.error && isNotFound(result.error)) return void 0;
505
+ throw failure("get", key, result.error);
506
+ }
507
+ const blob = result.data;
508
+ return new Uint8Array(await blob.arrayBuffer());
509
+ },
510
+ async delete(key) {
511
+ const path = resolveKey(prefix, key);
512
+ const result = await run("delete", key, () => bucket().remove([path]));
513
+ if (result.error) throw failure("delete", key, result.error);
514
+ },
515
+ async getUrl(key, urlOptions = {}) {
516
+ const path = resolveKey(prefix, key);
517
+ if (options.public && urlOptions.expiresInSeconds === void 0) return bucket().getPublicUrl(path).data.publicUrl;
518
+ const expiresIn = assertExpires(urlOptions.expiresInSeconds ?? 3600, SUPABASE_MAX_SIGNED_URL_SECONDS, key);
519
+ const result = await run("getUrl", key, () => bucket().createSignedUrl(path, expiresIn));
520
+ if (!result.data) throw failure("getUrl", key, result.error);
521
+ return result.data.signedUrl;
522
+ }
523
+ };
524
+ }
525
+ //#endregion
526
+ //#region src/storage/uploadthing.ts
527
+ const UPLOADTHING_MAX_CUSTOM_ID_LENGTH = 128;
528
+ const UPLOADTHING_MAX_SIGNED_URL_SECONDS = 604800;
529
+ function uploadthingStorage(options) {
530
+ const { utapi } = options;
531
+ const prefix = normalizePrefix(options.prefix);
532
+ const uploadOptions = {
533
+ ...options.acl === void 0 ? {} : { acl: options.acl },
534
+ ...options.contentDisposition === void 0 ? {} : { contentDisposition: options.contentDisposition }
535
+ };
536
+ return {
537
+ async put(key, body, putOptions) {
538
+ const customId = resolveKey(prefix, key);
539
+ if (customId.length > 128) throw new StorageError(`Az UploadThing customId legfeljebb 128 karakter lehet, a kulcs ${customId.length} karakteres.`, {
540
+ operation: "key",
541
+ key
542
+ });
543
+ const file = Object.assign(new File([toArrayBuffer(body)], basename(customId), { type: putOptions.contentType }), { customId });
544
+ const result = await guardStorageCall("UploadThing", "put", key, () => utapi.uploadFiles(file, uploadOptions));
545
+ if (!result.data) throw new StorageError(`UploadThing hiba (put): ${result.error?.message ?? "ismeretlen hiba"}`, {
546
+ operation: "put",
547
+ key,
548
+ cause: result.error
549
+ });
550
+ return {
551
+ key,
552
+ url: result.data.ufsUrl ?? result.data.url,
553
+ size: result.data.size,
554
+ contentType: putOptions.contentType
555
+ };
556
+ },
557
+ async delete(key) {
558
+ const customId = resolveKey(prefix, key);
559
+ await guardStorageCall("UploadThing", "delete", key, () => utapi.deleteFiles(customId, { keyType: "customId" }));
560
+ },
561
+ async getUrl(key, urlOptions = {}) {
562
+ const customId = resolveKey(prefix, key);
563
+ const generate = utapi.generateSignedURL;
564
+ if (!generate) throw new StorageError("Ez az UploadThing verzió nem támogatja a generateSignedURL-t, frissíts uploadthing v7-re.", {
565
+ operation: "getUrl",
566
+ key
567
+ });
568
+ const expiresIn = assertExpires(urlOptions.expiresInSeconds ?? 3600, UPLOADTHING_MAX_SIGNED_URL_SECONDS, key);
569
+ return (await guardStorageCall("UploadThing", "getUrl", key, () => generate.call(utapi, customId, { expiresIn }))).ufsUrl;
570
+ }
571
+ };
572
+ }
573
+ //#endregion
574
+ //#region src/storage/vercel-blob.ts
575
+ function missingFunction(name, key, operation) {
576
+ return new StorageError(`Ehhez a művelethez add át a @vercel/blob ${name} függvényét a vercelBlobStorage-nak.`, {
577
+ operation,
578
+ key
579
+ });
580
+ }
581
+ function vercelBlobStorage(options) {
582
+ const prefix = normalizePrefix(options.prefix);
583
+ const commandOptions = options.token ? { token: options.token } : {};
584
+ return {
585
+ async put(key, body, putOptions) {
586
+ const fullKey = resolveKey(prefix, key);
587
+ const blobOptions = {
588
+ access: options.access,
589
+ contentType: putOptions.contentType,
590
+ addRandomSuffix: false,
591
+ allowOverwrite: options.allowOverwrite ?? true,
592
+ ...commandOptions,
593
+ ...options.cacheControlMaxAge === void 0 ? {} : { cacheControlMaxAge: options.cacheControlMaxAge }
594
+ };
595
+ const blob = new Blob([toArrayBuffer(body)], { type: putOptions.contentType });
596
+ return {
597
+ key,
598
+ url: (await guardStorageCall("Vercel Blob", "put", key, () => options.put(fullKey, blob, blobOptions))).url,
599
+ size: body.byteLength,
600
+ contentType: putOptions.contentType
601
+ };
602
+ },
603
+ async delete(key) {
604
+ const fullKey = resolveKey(prefix, key);
605
+ const del = options.del;
606
+ if (!del) throw missingFunction("del", key, "delete");
607
+ await guardStorageCall("Vercel Blob", "delete", key, () => del(fullKey, commandOptions));
608
+ },
609
+ async getUrl(key, urlOptions = {}) {
610
+ const fullKey = resolveKey(prefix, key);
611
+ if (urlOptions.expiresInSeconds !== void 0) throw unsupportedSignedUrl("vercelBlobStorage", key);
612
+ const head = options.head;
613
+ if (!head) throw missingFunction("head", key, "getUrl");
614
+ return (await guardStorageCall("Vercel Blob", "getUrl", key, () => head(fullKey, commandOptions))).url;
615
+ }
616
+ };
617
+ }
618
+ //#endregion
619
+ export { DEFAULT_INVOICE_KEY_PREFIX, DEFAULT_RECEIPT_KEY_PREFIX, PDF_CONTENT_TYPE, S3_MAX_PRESIGN_SECONDS, SUPABASE_MAX_SIGNED_URL_SECONDS, StorageError, UPLOADTHING_MAX_CUSTOM_ID_LENGTH, UPLOADTHING_MAX_SIGNED_URL_SECONDS, assertStorageKey, guardStorageCall, invoicePdfKey, isStorageError, memoryStorage, presignAwsUrl, r2BindingStorage, receiptPdfKey, s3FetchStorage, s3Storage, sanitizeKeySegment, signAwsRequest, storePdf, supabaseStorage, uploadthingStorage, vercelBlobStorage };