@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
@@ -389,7 +389,7 @@ function buildAthenaRequestHeaders(input) {
389
389
 
390
390
  // package.json
391
391
  var package_default = {
392
- version: "2.13.0"
392
+ version: "2.14.0"
393
393
  };
394
394
 
395
395
  // src/sdk-version.ts
@@ -2818,7 +2818,224 @@ async function withRetry(config, fn) {
2818
2818
  throw new Error("withRetry reached an unexpected state");
2819
2819
  }
2820
2820
 
2821
+ // src/storage/direct-upload.ts
2822
+ var SERVICE = "s3";
2823
+ var TERMINATOR = "aws4_request";
2824
+ async function putDirectStorageUploadBody(config, bucket, storageKey, body, uploadHeaders, signal, onProgress) {
2825
+ if (config.bucket && bucket && config.bucket !== bucket) {
2826
+ throw new Error(
2827
+ `athena.storage.file.upload direct mode bucket mismatch: configured ${config.bucket} but Athena returned ${bucket}`
2828
+ );
2829
+ }
2830
+ const target = createDirectUploadTarget(config, bucket, storageKey);
2831
+ const bytes = await bodyToArrayBuffer(body);
2832
+ const payloadHash = await sha256Hex(bytes);
2833
+ const headers = new Headers(uploadHeaders);
2834
+ if (isBlobBody(body) && body.type && !headers.has("Content-Type")) {
2835
+ headers.set("Content-Type", body.type);
2836
+ }
2837
+ const signed = await signDirectUploadRequest(config, target, headers, payloadHash);
2838
+ if (typeof XMLHttpRequest !== "undefined") {
2839
+ return putWithXhr(target.toString(), signed, body, signal, onProgress);
2840
+ }
2841
+ onProgress({ loaded: 0 });
2842
+ const response = await fetch(target, {
2843
+ method: "PUT",
2844
+ headers: signed.requestHeaders,
2845
+ body,
2846
+ signal
2847
+ });
2848
+ if (!response.ok) {
2849
+ throw new Error(`athena.storage.file.upload failed with status ${response.status}`);
2850
+ }
2851
+ onProgress({ loaded: bytes.byteLength });
2852
+ return response;
2853
+ }
2854
+ function createDirectUploadTarget(config, bucket, storageKey) {
2855
+ const resolvedBucket = config.bucket ?? bucket;
2856
+ if (!resolvedBucket?.trim()) {
2857
+ throw new Error(
2858
+ "athena.storage.file.upload direct mode requires a bucket in experimental.directStorageUpload or the server upload response"
2859
+ );
2860
+ }
2861
+ if (!storageKey.trim()) {
2862
+ throw new Error("athena.storage.file.upload direct mode requires a storage key");
2863
+ }
2864
+ let endpoint;
2865
+ try {
2866
+ endpoint = new URL(config.endpoint);
2867
+ } catch (error) {
2868
+ throw new Error(
2869
+ `athena.storage.file.upload direct mode received an invalid endpoint: ${error instanceof Error ? error.message : String(error)}`
2870
+ );
2871
+ }
2872
+ if (endpoint.search || endpoint.hash) {
2873
+ throw new Error("athena.storage.file.upload direct mode endpoint must not contain a query or hash");
2874
+ }
2875
+ const endpointPath = endpoint.pathname.replace(/\/+$/, "");
2876
+ const pathParts = config.forcePathStyle === false ? [endpointPath, storageKey] : [endpointPath, resolvedBucket, storageKey];
2877
+ if (config.forcePathStyle === false) {
2878
+ endpoint.hostname = `${resolvedBucket}.${endpoint.hostname}`;
2879
+ }
2880
+ endpoint.pathname = pathParts.filter(Boolean).flatMap((part) => part.split("/")).map(awsEncode).join("/").replace(/^([^/])/, "/$1");
2881
+ return endpoint;
2882
+ }
2883
+ async function signDirectUploadRequest(config, target, inputHeaders, payloadHash) {
2884
+ const accessKeyId = config.accessKeyId.trim();
2885
+ const secretAccessKey = config.secretAccessKey.trim();
2886
+ if (!accessKeyId || !secretAccessKey) {
2887
+ throw new Error(
2888
+ "athena.storage.file.upload direct mode requires accessKeyId and secretAccessKey"
2889
+ );
2890
+ }
2891
+ const now = /* @__PURE__ */ new Date();
2892
+ const amzDate = formatAmzDate(now);
2893
+ const shortDate = amzDate.slice(0, 8);
2894
+ const region = config.region?.trim() || "auto";
2895
+ const headers = {};
2896
+ inputHeaders.forEach((value, key) => {
2897
+ if (key.toLowerCase() !== "authorization" && key.toLowerCase() !== "host") {
2898
+ headers[key.toLowerCase()] = value.trim().replace(/\s+/g, " ");
2899
+ }
2900
+ });
2901
+ headers["x-amz-content-sha256"] = payloadHash;
2902
+ headers["x-amz-date"] = amzDate;
2903
+ if (config.sessionToken?.trim()) {
2904
+ headers["x-amz-security-token"] = config.sessionToken.trim();
2905
+ }
2906
+ const canonicalHeaders = Object.keys(headers).sort().map((key) => `${key}:${headers[key]}
2907
+ `).join("");
2908
+ const signedHeaders = Object.keys(headers).sort().join(";");
2909
+ const canonicalRequest = [
2910
+ "PUT",
2911
+ target.pathname,
2912
+ "",
2913
+ `host:${target.host}
2914
+ ${canonicalHeaders}`,
2915
+ `host;${signedHeaders}`,
2916
+ payloadHash
2917
+ ].join("\n");
2918
+ const credentialScope = `${shortDate}/${region}/${SERVICE}/${TERMINATOR}`;
2919
+ const stringToSign = [
2920
+ "AWS4-HMAC-SHA256",
2921
+ amzDate,
2922
+ credentialScope,
2923
+ await sha256Hex(canonicalRequest)
2924
+ ].join("\n");
2925
+ const dateKey = await hmac(`AWS4${secretAccessKey}`, shortDate);
2926
+ const regionKey = await hmac(dateKey, region);
2927
+ const serviceKey = await hmac(regionKey, SERVICE);
2928
+ const signingKey = await hmac(serviceKey, TERMINATOR);
2929
+ const signature = await hmacHex(signingKey, stringToSign);
2930
+ headers.authorization = `AWS4-HMAC-SHA256 Credential=${accessKeyId}/${credentialScope}, SignedHeaders=host;${signedHeaders}, Signature=${signature}`;
2931
+ return { requestHeaders: headers };
2932
+ }
2933
+ async function putWithXhr(url, signed, body, signal, onProgress) {
2934
+ const Xhr = XMLHttpRequest;
2935
+ if (Xhr === void 0) {
2936
+ return Promise.reject(new Error("athena.storage.file.upload direct mode requires XMLHttpRequest in this runtime"));
2937
+ }
2938
+ return new Promise((resolve, reject) => {
2939
+ const xhr = new Xhr();
2940
+ const abort = () => xhr.abort();
2941
+ xhr.open("PUT", url);
2942
+ Object.entries(signed.requestHeaders).forEach(([key, value]) => xhr.setRequestHeader(key, value));
2943
+ xhr.upload.onprogress = (event) => onProgress({ loaded: event.loaded });
2944
+ xhr.onload = () => {
2945
+ signal?.removeEventListener("abort", abort);
2946
+ if (xhr.status < 200 || xhr.status >= 300) {
2947
+ reject(new Error(`athena.storage.file.upload failed with status ${xhr.status}`));
2948
+ return;
2949
+ }
2950
+ onProgress({ loaded: bodySize(body) });
2951
+ resolve(new Response(xhr.response, {
2952
+ status: xhr.status,
2953
+ statusText: xhr.statusText,
2954
+ headers: parseXhrHeaders(xhr.getAllResponseHeaders())
2955
+ }));
2956
+ };
2957
+ xhr.onerror = () => {
2958
+ signal?.removeEventListener("abort", abort);
2959
+ reject(new Error("athena.storage.file.upload failed with a network error"));
2960
+ };
2961
+ xhr.onabort = () => {
2962
+ signal?.removeEventListener("abort", abort);
2963
+ reject(new DOMException("Upload aborted", "AbortError"));
2964
+ };
2965
+ if (signal) {
2966
+ if (signal.aborted) {
2967
+ abort();
2968
+ return;
2969
+ }
2970
+ signal.addEventListener("abort", abort, { once: true });
2971
+ }
2972
+ xhr.send(body);
2973
+ });
2974
+ }
2975
+ function isBlobBody(body) {
2976
+ return typeof Blob !== "undefined" && body instanceof Blob;
2977
+ }
2978
+ async function bodyToArrayBuffer(body) {
2979
+ if (isBlobBody(body)) return body.arrayBuffer();
2980
+ if (body instanceof ArrayBuffer) return body;
2981
+ if (ArrayBuffer.isView(body)) {
2982
+ return body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength);
2983
+ }
2984
+ throw new Error("athena.storage.file.upload direct mode does not support ReadableStream bodies");
2985
+ }
2986
+ function bodySize(body) {
2987
+ if (isBlobBody(body)) return body.size;
2988
+ if (body instanceof ArrayBuffer) return body.byteLength;
2989
+ if (ArrayBuffer.isView(body)) return body.byteLength;
2990
+ return 0;
2991
+ }
2992
+ function awsEncode(value) {
2993
+ return encodeURIComponent(value).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
2994
+ }
2995
+ function formatAmzDate(date) {
2996
+ return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
2997
+ }
2998
+ async function sha256Hex(value) {
2999
+ const bytes = typeof value === "string" ? new TextEncoder().encode(value) : value;
3000
+ const digest = await crypto.subtle.digest("SHA-256", bytes);
3001
+ return toHex(new Uint8Array(digest));
3002
+ }
3003
+ async function hmac(key, value) {
3004
+ const keyBytes = typeof key === "string" ? new TextEncoder().encode(key) : key;
3005
+ const cryptoKey = await crypto.subtle.importKey(
3006
+ "raw",
3007
+ keyBytes,
3008
+ { name: "HMAC", hash: "SHA-256" },
3009
+ false,
3010
+ ["sign"]
3011
+ );
3012
+ return crypto.subtle.sign("HMAC", cryptoKey, new TextEncoder().encode(value));
3013
+ }
3014
+ async function hmacHex(key, value) {
3015
+ return toHex(new Uint8Array(await hmac(key, value)));
3016
+ }
3017
+ function toHex(bytes) {
3018
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
3019
+ }
3020
+ function parseXhrHeaders(rawHeaders) {
3021
+ const headers = new Headers();
3022
+ rawHeaders.trim().split(/[\r\n]+/).forEach((line) => {
3023
+ const separator = line.indexOf(":");
3024
+ if (separator > 0) {
3025
+ headers.set(line.slice(0, separator).trim(), line.slice(separator + 1).trim());
3026
+ }
3027
+ });
3028
+ return headers;
3029
+ }
3030
+
2821
3031
  // src/storage/file.ts
3032
+ function mergeUploadHeaders(serverHeaders, inputHeaders) {
3033
+ const headers = { ...serverHeaders };
3034
+ new Headers(inputHeaders).forEach((value, key) => {
3035
+ headers[key] = value;
3036
+ });
3037
+ return headers;
3038
+ }
2822
3039
  function createStorageFileModule(base, config = {}) {
2823
3040
  const upload = async (input, options) => {
2824
3041
  const sources = normalizeUploadSources(input);
@@ -2854,16 +3071,25 @@ function createStorageFileModule(base, config = {}) {
2854
3071
  for (let index = 0; index < uploadRequests.length; index += 1) {
2855
3072
  const request2 = uploadRequests[index];
2856
3073
  const uploadUrl = uploadUrls[index];
2857
- const response = await putUploadBody(
3074
+ const aggregateProgress = (progress) => {
3075
+ aggregateLoaded[index] = progress.loaded;
3076
+ input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
3077
+ };
3078
+ const response = config.directUpload ? await putDirectStorageUploadBody(
3079
+ config.directUpload,
3080
+ uploadUrl.upload.bucket,
3081
+ uploadUrl.upload.storage_key,
3082
+ request2.source.source,
3083
+ mergeUploadHeaders(uploadUrl.upload.headers ?? {}, input.uploadHeaders),
3084
+ options?.signal,
3085
+ aggregateProgress
3086
+ ) : await putUploadBody(
2858
3087
  uploadUrl.upload.url,
2859
3088
  uploadUrl.upload.headers ?? {},
2860
3089
  request2.source,
2861
3090
  input,
2862
3091
  options,
2863
- (progress) => {
2864
- aggregateLoaded[index] = progress.loaded;
2865
- input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
2866
- }
3092
+ aggregateProgress
2867
3093
  );
2868
3094
  uploaded.push({
2869
3095
  file: uploadUrl.file,
@@ -3014,7 +3240,7 @@ function putUploadBodyWithXhr(url, source, headers, options, onProgress) {
3014
3240
  resolve(new Response(xhr.response, {
3015
3241
  status: xhr.status,
3016
3242
  statusText: xhr.statusText,
3017
- headers: parseXhrHeaders(xhr.getAllResponseHeaders())
3243
+ headers: parseXhrHeaders2(xhr.getAllResponseHeaders())
3018
3244
  }));
3019
3245
  };
3020
3246
  xhr.onerror = () => {
@@ -3152,7 +3378,7 @@ function createProgressSnapshot(phase, sources, fileIndex, loaded, aggregateLoad
3152
3378
  function sum(values) {
3153
3379
  return values.reduce((total, value) => total + value, 0);
3154
3380
  }
3155
- function parseXhrHeaders(raw) {
3381
+ function parseXhrHeaders2(raw) {
3156
3382
  const headers = new Headers();
3157
3383
  for (const line of raw.trim().split(/[\r\n]+/)) {
3158
3384
  const index = line.indexOf(":");
@@ -3169,6 +3395,230 @@ function isRecord5(value) {
3169
3395
  return Boolean(value) && typeof value === "object";
3170
3396
  }
3171
3397
 
3398
+ // src/storage/backup.ts
3399
+ function backupError(message, status, endpoint, method, cause, raw) {
3400
+ const error = new Error(message);
3401
+ error.name = "AthenaStorageError";
3402
+ error.code = status === 0 ? "NETWORK_ERROR" : "HTTP_ERROR";
3403
+ error.status = status;
3404
+ error.endpoint = endpoint;
3405
+ error.method = method;
3406
+ error.cause = cause;
3407
+ error.raw = raw;
3408
+ throw error;
3409
+ }
3410
+ function isRecord6(value) {
3411
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3412
+ }
3413
+ function asPath(path) {
3414
+ return path;
3415
+ }
3416
+ function appendQuery(path, query) {
3417
+ if (!query) return path;
3418
+ const params = new URLSearchParams();
3419
+ for (const [key, value] of Object.entries(query)) {
3420
+ if (value === void 0 || value === null || value === "") continue;
3421
+ params.set(key, String(value));
3422
+ }
3423
+ const text = params.toString();
3424
+ return text ? `${path}?${text}` : path;
3425
+ }
3426
+ function unwrapAthenaData(payload) {
3427
+ if (isRecord6(payload) && "data" in payload) {
3428
+ return payload.data;
3429
+ }
3430
+ return payload;
3431
+ }
3432
+ function requireKey(key) {
3433
+ const trimmed = key.trim();
3434
+ if (!trimmed || trimmed === "undefined" || trimmed === "null") {
3435
+ backupError("Backup object key is required", 400, "/admin/backups/{key}", "DELETE");
3436
+ }
3437
+ return trimmed;
3438
+ }
3439
+ function resolveMessage(payload, fallback) {
3440
+ if (isRecord6(payload)) {
3441
+ const message = payload.message ?? payload.error ?? payload.details;
3442
+ if (typeof message === "string" && message.trim()) return message.trim();
3443
+ }
3444
+ if (typeof payload === "string" && payload.trim()) return payload.trim();
3445
+ return fallback;
3446
+ }
3447
+ async function callBackupEndpoint(gateway, path, method, payload, options, runtime) {
3448
+ const endpoint = asPath(path);
3449
+ const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
3450
+ const url = buildAthenaGatewayUrl(baseUrl, endpoint);
3451
+ const headers = gateway.buildHeaders(options);
3452
+ const init = {
3453
+ method,
3454
+ headers,
3455
+ signal: options?.signal
3456
+ };
3457
+ if (payload !== void 0 && method !== "GET") {
3458
+ init.body = JSON.stringify(payload);
3459
+ }
3460
+ let response;
3461
+ try {
3462
+ response = await fetch(url, init);
3463
+ } catch (error) {
3464
+ backupError(
3465
+ error instanceof Error ? error.message : "Backup network error",
3466
+ 0,
3467
+ path,
3468
+ method,
3469
+ error
3470
+ );
3471
+ }
3472
+ const rawText = await response.text();
3473
+ let parsed = null;
3474
+ if (rawText) {
3475
+ try {
3476
+ parsed = JSON.parse(rawText);
3477
+ } catch {
3478
+ parsed = rawText;
3479
+ }
3480
+ }
3481
+ if (!response.ok) {
3482
+ backupError(
3483
+ resolveMessage(parsed, `Backup ${method} ${path} failed (${response.status})`),
3484
+ response.status,
3485
+ path,
3486
+ method,
3487
+ void 0,
3488
+ parsed
3489
+ );
3490
+ }
3491
+ return unwrapAthenaData(parsed);
3492
+ }
3493
+ function createStorageBackupModule(gateway, runtimeOptions) {
3494
+ const resolvedBaseUrl = () => String(gateway.baseUrl ?? "").replace(/\/+$/, "");
3495
+ return {
3496
+ async list(query, options) {
3497
+ const path = appendQuery("/admin/backups", {
3498
+ limit: query?.limit ?? 10,
3499
+ client_name: query?.client_name,
3500
+ cursor: query?.cursor ?? void 0
3501
+ });
3502
+ const data = await callBackupEndpoint(gateway, path, "GET", void 0, options);
3503
+ const backups = (data?.backups ?? []).map((row) => ({
3504
+ ...row,
3505
+ key: row.key ?? row.s3_key
3506
+ }));
3507
+ return {
3508
+ backups,
3509
+ next_cursor: data?.next_cursor ?? null
3510
+ };
3511
+ },
3512
+ async create(input, options) {
3513
+ const data = await callBackupEndpoint(gateway, "/admin/backups", "POST", input, options);
3514
+ return {
3515
+ job_id: Number(data?.job_id ?? 0),
3516
+ client_name: String(data?.client_name ?? input.client_name),
3517
+ status: String(data?.status ?? "pending")
3518
+ };
3519
+ },
3520
+ async restore(key, input, options) {
3521
+ const backupKey = requireKey(key);
3522
+ const path = `/admin/backups/${encodeURIComponent(backupKey)}/restore`;
3523
+ const data = await callBackupEndpoint(gateway, path, "POST", input, options);
3524
+ return {
3525
+ job_id: Number(data?.job_id ?? 0),
3526
+ client_name: String(data?.client_name ?? input.client_name),
3527
+ status: String(data?.status ?? "pending"),
3528
+ key: String(data?.key ?? backupKey)
3529
+ };
3530
+ },
3531
+ async delete(key, options) {
3532
+ const backupKey = requireKey(key);
3533
+ await callBackupEndpoint(
3534
+ gateway,
3535
+ `/admin/backups/${encodeURIComponent(backupKey)}`,
3536
+ "DELETE",
3537
+ void 0,
3538
+ options);
3539
+ },
3540
+ downloadUrl(key, options) {
3541
+ const backupKey = requireKey(key);
3542
+ const base = `${resolvedBaseUrl()}/admin/backups/${encodeURIComponent(backupKey)}/download`;
3543
+ return options?.apiKey ? `${base}?api_key=${encodeURIComponent(options.apiKey)}` : base;
3544
+ },
3545
+ jobs: {
3546
+ async list(query, options) {
3547
+ const path = appendQuery("/admin/backups/jobs", query ?? {});
3548
+ const data = await callBackupEndpoint(gateway, path, "GET", void 0, options);
3549
+ if (Array.isArray(data)) return data;
3550
+ if (isRecord6(data) && Array.isArray(data.jobs)) return data.jobs;
3551
+ return [];
3552
+ },
3553
+ async get(jobId, options) {
3554
+ return callBackupEndpoint(
3555
+ gateway,
3556
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}`,
3557
+ "GET",
3558
+ void 0,
3559
+ options);
3560
+ },
3561
+ async cancel(jobId, options) {
3562
+ return callBackupEndpoint(
3563
+ gateway,
3564
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}/cancel`,
3565
+ "POST",
3566
+ {},
3567
+ options);
3568
+ },
3569
+ async delete(jobId, options) {
3570
+ await callBackupEndpoint(
3571
+ gateway,
3572
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}`,
3573
+ "DELETE",
3574
+ void 0,
3575
+ options);
3576
+ },
3577
+ async openObjectUrl(jobId, options) {
3578
+ const data = await callBackupEndpoint(
3579
+ gateway,
3580
+ `/admin/backups/jobs/${encodeURIComponent(String(jobId))}/s3-open`,
3581
+ "GET",
3582
+ void 0,
3583
+ options);
3584
+ return String(data?.url ?? "");
3585
+ }
3586
+ },
3587
+ schedules: {
3588
+ async list(options) {
3589
+ const data = await callBackupEndpoint(gateway, "/admin/backups/schedules", "GET", void 0, options);
3590
+ if (Array.isArray(data)) return data;
3591
+ if (isRecord6(data) && Array.isArray(data.schedules)) return data.schedules;
3592
+ return [];
3593
+ },
3594
+ async create(input, options) {
3595
+ return callBackupEndpoint(
3596
+ gateway,
3597
+ "/admin/backups/schedules",
3598
+ "POST",
3599
+ input,
3600
+ options);
3601
+ },
3602
+ async update(id, input, options) {
3603
+ return callBackupEndpoint(
3604
+ gateway,
3605
+ `/admin/backups/schedules/${encodeURIComponent(String(id))}`,
3606
+ "PATCH",
3607
+ input,
3608
+ options);
3609
+ },
3610
+ async delete(id, options) {
3611
+ await callBackupEndpoint(
3612
+ gateway,
3613
+ `/admin/backups/schedules/${encodeURIComponent(String(id))}`,
3614
+ "DELETE",
3615
+ void 0,
3616
+ options);
3617
+ }
3618
+ }
3619
+ };
3620
+ }
3621
+
3172
3622
  // src/storage/module.ts
3173
3623
  var storageSdkManifest = {
3174
3624
  methods: [
@@ -3211,6 +3661,53 @@ var storageSdkManifest = {
3211
3661
  responseEnvelope: "raw",
3212
3662
  responseType: "{ data: S3CredentialListItem[] }"
3213
3663
  },
3664
+ {
3665
+ name: "backup.list",
3666
+ method: "GET",
3667
+ path: "/admin/backups",
3668
+ responseEnvelope: "athena",
3669
+ responseType: "StorageBackupListPage",
3670
+ note: "Admin backup archives on server S3/R2 profile"
3671
+ },
3672
+ {
3673
+ name: "backup.create",
3674
+ method: "POST",
3675
+ path: "/admin/backups",
3676
+ requestType: "StorageBackupCreateRequest",
3677
+ responseEnvelope: "athena",
3678
+ responseType: "StorageBackupQueuedJob"
3679
+ },
3680
+ {
3681
+ name: "backup.restore",
3682
+ method: "POST",
3683
+ path: "/admin/backups/{key}/restore",
3684
+ pathParams: ["key"],
3685
+ requestType: "StorageBackupRestoreRequest",
3686
+ responseEnvelope: "athena",
3687
+ responseType: "StorageBackupQueuedJob"
3688
+ },
3689
+ {
3690
+ name: "backup.delete",
3691
+ method: "DELETE",
3692
+ path: "/admin/backups/{key}",
3693
+ pathParams: ["key"],
3694
+ responseEnvelope: "athena",
3695
+ responseType: "void"
3696
+ },
3697
+ {
3698
+ name: "backup.jobs.list",
3699
+ method: "GET",
3700
+ path: "/admin/backups/jobs",
3701
+ responseEnvelope: "athena",
3702
+ responseType: "StorageBackupJob[]"
3703
+ },
3704
+ {
3705
+ name: "backup.schedules.list",
3706
+ method: "GET",
3707
+ path: "/admin/backups/schedules",
3708
+ responseEnvelope: "athena",
3709
+ responseType: "StorageBackupSchedule[]"
3710
+ },
3214
3711
  {
3215
3712
  name: "createStorageUploadUrl",
3216
3713
  method: "POST",
@@ -3858,7 +4355,7 @@ var AthenaStorageError = class extends Error {
3858
4355
  };
3859
4356
  }
3860
4357
  };
3861
- function isRecord6(value) {
4358
+ function isRecord7(value) {
3862
4359
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3863
4360
  }
3864
4361
  function causeToString(cause) {
@@ -3956,7 +4453,7 @@ function parseResponseBody3(rawText, contentType) {
3956
4453
  return { parsed: rawText, parseFailed: true };
3957
4454
  }
3958
4455
  }
3959
- function appendQuery(path, query) {
4456
+ function appendQuery2(path, query) {
3960
4457
  if (!query) return path;
3961
4458
  const params = new URLSearchParams();
3962
4459
  for (const [key, value] of Object.entries(query)) {
@@ -3982,7 +4479,7 @@ function withPathParam(path, name, value) {
3982
4479
  return path.replace(`{${name}}`, encodeURIComponent(value));
3983
4480
  }
3984
4481
  function resolveErrorMessage3(payload, fallback) {
3985
- if (isRecord6(payload)) {
4482
+ if (isRecord7(payload)) {
3986
4483
  const message = payload.message ?? payload.error ?? payload.details;
3987
4484
  if (typeof message === "string" && message.trim()) {
3988
4485
  return message.trim();
@@ -3994,12 +4491,12 @@ function resolveErrorMessage3(payload, fallback) {
3994
4491
  return fallback;
3995
4492
  }
3996
4493
  function resolveErrorHint2(payload) {
3997
- if (!isRecord6(payload)) return void 0;
4494
+ if (!isRecord7(payload)) return void 0;
3998
4495
  const hint = payload.hint ?? payload.suggestion;
3999
4496
  return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
4000
4497
  }
4001
4498
  function resolveErrorCause(payload) {
4002
- if (!isRecord6(payload)) return void 0;
4499
+ if (!isRecord7(payload)) return void 0;
4003
4500
  const cause = payload.cause ?? payload.reason;
4004
4501
  return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
4005
4502
  }
@@ -4118,7 +4615,7 @@ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload,
4118
4615
  );
4119
4616
  }
4120
4617
  if (envelope === "athena") {
4121
- if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4618
+ if (!isRecord7(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4122
4619
  return rejectStorageError(
4123
4620
  {
4124
4621
  code: "INVALID_ATHENA_ENVELOPE",
@@ -4226,7 +4723,7 @@ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, run
4226
4723
  runtimeOptions
4227
4724
  );
4228
4725
  }
4229
- function isBlobBody(body) {
4726
+ function isBlobBody2(body) {
4230
4727
  return typeof Blob !== "undefined" && body instanceof Blob;
4231
4728
  }
4232
4729
  function isReadableStreamBody(body) {
@@ -4235,7 +4732,7 @@ function isReadableStreamBody(body) {
4235
4732
  async function putPresignedUploadBody(uploadUrl, uploadHeaders, body, options) {
4236
4733
  const headers = new Headers(uploadHeaders);
4237
4734
  Object.entries(options?.headers ?? {}).forEach(([key, value]) => headers.set(key, value));
4238
- if (!headers.has("Content-Type") && isBlobBody(body) && body.type) {
4735
+ if (!headers.has("Content-Type") && isBlobBody2(body) && body.type) {
4239
4736
  headers.set("Content-Type", body.type);
4240
4737
  }
4241
4738
  const init = {
@@ -4330,7 +4827,7 @@ async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options,
4330
4827
  }
4331
4828
  delete headers["Content-Type"];
4332
4829
  delete headers["content-type"];
4333
- if (isBlobBody(body) && body.type) {
4830
+ if (isBlobBody2(body) && body.type) {
4334
4831
  headers["Content-Type"] = body.type;
4335
4832
  }
4336
4833
  const requestInit = {
@@ -4415,7 +4912,7 @@ async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options,
4415
4912
  runtimeOptions
4416
4913
  );
4417
4914
  }
4418
- if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4915
+ if (!isRecord7(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
4419
4916
  return rejectStorageError(
4420
4917
  {
4421
4918
  code: "INVALID_ATHENA_ENVELOPE",
@@ -4487,14 +4984,14 @@ function createStorageModule(gateway, runtimeOptions) {
4487
4984
  return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "GET", void 0, options);
4488
4985
  },
4489
4986
  getStorageFileUrl(fileId, query, options) {
4490
- const path = appendQuery(
4987
+ const path = appendQuery2(
4491
4988
  withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
4492
4989
  query
4493
4990
  );
4494
4991
  return callAthena2(path, "GET", void 0, options);
4495
4992
  },
4496
4993
  getStorageFileProxy(fileId, query, options) {
4497
- const path = appendQuery(
4994
+ const path = appendQuery2(
4498
4995
  withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
4499
4996
  query
4500
4997
  );
@@ -4518,7 +5015,7 @@ function createStorageModule(gateway, runtimeOptions) {
4518
5015
  };
4519
5016
  const fileFacade = createStorageFileModule(base, runtimeOptions);
4520
5017
  const fileUpload = ((input, options) => {
4521
- if (isRecord6(input) && "files" in input) {
5018
+ if (isRecord7(input) && "files" in input) {
4522
5019
  return fileFacade.upload(input, options);
4523
5020
  }
4524
5021
  return base.createStorageUploadUrl(
@@ -4580,7 +5077,7 @@ function createStorageModule(gateway, runtimeOptions) {
4580
5077
  return callAthena2(withPathParam("/storage/files/{file_id}/public-url", "file_id", fileId), "GET", void 0, options);
4581
5078
  },
4582
5079
  proxyUrl(fileId, query, options) {
4583
- const path = appendQuery(
5080
+ const path = appendQuery2(
4584
5081
  withPathParam("/storage/files/{file_id}/proxy-url", "file_id", fileId),
4585
5082
  query
4586
5083
  );
@@ -4618,7 +5115,7 @@ function createStorageModule(gateway, runtimeOptions) {
4618
5115
  },
4619
5116
  retention: {
4620
5117
  get(fileId, query, options) {
4621
- const path = appendQuery(
5118
+ const path = appendQuery2(
4622
5119
  withPathParam("/storage/files/{file_id}/retention", "file_id", fileId),
4623
5120
  query
4624
5121
  );
@@ -4820,6 +5317,7 @@ function createStorageModule(gateway, runtimeOptions) {
4820
5317
  return callAthena2("/storage/audit/list", "POST", input, options);
4821
5318
  }
4822
5319
  };
5320
+ const backup = createStorageBackupModule(gateway);
4823
5321
  return {
4824
5322
  ...base,
4825
5323
  credentials,
@@ -4831,6 +5329,7 @@ function createStorageModule(gateway, runtimeOptions) {
4831
5329
  bucket,
4832
5330
  multipart,
4833
5331
  audit,
5332
+ backup,
4834
5333
  delete: file.delete
4835
5334
  };
4836
5335
  }
@@ -4880,7 +5379,7 @@ function normalizeWsUrl(value, label) {
4880
5379
  parsed.pathname = parsed.pathname.replace(/\/+$/, "");
4881
5380
  return parsed.toString().replace(/\/$/, "");
4882
5381
  }
4883
- function isRecord7(value) {
5382
+ function isRecord8(value) {
4884
5383
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4885
5384
  }
4886
5385
  function parseResponseBody4(rawText, contentType) {
@@ -4902,7 +5401,7 @@ function resolveRequestId3(headers) {
4902
5401
  return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
4903
5402
  }
4904
5403
  function resolveErrorMessage4(payload, fallback) {
4905
- if (isRecord7(payload)) {
5404
+ if (isRecord8(payload)) {
4906
5405
  for (const candidate of [payload.error, payload.message, payload.details]) {
4907
5406
  if (typeof candidate === "string" && candidate.trim().length > 0) {
4908
5407
  return candidate.trim();
@@ -5516,7 +6015,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
5516
6015
  "ilike",
5517
6016
  "is"
5518
6017
  ]);
5519
- function isRecord8(value) {
6018
+ function isRecord9(value) {
5520
6019
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5521
6020
  }
5522
6021
  function isUuidString(value) {
@@ -5529,7 +6028,7 @@ function shouldUseUuidTextComparison(column, value) {
5529
6028
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
5530
6029
  }
5531
6030
  function isRelationSelectNode(value) {
5532
- return isRecord8(value) && isRecord8(value.select);
6031
+ return isRecord9(value) && isRecord9(value.select);
5533
6032
  }
5534
6033
  function normalizeIdentifier(value, label) {
5535
6034
  const normalized = value.trim();
@@ -5585,7 +6084,7 @@ function compileRelationToken(key, node) {
5585
6084
  return `${prefix}${relationToken}(${nested})`;
5586
6085
  }
5587
6086
  function compileSelectShape(select) {
5588
- if (!isRecord8(select)) {
6087
+ if (!isRecord9(select)) {
5589
6088
  throw new Error("findMany select must be an object");
5590
6089
  }
5591
6090
  const tokens = [];
@@ -5609,7 +6108,7 @@ function compileSelectShape(select) {
5609
6108
  return tokens.join(",");
5610
6109
  }
5611
6110
  function selectShapeUsesRelationSchema(select) {
5612
- if (!isRecord8(select)) {
6111
+ if (!isRecord9(select)) {
5613
6112
  return false;
5614
6113
  }
5615
6114
  for (const rawValue of Object.values(select)) {
@@ -5627,7 +6126,7 @@ function selectShapeUsesRelationSchema(select) {
5627
6126
  }
5628
6127
  function compileColumnWhere(column, input) {
5629
6128
  const normalizedColumn = normalizeIdentifier(column, "where column");
5630
- if (!isRecord8(input)) {
6129
+ if (!isRecord9(input)) {
5631
6130
  return [buildGatewayCondition("eq", normalizedColumn, input)];
5632
6131
  }
5633
6132
  const conditions = [];
@@ -5655,7 +6154,7 @@ function compileColumnWhere(column, input) {
5655
6154
  return conditions;
5656
6155
  }
5657
6156
  function compileBooleanExpressionTerms(clause, label) {
5658
- if (!isRecord8(clause)) {
6157
+ if (!isRecord9(clause)) {
5659
6158
  throw new Error(`findMany where.${label} clauses must be objects`);
5660
6159
  }
5661
6160
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -5664,7 +6163,7 @@ function compileBooleanExpressionTerms(clause, label) {
5664
6163
  }
5665
6164
  const [rawColumn, rawValue] = entries[0];
5666
6165
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
5667
- if (!isRecord8(rawValue)) {
6166
+ if (!isRecord9(rawValue)) {
5668
6167
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
5669
6168
  }
5670
6169
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -5688,7 +6187,7 @@ function compileWhere(where) {
5688
6187
  if (where === void 0) {
5689
6188
  return void 0;
5690
6189
  }
5691
- if (!isRecord8(where)) {
6190
+ if (!isRecord9(where)) {
5692
6191
  throw new Error("findMany where must be an object");
5693
6192
  }
5694
6193
  const conditions = [];
@@ -5738,7 +6237,7 @@ function compileOrderBy(orderBy) {
5738
6237
  if (orderBy === void 0) {
5739
6238
  return void 0;
5740
6239
  }
5741
- if (!isRecord8(orderBy)) {
6240
+ if (!isRecord9(orderBy)) {
5742
6241
  throw new Error("findMany orderBy must be an object");
5743
6242
  }
5744
6243
  if ("column" in orderBy) {
@@ -5913,11 +6412,11 @@ function toFindManyAstOrder(order) {
5913
6412
  ascending: order.direction !== "descending"
5914
6413
  };
5915
6414
  }
5916
- function isRecord9(value) {
6415
+ function isRecord10(value) {
5917
6416
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5918
6417
  }
5919
6418
  function normalizeFindManyAstColumnPredicate(value) {
5920
- if (!isRecord9(value)) {
6419
+ if (!isRecord10(value)) {
5921
6420
  return {
5922
6421
  eq: value
5923
6422
  };
@@ -5941,7 +6440,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
5941
6440
  return normalized;
5942
6441
  }
5943
6442
  function normalizeFindManyAstWhere(where) {
5944
- if (!where || !isRecord9(where)) {
6443
+ if (!where || !isRecord10(where)) {
5945
6444
  return where;
5946
6445
  }
5947
6446
  const normalized = {};
@@ -5955,7 +6454,7 @@ function normalizeFindManyAstWhere(where) {
5955
6454
  );
5956
6455
  continue;
5957
6456
  }
5958
- if (key === "not" && isRecord9(value)) {
6457
+ if (key === "not" && isRecord10(value)) {
5959
6458
  normalized.not = normalizeFindManyAstBooleanOperand(
5960
6459
  value
5961
6460
  );
@@ -5966,7 +6465,7 @@ function normalizeFindManyAstWhere(where) {
5966
6465
  return normalized;
5967
6466
  }
5968
6467
  function predicateRequiresUuidQueryFallback(column, value) {
5969
- if (!isRecord9(value)) {
6468
+ if (!isRecord10(value)) {
5970
6469
  return shouldUseUuidTextComparison(column, value);
5971
6470
  }
5972
6471
  const eqValue = value.eq;
@@ -5984,7 +6483,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
5984
6483
  return false;
5985
6484
  }
5986
6485
  function findManyAstWhereRequiresLegacyTransport(where) {
5987
- if (!where || !isRecord9(where)) {
6486
+ if (!where || !isRecord10(where)) {
5988
6487
  return false;
5989
6488
  }
5990
6489
  for (const [key, value] of Object.entries(where)) {
@@ -5999,7 +6498,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
5999
6498
  }
6000
6499
  continue;
6001
6500
  }
6002
- if (key === "not" && isRecord9(value)) {
6501
+ if (key === "not" && isRecord10(value)) {
6003
6502
  if (booleanOperandRequiresUuidQueryFallback(value)) {
6004
6503
  return true;
6005
6504
  }
@@ -6619,7 +7118,7 @@ async function executeExperimentalRead(experimental, runner) {
6619
7118
  throw error;
6620
7119
  }
6621
7120
  }
6622
- function isRecord10(value) {
7121
+ function isRecord11(value) {
6623
7122
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6624
7123
  }
6625
7124
  function firstNonEmptyString2(...values) {
@@ -6631,8 +7130,8 @@ function firstNonEmptyString2(...values) {
6631
7130
  return void 0;
6632
7131
  }
6633
7132
  function resolveStructuredErrorPayload2(raw) {
6634
- if (!isRecord10(raw)) return null;
6635
- return isRecord10(raw.error) ? raw.error : raw;
7133
+ if (!isRecord11(raw)) return null;
7134
+ return isRecord11(raw.error) ? raw.error : raw;
6636
7135
  }
6637
7136
  function resolveStructuredErrorDetails(payload, message) {
6638
7137
  if (!payload || !("details" in payload)) {
@@ -6648,7 +7147,7 @@ function resolveStructuredErrorDetails(payload, message) {
6648
7147
  return details;
6649
7148
  }
6650
7149
  function createResultError(response, result, normalized) {
6651
- const rawRecord = isRecord10(response.raw) ? response.raw : null;
7150
+ const rawRecord = isRecord11(response.raw) ? response.raw : null;
6652
7151
  const payload = resolveStructuredErrorPayload2(response.raw);
6653
7152
  const message = firstNonEmptyString2(
6654
7153
  response.error,
@@ -8557,6 +9056,7 @@ function createClientFromConfig(config, sourceConfig) {
8557
9056
  withOptions: storageWithOptions,
8558
9057
  storage: createStorageModule(gateway, {
8559
9058
  ...config.experimental.storage,
9059
+ ...config.experimental.directStorageUpload ? { directUpload: config.experimental.directStorageUpload } : {},
8560
9060
  ...config.storageUrl ? {
8561
9061
  baseUrl: config.storageUrl,
8562
9062
  stripBasePath: true