@xylex-group/athena 2.13.0 → 2.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.
Files changed (61) hide show
  1. package/README.md +1 -1
  2. package/bin/athena-js.js +0 -0
  3. package/dist/browser.cjs +552 -52
  4. package/dist/browser.cjs.map +1 -1
  5. package/dist/browser.d.cts +9 -9
  6. package/dist/browser.d.ts +9 -9
  7. package/dist/browser.js +552 -52
  8. package/dist/browser.js.map +1 -1
  9. package/dist/cli/index.cjs +545 -45
  10. package/dist/cli/index.cjs.map +1 -1
  11. package/dist/cli/index.d.cts +4 -4
  12. package/dist/cli/index.d.ts +4 -4
  13. package/dist/cli/index.js +545 -45
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/{client-DVOKSYDI.d.ts → client-uthENhaf.d.ts} +289 -92
  16. package/dist/{client-BJjUwDSg.d.cts → client-wU2J9yqb.d.cts} +289 -92
  17. package/dist/index.cjs +552 -52
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +9 -9
  20. package/dist/index.d.ts +9 -9
  21. package/dist/index.js +552 -52
  22. package/dist/index.js.map +1 -1
  23. package/dist/{model-form-Dw4zEL5a.d.cts → model-form-BE1_Bmdd.d.cts} +2 -2
  24. package/dist/{model-form-yRg71q3H.d.ts → model-form-DcH3R7WD.d.ts} +2 -2
  25. package/dist/{module-DBteUIob.d.ts → module-Ca3_OQqR.d.ts} +5 -5
  26. package/dist/{module-yoX49uQC.d.cts → module-DFGZXCtt.d.cts} +5 -5
  27. package/dist/next/client.cjs +545 -45
  28. package/dist/next/client.cjs.map +1 -1
  29. package/dist/next/client.d.cts +5 -5
  30. package/dist/next/client.d.ts +5 -5
  31. package/dist/next/client.js +545 -45
  32. package/dist/next/client.js.map +1 -1
  33. package/dist/next/server.cjs +545 -45
  34. package/dist/next/server.cjs.map +1 -1
  35. package/dist/next/server.d.cts +5 -5
  36. package/dist/next/server.d.ts +5 -5
  37. package/dist/next/server.js +545 -45
  38. package/dist/next/server.js.map +1 -1
  39. package/dist/{payload-DEOWN_oo.d.ts → payload-BbSCmILD.d.ts} +2 -2
  40. package/dist/{payload-BzVbUgY_.d.cts → payload-zXIwKTQf.d.cts} +2 -2
  41. package/dist/{pipeline-Dwck-wZO.d.cts → pipeline-CwQoD5G9.d.cts} +1 -1
  42. package/dist/{pipeline-Bj6RWt1A.d.ts → pipeline-DqwehoQV.d.ts} +1 -1
  43. package/dist/react.cjs +1 -1
  44. package/dist/react.cjs.map +1 -1
  45. package/dist/react.d.cts +5 -5
  46. package/dist/react.d.ts +5 -5
  47. package/dist/react.js +1 -1
  48. package/dist/react.js.map +1 -1
  49. package/dist/social-providers.cjs +24 -15
  50. package/dist/social-providers.cjs.map +1 -1
  51. package/dist/social-providers.js +24 -15
  52. package/dist/social-providers.js.map +1 -1
  53. package/dist/{types-BU8uJH_b.d.cts → types-6H575ITc.d.cts} +1 -1
  54. package/dist/{types-DPgejxYC.d.ts → types-C1swabT5.d.ts} +2 -2
  55. package/dist/{types-BRP7sfSF.d.ts → types-CD6K05JQ.d.ts} +1 -1
  56. package/dist/{types-CH78O90i.d.cts → types-YQUR7wu0.d.cts} +1 -1
  57. package/dist/{types-CH78O90i.d.ts → types-YQUR7wu0.d.ts} +1 -1
  58. package/dist/{types-CjC9_5ZQ.d.cts → types-dHnjluBC.d.cts} +2 -2
  59. package/dist/utils.d.cts +1 -1
  60. package/dist/utils.d.ts +1 -1
  61. package/package.json +22 -21
@@ -405,7 +405,7 @@ function buildAthenaRequestHeaders(input) {
405
405
 
406
406
  // package.json
407
407
  var package_default = {
408
- version: "2.13.0"
408
+ version: "2.14.0"
409
409
  };
410
410
 
411
411
  // src/sdk-version.ts
@@ -2834,7 +2834,224 @@ async function withRetry(config, fn) {
2834
2834
  throw new Error("withRetry reached an unexpected state");
2835
2835
  }
2836
2836
 
2837
+ // src/storage/direct-upload.ts
2838
+ var SERVICE = "s3";
2839
+ var TERMINATOR = "aws4_request";
2840
+ async function putDirectStorageUploadBody(config, bucket, storageKey, body, uploadHeaders, signal, onProgress) {
2841
+ if (config.bucket && bucket && config.bucket !== bucket) {
2842
+ throw new Error(
2843
+ `athena.storage.file.upload direct mode bucket mismatch: configured ${config.bucket} but Athena returned ${bucket}`
2844
+ );
2845
+ }
2846
+ const target = createDirectUploadTarget(config, bucket, storageKey);
2847
+ const bytes = await bodyToArrayBuffer(body);
2848
+ const payloadHash = await sha256Hex(bytes);
2849
+ const headers = new Headers(uploadHeaders);
2850
+ if (isBlobBody(body) && body.type && !headers.has("Content-Type")) {
2851
+ headers.set("Content-Type", body.type);
2852
+ }
2853
+ const signed = await signDirectUploadRequest(config, target, headers, payloadHash);
2854
+ if (typeof XMLHttpRequest !== "undefined") {
2855
+ return putWithXhr(target.toString(), signed, body, signal, onProgress);
2856
+ }
2857
+ onProgress({ loaded: 0 });
2858
+ const response = await fetch(target, {
2859
+ method: "PUT",
2860
+ headers: signed.requestHeaders,
2861
+ body,
2862
+ signal
2863
+ });
2864
+ if (!response.ok) {
2865
+ throw new Error(`athena.storage.file.upload failed with status ${response.status}`);
2866
+ }
2867
+ onProgress({ loaded: bytes.byteLength });
2868
+ return response;
2869
+ }
2870
+ function createDirectUploadTarget(config, bucket, storageKey) {
2871
+ const resolvedBucket = config.bucket ?? bucket;
2872
+ if (!resolvedBucket?.trim()) {
2873
+ throw new Error(
2874
+ "athena.storage.file.upload direct mode requires a bucket in experimental.directStorageUpload or the server upload response"
2875
+ );
2876
+ }
2877
+ if (!storageKey.trim()) {
2878
+ throw new Error("athena.storage.file.upload direct mode requires a storage key");
2879
+ }
2880
+ let endpoint;
2881
+ try {
2882
+ endpoint = new URL(config.endpoint);
2883
+ } catch (error) {
2884
+ throw new Error(
2885
+ `athena.storage.file.upload direct mode received an invalid endpoint: ${error instanceof Error ? error.message : String(error)}`
2886
+ );
2887
+ }
2888
+ if (endpoint.search || endpoint.hash) {
2889
+ throw new Error("athena.storage.file.upload direct mode endpoint must not contain a query or hash");
2890
+ }
2891
+ const endpointPath = endpoint.pathname.replace(/\/+$/, "");
2892
+ const pathParts = config.forcePathStyle === false ? [endpointPath, storageKey] : [endpointPath, resolvedBucket, storageKey];
2893
+ if (config.forcePathStyle === false) {
2894
+ endpoint.hostname = `${resolvedBucket}.${endpoint.hostname}`;
2895
+ }
2896
+ endpoint.pathname = pathParts.filter(Boolean).flatMap((part) => part.split("/")).map(awsEncode).join("/").replace(/^([^/])/, "/$1");
2897
+ return endpoint;
2898
+ }
2899
+ async function signDirectUploadRequest(config, target, inputHeaders, payloadHash) {
2900
+ const accessKeyId = config.accessKeyId.trim();
2901
+ const secretAccessKey = config.secretAccessKey.trim();
2902
+ if (!accessKeyId || !secretAccessKey) {
2903
+ throw new Error(
2904
+ "athena.storage.file.upload direct mode requires accessKeyId and secretAccessKey"
2905
+ );
2906
+ }
2907
+ const now = /* @__PURE__ */ new Date();
2908
+ const amzDate = formatAmzDate(now);
2909
+ const shortDate = amzDate.slice(0, 8);
2910
+ const region = config.region?.trim() || "auto";
2911
+ const headers = {};
2912
+ inputHeaders.forEach((value, key) => {
2913
+ if (key.toLowerCase() !== "authorization" && key.toLowerCase() !== "host") {
2914
+ headers[key.toLowerCase()] = value.trim().replace(/\s+/g, " ");
2915
+ }
2916
+ });
2917
+ headers["x-amz-content-sha256"] = payloadHash;
2918
+ headers["x-amz-date"] = amzDate;
2919
+ if (config.sessionToken?.trim()) {
2920
+ headers["x-amz-security-token"] = config.sessionToken.trim();
2921
+ }
2922
+ const canonicalHeaders = Object.keys(headers).sort().map((key) => `${key}:${headers[key]}
2923
+ `).join("");
2924
+ const signedHeaders = Object.keys(headers).sort().join(";");
2925
+ const canonicalRequest = [
2926
+ "PUT",
2927
+ target.pathname,
2928
+ "",
2929
+ `host:${target.host}
2930
+ ${canonicalHeaders}`,
2931
+ `host;${signedHeaders}`,
2932
+ payloadHash
2933
+ ].join("\n");
2934
+ const credentialScope = `${shortDate}/${region}/${SERVICE}/${TERMINATOR}`;
2935
+ const stringToSign = [
2936
+ "AWS4-HMAC-SHA256",
2937
+ amzDate,
2938
+ credentialScope,
2939
+ await sha256Hex(canonicalRequest)
2940
+ ].join("\n");
2941
+ const dateKey = await hmac(`AWS4${secretAccessKey}`, shortDate);
2942
+ const regionKey = await hmac(dateKey, region);
2943
+ const serviceKey = await hmac(regionKey, SERVICE);
2944
+ const signingKey = await hmac(serviceKey, TERMINATOR);
2945
+ const signature = await hmacHex(signingKey, stringToSign);
2946
+ headers.authorization = `AWS4-HMAC-SHA256 Credential=${accessKeyId}/${credentialScope}, SignedHeaders=host;${signedHeaders}, Signature=${signature}`;
2947
+ return { requestHeaders: headers };
2948
+ }
2949
+ async function putWithXhr(url, signed, body, signal, onProgress) {
2950
+ const Xhr = XMLHttpRequest;
2951
+ if (Xhr === void 0) {
2952
+ return Promise.reject(new Error("athena.storage.file.upload direct mode requires XMLHttpRequest in this runtime"));
2953
+ }
2954
+ return new Promise((resolve, reject) => {
2955
+ const xhr = new Xhr();
2956
+ const abort = () => xhr.abort();
2957
+ xhr.open("PUT", url);
2958
+ Object.entries(signed.requestHeaders).forEach(([key, value]) => xhr.setRequestHeader(key, value));
2959
+ xhr.upload.onprogress = (event) => onProgress({ loaded: event.loaded });
2960
+ xhr.onload = () => {
2961
+ signal?.removeEventListener("abort", abort);
2962
+ if (xhr.status < 200 || xhr.status >= 300) {
2963
+ reject(new Error(`athena.storage.file.upload failed with status ${xhr.status}`));
2964
+ return;
2965
+ }
2966
+ onProgress({ loaded: bodySize(body) });
2967
+ resolve(new Response(xhr.response, {
2968
+ status: xhr.status,
2969
+ statusText: xhr.statusText,
2970
+ headers: parseXhrHeaders(xhr.getAllResponseHeaders())
2971
+ }));
2972
+ };
2973
+ xhr.onerror = () => {
2974
+ signal?.removeEventListener("abort", abort);
2975
+ reject(new Error("athena.storage.file.upload failed with a network error"));
2976
+ };
2977
+ xhr.onabort = () => {
2978
+ signal?.removeEventListener("abort", abort);
2979
+ reject(new DOMException("Upload aborted", "AbortError"));
2980
+ };
2981
+ if (signal) {
2982
+ if (signal.aborted) {
2983
+ abort();
2984
+ return;
2985
+ }
2986
+ signal.addEventListener("abort", abort, { once: true });
2987
+ }
2988
+ xhr.send(body);
2989
+ });
2990
+ }
2991
+ function isBlobBody(body) {
2992
+ return typeof Blob !== "undefined" && body instanceof Blob;
2993
+ }
2994
+ async function bodyToArrayBuffer(body) {
2995
+ if (isBlobBody(body)) return body.arrayBuffer();
2996
+ if (body instanceof ArrayBuffer) return body;
2997
+ if (ArrayBuffer.isView(body)) {
2998
+ return body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength);
2999
+ }
3000
+ throw new Error("athena.storage.file.upload direct mode does not support ReadableStream bodies");
3001
+ }
3002
+ function bodySize(body) {
3003
+ if (isBlobBody(body)) return body.size;
3004
+ if (body instanceof ArrayBuffer) return body.byteLength;
3005
+ if (ArrayBuffer.isView(body)) return body.byteLength;
3006
+ return 0;
3007
+ }
3008
+ function awsEncode(value) {
3009
+ return encodeURIComponent(value).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
3010
+ }
3011
+ function formatAmzDate(date) {
3012
+ return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
3013
+ }
3014
+ async function sha256Hex(value) {
3015
+ const bytes = typeof value === "string" ? new TextEncoder().encode(value) : value;
3016
+ const digest = await crypto.subtle.digest("SHA-256", bytes);
3017
+ return toHex(new Uint8Array(digest));
3018
+ }
3019
+ async function hmac(key, value) {
3020
+ const keyBytes = typeof key === "string" ? new TextEncoder().encode(key) : key;
3021
+ const cryptoKey = await crypto.subtle.importKey(
3022
+ "raw",
3023
+ keyBytes,
3024
+ { name: "HMAC", hash: "SHA-256" },
3025
+ false,
3026
+ ["sign"]
3027
+ );
3028
+ return crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(value));
3029
+ }
3030
+ async function hmacHex(key, value) {
3031
+ return toHex(new Uint8Array(await hmac(key, value)));
3032
+ }
3033
+ function toHex(bytes) {
3034
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
3035
+ }
3036
+ function parseXhrHeaders(rawHeaders) {
3037
+ const headers = new Headers();
3038
+ rawHeaders.trim().split(/[\r\n]+/).forEach((line) => {
3039
+ const separator = line.indexOf(":");
3040
+ if (separator > 0) {
3041
+ headers.set(line.slice(0, separator).trim(), line.slice(separator + 1).trim());
3042
+ }
3043
+ });
3044
+ return headers;
3045
+ }
3046
+
2837
3047
  // src/storage/file.ts
3048
+ function mergeUploadHeaders(serverHeaders, inputHeaders) {
3049
+ const headers = { ...serverHeaders };
3050
+ new Headers(inputHeaders).forEach((value, key) => {
3051
+ headers[key] = value;
3052
+ });
3053
+ return headers;
3054
+ }
2838
3055
  function createStorageFileModule(base, config = {}) {
2839
3056
  const upload = async (input, options) => {
2840
3057
  const sources = normalizeUploadSources(input);
@@ -2870,16 +3087,25 @@ function createStorageFileModule(base, config = {}) {
2870
3087
  for (let index = 0; index < uploadRequests.length; index += 1) {
2871
3088
  const request2 = uploadRequests[index];
2872
3089
  const uploadUrl = uploadUrls[index];
2873
- const response = await putUploadBody(
3090
+ const aggregateProgress = (progress) => {
3091
+ aggregateLoaded[index] = progress.loaded;
3092
+ input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
3093
+ };
3094
+ const response = config.directUpload ? await putDirectStorageUploadBody(
3095
+ config.directUpload,
3096
+ uploadUrl.upload.bucket,
3097
+ uploadUrl.upload.storage_key,
3098
+ request2.source.source,
3099
+ mergeUploadHeaders(uploadUrl.upload.headers ?? {}, input.uploadHeaders),
3100
+ options?.signal,
3101
+ aggregateProgress
3102
+ ) : await putUploadBody(
2874
3103
  uploadUrl.upload.url,
2875
3104
  uploadUrl.upload.headers ?? {},
2876
3105
  request2.source,
2877
3106
  input,
2878
3107
  options,
2879
- (progress) => {
2880
- aggregateLoaded[index] = progress.loaded;
2881
- input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
2882
- }
3108
+ aggregateProgress
2883
3109
  );
2884
3110
  uploaded.push({
2885
3111
  file: uploadUrl.file,
@@ -3030,7 +3256,7 @@ function putUploadBodyWithXhr(url, source, headers, options, onProgress) {
3030
3256
  resolve(new Response(xhr.response, {
3031
3257
  status: xhr.status,
3032
3258
  statusText: xhr.statusText,
3033
- headers: parseXhrHeaders(xhr.getAllResponseHeaders())
3259
+ headers: parseXhrHeaders2(xhr.getAllResponseHeaders())
3034
3260
  }));
3035
3261
  };
3036
3262
  xhr.onerror = () => {
@@ -3168,7 +3394,7 @@ function createProgressSnapshot(phase, sources, fileIndex, loaded, aggregateLoad
3168
3394
  function sum(values) {
3169
3395
  return values.reduce((total, value) => total + value, 0);
3170
3396
  }
3171
- function parseXhrHeaders(raw) {
3397
+ function parseXhrHeaders2(raw) {
3172
3398
  const headers = new Headers();
3173
3399
  for (const line of raw.trim().split(/[\r\n]+/)) {
3174
3400
  const index = line.indexOf(":");
@@ -3185,6 +3411,230 @@ function isRecord5(value) {
3185
3411
  return Boolean(value) && typeof value === "object";
3186
3412
  }
3187
3413
 
3414
+ // src/storage/backup.ts
3415
+ function backupError(message, status, endpoint, method, cause, raw) {
3416
+ const error = new Error(message);
3417
+ error.name = "AthenaStorageError";
3418
+ error.code = status === 0 ? "NETWORK_ERROR" : "HTTP_ERROR";
3419
+ error.status = status;
3420
+ error.endpoint = endpoint;
3421
+ error.method = method;
3422
+ error.cause = cause;
3423
+ error.raw = raw;
3424
+ throw error;
3425
+ }
3426
+ function isRecord6(value) {
3427
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3428
+ }
3429
+ function asPath(path) {
3430
+ return path;
3431
+ }
3432
+ function appendQuery(path, query) {
3433
+ if (!query) return path;
3434
+ const params = new URLSearchParams();
3435
+ for (const [key, value] of Object.entries(query)) {
3436
+ if (value === void 0 || value === null || value === "") continue;
3437
+ params.set(key, String(value));
3438
+ }
3439
+ const text = params.toString();
3440
+ return text ? `${path}?${text}` : path;
3441
+ }
3442
+ function unwrapAthenaData(payload) {
3443
+ if (isRecord6(payload) && "data" in payload) {
3444
+ return payload.data;
3445
+ }
3446
+ return payload;
3447
+ }
3448
+ function requireKey(key) {
3449
+ const trimmed = key.trim();
3450
+ if (!trimmed || trimmed === "undefined" || trimmed === "null") {
3451
+ backupError("Backup object key is required", 400, "/admin/backups/{key}", "DELETE");
3452
+ }
3453
+ return trimmed;
3454
+ }
3455
+ function resolveMessage(payload, fallback) {
3456
+ if (isRecord6(payload)) {
3457
+ const message = payload.message ?? payload.error ?? payload.details;
3458
+ if (typeof message === "string" && message.trim()) return message.trim();
3459
+ }
3460
+ if (typeof payload === "string" && payload.trim()) return payload.trim();
3461
+ return fallback;
3462
+ }
3463
+ async function callBackupEndpoint(gateway, path, method, payload, options, runtime) {
3464
+ const endpoint = asPath(path);
3465
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3466
+ const url = buildAthenaGatewayUrl(baseUrl, endpoint);
3467
+ const headers = gateway.buildHeaders(options);
3468
+ const init = {
3469
+ method,
3470
+ headers,
3471
+ signal: options?.signal
3472
+ };
3473
+ if (payload !== void 0 && method !== "GET") {
3474
+ init.body = JSON.stringify(payload);
3475
+ }
3476
+ let response;
3477
+ try {
3478
+ response = await fetch(url, init);
3479
+ } catch (error) {
3480
+ backupError(
3481
+ error instanceof Error ? error.message : "Backup network error",
3482
+ 0,
3483
+ path,
3484
+ method,
3485
+ error
3486
+ );
3487
+ }
3488
+ const rawText = await response.text();
3489
+ let parsed = null;
3490
+ if (rawText) {
3491
+ try {
3492
+ parsed = JSON.parse(rawText);
3493
+ } catch {
3494
+ parsed = rawText;
3495
+ }
3496
+ }
3497
+ if (!response.ok) {
3498
+ backupError(
3499
+ resolveMessage(parsed, `Backup ${method} ${path} failed (${response.status})`),
3500
+ response.status,
3501
+ path,
3502
+ method,
3503
+ void 0,
3504
+ parsed
3505
+ );
3506
+ }
3507
+ return unwrapAthenaData(parsed);
3508
+ }
3509
+ function createStorageBackupModule(gateway, runtimeOptions) {
3510
+ const resolvedBaseUrl = () => String(gateway.baseUrl ?? "").replace(/\/+$/, "");
3511
+ return {
3512
+ async list(query, options) {
3513
+ const path = appendQuery("/admin/backups", {
3514
+ limit: query?.limit ?? 10,
3515
+ client_name: query?.client_name,
3516
+ cursor: query?.cursor ?? void 0
3517
+ });
3518
+ const data = await callBackupEndpoint(gateway, path, "GET", void 0, options);
3519
+ const backups = (data?.backups ?? []).map((row) => ({
3520
+ ...row,
3521
+ key: row.key ?? row.s3_key
3522
+ }));
3523
+ return {
3524
+ backups,
3525
+ next_cursor: data?.next_cursor ?? null
3526
+ };
3527
+ },
3528
+ async create(input, options) {
3529
+ const data = await callBackupEndpoint(gateway, "/admin/backups", "POST", input, options);
3530
+ return {
3531
+ job_id: Number(data?.job_id ?? 0),
3532
+ client_name: String(data?.client_name ?? input.client_name),
3533
+ status: String(data?.status ?? "pending")
3534
+ };
3535
+ },
3536
+ async restore(key, input, options) {
3537
+ const backupKey = requireKey(key);
3538
+ const path = `/admin/backups/${encodeURIComponent(backupKey)}/restore`;
3539
+ const data = await callBackupEndpoint(gateway, path, "POST", input, options);
3540
+ return {
3541
+ job_id: Number(data?.job_id ?? 0),
3542
+ client_name: String(data?.client_name ?? input.client_name),
3543
+ status: String(data?.status ?? "pending"),
3544
+ key: String(data?.key ?? backupKey)
3545
+ };
3546
+ },
3547
+ async delete(key, options) {
3548
+ const backupKey = requireKey(key);
3549
+ await callBackupEndpoint(
3550
+ gateway,
3551
+ `/admin/backups/${encodeURIComponent(backupKey)}`,
3552
+ "DELETE",
3553
+ void 0,
3554
+ options);
3555
+ },
3556
+ downloadUrl(key, options) {
3557
+ const backupKey = requireKey(key);
3558
+ const base = `${resolvedBaseUrl()}/admin/backups/${encodeURIComponent(backupKey)}/download`;
3559
+ return options?.apiKey ? `${base}?api_key=${encodeURIComponent(options.apiKey)}` : base;
3560
+ },
3561
+ jobs: {
3562
+ async list(query, options) {
3563
+ const path = appendQuery("/admin/backups/jobs", query ?? {});
3564
+ const data = await callBackupEndpoint(gateway, path, "GET", void 0, options);
3565
+ if (Array.isArray(data)) return data;
3566
+ if (isRecord6(data) && Array.isArray(data.jobs)) return data.jobs;
3567
+ return [];
3568
+ },
3569
+ async get(jobId, options) {
3570
+ return callBackupEndpoint(
3571
+ gateway,
3572
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}`,
3573
+ "GET",
3574
+ void 0,
3575
+ options);
3576
+ },
3577
+ async cancel(jobId, options) {
3578
+ return callBackupEndpoint(
3579
+ gateway,
3580
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}/cancel`,
3581
+ "POST",
3582
+ {},
3583
+ options);
3584
+ },
3585
+ async delete(jobId, options) {
3586
+ await callBackupEndpoint(
3587
+ gateway,
3588
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}`,
3589
+ "DELETE",
3590
+ void 0,
3591
+ options);
3592
+ },
3593
+ async openObjectUrl(jobId, options) {
3594
+ const data = await callBackupEndpoint(
3595
+ gateway,
3596
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}/s3-open`,
3597
+ "GET",
3598
+ void 0,
3599
+ options);
3600
+ return String(data?.url ?? "");
3601
+ }
3602
+ },
3603
+ schedules: {
3604
+ async list(options) {
3605
+ const data = await callBackupEndpoint(gateway, "/admin/backups/schedules", "GET", void 0, options);
3606
+ if (Array.isArray(data)) return data;
3607
+ if (isRecord6(data) && Array.isArray(data.schedules)) return data.schedules;
3608
+ return [];
3609
+ },
3610
+ async create(input, options) {
3611
+ return callBackupEndpoint(
3612
+ gateway,
3613
+ "/admin/backups/schedules",
3614
+ "POST",
3615
+ input,
3616
+ options);
3617
+ },
3618
+ async update(id, input, options) {
3619
+ return callBackupEndpoint(
3620
+ gateway,
3621
+ `/admin/backups/schedules/${encodeURIComponent(String(id))}`,
3622
+ "PATCH",
3623
+ input,
3624
+ options);
3625
+ },
3626
+ async delete(id, options) {
3627
+ await callBackupEndpoint(
3628
+ gateway,
3629
+ `/admin/backups/schedules/${encodeURIComponent(String(id))}`,
3630
+ "DELETE",
3631
+ void 0,
3632
+ options);
3633
+ }
3634
+ }
3635
+ };
3636
+ }
3637
+
3188
3638
  // src/storage/module.ts
3189
3639
  var storageSdkManifest = {
3190
3640
  methods: [
@@ -3227,6 +3677,53 @@ var storageSdkManifest = {
3227
3677
  responseEnvelope: "raw",
3228
3678
  responseType: "{ data: S3CredentialListItem[] }"
3229
3679
  },
3680
+ {
3681
+ name: "backup.list",
3682
+ method: "GET",
3683
+ path: "/admin/backups",
3684
+ responseEnvelope: "athena",
3685
+ responseType: "StorageBackupListPage",
3686
+ note: "Admin backup archives on server S3/R2 profile"
3687
+ },
3688
+ {
3689
+ name: "backup.create",
3690
+ method: "POST",
3691
+ path: "/admin/backups",
3692
+ requestType: "StorageBackupCreateRequest",
3693
+ responseEnvelope: "athena",
3694
+ responseType: "StorageBackupQueuedJob"
3695
+ },
3696
+ {
3697
+ name: "backup.restore",
3698
+ method: "POST",
3699
+ path: "/admin/backups/{key}/restore",
3700
+ pathParams: ["key"],
3701
+ requestType: "StorageBackupRestoreRequest",
3702
+ responseEnvelope: "athena",
3703
+ responseType: "StorageBackupQueuedJob"
3704
+ },
3705
+ {
3706
+ name: "backup.delete",
3707
+ method: "DELETE",
3708
+ path: "/admin/backups/{key}",
3709
+ pathParams: ["key"],
3710
+ responseEnvelope: "athena",
3711
+ responseType: "void"
3712
+ },
3713
+ {
3714
+ name: "backup.jobs.list",
3715
+ method: "GET",
3716
+ path: "/admin/backups/jobs",
3717
+ responseEnvelope: "athena",
3718
+ responseType: "StorageBackupJob[]"
3719
+ },
3720
+ {
3721
+ name: "backup.schedules.list",
3722
+ method: "GET",
3723
+ path: "/admin/backups/schedules",
3724
+ responseEnvelope: "athena",
3725
+ responseType: "StorageBackupSchedule[]"
3726
+ },
3230
3727
  {
3231
3728
  name: "createStorageUploadUrl",
3232
3729
  method: "POST",
@@ -3874,7 +4371,7 @@ var AthenaStorageError = class extends Error {
3874
4371
  };
3875
4372
  }
3876
4373
  };
3877
- function isRecord6(value) {
4374
+ function isRecord7(value) {
3878
4375
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3879
4376
  }
3880
4377
  function causeToString(cause) {
@@ -3972,7 +4469,7 @@ function parseResponseBody3(rawText, contentType) {
3972
4469
  return { parsed: rawText, parseFailed: true };
3973
4470
  }
3974
4471
  }
3975
- function appendQuery(path, query) {
4472
+ function appendQuery2(path, query) {
3976
4473
  if (!query) return path;
3977
4474
  const params = new URLSearchParams();
3978
4475
  for (const [key, value] of Object.entries(query)) {
@@ -3998,7 +4495,7 @@ function withPathParam(path, name, value) {
3998
4495
  return path.replace(`{${name}}`, encodeURIComponent(value));
3999
4496
  }
4000
4497
  function resolveErrorMessage3(payload, fallback) {
4001
- if (isRecord6(payload)) {
4498
+ if (isRecord7(payload)) {
4002
4499
  const message = payload.message ?? payload.error ?? payload.details;
4003
4500
  if (typeof message === "string" && message.trim()) {
4004
4501
  return message.trim();
@@ -4010,12 +4507,12 @@ function resolveErrorMessage3(payload, fallback) {
4010
4507
  return fallback;
4011
4508
  }
4012
4509
  function resolveErrorHint2(payload) {
4013
- if (!isRecord6(payload)) return void 0;
4510
+ if (!isRecord7(payload)) return void 0;
4014
4511
  const hint = payload.hint ?? payload.suggestion;
4015
4512
  return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
4016
4513
  }
4017
4514
  function resolveErrorCause(payload) {
4018
- if (!isRecord6(payload)) return void 0;
4515
+ if (!isRecord7(payload)) return void 0;
4019
4516
  const cause = payload.cause ?? payload.reason;
4020
4517
  return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
4021
4518
  }
@@ -4134,7 +4631,7 @@ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload,
4134
4631
  );
4135
4632
  }
4136
4633
  if (envelope === "athena") {
4137
- if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4634
+ if (!isRecord7(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4138
4635
  return rejectStorageError(
4139
4636
  {
4140
4637
  code: "INVALID_ATHENA_ENVELOPE",
@@ -4242,7 +4739,7 @@ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, run
4242
4739
  runtimeOptions
4243
4740
  );
4244
4741
  }
4245
- function isBlobBody(body) {
4742
+ function isBlobBody2(body) {
4246
4743
  return typeof Blob !== "undefined" && body instanceof Blob;
4247
4744
  }
4248
4745
  function isReadableStreamBody(body) {
@@ -4251,7 +4748,7 @@ function isReadableStreamBody(body) {
4251
4748
  async function putPresignedUploadBody(uploadUrl, uploadHeaders, body, options) {
4252
4749
  const headers = new Headers(uploadHeaders);
4253
4750
  Object.entries(options?.headers ?? {}).forEach(([key, value]) => headers.set(key, value));
4254
- if (!headers.has("Content-Type") && isBlobBody(body) && body.type) {
4751
+ if (!headers.has("Content-Type") && isBlobBody2(body) && body.type) {
4255
4752
  headers.set("Content-Type", body.type);
4256
4753
  }
4257
4754
  const init = {
@@ -4346,7 +4843,7 @@ async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options,
4346
4843
  }
4347
4844
  delete headers["Content-Type"];
4348
4845
  delete headers["content-type"];
4349
- if (isBlobBody(body) && body.type) {
4846
+ if (isBlobBody2(body) && body.type) {
4350
4847
  headers["Content-Type"] = body.type;
4351
4848
  }
4352
4849
  const requestInit = {
@@ -4431,7 +4928,7 @@ async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options,
4431
4928
  runtimeOptions
4432
4929
  );
4433
4930
  }
4434
- if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4931
+ if (!isRecord7(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4435
4932
  return rejectStorageError(
4436
4933
  {
4437
4934
  code: "INVALID_ATHENA_ENVELOPE",
@@ -4503,14 +5000,14 @@ function createStorageModule(gateway, runtimeOptions) {
4503
5000
  return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "GET", void 0, options);
4504
5001
  },
4505
5002
  getStorageFileUrl(fileId, query, options) {
4506
- const path = appendQuery(
5003
+ const path = appendQuery2(
4507
5004
  withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
4508
5005
  query
4509
5006
  );
4510
5007
  return callAthena2(path, "GET", void 0, options);
4511
5008
  },
4512
5009
  getStorageFileProxy(fileId, query, options) {
4513
- const path = appendQuery(
5010
+ const path = appendQuery2(
4514
5011
  withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
4515
5012
  query
4516
5013
  );
@@ -4534,7 +5031,7 @@ function createStorageModule(gateway, runtimeOptions) {
4534
5031
  };
4535
5032
  const fileFacade = createStorageFileModule(base, runtimeOptions);
4536
5033
  const fileUpload = ((input, options) => {
4537
- if (isRecord6(input) && "files" in input) {
5034
+ if (isRecord7(input) && "files" in input) {
4538
5035
  return fileFacade.upload(input, options);
4539
5036
  }
4540
5037
  return base.createStorageUploadUrl(
@@ -4596,7 +5093,7 @@ function createStorageModule(gateway, runtimeOptions) {
4596
5093
  return callAthena2(withPathParam("/storage/files/{file_id}/public-url", "file_id", fileId), "GET", void 0, options);
4597
5094
  },
4598
5095
  proxyUrl(fileId, query, options) {
4599
- const path = appendQuery(
5096
+ const path = appendQuery2(
4600
5097
  withPathParam("/storage/files/{file_id}/proxy-url", "file_id", fileId),
4601
5098
  query
4602
5099
  );
@@ -4634,7 +5131,7 @@ function createStorageModule(gateway, runtimeOptions) {
4634
5131
  },
4635
5132
  retention: {
4636
5133
  get(fileId, query, options) {
4637
- const path = appendQuery(
5134
+ const path = appendQuery2(
4638
5135
  withPathParam("/storage/files/{file_id}/retention", "file_id", fileId),
4639
5136
  query
4640
5137
  );
@@ -4836,6 +5333,7 @@ function createStorageModule(gateway, runtimeOptions) {
4836
5333
  return callAthena2("/storage/audit/list", "POST", input, options);
4837
5334
  }
4838
5335
  };
5336
+ const backup = createStorageBackupModule(gateway);
4839
5337
  return {
4840
5338
  ...base,
4841
5339
  credentials,
@@ -4847,6 +5345,7 @@ function createStorageModule(gateway, runtimeOptions) {
4847
5345
  bucket,
4848
5346
  multipart,
4849
5347
  audit,
5348
+ backup,
4850
5349
  delete: file.delete
4851
5350
  };
4852
5351
  }
@@ -4896,7 +5395,7 @@ function normalizeWsUrl(value, label) {
4896
5395
  parsed.pathname = parsed.pathname.replace(/\/+$/, "");
4897
5396
  return parsed.toString().replace(/\/$/, "");
4898
5397
  }
4899
- function isRecord7(value) {
5398
+ function isRecord8(value) {
4900
5399
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4901
5400
  }
4902
5401
  function parseResponseBody4(rawText, contentType) {
@@ -4918,7 +5417,7 @@ function resolveRequestId3(headers) {
4918
5417
  return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
4919
5418
  }
4920
5419
  function resolveErrorMessage4(payload, fallback) {
4921
- if (isRecord7(payload)) {
5420
+ if (isRecord8(payload)) {
4922
5421
  for (const candidate of [payload.error, payload.message, payload.details]) {
4923
5422
  if (typeof candidate === "string" && candidate.trim().length > 0) {
4924
5423
  return candidate.trim();
@@ -5532,7 +6031,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
5532
6031
  "ilike",
5533
6032
  "is"
5534
6033
  ]);
5535
- function isRecord8(value) {
6034
+ function isRecord9(value) {
5536
6035
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5537
6036
  }
5538
6037
  function isUuidString(value) {
@@ -5545,7 +6044,7 @@ function shouldUseUuidTextComparison(column, value) {
5545
6044
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
5546
6045
  }
5547
6046
  function isRelationSelectNode(value) {
5548
- return isRecord8(value) && isRecord8(value.select);
6047
+ return isRecord9(value) && isRecord9(value.select);
5549
6048
  }
5550
6049
  function normalizeIdentifier(value, label) {
5551
6050
  const normalized = value.trim();
@@ -5601,7 +6100,7 @@ function compileRelationToken(key, node) {
5601
6100
  return `${prefix}${relationToken}(${nested})`;
5602
6101
  }
5603
6102
  function compileSelectShape(select) {
5604
- if (!isRecord8(select)) {
6103
+ if (!isRecord9(select)) {
5605
6104
  throw new Error("findMany select must be an object");
5606
6105
  }
5607
6106
  const tokens = [];
@@ -5625,7 +6124,7 @@ function compileSelectShape(select) {
5625
6124
  return tokens.join(",");
5626
6125
  }
5627
6126
  function selectShapeUsesRelationSchema(select) {
5628
- if (!isRecord8(select)) {
6127
+ if (!isRecord9(select)) {
5629
6128
  return false;
5630
6129
  }
5631
6130
  for (const rawValue of Object.values(select)) {
@@ -5643,7 +6142,7 @@ function selectShapeUsesRelationSchema(select) {
5643
6142
  }
5644
6143
  function compileColumnWhere(column, input) {
5645
6144
  const normalizedColumn = normalizeIdentifier(column, "where column");
5646
- if (!isRecord8(input)) {
6145
+ if (!isRecord9(input)) {
5647
6146
  return [buildGatewayCondition("eq", normalizedColumn, input)];
5648
6147
  }
5649
6148
  const conditions = [];
@@ -5671,7 +6170,7 @@ function compileColumnWhere(column, input) {
5671
6170
  return conditions;
5672
6171
  }
5673
6172
  function compileBooleanExpressionTerms(clause, label) {
5674
- if (!isRecord8(clause)) {
6173
+ if (!isRecord9(clause)) {
5675
6174
  throw new Error(`findMany where.${label} clauses must be objects`);
5676
6175
  }
5677
6176
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -5680,7 +6179,7 @@ function compileBooleanExpressionTerms(clause, label) {
5680
6179
  }
5681
6180
  const [rawColumn, rawValue] = entries[0];
5682
6181
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
5683
- if (!isRecord8(rawValue)) {
6182
+ if (!isRecord9(rawValue)) {
5684
6183
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
5685
6184
  }
5686
6185
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -5704,7 +6203,7 @@ function compileWhere(where) {
5704
6203
  if (where === void 0) {
5705
6204
  return void 0;
5706
6205
  }
5707
- if (!isRecord8(where)) {
6206
+ if (!isRecord9(where)) {
5708
6207
  throw new Error("findMany where must be an object");
5709
6208
  }
5710
6209
  const conditions = [];
@@ -5754,7 +6253,7 @@ function compileOrderBy(orderBy) {
5754
6253
  if (orderBy === void 0) {
5755
6254
  return void 0;
5756
6255
  }
5757
- if (!isRecord8(orderBy)) {
6256
+ if (!isRecord9(orderBy)) {
5758
6257
  throw new Error("findMany orderBy must be an object");
5759
6258
  }
5760
6259
  if ("column" in orderBy) {
@@ -5929,11 +6428,11 @@ function toFindManyAstOrder(order) {
5929
6428
  ascending: order.direction !== "descending"
5930
6429
  };
5931
6430
  }
5932
- function isRecord9(value) {
6431
+ function isRecord10(value) {
5933
6432
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5934
6433
  }
5935
6434
  function normalizeFindManyAstColumnPredicate(value) {
5936
- if (!isRecord9(value)) {
6435
+ if (!isRecord10(value)) {
5937
6436
  return {
5938
6437
  eq: value
5939
6438
  };
@@ -5957,7 +6456,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
5957
6456
  return normalized;
5958
6457
  }
5959
6458
  function normalizeFindManyAstWhere(where) {
5960
- if (!where || !isRecord9(where)) {
6459
+ if (!where || !isRecord10(where)) {
5961
6460
  return where;
5962
6461
  }
5963
6462
  const normalized = {};
@@ -5971,7 +6470,7 @@ function normalizeFindManyAstWhere(where) {
5971
6470
  );
5972
6471
  continue;
5973
6472
  }
5974
- if (key === "not" && isRecord9(value)) {
6473
+ if (key === "not" && isRecord10(value)) {
5975
6474
  normalized.not = normalizeFindManyAstBooleanOperand(
5976
6475
  value
5977
6476
  );
@@ -5982,7 +6481,7 @@ function normalizeFindManyAstWhere(where) {
5982
6481
  return normalized;
5983
6482
  }
5984
6483
  function predicateRequiresUuidQueryFallback(column, value) {
5985
- if (!isRecord9(value)) {
6484
+ if (!isRecord10(value)) {
5986
6485
  return shouldUseUuidTextComparison(column, value);
5987
6486
  }
5988
6487
  const eqValue = value.eq;
@@ -6000,7 +6499,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
6000
6499
  return false;
6001
6500
  }
6002
6501
  function findManyAstWhereRequiresLegacyTransport(where) {
6003
- if (!where || !isRecord9(where)) {
6502
+ if (!where || !isRecord10(where)) {
6004
6503
  return false;
6005
6504
  }
6006
6505
  for (const [key, value] of Object.entries(where)) {
@@ -6015,7 +6514,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
6015
6514
  }
6016
6515
  continue;
6017
6516
  }
6018
- if (key === "not" && isRecord9(value)) {
6517
+ if (key === "not" && isRecord10(value)) {
6019
6518
  if (booleanOperandRequiresUuidQueryFallback(value)) {
6020
6519
  return true;
6021
6520
  }
@@ -6635,7 +7134,7 @@ async function executeExperimentalRead(experimental, runner) {
6635
7134
  throw error;
6636
7135
  }
6637
7136
  }
6638
- function isRecord10(value) {
7137
+ function isRecord11(value) {
6639
7138
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6640
7139
  }
6641
7140
  function firstNonEmptyString2(...values) {
@@ -6647,8 +7146,8 @@ function firstNonEmptyString2(...values) {
6647
7146
  return void 0;
6648
7147
  }
6649
7148
  function resolveStructuredErrorPayload2(raw) {
6650
- if (!isRecord10(raw)) return null;
6651
- return isRecord10(raw.error) ? raw.error : raw;
7149
+ if (!isRecord11(raw)) return null;
7150
+ return isRecord11(raw.error) ? raw.error : raw;
6652
7151
  }
6653
7152
  function resolveStructuredErrorDetails(payload, message) {
6654
7153
  if (!payload || !("details" in payload)) {
@@ -6664,7 +7163,7 @@ function resolveStructuredErrorDetails(payload, message) {
6664
7163
  return details;
6665
7164
  }
6666
7165
  function createResultError(response, result, normalized) {
6667
- const rawRecord = isRecord10(response.raw) ? response.raw : null;
7166
+ const rawRecord = isRecord11(response.raw) ? response.raw : null;
6668
7167
  const payload = resolveStructuredErrorPayload2(response.raw);
6669
7168
  const message = firstNonEmptyString2(
6670
7169
  response.error,
@@ -8573,6 +9072,7 @@ function createClientFromConfig(config, sourceConfig) {
8573
9072
  withOptions: storageWithOptions,
8574
9073
  storage: createStorageModule(gateway, {
8575
9074
  ...config.experimental.storage,
9075
+ ...config.experimental.directStorageUpload ? { directUpload: config.experimental.directStorageUpload } : {},
8576
9076
  ...config.storageUrl ? {
8577
9077
  baseUrl: config.storageUrl,
8578
9078
  stripBasePath: true