@xylex-group/athena 2.4.1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -1
- package/bin/athena-js.js +0 -0
- package/dist/browser.cjs +2642 -56
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +8 -7
- package/dist/browser.d.ts +8 -7
- package/dist/browser.js +2635 -57
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +1648 -239
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -3
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +1648 -239
- package/dist/cli/index.js.map +1 -1
- package/dist/cookies.cjs +10 -3
- package/dist/cookies.cjs.map +1 -1
- package/dist/cookies.d.cts +1 -174
- package/dist/cookies.d.ts +1 -174
- package/dist/cookies.js +10 -3
- package/dist/cookies.js.map +1 -1
- package/dist/index-CVcQCGyG.d.cts +174 -0
- package/dist/index-CVcQCGyG.d.ts +174 -0
- package/dist/index.cjs +2642 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +2635 -57
- package/dist/index.js.map +1 -1
- package/dist/model-form-AKYrgede.d.ts +2772 -0
- package/dist/model-form-ehfqLuG7.d.cts +2772 -0
- package/dist/{pipeline-CR4V15jF.d.ts → pipeline-BUsR9XlO.d.ts} +1 -1
- package/dist/{pipeline-DZeExYMA.d.cts → pipeline-BfCWSRYl.d.cts} +1 -1
- package/dist/react-email-BQzmXBDE.d.cts +304 -0
- package/dist/react-email-BrVRp80B.d.ts +304 -0
- package/dist/react.cjs +178 -71
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +22 -5
- package/dist/react.d.ts +22 -5
- package/dist/react.js +92 -5
- package/dist/react.js.map +1 -1
- package/dist/{types-D1JvL21V.d.cts → types-BSIsyss1.d.cts} +1 -1
- package/dist/{types-09Q4D86N.d.cts → types-BsyRW49r.d.cts} +3 -3
- package/dist/{types-09Q4D86N.d.ts → types-BsyRW49r.d.ts} +3 -3
- package/dist/{types-DU3gNdFv.d.ts → types-t_TVqnmp.d.ts} +1 -1
- package/package.json +22 -21
- package/dist/model-form-4LPnOPAF.d.cts +0 -1383
- package/dist/model-form-CO4-LmNC.d.ts +0 -1383
- package/dist/react-email-6mOyxBo4.d.cts +0 -657
- package/dist/react-email-Buhcpglm.d.ts +0 -657
package/dist/index.cjs
CHANGED
|
@@ -132,6 +132,60 @@ function buildAthenaGatewayUrl(baseUrl, path) {
|
|
|
132
132
|
return `${baseUrl}${path}`;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// src/cookies/base64.ts
|
|
136
|
+
function getAtob() {
|
|
137
|
+
const candidate = globalThis.atob;
|
|
138
|
+
return typeof candidate === "function" ? candidate : void 0;
|
|
139
|
+
}
|
|
140
|
+
function getBtoa() {
|
|
141
|
+
const candidate = globalThis.btoa;
|
|
142
|
+
return typeof candidate === "function" ? candidate : void 0;
|
|
143
|
+
}
|
|
144
|
+
function bytesToBinaryString(bytes) {
|
|
145
|
+
let result = "";
|
|
146
|
+
for (const byte of bytes) {
|
|
147
|
+
result += String.fromCharCode(byte);
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
function binaryStringToBytes(binary) {
|
|
152
|
+
const bytes = new Uint8Array(binary.length);
|
|
153
|
+
for (let i = 0; i < binary.length; i++) {
|
|
154
|
+
bytes[i] = binary.charCodeAt(i);
|
|
155
|
+
}
|
|
156
|
+
return bytes;
|
|
157
|
+
}
|
|
158
|
+
function encodeBase64(bytes) {
|
|
159
|
+
const btoaFn = getBtoa();
|
|
160
|
+
if (btoaFn) {
|
|
161
|
+
return btoaFn(bytesToBinaryString(bytes));
|
|
162
|
+
}
|
|
163
|
+
return Buffer.from(bytes).toString("base64");
|
|
164
|
+
}
|
|
165
|
+
function decodeBase64(base64) {
|
|
166
|
+
const atobFn = getAtob();
|
|
167
|
+
if (atobFn) {
|
|
168
|
+
return binaryStringToBytes(atobFn(base64));
|
|
169
|
+
}
|
|
170
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
171
|
+
}
|
|
172
|
+
function encodeBytesToBase64Url(bytes) {
|
|
173
|
+
return encodeBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
174
|
+
}
|
|
175
|
+
function encodeStringToBase64Url(value) {
|
|
176
|
+
const bytes = new TextEncoder().encode(value);
|
|
177
|
+
return encodeBytesToBase64Url(bytes);
|
|
178
|
+
}
|
|
179
|
+
function decodeBase64UrlToBytes(value) {
|
|
180
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
181
|
+
const paddingLength = normalized.length % 4;
|
|
182
|
+
const padded = paddingLength === 0 ? normalized : `${normalized}${"=".repeat(4 - paddingLength)}`;
|
|
183
|
+
return decodeBase64(padded);
|
|
184
|
+
}
|
|
185
|
+
function decodeBase64UrlToString(value) {
|
|
186
|
+
return new TextDecoder().decode(decodeBase64UrlToBytes(value));
|
|
187
|
+
}
|
|
188
|
+
|
|
135
189
|
// src/cookies/cookie-utils.ts
|
|
136
190
|
var SECURE_COOKIE_PREFIX = "__Secure-";
|
|
137
191
|
function parseCookies(cookieHeader) {
|
|
@@ -143,24 +197,615 @@ function parseCookies(cookieHeader) {
|
|
|
143
197
|
});
|
|
144
198
|
return cookieMap;
|
|
145
199
|
}
|
|
200
|
+
|
|
201
|
+
// src/cookies/crypto.ts
|
|
202
|
+
var HS256_ALG = "HS256";
|
|
203
|
+
async function getSubtleCrypto() {
|
|
204
|
+
const globalCrypto = globalThis.crypto;
|
|
205
|
+
if (globalCrypto?.subtle) {
|
|
206
|
+
return globalCrypto.subtle;
|
|
207
|
+
}
|
|
208
|
+
const { webcrypto } = await import('crypto');
|
|
209
|
+
const subtle = webcrypto.subtle;
|
|
210
|
+
if (!subtle) {
|
|
211
|
+
throw new Error("Web Crypto subtle API is unavailable.");
|
|
212
|
+
}
|
|
213
|
+
return subtle;
|
|
214
|
+
}
|
|
215
|
+
async function importHmacKey(secret, usage) {
|
|
216
|
+
const subtle = await getSubtleCrypto();
|
|
217
|
+
return subtle.importKey(
|
|
218
|
+
"raw",
|
|
219
|
+
new TextEncoder().encode(secret),
|
|
220
|
+
{
|
|
221
|
+
name: "HMAC",
|
|
222
|
+
hash: "SHA-256"
|
|
223
|
+
},
|
|
224
|
+
false,
|
|
225
|
+
[usage]
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
function bufferToBytes(buffer) {
|
|
229
|
+
return new Uint8Array(buffer);
|
|
230
|
+
}
|
|
231
|
+
function parseJwtPayload(payloadSegment) {
|
|
232
|
+
try {
|
|
233
|
+
const decoded = decodeBase64UrlToString(payloadSegment);
|
|
234
|
+
const payload = JSON.parse(decoded);
|
|
235
|
+
if (!payload || typeof payload !== "object") {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return payload;
|
|
239
|
+
} catch {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function isJwtExpired(payload) {
|
|
244
|
+
const exp = payload.exp;
|
|
245
|
+
if (typeof exp !== "number") {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
return exp < Math.floor(Date.now() / 1e3);
|
|
249
|
+
}
|
|
250
|
+
async function signHmacBase64Url(secret, value) {
|
|
251
|
+
const subtle = await getSubtleCrypto();
|
|
252
|
+
const key = await importHmacKey(secret, "sign");
|
|
253
|
+
const signature = await subtle.sign("HMAC", key, new TextEncoder().encode(value));
|
|
254
|
+
return encodeBytesToBase64Url(bufferToBytes(signature));
|
|
255
|
+
}
|
|
256
|
+
async function signJwtHS256(payload, secret, expiresIn = 60 * 5) {
|
|
257
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
258
|
+
const header = { alg: HS256_ALG, typ: "JWT" };
|
|
259
|
+
const fullPayload = {
|
|
260
|
+
...payload,
|
|
261
|
+
iat: now,
|
|
262
|
+
exp: now + expiresIn
|
|
263
|
+
};
|
|
264
|
+
const headerPart = encodeStringToBase64Url(JSON.stringify(header));
|
|
265
|
+
const payloadPart = encodeStringToBase64Url(JSON.stringify(fullPayload));
|
|
266
|
+
const message = `${headerPart}.${payloadPart}`;
|
|
267
|
+
const signature = await signHmacBase64Url(secret, message);
|
|
268
|
+
return `${message}.${signature}`;
|
|
269
|
+
}
|
|
270
|
+
async function verifyJwtHS256(token, secret) {
|
|
271
|
+
const parts = token.split(".");
|
|
272
|
+
if (parts.length !== 3) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
const [headerPart, payloadPart, signaturePart] = parts;
|
|
276
|
+
if (!headerPart || !payloadPart || !signaturePart) {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
let header = null;
|
|
280
|
+
try {
|
|
281
|
+
header = JSON.parse(decodeBase64UrlToString(headerPart));
|
|
282
|
+
} catch {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
if (!header || header.alg !== HS256_ALG) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
const payload = parseJwtPayload(payloadPart);
|
|
289
|
+
if (!payload) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
const expectedSignature = await signHmacBase64Url(secret, `${headerPart}.${payloadPart}`);
|
|
293
|
+
if (expectedSignature !== signaturePart) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
if (isJwtExpired(payload)) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
return payload;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// src/cookies/session-store.ts
|
|
303
|
+
var ALLOWED_COOKIE_SIZE = 4096;
|
|
304
|
+
var ESTIMATED_EMPTY_COOKIE_SIZE = 200;
|
|
305
|
+
var CHUNK_SIZE = ALLOWED_COOKIE_SIZE - ESTIMATED_EMPTY_COOKIE_SIZE;
|
|
306
|
+
function getChunkIndex(cookieName) {
|
|
307
|
+
const parts = cookieName.split(".");
|
|
308
|
+
const lastPart = parts[parts.length - 1];
|
|
309
|
+
const index = parseInt(lastPart || "0", 10);
|
|
310
|
+
return Number.isNaN(index) ? 0 : index;
|
|
311
|
+
}
|
|
312
|
+
function readExistingChunks(cookieName, ctx) {
|
|
313
|
+
const chunks = {};
|
|
314
|
+
const cookies = parseCookies(ctx.headers?.get("cookie") || "");
|
|
315
|
+
for (const [name, value] of cookies) {
|
|
316
|
+
if (name.startsWith(cookieName)) {
|
|
317
|
+
chunks[name] = value;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return chunks;
|
|
321
|
+
}
|
|
322
|
+
function joinChunks(chunks) {
|
|
323
|
+
const sortedKeys = Object.keys(chunks).sort((left, right) => getChunkIndex(left) - getChunkIndex(right));
|
|
324
|
+
return sortedKeys.map((key) => chunks[key]).join("");
|
|
325
|
+
}
|
|
326
|
+
function chunkCookie(storeName, cookie, chunks, ctx) {
|
|
327
|
+
const chunkCount = Math.ceil(cookie.value.length / CHUNK_SIZE);
|
|
328
|
+
if (chunkCount === 1) {
|
|
329
|
+
chunks[cookie.name] = cookie.value;
|
|
330
|
+
return [cookie];
|
|
331
|
+
}
|
|
332
|
+
const cookies = [];
|
|
333
|
+
for (let index = 0; index < chunkCount; index++) {
|
|
334
|
+
const name = `${cookie.name}.${index}`;
|
|
335
|
+
const start = index * CHUNK_SIZE;
|
|
336
|
+
const value = cookie.value.substring(start, start + CHUNK_SIZE);
|
|
337
|
+
cookies.push({
|
|
338
|
+
...cookie,
|
|
339
|
+
name,
|
|
340
|
+
value
|
|
341
|
+
});
|
|
342
|
+
chunks[name] = value;
|
|
343
|
+
}
|
|
344
|
+
ctx.logger?.debug?.(`CHUNKING_${storeName.toUpperCase()}_COOKIE`, {
|
|
345
|
+
message: `${storeName} cookie exceeds allowed ${ALLOWED_COOKIE_SIZE} bytes.`,
|
|
346
|
+
emptyCookieSize: ESTIMATED_EMPTY_COOKIE_SIZE,
|
|
347
|
+
valueSize: cookie.value.length,
|
|
348
|
+
chunkCount,
|
|
349
|
+
chunks: cookies.map((entry) => entry.value.length + ESTIMATED_EMPTY_COOKIE_SIZE)
|
|
350
|
+
});
|
|
351
|
+
return cookies;
|
|
352
|
+
}
|
|
353
|
+
function getCleanCookies(chunks, cookieOptions) {
|
|
354
|
+
const cleanedChunks = {};
|
|
355
|
+
for (const name in chunks) {
|
|
356
|
+
cleanedChunks[name] = {
|
|
357
|
+
name,
|
|
358
|
+
value: "",
|
|
359
|
+
attributes: {
|
|
360
|
+
...cookieOptions,
|
|
361
|
+
maxAge: 0
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return cleanedChunks;
|
|
366
|
+
}
|
|
367
|
+
var storeFactory = (storeName) => (cookieName, cookieOptions, ctx) => {
|
|
368
|
+
const chunks = readExistingChunks(cookieName, ctx);
|
|
369
|
+
return {
|
|
370
|
+
getValue() {
|
|
371
|
+
return joinChunks(chunks);
|
|
372
|
+
},
|
|
373
|
+
hasChunks() {
|
|
374
|
+
return Object.keys(chunks).length > 0;
|
|
375
|
+
},
|
|
376
|
+
chunk(value, options) {
|
|
377
|
+
const cleanedChunks = getCleanCookies(chunks, cookieOptions);
|
|
378
|
+
for (const name in chunks) {
|
|
379
|
+
delete chunks[name];
|
|
380
|
+
}
|
|
381
|
+
const cookies = cleanedChunks;
|
|
382
|
+
const chunked = chunkCookie(
|
|
383
|
+
storeName,
|
|
384
|
+
{
|
|
385
|
+
name: cookieName,
|
|
386
|
+
value,
|
|
387
|
+
attributes: {
|
|
388
|
+
...cookieOptions,
|
|
389
|
+
...options
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
chunks,
|
|
393
|
+
ctx
|
|
394
|
+
);
|
|
395
|
+
for (const chunk of chunked) {
|
|
396
|
+
cookies[chunk.name] = chunk;
|
|
397
|
+
}
|
|
398
|
+
return Object.values(cookies);
|
|
399
|
+
},
|
|
400
|
+
clean() {
|
|
401
|
+
const cleanedChunks = getCleanCookies(chunks, cookieOptions);
|
|
402
|
+
for (const name in chunks) {
|
|
403
|
+
delete chunks[name];
|
|
404
|
+
}
|
|
405
|
+
return Object.values(cleanedChunks);
|
|
406
|
+
},
|
|
407
|
+
setCookies(cookies) {
|
|
408
|
+
for (const cookie of cookies) {
|
|
409
|
+
ctx.setCookie(cookie.name, cookie.value, cookie.attributes);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
var createSessionStore = storeFactory("Session");
|
|
415
|
+
var createAccountStore = storeFactory("Account");
|
|
416
|
+
|
|
417
|
+
// src/cookies/index.ts
|
|
418
|
+
var DEFAULT_COOKIE_PREFIX = "athena-auth";
|
|
419
|
+
var LEGACY_COOKIE_PREFIX = "better-auth";
|
|
420
|
+
var DEFAULT_SESSION_MAX_AGE = 7 * 24 * 60 * 60;
|
|
421
|
+
var DEFAULT_CACHE_MAX_AGE = 60 * 5;
|
|
422
|
+
function isProductionRuntime() {
|
|
423
|
+
return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
424
|
+
}
|
|
425
|
+
function getEnvironmentSecret() {
|
|
426
|
+
if (typeof process === "undefined") {
|
|
427
|
+
return void 0;
|
|
428
|
+
}
|
|
429
|
+
return process.env?.ATHENA_AUTH_SECRET || process.env?.BETTER_AUTH_SECRET || process.env?.AUTH_SECRET;
|
|
430
|
+
}
|
|
431
|
+
function isDynamicBaseURLConfig(baseURL) {
|
|
432
|
+
return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
|
|
433
|
+
}
|
|
434
|
+
function resolveCookiePrefixes(primaryPrefix) {
|
|
435
|
+
const prefixes = [primaryPrefix];
|
|
436
|
+
if (!prefixes.includes(DEFAULT_COOKIE_PREFIX)) {
|
|
437
|
+
prefixes.push(DEFAULT_COOKIE_PREFIX);
|
|
438
|
+
}
|
|
439
|
+
if (!prefixes.includes(LEGACY_COOKIE_PREFIX)) {
|
|
440
|
+
prefixes.push(LEGACY_COOKIE_PREFIX);
|
|
441
|
+
}
|
|
442
|
+
return prefixes;
|
|
443
|
+
}
|
|
444
|
+
function createError(message) {
|
|
445
|
+
return new Error(`@xylex-group/athena/cookies: ${message}`);
|
|
446
|
+
}
|
|
447
|
+
function getSecretOrThrow(secret) {
|
|
448
|
+
const resolved = secret || getEnvironmentSecret();
|
|
449
|
+
if (!resolved) {
|
|
450
|
+
throw createError(
|
|
451
|
+
"getCookieCache requires a secret. Pass `secret` or set ATHENA_AUTH_SECRET/BETTER_AUTH_SECRET/AUTH_SECRET."
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
return resolved;
|
|
455
|
+
}
|
|
456
|
+
function asObject(value) {
|
|
457
|
+
if (!value || typeof value !== "object") {
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
return value;
|
|
461
|
+
}
|
|
462
|
+
function getSessionTokenFromPair(session) {
|
|
463
|
+
const token = session.session?.token;
|
|
464
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
465
|
+
throw createError("setSessionCookie requires `session.session.token` to be a non-empty string.");
|
|
466
|
+
}
|
|
467
|
+
return token;
|
|
468
|
+
}
|
|
469
|
+
async function resolveCookieVersion(versionConfig, session, user) {
|
|
470
|
+
if (!versionConfig) {
|
|
471
|
+
return "1";
|
|
472
|
+
}
|
|
473
|
+
if (typeof versionConfig === "string") {
|
|
474
|
+
return versionConfig;
|
|
475
|
+
}
|
|
476
|
+
return versionConfig(session, user);
|
|
477
|
+
}
|
|
478
|
+
function getSessionCookieCacheName(cookiePrefix, cookieName, isSecure) {
|
|
479
|
+
return isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
|
|
480
|
+
}
|
|
481
|
+
async function setCookieValue(ctx, name, value, attributes) {
|
|
482
|
+
const secret = ctx.context.secret;
|
|
483
|
+
if (secret && typeof ctx.setSignedCookie === "function") {
|
|
484
|
+
await ctx.setSignedCookie(name, value, secret, attributes);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
ctx.setCookie(name, value, attributes);
|
|
488
|
+
}
|
|
489
|
+
function parseJsonSafely(value) {
|
|
490
|
+
try {
|
|
491
|
+
return JSON.parse(value);
|
|
492
|
+
} catch {
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function getIsSecureCookie(config) {
|
|
497
|
+
if (config?.isSecure !== void 0) {
|
|
498
|
+
return config.isSecure;
|
|
499
|
+
}
|
|
500
|
+
return isProductionRuntime();
|
|
501
|
+
}
|
|
502
|
+
function createCookieGetter(options) {
|
|
503
|
+
const baseURLString = typeof options.baseURL === "string" ? options.baseURL : void 0;
|
|
504
|
+
const dynamicProtocol = typeof options.baseURL === "object" && options.baseURL !== null ? options.baseURL.protocol : void 0;
|
|
505
|
+
const secure = options.advanced?.useSecureCookies !== void 0 ? options.advanced.useSecureCookies : dynamicProtocol === "https" ? true : dynamicProtocol === "http" ? false : baseURLString ? baseURLString.startsWith("https://") : isProductionRuntime();
|
|
506
|
+
const secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : "";
|
|
507
|
+
const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled;
|
|
508
|
+
const domain = crossSubdomainEnabled ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : void 0) : void 0;
|
|
509
|
+
if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) {
|
|
510
|
+
throw createError("baseURL is required when `crossSubDomainCookies.enabled` is true.");
|
|
511
|
+
}
|
|
512
|
+
function createCookie(cookieName, overrideAttributes = {}) {
|
|
513
|
+
const prefix = options.advanced?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
|
|
514
|
+
const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`;
|
|
515
|
+
const attributes = options.advanced?.cookies?.[cookieName]?.attributes || {};
|
|
516
|
+
return {
|
|
517
|
+
name: `${secureCookiePrefix}${name}`,
|
|
518
|
+
attributes: {
|
|
519
|
+
secure: !!secureCookiePrefix,
|
|
520
|
+
sameSite: "lax",
|
|
521
|
+
path: "/",
|
|
522
|
+
httpOnly: true,
|
|
523
|
+
...crossSubdomainEnabled ? { domain } : {},
|
|
524
|
+
...options.advanced?.defaultCookieAttributes,
|
|
525
|
+
...overrideAttributes,
|
|
526
|
+
...attributes
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
return createCookie;
|
|
531
|
+
}
|
|
532
|
+
function getCookies(options) {
|
|
533
|
+
const createCookie = createCookieGetter(options);
|
|
534
|
+
const sessionToken = createCookie("session_token", { maxAge: options.session?.expiresIn || DEFAULT_SESSION_MAX_AGE });
|
|
535
|
+
const sessionData = createCookie("session_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
|
|
536
|
+
const accountData = createCookie("account_data", { maxAge: options.session?.cookieCache?.maxAge || DEFAULT_CACHE_MAX_AGE });
|
|
537
|
+
const dontRememberToken = createCookie("dont_remember");
|
|
538
|
+
return {
|
|
539
|
+
sessionToken: {
|
|
540
|
+
name: sessionToken.name,
|
|
541
|
+
attributes: sessionToken.attributes
|
|
542
|
+
},
|
|
543
|
+
sessionData: {
|
|
544
|
+
name: sessionData.name,
|
|
545
|
+
attributes: sessionData.attributes
|
|
546
|
+
},
|
|
547
|
+
dontRememberToken: {
|
|
548
|
+
name: dontRememberToken.name,
|
|
549
|
+
attributes: dontRememberToken.attributes
|
|
550
|
+
},
|
|
551
|
+
accountData: {
|
|
552
|
+
name: accountData.name,
|
|
553
|
+
attributes: accountData.attributes
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
async function setCookieCache(ctx, session, dontRememberMe) {
|
|
558
|
+
const cookieCacheConfig = ctx.context.options?.session?.cookieCache;
|
|
559
|
+
if (!cookieCacheConfig?.enabled) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
const version = await resolveCookieVersion(
|
|
563
|
+
cookieCacheConfig.version,
|
|
564
|
+
session.session,
|
|
565
|
+
session.user
|
|
566
|
+
);
|
|
567
|
+
const sessionData = {
|
|
568
|
+
session: session.session,
|
|
569
|
+
user: session.user,
|
|
570
|
+
updatedAt: Date.now(),
|
|
571
|
+
version
|
|
572
|
+
};
|
|
573
|
+
const baseAttributes = ctx.context.authCookies.sessionData.attributes;
|
|
574
|
+
const maxAge = dontRememberMe ? void 0 : baseAttributes.maxAge;
|
|
575
|
+
const options = {
|
|
576
|
+
...baseAttributes,
|
|
577
|
+
maxAge
|
|
578
|
+
};
|
|
579
|
+
const expiresAt = Date.now() + (options.maxAge || 60) * 1e3;
|
|
580
|
+
const strategy = cookieCacheConfig.strategy || "compact";
|
|
581
|
+
const secret = getSecretOrThrow(ctx.context.secret);
|
|
582
|
+
let encoded;
|
|
583
|
+
if (strategy === "jwt") {
|
|
584
|
+
encoded = await signJwtHS256(sessionData, secret, options.maxAge || DEFAULT_CACHE_MAX_AGE);
|
|
585
|
+
} else if (strategy === "jwe") {
|
|
586
|
+
throw createError("`jwe` strategy is not supported by the SDK cookie helper.");
|
|
587
|
+
} else {
|
|
588
|
+
const signature = await signHmacBase64Url(
|
|
589
|
+
secret,
|
|
590
|
+
JSON.stringify({
|
|
591
|
+
...sessionData,
|
|
592
|
+
expiresAt
|
|
593
|
+
})
|
|
594
|
+
);
|
|
595
|
+
encoded = encodeStringToBase64Url(
|
|
596
|
+
JSON.stringify({
|
|
597
|
+
session: sessionData,
|
|
598
|
+
expiresAt,
|
|
599
|
+
signature
|
|
600
|
+
})
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
if (encoded.length > 4093) {
|
|
604
|
+
const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
|
|
605
|
+
const cookies = store.chunk(encoded, options);
|
|
606
|
+
store.setCookies(cookies);
|
|
607
|
+
} else {
|
|
608
|
+
const store = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
|
|
609
|
+
if (store.hasChunks()) {
|
|
610
|
+
store.setCookies(store.clean());
|
|
611
|
+
}
|
|
612
|
+
ctx.setCookie(ctx.context.authCookies.sessionData.name, encoded, options);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
async function setSessionCookie(ctx, session, dontRememberMe, overrides) {
|
|
616
|
+
if (dontRememberMe === void 0 && typeof ctx.getSignedCookie === "function" && ctx.context.secret) {
|
|
617
|
+
const existingFlag = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
|
|
618
|
+
dontRememberMe = !!existingFlag;
|
|
619
|
+
}
|
|
620
|
+
const resolvedDontRememberMe = dontRememberMe ?? false;
|
|
621
|
+
const token = getSessionTokenFromPair(session);
|
|
622
|
+
const options = ctx.context.authCookies.sessionToken.attributes;
|
|
623
|
+
const maxAge = resolvedDontRememberMe ? void 0 : ctx.context.sessionConfig?.expiresIn;
|
|
624
|
+
await setCookieValue(ctx, ctx.context.authCookies.sessionToken.name, token, {
|
|
625
|
+
...options,
|
|
626
|
+
maxAge,
|
|
627
|
+
...overrides
|
|
628
|
+
});
|
|
629
|
+
if (resolvedDontRememberMe) {
|
|
630
|
+
await setCookieValue(
|
|
631
|
+
ctx,
|
|
632
|
+
ctx.context.authCookies.dontRememberToken.name,
|
|
633
|
+
"true",
|
|
634
|
+
ctx.context.authCookies.dontRememberToken.attributes
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
await setCookieCache(ctx, session, resolvedDontRememberMe);
|
|
638
|
+
ctx.context.setNewSession?.(session);
|
|
639
|
+
}
|
|
640
|
+
function expireCookie(ctx, cookie) {
|
|
641
|
+
ctx.setCookie(cookie.name, "", {
|
|
642
|
+
...cookie.attributes,
|
|
643
|
+
maxAge: 0
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
function deleteSessionCookie(ctx, skipDontRememberMe) {
|
|
647
|
+
expireCookie(ctx, ctx.context.authCookies.sessionToken);
|
|
648
|
+
expireCookie(ctx, ctx.context.authCookies.sessionData);
|
|
649
|
+
if (ctx.context.options?.account?.storeAccountCookie) {
|
|
650
|
+
expireCookie(ctx, ctx.context.authCookies.accountData);
|
|
651
|
+
const accountStore = createAccountStore(
|
|
652
|
+
ctx.context.authCookies.accountData.name,
|
|
653
|
+
ctx.context.authCookies.accountData.attributes,
|
|
654
|
+
ctx
|
|
655
|
+
);
|
|
656
|
+
accountStore.setCookies(accountStore.clean());
|
|
657
|
+
}
|
|
658
|
+
const sessionStore = createSessionStore(
|
|
659
|
+
ctx.context.authCookies.sessionData.name,
|
|
660
|
+
ctx.context.authCookies.sessionData.attributes,
|
|
661
|
+
ctx
|
|
662
|
+
);
|
|
663
|
+
sessionStore.setCookies(sessionStore.clean());
|
|
664
|
+
if (!skipDontRememberMe) {
|
|
665
|
+
expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
146
668
|
var getSessionCookie = (request, config) => {
|
|
147
669
|
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
148
670
|
if (!cookies) {
|
|
149
671
|
return null;
|
|
150
672
|
}
|
|
151
|
-
const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
|
|
673
|
+
const { cookieName = "session_token", cookiePrefix = "athena-auth" } = config || {};
|
|
152
674
|
const parsedCookie = parseCookies(cookies);
|
|
153
675
|
const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
676
|
+
const candidateCookieNames = Array.from(/* @__PURE__ */ new Set([
|
|
677
|
+
cookieName,
|
|
678
|
+
cookieName.replace(/_/g, "-"),
|
|
679
|
+
cookieName.replace(/-/g, "_")
|
|
680
|
+
])).filter(Boolean);
|
|
681
|
+
for (const candidateName of candidateCookieNames) {
|
|
682
|
+
const sessionToken = getCookie(`${cookiePrefix}.${candidateName}`) || getCookie(`${cookiePrefix}-${candidateName}`);
|
|
683
|
+
if (sessionToken) {
|
|
684
|
+
return sessionToken;
|
|
685
|
+
}
|
|
157
686
|
}
|
|
158
687
|
return null;
|
|
159
688
|
};
|
|
689
|
+
var getCookieCache = async (request, config) => {
|
|
690
|
+
const headers = request instanceof Headers || !("headers" in request) ? request : request.headers;
|
|
691
|
+
const cookieHeader = headers.get("cookie");
|
|
692
|
+
if (!cookieHeader) {
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
const parsedCookie = parseCookies(cookieHeader);
|
|
696
|
+
const cookieName = config?.cookieName || "session_data";
|
|
697
|
+
const requestedPrefix = config?.cookiePrefix || DEFAULT_COOKIE_PREFIX;
|
|
698
|
+
const strategy = config?.strategy || "compact";
|
|
699
|
+
const cookiePrefixes = resolveCookiePrefixes(requestedPrefix);
|
|
700
|
+
const isSecure = getIsSecureCookie(config);
|
|
701
|
+
const secret = getSecretOrThrow(config?.secret);
|
|
702
|
+
let sessionData;
|
|
703
|
+
for (const prefix of cookiePrefixes) {
|
|
704
|
+
const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
|
|
705
|
+
const cookieValue = parsedCookie.get(candidate);
|
|
706
|
+
if (cookieValue) {
|
|
707
|
+
sessionData = cookieValue;
|
|
708
|
+
break;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
if (!sessionData) {
|
|
712
|
+
const reconstructedChunks = [];
|
|
713
|
+
for (const prefix of cookiePrefixes) {
|
|
714
|
+
const candidate = getSessionCookieCacheName(prefix, cookieName, isSecure);
|
|
715
|
+
for (const [name, value] of parsedCookie.entries()) {
|
|
716
|
+
if (!name.startsWith(`${candidate}.`)) {
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
const parts = name.split(".");
|
|
720
|
+
const indexStr = parts[parts.length - 1];
|
|
721
|
+
const index = parseInt(indexStr || "0", 10);
|
|
722
|
+
if (!Number.isNaN(index)) {
|
|
723
|
+
reconstructedChunks.push({ index, value });
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
if (reconstructedChunks.length > 0) {
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
if (reconstructedChunks.length > 0) {
|
|
731
|
+
reconstructedChunks.sort((left, right) => left.index - right.index);
|
|
732
|
+
sessionData = reconstructedChunks.map((chunk) => chunk.value).join("");
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
if (!sessionData) {
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
if (strategy === "jwe") {
|
|
739
|
+
throw createError(
|
|
740
|
+
"`jwe` strategy is not supported by the SDK cookie helper. Use compact/jwt or pass cookie data through the auth server."
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
if (strategy === "jwt") {
|
|
744
|
+
const payload = await verifyJwtHS256(sessionData, secret);
|
|
745
|
+
if (!payload) {
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
const sessionRecord = asObject(payload.session);
|
|
749
|
+
const userRecord = asObject(payload.user);
|
|
750
|
+
const updatedAt = payload.updatedAt;
|
|
751
|
+
if (!sessionRecord || !userRecord || typeof updatedAt !== "number") {
|
|
752
|
+
return null;
|
|
753
|
+
}
|
|
754
|
+
if (config?.version) {
|
|
755
|
+
const cookieVersion = typeof payload.version === "string" ? payload.version : "1";
|
|
756
|
+
const expectedVersion = typeof config.version === "string" ? config.version : await config.version(sessionRecord, userRecord);
|
|
757
|
+
if (cookieVersion !== expectedVersion) {
|
|
758
|
+
return null;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
session: sessionRecord,
|
|
763
|
+
user: userRecord,
|
|
764
|
+
updatedAt,
|
|
765
|
+
version: typeof payload.version === "string" ? payload.version : void 0
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
const compactPayload = parseJsonSafely(decodeBase64UrlToString(sessionData));
|
|
769
|
+
if (!compactPayload) {
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
const expectedSignature = await signHmacBase64Url(
|
|
773
|
+
secret,
|
|
774
|
+
JSON.stringify({
|
|
775
|
+
...compactPayload.session,
|
|
776
|
+
expiresAt: compactPayload.expiresAt
|
|
777
|
+
})
|
|
778
|
+
);
|
|
779
|
+
if (expectedSignature !== compactPayload.signature) {
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
if (compactPayload.expiresAt <= Date.now()) {
|
|
783
|
+
return null;
|
|
784
|
+
}
|
|
785
|
+
const resolvedSession = compactPayload.session;
|
|
786
|
+
if (config?.version) {
|
|
787
|
+
const cookieVersion = resolvedSession.version || "1";
|
|
788
|
+
const expectedVersion = typeof config.version === "string" ? config.version : await config.version(resolvedSession.session, resolvedSession.user);
|
|
789
|
+
if (cookieVersion !== expectedVersion) {
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
const sessionObject = asObject(resolvedSession.session);
|
|
794
|
+
const userObject = asObject(resolvedSession.user);
|
|
795
|
+
if (!sessionObject || !userObject) {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
return {
|
|
799
|
+
session: sessionObject,
|
|
800
|
+
user: userObject,
|
|
801
|
+
updatedAt: resolvedSession.updatedAt,
|
|
802
|
+
version: resolvedSession.version
|
|
803
|
+
};
|
|
804
|
+
};
|
|
160
805
|
|
|
161
806
|
// package.json
|
|
162
807
|
var package_default = {
|
|
163
|
-
version: "2.
|
|
808
|
+
version: "2.7.0"
|
|
164
809
|
};
|
|
165
810
|
|
|
166
811
|
// src/sdk-version.ts
|
|
@@ -2697,42 +3342,1450 @@ async function withRetry(config, fn) {
|
|
|
2697
3342
|
if (!retry) {
|
|
2698
3343
|
throw error;
|
|
2699
3344
|
}
|
|
2700
|
-
const delay = computeDelayMs(currentAttempt, error, resolvedConfig);
|
|
2701
|
-
await sleep(delay);
|
|
3345
|
+
const delay = computeDelayMs(currentAttempt, error, resolvedConfig);
|
|
3346
|
+
await sleep(delay);
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
throw new Error("withRetry reached an unexpected state");
|
|
3350
|
+
}
|
|
3351
|
+
|
|
3352
|
+
// src/db/module.ts
|
|
3353
|
+
function createDbModule(input) {
|
|
3354
|
+
const db = {
|
|
3355
|
+
from(table, options) {
|
|
3356
|
+
return input.from(table, options);
|
|
3357
|
+
},
|
|
3358
|
+
select(table, columns, options) {
|
|
3359
|
+
return input.from(table).select(columns, options);
|
|
3360
|
+
},
|
|
3361
|
+
insert(table, values, options) {
|
|
3362
|
+
return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
|
|
3363
|
+
},
|
|
3364
|
+
upsert(table, values, options) {
|
|
3365
|
+
return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
|
|
3366
|
+
},
|
|
3367
|
+
update(table, values, options) {
|
|
3368
|
+
return input.from(table).update(values, options);
|
|
3369
|
+
},
|
|
3370
|
+
delete(table, options) {
|
|
3371
|
+
return input.from(table).delete(options);
|
|
3372
|
+
},
|
|
3373
|
+
rpc(fn, args, options) {
|
|
3374
|
+
return input.rpc(fn, args, options);
|
|
3375
|
+
},
|
|
3376
|
+
query(query, options) {
|
|
3377
|
+
return input.query(query, options);
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
return db;
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
// src/storage/file.ts
|
|
3384
|
+
function createStorageFileModule(base, config = {}) {
|
|
3385
|
+
const upload = async (input, options) => {
|
|
3386
|
+
const sources = normalizeUploadSources(input);
|
|
3387
|
+
validateUploadConstraints(sources, input);
|
|
3388
|
+
const uploadRequests = sources.map((source, index) => {
|
|
3389
|
+
const storageKey = resolveUploadStorageKey(input, source, index, options, config);
|
|
3390
|
+
return {
|
|
3391
|
+
source,
|
|
3392
|
+
uploadRequest: {
|
|
3393
|
+
s3_id: input.s3_id,
|
|
3394
|
+
bucket: input.bucket,
|
|
3395
|
+
storage_key: storageKey,
|
|
3396
|
+
name: input.name ?? source.fileName,
|
|
3397
|
+
original_name: input.original_name ?? source.fileName,
|
|
3398
|
+
resource_id: input.resource_id ?? input.resourceId,
|
|
3399
|
+
mime_type: input.mime_type ?? source.contentType,
|
|
3400
|
+
content_type: input.content_type ?? source.contentType,
|
|
3401
|
+
size_bytes: source.sizeBytes,
|
|
3402
|
+
public: input.public,
|
|
3403
|
+
metadata: input.metadata
|
|
3404
|
+
}
|
|
3405
|
+
};
|
|
3406
|
+
});
|
|
3407
|
+
input.onProgress?.(createProgressSnapshot("preparing", sources, 0, 0, 0));
|
|
3408
|
+
const uploadUrls = uploadRequests.length === 1 ? [await base.createStorageUploadUrl(uploadRequests[0].uploadRequest, options)] : (await base.createStorageUploadUrls({ files: uploadRequests.map((request) => request.uploadRequest) }, options)).files;
|
|
3409
|
+
const aggregateLoaded = new Array(uploadRequests.length).fill(0);
|
|
3410
|
+
const uploaded = [];
|
|
3411
|
+
for (let index = 0; index < uploadRequests.length; index += 1) {
|
|
3412
|
+
const request = uploadRequests[index];
|
|
3413
|
+
const uploadUrl = uploadUrls[index];
|
|
3414
|
+
const response = await putUploadBody(uploadUrl.upload.url, request.source, input, options, (progress) => {
|
|
3415
|
+
aggregateLoaded[index] = progress.loaded;
|
|
3416
|
+
input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
|
|
3417
|
+
});
|
|
3418
|
+
uploaded.push({
|
|
3419
|
+
file: uploadUrl.file,
|
|
3420
|
+
upload: uploadUrl.upload,
|
|
3421
|
+
source: request.source.source,
|
|
3422
|
+
fileName: request.source.fileName,
|
|
3423
|
+
storage_key: request.uploadRequest.storage_key,
|
|
3424
|
+
response
|
|
3425
|
+
});
|
|
3426
|
+
aggregateLoaded[index] = request.source.sizeBytes;
|
|
3427
|
+
input.onProgress?.(createProgressSnapshot("complete", sources, index, request.source.sizeBytes, sum(aggregateLoaded)));
|
|
3428
|
+
}
|
|
3429
|
+
return {
|
|
3430
|
+
files: uploaded,
|
|
3431
|
+
count: uploaded.length
|
|
3432
|
+
};
|
|
3433
|
+
};
|
|
3434
|
+
const download = ((input, queryOrOptions, maybeOptions) => {
|
|
3435
|
+
const { fileIds, query, options } = normalizeDownloadArgs(input, queryOrOptions, maybeOptions);
|
|
3436
|
+
const downloads = fileIds.map((fileId) => base.getStorageFileProxy(fileId, query, options));
|
|
3437
|
+
return Array.isArray(input) || isRecord5(input) && Array.isArray(input.fileIds) ? Promise.all(downloads) : downloads[0];
|
|
3438
|
+
});
|
|
3439
|
+
const deleteFile = ((input, options) => {
|
|
3440
|
+
if (Array.isArray(input)) {
|
|
3441
|
+
return Promise.all(input.map((fileId) => base.deleteStorageFile(fileId, options)));
|
|
3442
|
+
}
|
|
3443
|
+
return base.deleteStorageFile(input, options);
|
|
3444
|
+
});
|
|
3445
|
+
return {
|
|
3446
|
+
upload,
|
|
3447
|
+
download,
|
|
3448
|
+
list(input, options) {
|
|
3449
|
+
const prefix = resolveStoragePath(input.prefix ?? "", input, options, config);
|
|
3450
|
+
return base.listStorageFiles(
|
|
3451
|
+
{
|
|
3452
|
+
s3_id: input.s3_id,
|
|
3453
|
+
prefix
|
|
3454
|
+
},
|
|
3455
|
+
options
|
|
3456
|
+
);
|
|
3457
|
+
},
|
|
3458
|
+
delete: deleteFile
|
|
3459
|
+
};
|
|
3460
|
+
}
|
|
3461
|
+
function resolveStoragePath(path, input, options, config = {}) {
|
|
3462
|
+
const context = createPathContext(input, options, config);
|
|
3463
|
+
const prefixPath = input.prefixPath ?? config.prefixPath;
|
|
3464
|
+
const prefix = typeof prefixPath === "function" ? prefixPath(context) : prefixPath;
|
|
3465
|
+
return joinStoragePath(renderStorageTemplate(prefix ?? "", context), renderStorageTemplate(path, context));
|
|
3466
|
+
}
|
|
3467
|
+
function resolveUploadStorageKey(input, source, index, options, config) {
|
|
3468
|
+
const explicitKey = input.storage_key ?? input.storageKey;
|
|
3469
|
+
const keyTemplate = input.storageKeyTemplate;
|
|
3470
|
+
const fallbackName = source.fileName;
|
|
3471
|
+
const context = createPathContext(input, options, config);
|
|
3472
|
+
const key = keyTemplate ? renderStorageTemplate(keyTemplate, {
|
|
3473
|
+
...context,
|
|
3474
|
+
vars: {
|
|
3475
|
+
...context.vars,
|
|
3476
|
+
index,
|
|
3477
|
+
fileName: source.fileName,
|
|
3478
|
+
name: source.fileName
|
|
3479
|
+
}
|
|
3480
|
+
}) : explicitKey ?? fallbackName;
|
|
3481
|
+
return resolveStoragePath(key, input, options, config);
|
|
3482
|
+
}
|
|
3483
|
+
function normalizeUploadSources(input) {
|
|
3484
|
+
const files = toArray(input.files);
|
|
3485
|
+
if (files.length === 0) {
|
|
3486
|
+
throw new Error("athena.storage.file.upload requires at least one file");
|
|
3487
|
+
}
|
|
3488
|
+
return files.map((source, index) => {
|
|
3489
|
+
const fileName = input.fileName ?? sourceName(source) ?? `file-${index + 1}`;
|
|
3490
|
+
const sizeBytes = sourceSize(source);
|
|
3491
|
+
const contentType = input.content_type ?? input.mime_type ?? sourceContentType(source);
|
|
3492
|
+
return {
|
|
3493
|
+
source,
|
|
3494
|
+
fileName,
|
|
3495
|
+
sizeBytes,
|
|
3496
|
+
contentType
|
|
3497
|
+
};
|
|
3498
|
+
});
|
|
3499
|
+
}
|
|
3500
|
+
function validateUploadConstraints(sources, input) {
|
|
3501
|
+
const maxFiles = input.maxFiles ?? 1;
|
|
3502
|
+
if (sources.length > maxFiles) {
|
|
3503
|
+
throw new Error(`athena.storage.file.upload accepts at most ${maxFiles} file${maxFiles === 1 ? "" : "s"} for this call`);
|
|
3504
|
+
}
|
|
3505
|
+
const maxFileSizeBytes = input.maxFileSizeBytes ?? (input.maxFileSizeMb === void 0 ? void 0 : Math.floor(input.maxFileSizeMb * 1024 * 1024));
|
|
3506
|
+
if (maxFileSizeBytes !== void 0) {
|
|
3507
|
+
const tooLarge = sources.find((source) => source.sizeBytes > maxFileSizeBytes);
|
|
3508
|
+
if (tooLarge) {
|
|
3509
|
+
throw new Error(`athena.storage.file.upload rejected ${tooLarge.fileName}: file exceeds ${maxFileSizeBytes} bytes`);
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
const allowedExtensions = normalizeExtensions(input.allowedExtensions ?? input.extensions);
|
|
3513
|
+
if (allowedExtensions.size > 0) {
|
|
3514
|
+
const invalid = sources.find((source) => !allowedExtensions.has(fileExtension(source.fileName)));
|
|
3515
|
+
if (invalid) {
|
|
3516
|
+
throw new Error(`athena.storage.file.upload rejected ${invalid.fileName}: extension is not allowed`);
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
async function putUploadBody(url, source, input, options, onProgress) {
|
|
3521
|
+
const headers = new Headers(input.uploadHeaders);
|
|
3522
|
+
if (source.contentType && !headers.has("Content-Type")) {
|
|
3523
|
+
headers.set("Content-Type", source.contentType);
|
|
3524
|
+
}
|
|
3525
|
+
if (typeof XMLHttpRequest !== "undefined") {
|
|
3526
|
+
return putUploadBodyWithXhr(url, source, headers, options, onProgress);
|
|
3527
|
+
}
|
|
3528
|
+
onProgress({ loaded: 0 });
|
|
3529
|
+
const response = await fetch(url, {
|
|
3530
|
+
method: "PUT",
|
|
3531
|
+
headers,
|
|
3532
|
+
body: source.source,
|
|
3533
|
+
signal: options?.signal
|
|
3534
|
+
});
|
|
3535
|
+
if (!response.ok) {
|
|
3536
|
+
throw new Error(`athena.storage.file.upload failed with status ${response.status}`);
|
|
3537
|
+
}
|
|
3538
|
+
onProgress({ loaded: source.sizeBytes });
|
|
3539
|
+
return response;
|
|
3540
|
+
}
|
|
3541
|
+
function putUploadBodyWithXhr(url, source, headers, options, onProgress) {
|
|
3542
|
+
const Xhr = XMLHttpRequest;
|
|
3543
|
+
if (Xhr === void 0) {
|
|
3544
|
+
return Promise.reject(new Error("athena.storage.file.upload requires XMLHttpRequest in this runtime"));
|
|
3545
|
+
}
|
|
3546
|
+
return new Promise((resolve3, reject) => {
|
|
3547
|
+
const xhr = new Xhr();
|
|
3548
|
+
const abort = () => xhr.abort();
|
|
3549
|
+
xhr.open("PUT", url);
|
|
3550
|
+
headers.forEach((value, key) => xhr.setRequestHeader(key, value));
|
|
3551
|
+
xhr.upload.onprogress = (event) => {
|
|
3552
|
+
onProgress({ loaded: event.loaded });
|
|
3553
|
+
};
|
|
3554
|
+
xhr.onload = () => {
|
|
3555
|
+
if (options?.signal) {
|
|
3556
|
+
options.signal.removeEventListener("abort", abort);
|
|
3557
|
+
}
|
|
3558
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
3559
|
+
reject(new Error(`athena.storage.file.upload failed with status ${xhr.status}`));
|
|
3560
|
+
return;
|
|
3561
|
+
}
|
|
3562
|
+
onProgress({ loaded: source.sizeBytes });
|
|
3563
|
+
resolve3(new Response(xhr.response, {
|
|
3564
|
+
status: xhr.status,
|
|
3565
|
+
statusText: xhr.statusText,
|
|
3566
|
+
headers: parseXhrHeaders(xhr.getAllResponseHeaders())
|
|
3567
|
+
}));
|
|
3568
|
+
};
|
|
3569
|
+
xhr.onerror = () => {
|
|
3570
|
+
if (options?.signal) {
|
|
3571
|
+
options.signal.removeEventListener("abort", abort);
|
|
3572
|
+
}
|
|
3573
|
+
reject(new Error("athena.storage.file.upload failed with a network error"));
|
|
3574
|
+
};
|
|
3575
|
+
xhr.onabort = () => {
|
|
3576
|
+
if (options?.signal) {
|
|
3577
|
+
options.signal.removeEventListener("abort", abort);
|
|
3578
|
+
}
|
|
3579
|
+
reject(new DOMException("Upload aborted", "AbortError"));
|
|
3580
|
+
};
|
|
3581
|
+
if (options?.signal) {
|
|
3582
|
+
if (options.signal.aborted) {
|
|
3583
|
+
abort();
|
|
3584
|
+
return;
|
|
3585
|
+
}
|
|
3586
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
3587
|
+
}
|
|
3588
|
+
xhr.send(source.source);
|
|
3589
|
+
});
|
|
3590
|
+
}
|
|
3591
|
+
function normalizeDownloadArgs(input, queryOrOptions, maybeOptions) {
|
|
3592
|
+
if (typeof input === "string") {
|
|
3593
|
+
return { fileIds: [input], query: queryOrOptions, options: maybeOptions };
|
|
3594
|
+
}
|
|
3595
|
+
if (Array.isArray(input)) {
|
|
3596
|
+
return { fileIds: [...input], query: queryOrOptions, options: maybeOptions };
|
|
3597
|
+
}
|
|
3598
|
+
const downloadInput = input;
|
|
3599
|
+
const { fileId, fileIds, ...query } = downloadInput;
|
|
3600
|
+
return {
|
|
3601
|
+
fileIds: fileIds ? [...fileIds] : fileId ? [fileId] : [],
|
|
3602
|
+
query,
|
|
3603
|
+
options: queryOrOptions
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
function createPathContext(input, options, config) {
|
|
3607
|
+
const organizationId = input.organizationId ?? input.organization_id ?? options?.organizationId ?? void 0;
|
|
3608
|
+
const userId = input.userId ?? input.user_id ?? options?.userId ?? void 0;
|
|
3609
|
+
const resourceId = input.resourceId ?? input.resource_id ?? void 0;
|
|
3610
|
+
const vars = {
|
|
3611
|
+
...config.vars ?? {},
|
|
3612
|
+
...input.vars ?? {}
|
|
3613
|
+
};
|
|
3614
|
+
if (organizationId !== void 0) {
|
|
3615
|
+
vars.organizationId = organizationId;
|
|
3616
|
+
vars.organization_id = organizationId;
|
|
3617
|
+
}
|
|
3618
|
+
if (userId !== void 0) {
|
|
3619
|
+
vars.userId = userId;
|
|
3620
|
+
vars.user_id = userId;
|
|
3621
|
+
}
|
|
3622
|
+
if (resourceId !== void 0) {
|
|
3623
|
+
vars.resourceId = resourceId;
|
|
3624
|
+
vars.resource_id = resourceId;
|
|
3625
|
+
}
|
|
3626
|
+
return {
|
|
3627
|
+
vars,
|
|
3628
|
+
env: {
|
|
3629
|
+
...readProcessEnv(),
|
|
3630
|
+
...config.env ?? {},
|
|
3631
|
+
...input.env ?? {}
|
|
3632
|
+
},
|
|
3633
|
+
organizationId,
|
|
3634
|
+
organization_id: organizationId,
|
|
3635
|
+
userId,
|
|
3636
|
+
user_id: userId,
|
|
3637
|
+
resourceId,
|
|
3638
|
+
resource_id: resourceId
|
|
3639
|
+
};
|
|
3640
|
+
}
|
|
3641
|
+
function renderStorageTemplate(template, context) {
|
|
3642
|
+
return template.replace(/\$\{([^}]+)\}|\{([^}]+)\}/g, (_match, shellToken, braceToken) => {
|
|
3643
|
+
const token = (shellToken ?? braceToken ?? "").trim();
|
|
3644
|
+
if (!token) return "";
|
|
3645
|
+
const value = resolveTemplateToken(token, context);
|
|
3646
|
+
return value === void 0 || value === null ? "" : String(value);
|
|
3647
|
+
});
|
|
3648
|
+
}
|
|
3649
|
+
function resolveTemplateToken(token, context) {
|
|
3650
|
+
if (token.startsWith("env.")) {
|
|
3651
|
+
return context.env[token.slice(4)];
|
|
3652
|
+
}
|
|
3653
|
+
if (token in context.vars) {
|
|
3654
|
+
return context.vars[token];
|
|
3655
|
+
}
|
|
3656
|
+
return context.env[token];
|
|
3657
|
+
}
|
|
3658
|
+
function joinStoragePath(...parts) {
|
|
3659
|
+
return parts.map((part) => part.trim().replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
|
|
3660
|
+
}
|
|
3661
|
+
function toArray(files) {
|
|
3662
|
+
if (isUploadSource(files)) return [files];
|
|
3663
|
+
return Array.from(files);
|
|
3664
|
+
}
|
|
3665
|
+
function isUploadSource(value) {
|
|
3666
|
+
return value instanceof Blob || value instanceof ArrayBuffer || value instanceof Uint8Array;
|
|
3667
|
+
}
|
|
3668
|
+
function sourceName(source) {
|
|
3669
|
+
return isRecord5(source) && typeof source.name === "string" && source.name.trim() ? source.name.trim() : void 0;
|
|
3670
|
+
}
|
|
3671
|
+
function sourceSize(source) {
|
|
3672
|
+
if (source instanceof Blob) return source.size;
|
|
3673
|
+
return source.byteLength;
|
|
3674
|
+
}
|
|
3675
|
+
function sourceContentType(source) {
|
|
3676
|
+
return source instanceof Blob && source.type.trim() ? source.type.trim() : void 0;
|
|
3677
|
+
}
|
|
3678
|
+
function normalizeExtensions(extensions) {
|
|
3679
|
+
return new Set((extensions ?? []).map((extension) => extension.replace(/^\./, "").toLowerCase()).filter(Boolean));
|
|
3680
|
+
}
|
|
3681
|
+
function fileExtension(fileName) {
|
|
3682
|
+
const lastDot = fileName.lastIndexOf(".");
|
|
3683
|
+
return lastDot === -1 ? "" : fileName.slice(lastDot + 1).toLowerCase();
|
|
3684
|
+
}
|
|
3685
|
+
function createProgressSnapshot(phase, sources, fileIndex, loaded, aggregateLoaded) {
|
|
3686
|
+
const total = sources[fileIndex]?.sizeBytes ?? 0;
|
|
3687
|
+
const aggregateTotal = sources.reduce((totalBytes, source) => totalBytes + source.sizeBytes, 0);
|
|
3688
|
+
return {
|
|
3689
|
+
phase,
|
|
3690
|
+
fileIndex,
|
|
3691
|
+
fileCount: sources.length,
|
|
3692
|
+
fileName: sources[fileIndex]?.fileName ?? "",
|
|
3693
|
+
loaded,
|
|
3694
|
+
total,
|
|
3695
|
+
percent: total > 0 ? Math.round(loaded / total * 100) : 100,
|
|
3696
|
+
aggregateLoaded,
|
|
3697
|
+
aggregateTotal,
|
|
3698
|
+
aggregatePercent: aggregateTotal > 0 ? Math.round(aggregateLoaded / aggregateTotal * 100) : 100
|
|
3699
|
+
};
|
|
3700
|
+
}
|
|
3701
|
+
function sum(values) {
|
|
3702
|
+
return values.reduce((total, value) => total + value, 0);
|
|
3703
|
+
}
|
|
3704
|
+
function parseXhrHeaders(raw) {
|
|
3705
|
+
const headers = new Headers();
|
|
3706
|
+
for (const line of raw.trim().split(/[\r\n]+/)) {
|
|
3707
|
+
const index = line.indexOf(":");
|
|
3708
|
+
if (index === -1) continue;
|
|
3709
|
+
headers.set(line.slice(0, index).trim(), line.slice(index + 1).trim());
|
|
3710
|
+
}
|
|
3711
|
+
return headers;
|
|
3712
|
+
}
|
|
3713
|
+
function readProcessEnv() {
|
|
3714
|
+
const processLike = globalThis.process;
|
|
3715
|
+
return processLike?.env ?? {};
|
|
3716
|
+
}
|
|
3717
|
+
function isRecord5(value) {
|
|
3718
|
+
return Boolean(value) && typeof value === "object";
|
|
3719
|
+
}
|
|
3720
|
+
|
|
3721
|
+
// src/storage/module.ts
|
|
3722
|
+
var storageSdkManifest = {
|
|
3723
|
+
namespace: "storage",
|
|
3724
|
+
basePath: "/storage",
|
|
3725
|
+
envelopeKinds: {
|
|
3726
|
+
raw: "response body is the payload",
|
|
3727
|
+
athena: "response body is { status, message, data }"
|
|
3728
|
+
},
|
|
3729
|
+
methods: [
|
|
3730
|
+
{
|
|
3731
|
+
name: "listStorageCatalogs",
|
|
3732
|
+
method: "GET",
|
|
3733
|
+
path: "/storage/catalogs",
|
|
3734
|
+
responseEnvelope: "raw",
|
|
3735
|
+
responseType: "{ data: S3CatalogItem[] }"
|
|
3736
|
+
},
|
|
3737
|
+
{
|
|
3738
|
+
name: "createStorageCatalog",
|
|
3739
|
+
method: "POST",
|
|
3740
|
+
path: "/storage/catalogs",
|
|
3741
|
+
requestType: "CreateStorageCatalogRequest",
|
|
3742
|
+
responseEnvelope: "raw",
|
|
3743
|
+
responseType: "S3CatalogItem"
|
|
3744
|
+
},
|
|
3745
|
+
{
|
|
3746
|
+
name: "updateStorageCatalog",
|
|
3747
|
+
method: "PATCH",
|
|
3748
|
+
path: "/storage/catalogs/{id}",
|
|
3749
|
+
pathParams: ["id"],
|
|
3750
|
+
requestType: "UpdateStorageCatalogRequest",
|
|
3751
|
+
responseEnvelope: "raw",
|
|
3752
|
+
responseType: "S3CatalogItem"
|
|
3753
|
+
},
|
|
3754
|
+
{
|
|
3755
|
+
name: "deleteStorageCatalog",
|
|
3756
|
+
method: "DELETE",
|
|
3757
|
+
path: "/storage/catalogs/{id}",
|
|
3758
|
+
pathParams: ["id"],
|
|
3759
|
+
responseEnvelope: "raw",
|
|
3760
|
+
responseType: "{ id: string; deleted: boolean }"
|
|
3761
|
+
},
|
|
3762
|
+
{
|
|
3763
|
+
name: "listStorageCredentials",
|
|
3764
|
+
method: "GET",
|
|
3765
|
+
path: "/storage/credentials",
|
|
3766
|
+
responseEnvelope: "raw",
|
|
3767
|
+
responseType: "{ data: S3CredentialListItem[] }"
|
|
3768
|
+
},
|
|
3769
|
+
{
|
|
3770
|
+
name: "createStorageUploadUrl",
|
|
3771
|
+
method: "POST",
|
|
3772
|
+
path: "/storage/files/upload-url",
|
|
3773
|
+
requestType: "CreateStorageUploadUrlRequest",
|
|
3774
|
+
responseEnvelope: "athena",
|
|
3775
|
+
responseType: "StorageUploadUrlResponse"
|
|
3776
|
+
},
|
|
3777
|
+
{
|
|
3778
|
+
name: "createStorageUploadUrls",
|
|
3779
|
+
method: "POST",
|
|
3780
|
+
path: "/storage/files/upload-urls",
|
|
3781
|
+
requestType: "CreateStorageUploadUrlsRequest",
|
|
3782
|
+
responseEnvelope: "athena",
|
|
3783
|
+
responseType: "StorageBatchUploadUrlResponse"
|
|
3784
|
+
},
|
|
3785
|
+
{
|
|
3786
|
+
name: "listStorageFiles",
|
|
3787
|
+
method: "POST",
|
|
3788
|
+
path: "/storage/files/list",
|
|
3789
|
+
requestType: "ListStorageFilesRequest",
|
|
3790
|
+
responseEnvelope: "athena",
|
|
3791
|
+
responseType: "StorageListFilesResponse"
|
|
3792
|
+
},
|
|
3793
|
+
{
|
|
3794
|
+
name: "getStorageFile",
|
|
3795
|
+
method: "GET",
|
|
3796
|
+
path: "/storage/files/{file_id}",
|
|
3797
|
+
pathParams: ["file_id"],
|
|
3798
|
+
responseEnvelope: "athena",
|
|
3799
|
+
responseType: "StorageFileMutationResponse"
|
|
3800
|
+
},
|
|
3801
|
+
{
|
|
3802
|
+
name: "getStorageFileUrl",
|
|
3803
|
+
method: "GET",
|
|
3804
|
+
path: "/storage/files/{file_id}/url",
|
|
3805
|
+
pathParams: ["file_id"],
|
|
3806
|
+
queryParams: ["purpose"],
|
|
3807
|
+
responseEnvelope: "athena",
|
|
3808
|
+
responseType: "PresignedFileUrlResponse"
|
|
3809
|
+
},
|
|
3810
|
+
{
|
|
3811
|
+
name: "getStorageFileProxy",
|
|
3812
|
+
method: "GET",
|
|
3813
|
+
path: "/storage/files/{file_id}/proxy",
|
|
3814
|
+
pathParams: ["file_id"],
|
|
3815
|
+
queryParams: ["purpose"],
|
|
3816
|
+
responseEnvelope: "raw",
|
|
3817
|
+
responseType: "Response",
|
|
3818
|
+
binary: true
|
|
3819
|
+
},
|
|
3820
|
+
{
|
|
3821
|
+
name: "updateStorageFile",
|
|
3822
|
+
method: "PATCH",
|
|
3823
|
+
path: "/storage/files/{file_id}",
|
|
3824
|
+
pathParams: ["file_id"],
|
|
3825
|
+
requestType: "UpdateStorageFileRequest",
|
|
3826
|
+
responseEnvelope: "athena",
|
|
3827
|
+
responseType: "StorageFileMutationResponse"
|
|
3828
|
+
},
|
|
3829
|
+
{
|
|
3830
|
+
name: "deleteStorageFile",
|
|
3831
|
+
method: "DELETE",
|
|
3832
|
+
path: "/storage/files/{file_id}",
|
|
3833
|
+
pathParams: ["file_id"],
|
|
3834
|
+
responseEnvelope: "athena",
|
|
3835
|
+
responseType: "StorageFileMutationResponse"
|
|
3836
|
+
},
|
|
3837
|
+
{
|
|
3838
|
+
name: "setStorageFileVisibility",
|
|
3839
|
+
method: "PATCH",
|
|
3840
|
+
path: "/storage/files/{file_id}/visibility",
|
|
3841
|
+
pathParams: ["file_id"],
|
|
3842
|
+
requestType: "SetStorageFileVisibilityRequest",
|
|
3843
|
+
responseEnvelope: "athena",
|
|
3844
|
+
responseType: "StorageFileMutationResponse"
|
|
3845
|
+
},
|
|
3846
|
+
{
|
|
3847
|
+
name: "deleteStorageFolder",
|
|
3848
|
+
method: "POST",
|
|
3849
|
+
path: "/storage/folders/delete",
|
|
3850
|
+
requestType: "DeleteStorageFolderRequest",
|
|
3851
|
+
responseEnvelope: "athena",
|
|
3852
|
+
responseType: "StorageFolderMutationResponse"
|
|
3853
|
+
},
|
|
3854
|
+
{
|
|
3855
|
+
name: "moveStorageFolder",
|
|
3856
|
+
method: "POST",
|
|
3857
|
+
path: "/storage/folders/move",
|
|
3858
|
+
requestType: "MoveStorageFolderRequest",
|
|
3859
|
+
responseEnvelope: "athena",
|
|
3860
|
+
responseType: "StorageFolderMutationResponse"
|
|
3861
|
+
}
|
|
3862
|
+
]
|
|
3863
|
+
};
|
|
3864
|
+
var AthenaStorageErrorCode = {
|
|
3865
|
+
InvalidUrl: "INVALID_URL",
|
|
3866
|
+
NetworkError: "NETWORK_ERROR",
|
|
3867
|
+
HttpError: "HTTP_ERROR",
|
|
3868
|
+
InvalidJson: "INVALID_JSON",
|
|
3869
|
+
InvalidAthenaEnvelope: "INVALID_ATHENA_ENVELOPE",
|
|
3870
|
+
UnknownError: "UNKNOWN_ERROR"
|
|
3871
|
+
};
|
|
3872
|
+
var AthenaStorageError = class extends Error {
|
|
3873
|
+
code;
|
|
3874
|
+
athenaCode;
|
|
3875
|
+
kind;
|
|
3876
|
+
category;
|
|
3877
|
+
retryable;
|
|
3878
|
+
status;
|
|
3879
|
+
endpoint;
|
|
3880
|
+
method;
|
|
3881
|
+
requestId;
|
|
3882
|
+
hint;
|
|
3883
|
+
causeDetail;
|
|
3884
|
+
raw;
|
|
3885
|
+
normalized;
|
|
3886
|
+
__athenaNormalizedError;
|
|
3887
|
+
constructor(input) {
|
|
3888
|
+
super(input.message, { cause: input.cause });
|
|
3889
|
+
this.name = "AthenaStorageError";
|
|
3890
|
+
this.code = input.code;
|
|
3891
|
+
this.status = input.status;
|
|
3892
|
+
this.endpoint = input.endpoint;
|
|
3893
|
+
this.method = input.method;
|
|
3894
|
+
this.requestId = input.requestId;
|
|
3895
|
+
this.hint = input.hint;
|
|
3896
|
+
this.causeDetail = causeToString(input.cause);
|
|
3897
|
+
this.raw = input.raw ?? null;
|
|
3898
|
+
this.normalized = normalizeStorageErrorInput(input);
|
|
3899
|
+
this.__athenaNormalizedError = this.normalized;
|
|
3900
|
+
this.athenaCode = this.normalized.code;
|
|
3901
|
+
this.kind = this.normalized.kind;
|
|
3902
|
+
this.category = this.normalized.category;
|
|
3903
|
+
this.retryable = this.normalized.retryable;
|
|
3904
|
+
Object.defineProperty(this, "__athenaNormalizedError", {
|
|
3905
|
+
value: this.normalized,
|
|
3906
|
+
enumerable: false,
|
|
3907
|
+
configurable: false,
|
|
3908
|
+
writable: false
|
|
3909
|
+
});
|
|
3910
|
+
}
|
|
3911
|
+
toDetails() {
|
|
3912
|
+
return {
|
|
3913
|
+
code: this.code,
|
|
3914
|
+
athenaCode: this.athenaCode,
|
|
3915
|
+
kind: this.kind,
|
|
3916
|
+
category: this.category,
|
|
3917
|
+
retryable: this.retryable,
|
|
3918
|
+
message: this.message,
|
|
3919
|
+
status: this.status,
|
|
3920
|
+
endpoint: this.endpoint,
|
|
3921
|
+
method: this.method,
|
|
3922
|
+
requestId: this.requestId,
|
|
3923
|
+
hint: this.hint,
|
|
3924
|
+
cause: this.causeDetail,
|
|
3925
|
+
raw: this.raw
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3928
|
+
};
|
|
3929
|
+
function isRecord6(value) {
|
|
3930
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3931
|
+
}
|
|
3932
|
+
function causeToString(cause) {
|
|
3933
|
+
if (cause === void 0 || cause === null) return void 0;
|
|
3934
|
+
if (typeof cause === "string") return cause;
|
|
3935
|
+
if (cause instanceof Error && cause.message.trim()) return cause.message.trim();
|
|
3936
|
+
try {
|
|
3937
|
+
return JSON.stringify(cause);
|
|
3938
|
+
} catch {
|
|
3939
|
+
return String(cause);
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
function storageGatewayCode(code) {
|
|
3943
|
+
if (code === "INVALID_URL") return "INVALID_URL";
|
|
3944
|
+
if (code === "NETWORK_ERROR") return "NETWORK_ERROR";
|
|
3945
|
+
if (code === "INVALID_JSON" || code === "INVALID_ATHENA_ENVELOPE") return "INVALID_JSON";
|
|
3946
|
+
if (code === "HTTP_ERROR") return "HTTP_ERROR";
|
|
3947
|
+
return "UNKNOWN_ERROR";
|
|
3948
|
+
}
|
|
3949
|
+
function headerValue(headers, names) {
|
|
3950
|
+
for (const name of names) {
|
|
3951
|
+
const value = headers.get(name);
|
|
3952
|
+
if (value?.trim()) return value.trim();
|
|
3953
|
+
}
|
|
3954
|
+
return void 0;
|
|
3955
|
+
}
|
|
3956
|
+
function storageOperationFromEndpoint(endpoint, method) {
|
|
3957
|
+
const endpointPath = String(endpoint).split("?")[0];
|
|
3958
|
+
for (const candidate of storageSdkManifest.methods) {
|
|
3959
|
+
if (candidate.method !== method) continue;
|
|
3960
|
+
const pattern = `^${candidate.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\{[^/]+\\\}/g, "[^/]+")}$`;
|
|
3961
|
+
if (new RegExp(pattern).test(endpointPath)) {
|
|
3962
|
+
return candidate.name;
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
return `storage:${method.toLowerCase()}`;
|
|
3966
|
+
}
|
|
3967
|
+
function normalizeStorageErrorInput(input) {
|
|
3968
|
+
return normalizeAthenaError(
|
|
3969
|
+
{
|
|
3970
|
+
data: null,
|
|
3971
|
+
error: {
|
|
3972
|
+
message: input.message,
|
|
3973
|
+
gatewayCode: storageGatewayCode(input.code),
|
|
3974
|
+
status: input.status,
|
|
3975
|
+
raw: input.raw ?? input.cause ?? null
|
|
3976
|
+
},
|
|
3977
|
+
errorDetails: {
|
|
3978
|
+
code: storageGatewayCode(input.code),
|
|
3979
|
+
message: input.message,
|
|
3980
|
+
status: input.status,
|
|
3981
|
+
endpoint: input.endpoint,
|
|
3982
|
+
method: input.method,
|
|
3983
|
+
requestId: input.requestId,
|
|
3984
|
+
hint: input.hint,
|
|
3985
|
+
cause: causeToString(input.cause)
|
|
3986
|
+
},
|
|
3987
|
+
raw: input.raw ?? input.cause ?? null,
|
|
3988
|
+
status: input.status
|
|
3989
|
+
},
|
|
3990
|
+
{ operation: storageOperationFromEndpoint(input.endpoint, input.method) }
|
|
3991
|
+
);
|
|
3992
|
+
}
|
|
3993
|
+
function createAthenaStorageError(input) {
|
|
3994
|
+
return new AthenaStorageError(input);
|
|
3995
|
+
}
|
|
3996
|
+
async function notifyStorageError(error, options, runtimeOptions) {
|
|
3997
|
+
const handlers = [runtimeOptions?.onError, options?.onError].filter(
|
|
3998
|
+
(handler) => typeof handler === "function"
|
|
3999
|
+
);
|
|
4000
|
+
for (const handler of handlers) {
|
|
4001
|
+
try {
|
|
4002
|
+
await handler(error);
|
|
4003
|
+
} catch {
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
async function rejectStorageError(input, options, runtimeOptions) {
|
|
4008
|
+
const error = createAthenaStorageError(input);
|
|
4009
|
+
await notifyStorageError(error, options, runtimeOptions);
|
|
4010
|
+
throw error;
|
|
4011
|
+
}
|
|
4012
|
+
function parseResponseBody3(rawText, contentType) {
|
|
4013
|
+
if (!rawText) {
|
|
4014
|
+
return { parsed: null, parseFailed: false };
|
|
4015
|
+
}
|
|
4016
|
+
const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
|
|
4017
|
+
const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
|
|
4018
|
+
if (!looksJson) {
|
|
4019
|
+
return { parsed: rawText, parseFailed: false };
|
|
4020
|
+
}
|
|
4021
|
+
try {
|
|
4022
|
+
return { parsed: JSON.parse(rawText), parseFailed: false };
|
|
4023
|
+
} catch {
|
|
4024
|
+
return { parsed: rawText, parseFailed: true };
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
function appendQuery(path, query) {
|
|
4028
|
+
if (!query) return path;
|
|
4029
|
+
const params = new URLSearchParams();
|
|
4030
|
+
for (const [key, value] of Object.entries(query)) {
|
|
4031
|
+
if (value === void 0 || value === null) continue;
|
|
4032
|
+
params.set(key, String(value));
|
|
4033
|
+
}
|
|
4034
|
+
const queryText = params.toString();
|
|
4035
|
+
return queryText ? `${path}?${queryText}` : path;
|
|
4036
|
+
}
|
|
4037
|
+
function storagePath(path) {
|
|
4038
|
+
return path;
|
|
4039
|
+
}
|
|
4040
|
+
function withPathParam(path, name, value) {
|
|
4041
|
+
return path.replace(`{${name}}`, encodeURIComponent(value));
|
|
4042
|
+
}
|
|
4043
|
+
function resolveErrorMessage3(payload, fallback) {
|
|
4044
|
+
if (isRecord6(payload)) {
|
|
4045
|
+
const message = payload.message ?? payload.error ?? payload.details;
|
|
4046
|
+
if (typeof message === "string" && message.trim()) {
|
|
4047
|
+
return message.trim();
|
|
4048
|
+
}
|
|
4049
|
+
}
|
|
4050
|
+
if (typeof payload === "string" && payload.trim()) {
|
|
4051
|
+
return payload.trim();
|
|
4052
|
+
}
|
|
4053
|
+
return fallback;
|
|
4054
|
+
}
|
|
4055
|
+
function resolveErrorHint2(payload) {
|
|
4056
|
+
if (!isRecord6(payload)) return void 0;
|
|
4057
|
+
const hint = payload.hint ?? payload.suggestion;
|
|
4058
|
+
return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
|
|
4059
|
+
}
|
|
4060
|
+
function resolveErrorCause(payload) {
|
|
4061
|
+
if (!isRecord6(payload)) return void 0;
|
|
4062
|
+
const cause = payload.cause ?? payload.reason;
|
|
4063
|
+
return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
|
|
4064
|
+
}
|
|
4065
|
+
function storageCodeFromUnknown(error) {
|
|
4066
|
+
if (isAthenaGatewayError(error)) {
|
|
4067
|
+
if (error.code === "INVALID_URL") return "INVALID_URL";
|
|
4068
|
+
if (error.code === "NETWORK_ERROR") return "NETWORK_ERROR";
|
|
4069
|
+
if (error.code === "INVALID_JSON") return "INVALID_JSON";
|
|
4070
|
+
if (error.code === "HTTP_ERROR") return "HTTP_ERROR";
|
|
4071
|
+
}
|
|
4072
|
+
return "UNKNOWN_ERROR";
|
|
4073
|
+
}
|
|
4074
|
+
async function callStorageEndpoint(gateway, endpoint, method, envelope, payload, options, runtimeOptions) {
|
|
4075
|
+
let url;
|
|
4076
|
+
let headers;
|
|
4077
|
+
try {
|
|
4078
|
+
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
|
|
4079
|
+
url = buildAthenaGatewayUrl(baseUrl, endpoint);
|
|
4080
|
+
headers = gateway.buildHeaders(options);
|
|
4081
|
+
} catch (error) {
|
|
4082
|
+
return rejectStorageError(
|
|
4083
|
+
{
|
|
4084
|
+
code: storageCodeFromUnknown(error),
|
|
4085
|
+
message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
|
|
4086
|
+
status: isAthenaGatewayError(error) ? error.status : 0,
|
|
4087
|
+
endpoint,
|
|
4088
|
+
method,
|
|
4089
|
+
raw: error,
|
|
4090
|
+
requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
|
|
4091
|
+
hint: isAthenaGatewayError(error) ? error.hint : void 0,
|
|
4092
|
+
cause: error
|
|
4093
|
+
},
|
|
4094
|
+
options,
|
|
4095
|
+
runtimeOptions
|
|
4096
|
+
);
|
|
4097
|
+
}
|
|
4098
|
+
const requestInit = {
|
|
4099
|
+
method,
|
|
4100
|
+
headers,
|
|
4101
|
+
signal: options?.signal
|
|
4102
|
+
};
|
|
4103
|
+
if (payload !== void 0 && method !== "GET") {
|
|
4104
|
+
requestInit.body = JSON.stringify(payload);
|
|
4105
|
+
}
|
|
4106
|
+
let response;
|
|
4107
|
+
try {
|
|
4108
|
+
response = await fetch(url, requestInit);
|
|
4109
|
+
} catch (error) {
|
|
4110
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4111
|
+
return rejectStorageError(
|
|
4112
|
+
{
|
|
4113
|
+
code: "NETWORK_ERROR",
|
|
4114
|
+
message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
|
|
4115
|
+
status: 0,
|
|
4116
|
+
endpoint,
|
|
4117
|
+
method,
|
|
4118
|
+
cause: error
|
|
4119
|
+
},
|
|
4120
|
+
options,
|
|
4121
|
+
runtimeOptions
|
|
4122
|
+
);
|
|
4123
|
+
}
|
|
4124
|
+
let rawText;
|
|
4125
|
+
try {
|
|
4126
|
+
rawText = await response.text();
|
|
4127
|
+
} catch (error) {
|
|
4128
|
+
return rejectStorageError(
|
|
4129
|
+
{
|
|
4130
|
+
code: "NETWORK_ERROR",
|
|
4131
|
+
message: `Athena storage ${method} ${endpoint} response body could not be read`,
|
|
4132
|
+
status: response.status,
|
|
4133
|
+
endpoint,
|
|
4134
|
+
method,
|
|
4135
|
+
requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
|
|
4136
|
+
cause: error
|
|
4137
|
+
},
|
|
4138
|
+
options,
|
|
4139
|
+
runtimeOptions
|
|
4140
|
+
);
|
|
4141
|
+
}
|
|
4142
|
+
const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
|
|
4143
|
+
const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
|
|
4144
|
+
if (parsedBody.parseFailed) {
|
|
4145
|
+
return rejectStorageError(
|
|
4146
|
+
{
|
|
4147
|
+
code: "INVALID_JSON",
|
|
4148
|
+
message: `Athena storage ${method} ${endpoint} returned malformed JSON`,
|
|
4149
|
+
status: response.status,
|
|
4150
|
+
endpoint,
|
|
4151
|
+
method,
|
|
4152
|
+
requestId,
|
|
4153
|
+
raw: parsedBody.parsed
|
|
4154
|
+
},
|
|
4155
|
+
options,
|
|
4156
|
+
runtimeOptions
|
|
4157
|
+
);
|
|
4158
|
+
}
|
|
4159
|
+
if (!response.ok) {
|
|
4160
|
+
return rejectStorageError(
|
|
4161
|
+
{
|
|
4162
|
+
code: "HTTP_ERROR",
|
|
4163
|
+
message: resolveErrorMessage3(
|
|
4164
|
+
parsedBody.parsed,
|
|
4165
|
+
`Athena storage ${method} ${endpoint} failed with status ${response.status}`
|
|
4166
|
+
),
|
|
4167
|
+
status: response.status,
|
|
4168
|
+
endpoint,
|
|
4169
|
+
method,
|
|
4170
|
+
requestId,
|
|
4171
|
+
hint: resolveErrorHint2(parsedBody.parsed),
|
|
4172
|
+
cause: resolveErrorCause(parsedBody.parsed),
|
|
4173
|
+
raw: parsedBody.parsed
|
|
4174
|
+
},
|
|
4175
|
+
options,
|
|
4176
|
+
runtimeOptions
|
|
4177
|
+
);
|
|
4178
|
+
}
|
|
4179
|
+
if (envelope === "athena") {
|
|
4180
|
+
if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
|
|
4181
|
+
return rejectStorageError(
|
|
4182
|
+
{
|
|
4183
|
+
code: "INVALID_ATHENA_ENVELOPE",
|
|
4184
|
+
message: `Athena storage ${method} ${endpoint} returned an invalid Athena envelope`,
|
|
4185
|
+
status: response.status,
|
|
4186
|
+
endpoint,
|
|
4187
|
+
method,
|
|
4188
|
+
requestId,
|
|
4189
|
+
raw: parsedBody.parsed
|
|
4190
|
+
},
|
|
4191
|
+
options,
|
|
4192
|
+
runtimeOptions
|
|
4193
|
+
);
|
|
4194
|
+
}
|
|
4195
|
+
return parsedBody.parsed.data;
|
|
4196
|
+
}
|
|
4197
|
+
return parsedBody.parsed;
|
|
4198
|
+
}
|
|
4199
|
+
async function callStorageBinaryEndpoint(gateway, endpoint, method, options, runtimeOptions) {
|
|
4200
|
+
let url;
|
|
4201
|
+
let headers;
|
|
4202
|
+
try {
|
|
4203
|
+
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
|
|
4204
|
+
url = buildAthenaGatewayUrl(baseUrl, endpoint);
|
|
4205
|
+
headers = gateway.buildHeaders(options);
|
|
4206
|
+
} catch (error) {
|
|
4207
|
+
return rejectStorageError(
|
|
4208
|
+
{
|
|
4209
|
+
code: storageCodeFromUnknown(error),
|
|
4210
|
+
message: error instanceof Error ? error.message : `Athena storage ${method} ${endpoint} failed before sending the request`,
|
|
4211
|
+
status: isAthenaGatewayError(error) ? error.status : 0,
|
|
4212
|
+
endpoint,
|
|
4213
|
+
method,
|
|
4214
|
+
raw: error,
|
|
4215
|
+
requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
|
|
4216
|
+
hint: isAthenaGatewayError(error) ? error.hint : void 0,
|
|
4217
|
+
cause: error
|
|
4218
|
+
},
|
|
4219
|
+
options,
|
|
4220
|
+
runtimeOptions
|
|
4221
|
+
);
|
|
4222
|
+
}
|
|
4223
|
+
let response;
|
|
4224
|
+
try {
|
|
4225
|
+
response = await fetch(url, {
|
|
4226
|
+
method,
|
|
4227
|
+
headers,
|
|
4228
|
+
signal: options?.signal
|
|
4229
|
+
});
|
|
4230
|
+
} catch (error) {
|
|
4231
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4232
|
+
return rejectStorageError(
|
|
4233
|
+
{
|
|
4234
|
+
code: "NETWORK_ERROR",
|
|
4235
|
+
message: `Network error while calling Athena storage ${method} ${endpoint}: ${message}`,
|
|
4236
|
+
status: 0,
|
|
4237
|
+
endpoint,
|
|
4238
|
+
method,
|
|
4239
|
+
cause: error
|
|
4240
|
+
},
|
|
4241
|
+
options,
|
|
4242
|
+
runtimeOptions
|
|
4243
|
+
);
|
|
4244
|
+
}
|
|
4245
|
+
if (response.ok) {
|
|
4246
|
+
return response;
|
|
4247
|
+
}
|
|
4248
|
+
const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
|
|
4249
|
+
let rawErrorBody = null;
|
|
4250
|
+
try {
|
|
4251
|
+
const rawText = await response.text();
|
|
4252
|
+
const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
|
|
4253
|
+
rawErrorBody = parsedBody.parsed;
|
|
4254
|
+
} catch (error) {
|
|
4255
|
+
return rejectStorageError(
|
|
4256
|
+
{
|
|
4257
|
+
code: "NETWORK_ERROR",
|
|
4258
|
+
message: `Athena storage ${method} ${endpoint} error response body could not be read`,
|
|
4259
|
+
status: response.status,
|
|
4260
|
+
endpoint,
|
|
4261
|
+
method,
|
|
4262
|
+
requestId,
|
|
4263
|
+
cause: error
|
|
4264
|
+
},
|
|
4265
|
+
options,
|
|
4266
|
+
runtimeOptions
|
|
4267
|
+
);
|
|
4268
|
+
}
|
|
4269
|
+
return rejectStorageError(
|
|
4270
|
+
{
|
|
4271
|
+
code: "HTTP_ERROR",
|
|
4272
|
+
message: resolveErrorMessage3(
|
|
4273
|
+
rawErrorBody,
|
|
4274
|
+
`Athena storage ${method} ${endpoint} failed with status ${response.status}`
|
|
4275
|
+
),
|
|
4276
|
+
status: response.status,
|
|
4277
|
+
endpoint,
|
|
4278
|
+
method,
|
|
4279
|
+
requestId,
|
|
4280
|
+
hint: resolveErrorHint2(rawErrorBody),
|
|
4281
|
+
cause: resolveErrorCause(rawErrorBody),
|
|
4282
|
+
raw: rawErrorBody
|
|
4283
|
+
},
|
|
4284
|
+
options,
|
|
4285
|
+
runtimeOptions
|
|
4286
|
+
);
|
|
4287
|
+
}
|
|
4288
|
+
function isBlobBody(body) {
|
|
4289
|
+
return typeof Blob !== "undefined" && body instanceof Blob;
|
|
4290
|
+
}
|
|
4291
|
+
function isReadableStreamBody(body) {
|
|
4292
|
+
return typeof ReadableStream !== "undefined" && body instanceof ReadableStream;
|
|
4293
|
+
}
|
|
4294
|
+
async function putPresignedUploadBody(uploadUrl, uploadHeaders, body, options) {
|
|
4295
|
+
const headers = new Headers(uploadHeaders);
|
|
4296
|
+
Object.entries(options?.headers ?? {}).forEach(([key, value]) => headers.set(key, value));
|
|
4297
|
+
if (!headers.has("Content-Type") && isBlobBody(body) && body.type) {
|
|
4298
|
+
headers.set("Content-Type", body.type);
|
|
4299
|
+
}
|
|
4300
|
+
const init = {
|
|
4301
|
+
method: "PUT",
|
|
4302
|
+
headers,
|
|
4303
|
+
body,
|
|
4304
|
+
signal: options?.signal
|
|
4305
|
+
};
|
|
4306
|
+
if (isReadableStreamBody(body)) {
|
|
4307
|
+
init.duplex = "half";
|
|
4308
|
+
}
|
|
4309
|
+
return fetch(uploadUrl, init);
|
|
4310
|
+
}
|
|
4311
|
+
function attachManagedUpload(upload) {
|
|
4312
|
+
const headers = {};
|
|
4313
|
+
return {
|
|
4314
|
+
...upload,
|
|
4315
|
+
method: "PUT",
|
|
4316
|
+
headers,
|
|
4317
|
+
expiresAt: upload.expires_at,
|
|
4318
|
+
put(body, options) {
|
|
4319
|
+
return putPresignedUploadBody(upload.url, headers, body, options);
|
|
4320
|
+
}
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4323
|
+
function attachUploadHelper(response) {
|
|
4324
|
+
return {
|
|
4325
|
+
...response,
|
|
4326
|
+
upload: attachManagedUpload(response.upload)
|
|
4327
|
+
};
|
|
4328
|
+
}
|
|
4329
|
+
function attachUploadHelpers(response) {
|
|
4330
|
+
return {
|
|
4331
|
+
files: response.files.map(attachUploadHelper)
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4334
|
+
function normalizeUploadUrlRequest(input) {
|
|
4335
|
+
const s3_id = input.s3_id ?? input.s3Id;
|
|
4336
|
+
const storage_key = input.storage_key ?? input.storageKey;
|
|
4337
|
+
if (!s3_id?.trim()) {
|
|
4338
|
+
throw new Error("athena.storage.file.upload requires s3_id or s3Id");
|
|
4339
|
+
}
|
|
4340
|
+
if (!storage_key?.trim()) {
|
|
4341
|
+
throw new Error("athena.storage.file.upload requires storage_key or storageKey");
|
|
4342
|
+
}
|
|
4343
|
+
const fileName = input.fileName?.trim();
|
|
4344
|
+
const originalName = input.originalName?.trim();
|
|
4345
|
+
return {
|
|
4346
|
+
s3_id,
|
|
4347
|
+
bucket: input.bucket,
|
|
4348
|
+
storage_key,
|
|
4349
|
+
name: input.name ?? fileName,
|
|
4350
|
+
original_name: input.original_name ?? originalName ?? fileName,
|
|
4351
|
+
resource_id: input.resource_id ?? input.resourceId,
|
|
4352
|
+
mime_type: input.mime_type ?? input.mimeType,
|
|
4353
|
+
content_type: input.content_type ?? input.contentType,
|
|
4354
|
+
size_bytes: input.size_bytes ?? input.sizeBytes,
|
|
4355
|
+
file_id: input.file_id ?? input.fileId,
|
|
4356
|
+
public: input.public,
|
|
4357
|
+
visibility: input.visibility,
|
|
4358
|
+
metadata: input.metadata
|
|
4359
|
+
};
|
|
4360
|
+
}
|
|
4361
|
+
async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options, runtimeOptions) {
|
|
4362
|
+
let url;
|
|
4363
|
+
let headers;
|
|
4364
|
+
try {
|
|
4365
|
+
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
|
|
4366
|
+
url = buildAthenaGatewayUrl(baseUrl, endpoint);
|
|
4367
|
+
headers = gateway.buildHeaders(options);
|
|
4368
|
+
} catch (error) {
|
|
4369
|
+
return rejectStorageError(
|
|
4370
|
+
{
|
|
4371
|
+
code: storageCodeFromUnknown(error),
|
|
4372
|
+
message: error instanceof Error ? error.message : `Athena storage PUT ${endpoint} failed before sending the request`,
|
|
4373
|
+
status: isAthenaGatewayError(error) ? error.status : 0,
|
|
4374
|
+
endpoint,
|
|
4375
|
+
method: "PUT",
|
|
4376
|
+
raw: error,
|
|
4377
|
+
requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
|
|
4378
|
+
hint: isAthenaGatewayError(error) ? error.hint : void 0,
|
|
4379
|
+
cause: error
|
|
4380
|
+
},
|
|
4381
|
+
options,
|
|
4382
|
+
runtimeOptions
|
|
4383
|
+
);
|
|
4384
|
+
}
|
|
4385
|
+
delete headers["Content-Type"];
|
|
4386
|
+
delete headers["content-type"];
|
|
4387
|
+
if (isBlobBody(body) && body.type) {
|
|
4388
|
+
headers["Content-Type"] = body.type;
|
|
4389
|
+
}
|
|
4390
|
+
const requestInit = {
|
|
4391
|
+
method: "PUT",
|
|
4392
|
+
headers,
|
|
4393
|
+
body,
|
|
4394
|
+
signal: options?.signal
|
|
4395
|
+
};
|
|
4396
|
+
if (isReadableStreamBody(body)) {
|
|
4397
|
+
requestInit.duplex = "half";
|
|
4398
|
+
}
|
|
4399
|
+
let response;
|
|
4400
|
+
try {
|
|
4401
|
+
response = await fetch(url, requestInit);
|
|
4402
|
+
} catch (error) {
|
|
4403
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4404
|
+
return rejectStorageError(
|
|
4405
|
+
{
|
|
4406
|
+
code: "NETWORK_ERROR",
|
|
4407
|
+
message: `Network error while calling Athena storage PUT ${endpoint}: ${message}`,
|
|
4408
|
+
status: 0,
|
|
4409
|
+
endpoint,
|
|
4410
|
+
method: "PUT",
|
|
4411
|
+
cause: error
|
|
4412
|
+
},
|
|
4413
|
+
options,
|
|
4414
|
+
runtimeOptions
|
|
4415
|
+
);
|
|
4416
|
+
}
|
|
4417
|
+
let rawText;
|
|
4418
|
+
try {
|
|
4419
|
+
rawText = await response.text();
|
|
4420
|
+
} catch (error) {
|
|
4421
|
+
return rejectStorageError(
|
|
4422
|
+
{
|
|
4423
|
+
code: "NETWORK_ERROR",
|
|
4424
|
+
message: `Athena storage PUT ${endpoint} response body could not be read`,
|
|
4425
|
+
status: response.status,
|
|
4426
|
+
endpoint,
|
|
4427
|
+
method: "PUT",
|
|
4428
|
+
requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
|
|
4429
|
+
cause: error
|
|
4430
|
+
},
|
|
4431
|
+
options,
|
|
4432
|
+
runtimeOptions
|
|
4433
|
+
);
|
|
4434
|
+
}
|
|
4435
|
+
const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
|
|
4436
|
+
const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
|
|
4437
|
+
if (parsedBody.parseFailed) {
|
|
4438
|
+
return rejectStorageError(
|
|
4439
|
+
{
|
|
4440
|
+
code: "INVALID_JSON",
|
|
4441
|
+
message: `Athena storage PUT ${endpoint} returned malformed JSON`,
|
|
4442
|
+
status: response.status,
|
|
4443
|
+
endpoint,
|
|
4444
|
+
method: "PUT",
|
|
4445
|
+
requestId,
|
|
4446
|
+
raw: parsedBody.parsed
|
|
4447
|
+
},
|
|
4448
|
+
options,
|
|
4449
|
+
runtimeOptions
|
|
4450
|
+
);
|
|
4451
|
+
}
|
|
4452
|
+
if (!response.ok) {
|
|
4453
|
+
return rejectStorageError(
|
|
4454
|
+
{
|
|
4455
|
+
code: "HTTP_ERROR",
|
|
4456
|
+
message: resolveErrorMessage3(
|
|
4457
|
+
parsedBody.parsed,
|
|
4458
|
+
`Athena storage PUT ${endpoint} failed with status ${response.status}`
|
|
4459
|
+
),
|
|
4460
|
+
status: response.status,
|
|
4461
|
+
endpoint,
|
|
4462
|
+
method: "PUT",
|
|
4463
|
+
requestId,
|
|
4464
|
+
hint: resolveErrorHint2(parsedBody.parsed),
|
|
4465
|
+
cause: resolveErrorCause(parsedBody.parsed),
|
|
4466
|
+
raw: parsedBody.parsed
|
|
4467
|
+
},
|
|
4468
|
+
options,
|
|
4469
|
+
runtimeOptions
|
|
4470
|
+
);
|
|
4471
|
+
}
|
|
4472
|
+
if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
|
|
4473
|
+
return rejectStorageError(
|
|
4474
|
+
{
|
|
4475
|
+
code: "INVALID_ATHENA_ENVELOPE",
|
|
4476
|
+
message: `Athena storage PUT ${endpoint} returned an invalid Athena envelope`,
|
|
4477
|
+
status: response.status,
|
|
4478
|
+
endpoint,
|
|
4479
|
+
method: "PUT",
|
|
4480
|
+
requestId,
|
|
4481
|
+
raw: parsedBody.parsed
|
|
4482
|
+
},
|
|
4483
|
+
options,
|
|
4484
|
+
runtimeOptions
|
|
4485
|
+
);
|
|
4486
|
+
}
|
|
4487
|
+
return parsedBody.parsed.data;
|
|
4488
|
+
}
|
|
4489
|
+
function createStorageModule(gateway, runtimeOptions) {
|
|
4490
|
+
const callRaw = (path, method, payload, options) => callStorageEndpoint(
|
|
4491
|
+
gateway,
|
|
4492
|
+
storagePath(path),
|
|
4493
|
+
method,
|
|
4494
|
+
"raw",
|
|
4495
|
+
payload,
|
|
4496
|
+
options,
|
|
4497
|
+
runtimeOptions
|
|
4498
|
+
);
|
|
4499
|
+
const callAthena2 = (path, method, payload, options) => callStorageEndpoint(
|
|
4500
|
+
gateway,
|
|
4501
|
+
storagePath(path),
|
|
4502
|
+
method,
|
|
4503
|
+
"athena",
|
|
4504
|
+
payload,
|
|
4505
|
+
options,
|
|
4506
|
+
runtimeOptions
|
|
4507
|
+
);
|
|
4508
|
+
const base = {
|
|
4509
|
+
listStorageCatalogs(options) {
|
|
4510
|
+
return callRaw("/storage/catalogs", "GET", void 0, options);
|
|
4511
|
+
},
|
|
4512
|
+
createStorageCatalog(input, options) {
|
|
4513
|
+
return callRaw("/storage/catalogs", "POST", input, options);
|
|
4514
|
+
},
|
|
4515
|
+
updateStorageCatalog(id, input, options) {
|
|
4516
|
+
return callRaw(withPathParam("/storage/catalogs/{id}", "id", id), "PATCH", input, options);
|
|
4517
|
+
},
|
|
4518
|
+
deleteStorageCatalog(id, options) {
|
|
4519
|
+
return callRaw(withPathParam("/storage/catalogs/{id}", "id", id), "DELETE", void 0, options);
|
|
4520
|
+
},
|
|
4521
|
+
listStorageCredentials(options) {
|
|
4522
|
+
return callRaw("/storage/credentials", "GET", void 0, options);
|
|
4523
|
+
},
|
|
4524
|
+
createStorageUploadUrl(input, options) {
|
|
4525
|
+
return callAthena2("/storage/files/upload-url", "POST", input, options);
|
|
4526
|
+
},
|
|
4527
|
+
createStorageUploadUrls(input, options) {
|
|
4528
|
+
return callAthena2("/storage/files/upload-urls", "POST", input, options);
|
|
4529
|
+
},
|
|
4530
|
+
listStorageFiles(input, options) {
|
|
4531
|
+
return callAthena2("/storage/files/list", "POST", input, options);
|
|
4532
|
+
},
|
|
4533
|
+
getStorageFile(fileId, options) {
|
|
4534
|
+
return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "GET", void 0, options);
|
|
4535
|
+
},
|
|
4536
|
+
getStorageFileUrl(fileId, query, options) {
|
|
4537
|
+
const path = appendQuery(
|
|
4538
|
+
withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
|
|
4539
|
+
query
|
|
4540
|
+
);
|
|
4541
|
+
return callAthena2(path, "GET", void 0, options);
|
|
4542
|
+
},
|
|
4543
|
+
getStorageFileProxy(fileId, query, options) {
|
|
4544
|
+
const path = appendQuery(
|
|
4545
|
+
withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
|
|
4546
|
+
query
|
|
4547
|
+
);
|
|
4548
|
+
return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, runtimeOptions);
|
|
4549
|
+
},
|
|
4550
|
+
updateStorageFile(fileId, input, options) {
|
|
4551
|
+
return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "PATCH", input, options);
|
|
4552
|
+
},
|
|
4553
|
+
deleteStorageFile(fileId, options) {
|
|
4554
|
+
return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "DELETE", void 0, options);
|
|
4555
|
+
},
|
|
4556
|
+
setStorageFileVisibility(fileId, input, options) {
|
|
4557
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId), "PATCH", input, options);
|
|
4558
|
+
},
|
|
4559
|
+
deleteStorageFolder(input, options) {
|
|
4560
|
+
return callAthena2("/storage/folders/delete", "POST", input, options);
|
|
4561
|
+
},
|
|
4562
|
+
moveStorageFolder(input, options) {
|
|
4563
|
+
return callAthena2("/storage/folders/move", "POST", input, options);
|
|
4564
|
+
}
|
|
4565
|
+
};
|
|
4566
|
+
const fileFacade = createStorageFileModule(base, runtimeOptions);
|
|
4567
|
+
const fileUpload = ((input, options) => {
|
|
4568
|
+
if (isRecord6(input) && "files" in input) {
|
|
4569
|
+
return fileFacade.upload(input, options);
|
|
4570
|
+
}
|
|
4571
|
+
return base.createStorageUploadUrl(
|
|
4572
|
+
normalizeUploadUrlRequest(input),
|
|
4573
|
+
options
|
|
4574
|
+
).then(attachUploadHelper);
|
|
4575
|
+
});
|
|
4576
|
+
const fileDelete = ((input, options) => fileFacade.delete(input, options));
|
|
4577
|
+
const file = {
|
|
4578
|
+
...fileFacade,
|
|
4579
|
+
upload: fileUpload,
|
|
4580
|
+
uploadMany(input, options) {
|
|
4581
|
+
return base.createStorageUploadUrls(
|
|
4582
|
+
{ files: input.files.map(normalizeUploadUrlRequest) },
|
|
4583
|
+
options
|
|
4584
|
+
).then(attachUploadHelpers);
|
|
4585
|
+
},
|
|
4586
|
+
confirmUpload(fileId, input, options) {
|
|
4587
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/confirm-upload", "file_id", fileId), "POST", input ?? {}, options);
|
|
4588
|
+
},
|
|
4589
|
+
uploadBinary(fileId, body, options) {
|
|
4590
|
+
return callStorageUploadBinaryEndpoint(
|
|
4591
|
+
gateway,
|
|
4592
|
+
storagePath(withPathParam("/storage/files/{file_id}/upload", "file_id", fileId)),
|
|
4593
|
+
body,
|
|
4594
|
+
options,
|
|
4595
|
+
runtimeOptions
|
|
4596
|
+
);
|
|
4597
|
+
},
|
|
4598
|
+
search(input, options) {
|
|
4599
|
+
return callAthena2("/storage/files/search", "POST", input, options);
|
|
4600
|
+
},
|
|
4601
|
+
get(fileId, options) {
|
|
4602
|
+
return base.getStorageFile(fileId, options);
|
|
4603
|
+
},
|
|
4604
|
+
update(fileId, input, options) {
|
|
4605
|
+
return base.updateStorageFile(fileId, input, options);
|
|
4606
|
+
},
|
|
4607
|
+
delete: fileDelete,
|
|
4608
|
+
deleteMany(input, options) {
|
|
4609
|
+
return callAthena2("/storage/files/delete-many", "POST", input, options);
|
|
4610
|
+
},
|
|
4611
|
+
updateMany(input, options) {
|
|
4612
|
+
return callAthena2("/storage/files/update-many", "POST", input, options);
|
|
4613
|
+
},
|
|
4614
|
+
restore(fileId, options) {
|
|
4615
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/restore", "file_id", fileId), "POST", {}, options);
|
|
4616
|
+
},
|
|
4617
|
+
purge(fileId, options) {
|
|
4618
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/purge", "file_id", fileId), "DELETE", void 0, options);
|
|
4619
|
+
},
|
|
4620
|
+
copy(fileId, input, options) {
|
|
4621
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/copy", "file_id", fileId), "POST", input, options);
|
|
4622
|
+
},
|
|
4623
|
+
url(fileId, query, options) {
|
|
4624
|
+
return base.getStorageFileUrl(fileId, query, options);
|
|
4625
|
+
},
|
|
4626
|
+
publicUrl(fileId, options) {
|
|
4627
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/public-url", "file_id", fileId), "GET", void 0, options);
|
|
4628
|
+
},
|
|
4629
|
+
proxy(fileId, query, options) {
|
|
4630
|
+
return base.getStorageFileProxy(fileId, query, options);
|
|
4631
|
+
},
|
|
4632
|
+
visibility: {
|
|
4633
|
+
set(fileId, input, options) {
|
|
4634
|
+
return base.setStorageFileVisibility(fileId, input, options);
|
|
4635
|
+
},
|
|
4636
|
+
setMany(input, options) {
|
|
4637
|
+
return callAthena2("/storage/files/visibility-many", "POST", input, options);
|
|
4638
|
+
}
|
|
2702
4639
|
}
|
|
2703
|
-
}
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
const
|
|
2710
|
-
|
|
2711
|
-
return
|
|
4640
|
+
};
|
|
4641
|
+
const credentials = {
|
|
4642
|
+
list(options) {
|
|
4643
|
+
return base.listStorageCredentials(options);
|
|
4644
|
+
}
|
|
4645
|
+
};
|
|
4646
|
+
const catalog = {
|
|
4647
|
+
list(options) {
|
|
4648
|
+
return base.listStorageCatalogs(options);
|
|
2712
4649
|
},
|
|
2713
|
-
|
|
2714
|
-
return
|
|
4650
|
+
create(input, options) {
|
|
4651
|
+
return base.createStorageCatalog(input, options);
|
|
2715
4652
|
},
|
|
2716
|
-
|
|
2717
|
-
return
|
|
4653
|
+
update(id, input, options) {
|
|
4654
|
+
return base.updateStorageCatalog(id, input, options);
|
|
2718
4655
|
},
|
|
2719
|
-
|
|
2720
|
-
return
|
|
4656
|
+
delete(id, options) {
|
|
4657
|
+
return base.deleteStorageCatalog(id, options);
|
|
4658
|
+
}
|
|
4659
|
+
};
|
|
4660
|
+
const folder = {
|
|
4661
|
+
list(input, options) {
|
|
4662
|
+
return callAthena2("/storage/folders/list", "POST", input, options);
|
|
2721
4663
|
},
|
|
2722
|
-
|
|
2723
|
-
return
|
|
4664
|
+
tree(input, options) {
|
|
4665
|
+
return callAthena2("/storage/folders/tree", "POST", input, options);
|
|
2724
4666
|
},
|
|
2725
|
-
delete(
|
|
2726
|
-
return
|
|
4667
|
+
delete(input, options) {
|
|
4668
|
+
return base.deleteStorageFolder(input, options);
|
|
2727
4669
|
},
|
|
2728
|
-
|
|
2729
|
-
return
|
|
4670
|
+
move(input, options) {
|
|
4671
|
+
return base.moveStorageFolder(input, options);
|
|
4672
|
+
}
|
|
4673
|
+
};
|
|
4674
|
+
const permission = {
|
|
4675
|
+
list(input, options) {
|
|
4676
|
+
return callAthena2("/storage/permissions/list", "POST", input, options);
|
|
2730
4677
|
},
|
|
2731
|
-
|
|
2732
|
-
return
|
|
4678
|
+
grant(input, options) {
|
|
4679
|
+
return callAthena2("/storage/permissions/grant", "POST", input, options);
|
|
4680
|
+
},
|
|
4681
|
+
revoke(input, options) {
|
|
4682
|
+
return callAthena2("/storage/permissions/revoke", "POST", input, options);
|
|
4683
|
+
},
|
|
4684
|
+
check(input, options) {
|
|
4685
|
+
return callAthena2("/storage/permissions/check", "POST", input, options);
|
|
2733
4686
|
}
|
|
2734
4687
|
};
|
|
2735
|
-
|
|
4688
|
+
const objectFolder = {
|
|
4689
|
+
create(input, options) {
|
|
4690
|
+
return callAthena2("/storage/objects/folder", "POST", input, options);
|
|
4691
|
+
},
|
|
4692
|
+
delete(input, options) {
|
|
4693
|
+
return callAthena2("/storage/objects/folder/delete", "POST", input, options);
|
|
4694
|
+
},
|
|
4695
|
+
rename(input, options) {
|
|
4696
|
+
return callAthena2("/storage/objects/folder/rename", "POST", input, options);
|
|
4697
|
+
}
|
|
4698
|
+
};
|
|
4699
|
+
const object = {
|
|
4700
|
+
list(input, options) {
|
|
4701
|
+
return callAthena2("/storage/objects", "POST", input, options);
|
|
4702
|
+
},
|
|
4703
|
+
head(input, options) {
|
|
4704
|
+
return callAthena2("/storage/objects/head", "POST", input, options);
|
|
4705
|
+
},
|
|
4706
|
+
exists(input, options) {
|
|
4707
|
+
return callAthena2("/storage/objects/exists", "POST", input, options);
|
|
4708
|
+
},
|
|
4709
|
+
validate(input, options) {
|
|
4710
|
+
return callAthena2("/storage/objects/validate", "POST", input, options);
|
|
4711
|
+
},
|
|
4712
|
+
update(input, options) {
|
|
4713
|
+
return callAthena2("/storage/objects/update", "POST", input, options);
|
|
4714
|
+
},
|
|
4715
|
+
copy(input, options) {
|
|
4716
|
+
return callAthena2("/storage/objects/copy", "POST", input, options);
|
|
4717
|
+
},
|
|
4718
|
+
url(input, options) {
|
|
4719
|
+
return callAthena2("/storage/objects/url", "POST", input, options);
|
|
4720
|
+
},
|
|
4721
|
+
publicUrl(input, options) {
|
|
4722
|
+
return callAthena2("/storage/objects/public-url", "POST", input, options);
|
|
4723
|
+
},
|
|
4724
|
+
delete(input, options) {
|
|
4725
|
+
return callAthena2("/storage/objects/delete", "POST", input, options);
|
|
4726
|
+
},
|
|
4727
|
+
uploadUrl(input, options) {
|
|
4728
|
+
return callAthena2("/storage/objects/upload-url", "POST", input, options);
|
|
4729
|
+
},
|
|
4730
|
+
folder: objectFolder
|
|
4731
|
+
};
|
|
4732
|
+
const bucket = {
|
|
4733
|
+
list(input, options) {
|
|
4734
|
+
return callAthena2("/storage/buckets/list", "POST", input, options);
|
|
4735
|
+
},
|
|
4736
|
+
create(input, options) {
|
|
4737
|
+
return callAthena2("/storage/buckets/create", "POST", input, options);
|
|
4738
|
+
},
|
|
4739
|
+
delete(input, options) {
|
|
4740
|
+
return callAthena2("/storage/buckets/delete", "POST", input, options);
|
|
4741
|
+
},
|
|
4742
|
+
cors: {
|
|
4743
|
+
get(input, options) {
|
|
4744
|
+
return callAthena2("/storage/buckets/cors", "POST", input, options);
|
|
4745
|
+
},
|
|
4746
|
+
set(input, options) {
|
|
4747
|
+
return callAthena2("/storage/buckets/cors/set", "POST", input, options);
|
|
4748
|
+
},
|
|
4749
|
+
delete(input, options) {
|
|
4750
|
+
return callAthena2("/storage/buckets/cors/delete", "POST", input, options);
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4753
|
+
};
|
|
4754
|
+
const multipart = {
|
|
4755
|
+
create(input, options) {
|
|
4756
|
+
return callAthena2("/storage/multipart/create", "POST", input, options);
|
|
4757
|
+
},
|
|
4758
|
+
signPart(input, options) {
|
|
4759
|
+
return callAthena2("/storage/multipart/sign-part", "POST", input, options);
|
|
4760
|
+
},
|
|
4761
|
+
complete(input, options) {
|
|
4762
|
+
return callAthena2("/storage/multipart/complete", "POST", input, options);
|
|
4763
|
+
},
|
|
4764
|
+
abort(input, options) {
|
|
4765
|
+
return callAthena2("/storage/multipart/abort", "POST", input, options);
|
|
4766
|
+
},
|
|
4767
|
+
listParts(input, options) {
|
|
4768
|
+
return callAthena2("/storage/multipart/list-parts", "POST", input, options);
|
|
4769
|
+
}
|
|
4770
|
+
};
|
|
4771
|
+
const audit = {
|
|
4772
|
+
list(input, options) {
|
|
4773
|
+
return callAthena2("/storage/audit/list", "POST", input, options);
|
|
4774
|
+
}
|
|
4775
|
+
};
|
|
4776
|
+
return {
|
|
4777
|
+
...base,
|
|
4778
|
+
credentials,
|
|
4779
|
+
catalog,
|
|
4780
|
+
file,
|
|
4781
|
+
folder,
|
|
4782
|
+
permission,
|
|
4783
|
+
object,
|
|
4784
|
+
bucket,
|
|
4785
|
+
multipart,
|
|
4786
|
+
audit,
|
|
4787
|
+
delete: file.delete
|
|
4788
|
+
};
|
|
2736
4789
|
}
|
|
2737
4790
|
|
|
2738
4791
|
// src/query-ast.ts
|
|
@@ -2762,7 +4815,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
2762
4815
|
"ilike",
|
|
2763
4816
|
"is"
|
|
2764
4817
|
]);
|
|
2765
|
-
function
|
|
4818
|
+
function isRecord7(value) {
|
|
2766
4819
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2767
4820
|
}
|
|
2768
4821
|
function isUuidString(value) {
|
|
@@ -2775,7 +4828,7 @@ function shouldUseUuidTextComparison(column, value) {
|
|
|
2775
4828
|
return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
|
|
2776
4829
|
}
|
|
2777
4830
|
function isRelationSelectNode(value) {
|
|
2778
|
-
return
|
|
4831
|
+
return isRecord7(value) && isRecord7(value.select);
|
|
2779
4832
|
}
|
|
2780
4833
|
function normalizeIdentifier(value, label) {
|
|
2781
4834
|
const normalized = value.trim();
|
|
@@ -2831,7 +4884,7 @@ function compileRelationToken(key, node) {
|
|
|
2831
4884
|
return `${prefix}${relationToken}(${nested})`;
|
|
2832
4885
|
}
|
|
2833
4886
|
function compileSelectShape(select) {
|
|
2834
|
-
if (!
|
|
4887
|
+
if (!isRecord7(select)) {
|
|
2835
4888
|
throw new Error("findMany select must be an object");
|
|
2836
4889
|
}
|
|
2837
4890
|
const tokens = [];
|
|
@@ -2855,7 +4908,7 @@ function compileSelectShape(select) {
|
|
|
2855
4908
|
return tokens.join(",");
|
|
2856
4909
|
}
|
|
2857
4910
|
function selectShapeUsesRelationSchema(select) {
|
|
2858
|
-
if (!
|
|
4911
|
+
if (!isRecord7(select)) {
|
|
2859
4912
|
return false;
|
|
2860
4913
|
}
|
|
2861
4914
|
for (const rawValue of Object.values(select)) {
|
|
@@ -2873,7 +4926,7 @@ function selectShapeUsesRelationSchema(select) {
|
|
|
2873
4926
|
}
|
|
2874
4927
|
function compileColumnWhere(column, input) {
|
|
2875
4928
|
const normalizedColumn = normalizeIdentifier(column, "where column");
|
|
2876
|
-
if (!
|
|
4929
|
+
if (!isRecord7(input)) {
|
|
2877
4930
|
return [buildGatewayCondition("eq", normalizedColumn, input)];
|
|
2878
4931
|
}
|
|
2879
4932
|
const conditions = [];
|
|
@@ -2901,7 +4954,7 @@ function compileColumnWhere(column, input) {
|
|
|
2901
4954
|
return conditions;
|
|
2902
4955
|
}
|
|
2903
4956
|
function compileBooleanExpressionTerms(clause, label) {
|
|
2904
|
-
if (!
|
|
4957
|
+
if (!isRecord7(clause)) {
|
|
2905
4958
|
throw new Error(`findMany where.${label} clauses must be objects`);
|
|
2906
4959
|
}
|
|
2907
4960
|
const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
|
|
@@ -2910,7 +4963,7 @@ function compileBooleanExpressionTerms(clause, label) {
|
|
|
2910
4963
|
}
|
|
2911
4964
|
const [rawColumn, rawValue] = entries[0];
|
|
2912
4965
|
const column = normalizeIdentifier(rawColumn, `where.${label} column`);
|
|
2913
|
-
if (!
|
|
4966
|
+
if (!isRecord7(rawValue)) {
|
|
2914
4967
|
return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
|
|
2915
4968
|
}
|
|
2916
4969
|
const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
|
|
@@ -2934,7 +4987,7 @@ function compileWhere(where) {
|
|
|
2934
4987
|
if (where === void 0) {
|
|
2935
4988
|
return void 0;
|
|
2936
4989
|
}
|
|
2937
|
-
if (!
|
|
4990
|
+
if (!isRecord7(where)) {
|
|
2938
4991
|
throw new Error("findMany where must be an object");
|
|
2939
4992
|
}
|
|
2940
4993
|
const conditions = [];
|
|
@@ -2984,7 +5037,7 @@ function compileOrderBy(orderBy) {
|
|
|
2984
5037
|
if (orderBy === void 0) {
|
|
2985
5038
|
return void 0;
|
|
2986
5039
|
}
|
|
2987
|
-
if (!
|
|
5040
|
+
if (!isRecord7(orderBy)) {
|
|
2988
5041
|
throw new Error("findMany orderBy must be an object");
|
|
2989
5042
|
}
|
|
2990
5043
|
if ("column" in orderBy) {
|
|
@@ -3159,11 +5212,11 @@ function toFindManyAstOrder(order) {
|
|
|
3159
5212
|
ascending: order.direction !== "descending"
|
|
3160
5213
|
};
|
|
3161
5214
|
}
|
|
3162
|
-
function
|
|
5215
|
+
function isRecord8(value) {
|
|
3163
5216
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3164
5217
|
}
|
|
3165
5218
|
function normalizeFindManyAstColumnPredicate(value) {
|
|
3166
|
-
if (!
|
|
5219
|
+
if (!isRecord8(value)) {
|
|
3167
5220
|
return {
|
|
3168
5221
|
eq: value
|
|
3169
5222
|
};
|
|
@@ -3187,7 +5240,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
|
|
|
3187
5240
|
return normalized;
|
|
3188
5241
|
}
|
|
3189
5242
|
function normalizeFindManyAstWhere(where) {
|
|
3190
|
-
if (!where || !
|
|
5243
|
+
if (!where || !isRecord8(where)) {
|
|
3191
5244
|
return where;
|
|
3192
5245
|
}
|
|
3193
5246
|
const normalized = {};
|
|
@@ -3201,7 +5254,7 @@ function normalizeFindManyAstWhere(where) {
|
|
|
3201
5254
|
);
|
|
3202
5255
|
continue;
|
|
3203
5256
|
}
|
|
3204
|
-
if (key === "not" &&
|
|
5257
|
+
if (key === "not" && isRecord8(value)) {
|
|
3205
5258
|
normalized.not = normalizeFindManyAstBooleanOperand(
|
|
3206
5259
|
value
|
|
3207
5260
|
);
|
|
@@ -3212,7 +5265,7 @@ function normalizeFindManyAstWhere(where) {
|
|
|
3212
5265
|
return normalized;
|
|
3213
5266
|
}
|
|
3214
5267
|
function predicateRequiresUuidQueryFallback(column, value) {
|
|
3215
|
-
if (!
|
|
5268
|
+
if (!isRecord8(value)) {
|
|
3216
5269
|
return shouldUseUuidTextComparison(column, value);
|
|
3217
5270
|
}
|
|
3218
5271
|
const eqValue = value.eq;
|
|
@@ -3230,7 +5283,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
|
|
|
3230
5283
|
return false;
|
|
3231
5284
|
}
|
|
3232
5285
|
function findManyAstWhereRequiresLegacyTransport(where) {
|
|
3233
|
-
if (!where || !
|
|
5286
|
+
if (!where || !isRecord8(where)) {
|
|
3234
5287
|
return false;
|
|
3235
5288
|
}
|
|
3236
5289
|
for (const [key, value] of Object.entries(where)) {
|
|
@@ -3245,7 +5298,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
|
|
|
3245
5298
|
}
|
|
3246
5299
|
continue;
|
|
3247
5300
|
}
|
|
3248
|
-
if (key === "not" &&
|
|
5301
|
+
if (key === "not" && isRecord8(value)) {
|
|
3249
5302
|
if (booleanOperandRequiresUuidQueryFallback(value)) {
|
|
3250
5303
|
return true;
|
|
3251
5304
|
}
|
|
@@ -3447,7 +5500,7 @@ async function executeExperimentalRead(experimental, runner) {
|
|
|
3447
5500
|
throw error;
|
|
3448
5501
|
}
|
|
3449
5502
|
}
|
|
3450
|
-
function
|
|
5503
|
+
function isRecord9(value) {
|
|
3451
5504
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3452
5505
|
}
|
|
3453
5506
|
function firstNonEmptyString2(...values) {
|
|
@@ -3459,8 +5512,8 @@ function firstNonEmptyString2(...values) {
|
|
|
3459
5512
|
return void 0;
|
|
3460
5513
|
}
|
|
3461
5514
|
function resolveStructuredErrorPayload2(raw) {
|
|
3462
|
-
if (!
|
|
3463
|
-
return
|
|
5515
|
+
if (!isRecord9(raw)) return null;
|
|
5516
|
+
return isRecord9(raw.error) ? raw.error : raw;
|
|
3464
5517
|
}
|
|
3465
5518
|
function resolveStructuredErrorDetails(payload, message) {
|
|
3466
5519
|
if (!payload || !("details" in payload)) {
|
|
@@ -3476,7 +5529,7 @@ function resolveStructuredErrorDetails(payload, message) {
|
|
|
3476
5529
|
return details;
|
|
3477
5530
|
}
|
|
3478
5531
|
function createResultError(response, result, normalized) {
|
|
3479
|
-
const rawRecord =
|
|
5532
|
+
const rawRecord = isRecord9(response.raw) ? response.raw : null;
|
|
3480
5533
|
const payload = resolveStructuredErrorPayload2(response.raw);
|
|
3481
5534
|
const message = firstNonEmptyString2(
|
|
3482
5535
|
response.error,
|
|
@@ -4939,7 +6992,7 @@ function createClientFromConfig(config) {
|
|
|
4939
6992
|
};
|
|
4940
6993
|
const query = createQueryBuilder(gateway, formatGatewayResult, config.experimental, queryTracer);
|
|
4941
6994
|
const db = createDbModule({ from, rpc, query });
|
|
4942
|
-
|
|
6995
|
+
const sdkClient = {
|
|
4943
6996
|
from,
|
|
4944
6997
|
db,
|
|
4945
6998
|
rpc,
|
|
@@ -4947,6 +7000,14 @@ function createClientFromConfig(config) {
|
|
|
4947
7000
|
verifyConnection: gateway.verifyConnection,
|
|
4948
7001
|
auth: auth.auth
|
|
4949
7002
|
};
|
|
7003
|
+
if (config.experimental?.athenaStorageBackend) {
|
|
7004
|
+
const storageClient = {
|
|
7005
|
+
...sdkClient,
|
|
7006
|
+
storage: createStorageModule(gateway, config.experimental.storage)
|
|
7007
|
+
};
|
|
7008
|
+
return storageClient;
|
|
7009
|
+
}
|
|
7010
|
+
return sdkClient;
|
|
4950
7011
|
}
|
|
4951
7012
|
var DEFAULT_BACKEND = { type: "athena" };
|
|
4952
7013
|
function toBackendConfig(b) {
|
|
@@ -4977,6 +7038,12 @@ function mergeExperimentalOptions(current, next) {
|
|
|
4977
7038
|
...next.traceQueries
|
|
4978
7039
|
};
|
|
4979
7040
|
}
|
|
7041
|
+
if (current?.storage || next.storage) {
|
|
7042
|
+
merged.storage = {
|
|
7043
|
+
...current?.storage ?? {},
|
|
7044
|
+
...next.storage ?? {}
|
|
7045
|
+
};
|
|
7046
|
+
}
|
|
4980
7047
|
return merged;
|
|
4981
7048
|
}
|
|
4982
7049
|
var AthenaClientBuilderImpl = class {
|
|
@@ -5013,7 +7080,7 @@ var AthenaClientBuilderImpl = class {
|
|
|
5013
7080
|
}
|
|
5014
7081
|
experimental(options) {
|
|
5015
7082
|
this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options);
|
|
5016
|
-
return this;
|
|
7083
|
+
return options.athenaStorageBackend ? this : this;
|
|
5017
7084
|
}
|
|
5018
7085
|
options(options) {
|
|
5019
7086
|
if (options.client !== void 0) {
|
|
@@ -5034,7 +7101,7 @@ var AthenaClientBuilderImpl = class {
|
|
|
5034
7101
|
if (options.experimental !== void 0) {
|
|
5035
7102
|
this.experimentalOptions = mergeExperimentalOptions(this.experimentalOptions, options.experimental);
|
|
5036
7103
|
}
|
|
5037
|
-
return this;
|
|
7104
|
+
return options.experimental?.athenaStorageBackend ? this : this;
|
|
5038
7105
|
}
|
|
5039
7106
|
build() {
|
|
5040
7107
|
if (!this.baseUrl || !this.apiKey) {
|
|
@@ -5665,7 +7732,7 @@ function resolveNullishValue(mode) {
|
|
|
5665
7732
|
if (mode === "null") return null;
|
|
5666
7733
|
return "";
|
|
5667
7734
|
}
|
|
5668
|
-
function
|
|
7735
|
+
function isRecord10(value) {
|
|
5669
7736
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
5670
7737
|
}
|
|
5671
7738
|
function isNullableColumn(model, key) {
|
|
@@ -5674,7 +7741,7 @@ function isNullableColumn(model, key) {
|
|
|
5674
7741
|
}
|
|
5675
7742
|
function toModelFormDefaults(model, values, options) {
|
|
5676
7743
|
const source = values;
|
|
5677
|
-
if (!
|
|
7744
|
+
if (!isRecord10(source)) {
|
|
5678
7745
|
return {};
|
|
5679
7746
|
}
|
|
5680
7747
|
const mode = options?.nullishMode ?? "empty-string";
|
|
@@ -6105,6 +8172,90 @@ async function loadGeneratorConfig(options = {}) {
|
|
|
6105
8172
|
}
|
|
6106
8173
|
}
|
|
6107
8174
|
|
|
8175
|
+
// src/generator/env.ts
|
|
8176
|
+
function readEnvStringValue2(key) {
|
|
8177
|
+
if (typeof process === "undefined" || !process.env) {
|
|
8178
|
+
return void 0;
|
|
8179
|
+
}
|
|
8180
|
+
const value = process.env[key];
|
|
8181
|
+
if (typeof value !== "string") {
|
|
8182
|
+
return void 0;
|
|
8183
|
+
}
|
|
8184
|
+
const trimmed = value.trim();
|
|
8185
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
8186
|
+
}
|
|
8187
|
+
function throwMissingEnvVar(key) {
|
|
8188
|
+
throw new Error(
|
|
8189
|
+
`Generator config env var ${key} is missing or empty. Set ${key} or provide a default value.`
|
|
8190
|
+
);
|
|
8191
|
+
}
|
|
8192
|
+
function resolveEnvValue(key, options, resolver) {
|
|
8193
|
+
const rawValue = readEnvStringValue2(key);
|
|
8194
|
+
if (rawValue === void 0) {
|
|
8195
|
+
if (options?.default !== void 0) {
|
|
8196
|
+
return options.default;
|
|
8197
|
+
}
|
|
8198
|
+
if (options?.optional) {
|
|
8199
|
+
return void 0;
|
|
8200
|
+
}
|
|
8201
|
+
return throwMissingEnvVar(key);
|
|
8202
|
+
}
|
|
8203
|
+
return resolver(rawValue);
|
|
8204
|
+
}
|
|
8205
|
+
function resolveStringEnv(key, options) {
|
|
8206
|
+
return resolveEnvValue(key, options, (value) => value);
|
|
8207
|
+
}
|
|
8208
|
+
function resolveBooleanEnv(key, options) {
|
|
8209
|
+
return resolveEnvValue(key, options, (value) => parseBooleanFlag2(value, false));
|
|
8210
|
+
}
|
|
8211
|
+
function resolveListEnv(key, options) {
|
|
8212
|
+
return resolveEnvValue(key, options, (value) => {
|
|
8213
|
+
const separator = options?.separator ?? ",";
|
|
8214
|
+
return value.split(separator).map((entry) => entry.trim()).filter((entry, index, entries) => entry.length > 0 && entries.indexOf(entry) === index);
|
|
8215
|
+
})?.slice();
|
|
8216
|
+
}
|
|
8217
|
+
function resolveJsonEnv(key, options) {
|
|
8218
|
+
return resolveEnvValue(key, options, (value) => {
|
|
8219
|
+
try {
|
|
8220
|
+
return JSON.parse(value);
|
|
8221
|
+
} catch (error) {
|
|
8222
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8223
|
+
throw new Error(`Generator config env var ${key} must contain valid JSON. ${message}`);
|
|
8224
|
+
}
|
|
8225
|
+
});
|
|
8226
|
+
}
|
|
8227
|
+
function resolveOneOfEnv(key, allowedValues, options) {
|
|
8228
|
+
return resolveEnvValue(key, options, (value) => {
|
|
8229
|
+
if (allowedValues.includes(value)) {
|
|
8230
|
+
return value;
|
|
8231
|
+
}
|
|
8232
|
+
throw new Error(
|
|
8233
|
+
`Generator config env var ${key} must be one of: ${allowedValues.join(", ")}. Received: ${value}.`
|
|
8234
|
+
);
|
|
8235
|
+
});
|
|
8236
|
+
}
|
|
8237
|
+
function generatorEnvString(key, options) {
|
|
8238
|
+
return resolveStringEnv(key, options);
|
|
8239
|
+
}
|
|
8240
|
+
function generatorEnvBoolean(key, options) {
|
|
8241
|
+
return resolveBooleanEnv(key, options);
|
|
8242
|
+
}
|
|
8243
|
+
function generatorEnvList(key, options) {
|
|
8244
|
+
return resolveListEnv(key, options);
|
|
8245
|
+
}
|
|
8246
|
+
function generatorEnvJson(key, options) {
|
|
8247
|
+
return resolveJsonEnv(key, options);
|
|
8248
|
+
}
|
|
8249
|
+
function generatorEnvOneOf(key, allowedValues, options) {
|
|
8250
|
+
return resolveOneOfEnv(key, allowedValues, options);
|
|
8251
|
+
}
|
|
8252
|
+
var generatorEnv = Object.assign(generatorEnvString, {
|
|
8253
|
+
boolean: generatorEnvBoolean,
|
|
8254
|
+
list: generatorEnvList,
|
|
8255
|
+
json: generatorEnvJson,
|
|
8256
|
+
oneOf: generatorEnvOneOf
|
|
8257
|
+
});
|
|
8258
|
+
|
|
6108
8259
|
// src/utils/slugify.ts
|
|
6109
8260
|
function slugify(input) {
|
|
6110
8261
|
return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64);
|
|
@@ -6862,22 +9013,455 @@ async function runSchemaGenerator(options = {}) {
|
|
|
6862
9013
|
};
|
|
6863
9014
|
}
|
|
6864
9015
|
|
|
9016
|
+
// src/auth/server.ts
|
|
9017
|
+
var DEFAULT_AUTH_BASE_PATH = "/api/auth";
|
|
9018
|
+
var ATHENA_AUTH_BASE_ERROR_CODES = {
|
|
9019
|
+
HANDLER_NOT_CONFIGURED: "HANDLER_NOT_CONFIGURED",
|
|
9020
|
+
INVALID_BASE_URL: "INVALID_BASE_URL",
|
|
9021
|
+
UNTRUSTED_HOST: "UNTRUSTED_HOST"
|
|
9022
|
+
};
|
|
9023
|
+
function capitalize2(value) {
|
|
9024
|
+
return value.length > 0 ? `${value[0]?.toUpperCase()}${value.slice(1)}` : value;
|
|
9025
|
+
}
|
|
9026
|
+
function serializeSetCookieValue(name, value, attributes) {
|
|
9027
|
+
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
9028
|
+
const knownKeys = /* @__PURE__ */ new Set([
|
|
9029
|
+
"maxAge",
|
|
9030
|
+
"expires",
|
|
9031
|
+
"domain",
|
|
9032
|
+
"path",
|
|
9033
|
+
"secure",
|
|
9034
|
+
"httpOnly",
|
|
9035
|
+
"partitioned",
|
|
9036
|
+
"sameSite"
|
|
9037
|
+
]);
|
|
9038
|
+
if (attributes.maxAge !== void 0) {
|
|
9039
|
+
parts.push(`Max-Age=${Math.trunc(attributes.maxAge)}`);
|
|
9040
|
+
}
|
|
9041
|
+
if (attributes.expires instanceof Date) {
|
|
9042
|
+
parts.push(`Expires=${attributes.expires.toUTCString()}`);
|
|
9043
|
+
}
|
|
9044
|
+
if (attributes.domain) {
|
|
9045
|
+
parts.push(`Domain=${attributes.domain}`);
|
|
9046
|
+
}
|
|
9047
|
+
if (attributes.path) {
|
|
9048
|
+
parts.push(`Path=${attributes.path}`);
|
|
9049
|
+
}
|
|
9050
|
+
if (attributes.secure) {
|
|
9051
|
+
parts.push("Secure");
|
|
9052
|
+
}
|
|
9053
|
+
if (attributes.httpOnly) {
|
|
9054
|
+
parts.push("HttpOnly");
|
|
9055
|
+
}
|
|
9056
|
+
if (attributes.partitioned) {
|
|
9057
|
+
parts.push("Partitioned");
|
|
9058
|
+
}
|
|
9059
|
+
if (attributes.sameSite) {
|
|
9060
|
+
parts.push(`SameSite=${capitalize2(attributes.sameSite)}`);
|
|
9061
|
+
}
|
|
9062
|
+
for (const [key, rawValue] of Object.entries(attributes)) {
|
|
9063
|
+
if (knownKeys.has(key) || rawValue === void 0 || rawValue === null || rawValue === false) {
|
|
9064
|
+
continue;
|
|
9065
|
+
}
|
|
9066
|
+
if (rawValue === true) {
|
|
9067
|
+
parts.push(key);
|
|
9068
|
+
continue;
|
|
9069
|
+
}
|
|
9070
|
+
parts.push(`${key}=${String(rawValue)}`);
|
|
9071
|
+
}
|
|
9072
|
+
return parts.join("; ");
|
|
9073
|
+
}
|
|
9074
|
+
function readCookieFromHeaders(headers, name) {
|
|
9075
|
+
const cookieHeader = headers?.get("cookie");
|
|
9076
|
+
if (!cookieHeader) {
|
|
9077
|
+
return void 0;
|
|
9078
|
+
}
|
|
9079
|
+
return parseCookies(cookieHeader).get(name);
|
|
9080
|
+
}
|
|
9081
|
+
function isRecord11(value) {
|
|
9082
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9083
|
+
}
|
|
9084
|
+
function resolveSessionCandidate(value) {
|
|
9085
|
+
if (!isRecord11(value)) {
|
|
9086
|
+
return null;
|
|
9087
|
+
}
|
|
9088
|
+
const session = isRecord11(value.session) ? value.session : void 0;
|
|
9089
|
+
const user = isRecord11(value.user) ? value.user : void 0;
|
|
9090
|
+
if (session && typeof session.token === "string" && session.token.length > 0 && user) {
|
|
9091
|
+
return {
|
|
9092
|
+
session,
|
|
9093
|
+
user
|
|
9094
|
+
};
|
|
9095
|
+
}
|
|
9096
|
+
return null;
|
|
9097
|
+
}
|
|
9098
|
+
function inferSessionPair(returned) {
|
|
9099
|
+
return resolveSessionCandidate(returned) ?? (isRecord11(returned) ? resolveSessionCandidate(returned.data) : null) ?? (isRecord11(returned) ? resolveSessionCandidate(returned.session) : null);
|
|
9100
|
+
}
|
|
9101
|
+
function resolveResponseHeaders(ctx) {
|
|
9102
|
+
if (ctx.context.responseHeaders instanceof Headers) {
|
|
9103
|
+
return ctx.context.responseHeaders;
|
|
9104
|
+
}
|
|
9105
|
+
const headers = new Headers();
|
|
9106
|
+
ctx.context.responseHeaders = headers;
|
|
9107
|
+
return headers;
|
|
9108
|
+
}
|
|
9109
|
+
function normalizeBaseURL(baseURL) {
|
|
9110
|
+
return baseURL.replace(/\/$/, "");
|
|
9111
|
+
}
|
|
9112
|
+
function normalizeBasePath(basePath) {
|
|
9113
|
+
if (!basePath || basePath === "/") {
|
|
9114
|
+
return DEFAULT_AUTH_BASE_PATH;
|
|
9115
|
+
}
|
|
9116
|
+
const normalized = basePath.startsWith("/") ? basePath : `/${basePath}`;
|
|
9117
|
+
return normalized.endsWith("/") && normalized.length > 1 ? normalized.slice(0, -1) : normalized;
|
|
9118
|
+
}
|
|
9119
|
+
function isDynamicBaseURLConfig2(baseURL) {
|
|
9120
|
+
return typeof baseURL === "object" && baseURL !== null && "allowedHosts" in baseURL && Array.isArray(baseURL.allowedHosts);
|
|
9121
|
+
}
|
|
9122
|
+
function getRequestUrl(request) {
|
|
9123
|
+
try {
|
|
9124
|
+
return new URL(request.url);
|
|
9125
|
+
} catch {
|
|
9126
|
+
return new URL("http://localhost");
|
|
9127
|
+
}
|
|
9128
|
+
}
|
|
9129
|
+
function getRequestHost(request, url) {
|
|
9130
|
+
const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
|
|
9131
|
+
const host = forwardedHost || request.headers.get("host") || url.host;
|
|
9132
|
+
return host || null;
|
|
9133
|
+
}
|
|
9134
|
+
function getRequestProtocol(request, configuredProtocol, url) {
|
|
9135
|
+
if (configuredProtocol === "http" || configuredProtocol === "https") {
|
|
9136
|
+
return configuredProtocol;
|
|
9137
|
+
}
|
|
9138
|
+
const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
|
|
9139
|
+
if (forwardedProto === "http" || forwardedProto === "https") {
|
|
9140
|
+
return forwardedProto;
|
|
9141
|
+
}
|
|
9142
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
9143
|
+
return url.protocol.slice(0, -1);
|
|
9144
|
+
}
|
|
9145
|
+
return "http";
|
|
9146
|
+
}
|
|
9147
|
+
function resolveRequestBaseURL(baseURL, request) {
|
|
9148
|
+
if (typeof baseURL === "string") {
|
|
9149
|
+
return normalizeBaseURL(baseURL);
|
|
9150
|
+
}
|
|
9151
|
+
const requestUrl = getRequestUrl(request);
|
|
9152
|
+
const host = getRequestHost(request, requestUrl);
|
|
9153
|
+
if (!host) {
|
|
9154
|
+
return null;
|
|
9155
|
+
}
|
|
9156
|
+
if (isDynamicBaseURLConfig2(baseURL)) {
|
|
9157
|
+
const allowedHosts = baseURL.allowedHosts ?? [];
|
|
9158
|
+
if (allowedHosts.length > 0 && !allowedHosts.includes(host)) {
|
|
9159
|
+
return null;
|
|
9160
|
+
}
|
|
9161
|
+
}
|
|
9162
|
+
const protocol = typeof baseURL === "object" && baseURL !== null ? getRequestProtocol(request, baseURL.protocol, requestUrl) : getRequestProtocol(request, void 0, requestUrl);
|
|
9163
|
+
return `${protocol}://${host}`;
|
|
9164
|
+
}
|
|
9165
|
+
function getOrigin(baseURL) {
|
|
9166
|
+
if (!baseURL) {
|
|
9167
|
+
return void 0;
|
|
9168
|
+
}
|
|
9169
|
+
try {
|
|
9170
|
+
return new URL(baseURL).origin;
|
|
9171
|
+
} catch {
|
|
9172
|
+
return void 0;
|
|
9173
|
+
}
|
|
9174
|
+
}
|
|
9175
|
+
async function resolveTrustedOrigins(config, baseURL, request) {
|
|
9176
|
+
const resolved = typeof config.trustedOrigins === "function" ? await config.trustedOrigins(request) : config.trustedOrigins ?? [];
|
|
9177
|
+
const values = [
|
|
9178
|
+
getOrigin(baseURL),
|
|
9179
|
+
...resolved
|
|
9180
|
+
];
|
|
9181
|
+
return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
|
|
9182
|
+
}
|
|
9183
|
+
async function resolveTrustedProviders(config, request) {
|
|
9184
|
+
const configured = typeof config.trustedProviders === "function" ? await config.trustedProviders(request) : config.trustedProviders ?? [];
|
|
9185
|
+
const values = [
|
|
9186
|
+
...Object.keys(config.socialProviders ?? {}),
|
|
9187
|
+
...configured
|
|
9188
|
+
];
|
|
9189
|
+
return Array.from(new Set(values.filter((value) => typeof value === "string" && value.length > 0)));
|
|
9190
|
+
}
|
|
9191
|
+
function createJsonResponse(payload, init) {
|
|
9192
|
+
const headers = new Headers(init?.headers);
|
|
9193
|
+
if (!headers.has("content-type")) {
|
|
9194
|
+
headers.set("content-type", "application/json; charset=utf-8");
|
|
9195
|
+
}
|
|
9196
|
+
return new Response(JSON.stringify(payload), {
|
|
9197
|
+
...init,
|
|
9198
|
+
headers
|
|
9199
|
+
});
|
|
9200
|
+
}
|
|
9201
|
+
function mergeResponseHeaders(response, headers) {
|
|
9202
|
+
return new Response(response.body, {
|
|
9203
|
+
status: response.status,
|
|
9204
|
+
statusText: response.statusText,
|
|
9205
|
+
headers
|
|
9206
|
+
});
|
|
9207
|
+
}
|
|
9208
|
+
function defineAthenaAuthConfig(config) {
|
|
9209
|
+
return config;
|
|
9210
|
+
}
|
|
9211
|
+
function athenaAuth(config) {
|
|
9212
|
+
const normalizedBasePath = normalizeBasePath(config.basePath);
|
|
9213
|
+
const staticBaseURL = typeof config.baseURL === "string" ? normalizeBaseURL(config.baseURL) : void 0;
|
|
9214
|
+
const runtime = {
|
|
9215
|
+
baseURL: staticBaseURL,
|
|
9216
|
+
basePath: normalizedBasePath,
|
|
9217
|
+
secret: config.secret,
|
|
9218
|
+
cookies: {
|
|
9219
|
+
session: config.session,
|
|
9220
|
+
advanced: config.advanced
|
|
9221
|
+
}
|
|
9222
|
+
};
|
|
9223
|
+
const resolvedDatabase = typeof config.database === "function" ? config.database(runtime) : config.database;
|
|
9224
|
+
const cookies = getCookies({
|
|
9225
|
+
baseURL: staticBaseURL ?? config.baseURL,
|
|
9226
|
+
session: config.session,
|
|
9227
|
+
advanced: config.advanced
|
|
9228
|
+
});
|
|
9229
|
+
const auth = {};
|
|
9230
|
+
const createCookieContext = (input = {}) => {
|
|
9231
|
+
const responseHeaders = input.responseHeaders ?? new Headers();
|
|
9232
|
+
const runtimeHeaders = input.headers;
|
|
9233
|
+
const authCookies = input.cookies ?? auth.cookies;
|
|
9234
|
+
const setCookie = input.setCookie ?? ((name, value, attributes) => {
|
|
9235
|
+
responseHeaders.append(
|
|
9236
|
+
"set-cookie",
|
|
9237
|
+
serializeSetCookieValue(name, value, attributes)
|
|
9238
|
+
);
|
|
9239
|
+
});
|
|
9240
|
+
return {
|
|
9241
|
+
headers: runtimeHeaders,
|
|
9242
|
+
getCookie: input.getCookie ?? ((name) => readCookieFromHeaders(runtimeHeaders, name)),
|
|
9243
|
+
setCookie,
|
|
9244
|
+
logger: input.logger,
|
|
9245
|
+
setSignedCookie: input.setSignedCookie,
|
|
9246
|
+
getSignedCookie: input.getSignedCookie,
|
|
9247
|
+
context: {
|
|
9248
|
+
secret: runtime.secret,
|
|
9249
|
+
authCookies,
|
|
9250
|
+
sessionConfig: {
|
|
9251
|
+
expiresIn: config.session?.expiresIn
|
|
9252
|
+
},
|
|
9253
|
+
options: {
|
|
9254
|
+
session: {
|
|
9255
|
+
cookieCache: config.session?.cookieCache
|
|
9256
|
+
},
|
|
9257
|
+
account: {
|
|
9258
|
+
storeAccountCookie: true
|
|
9259
|
+
}
|
|
9260
|
+
},
|
|
9261
|
+
setNewSession: input.setNewSession
|
|
9262
|
+
}
|
|
9263
|
+
};
|
|
9264
|
+
};
|
|
9265
|
+
const setSession = async (input, session, dontRememberMe, overrides) => {
|
|
9266
|
+
const cookieContext = createCookieContext(input);
|
|
9267
|
+
await setSessionCookie(cookieContext, session, dontRememberMe, overrides);
|
|
9268
|
+
};
|
|
9269
|
+
const clearSession = (input, skipDontRememberMe) => {
|
|
9270
|
+
const cookieContext = createCookieContext(input);
|
|
9271
|
+
deleteSessionCookie(cookieContext, skipDontRememberMe);
|
|
9272
|
+
};
|
|
9273
|
+
const applyResponseCookies = async (ctx) => {
|
|
9274
|
+
const responseHeaders = resolveResponseHeaders(ctx);
|
|
9275
|
+
const session = ctx.context.setSession ?? inferSessionPair(ctx.context.returned);
|
|
9276
|
+
if (ctx.context.clearSession) {
|
|
9277
|
+
clearSession({
|
|
9278
|
+
headers: ctx.headers,
|
|
9279
|
+
responseHeaders
|
|
9280
|
+
});
|
|
9281
|
+
}
|
|
9282
|
+
if (session) {
|
|
9283
|
+
await setSession(
|
|
9284
|
+
{
|
|
9285
|
+
headers: ctx.headers,
|
|
9286
|
+
responseHeaders
|
|
9287
|
+
},
|
|
9288
|
+
session,
|
|
9289
|
+
ctx.context.dontRememberMe,
|
|
9290
|
+
ctx.context.cookieOverrides
|
|
9291
|
+
);
|
|
9292
|
+
}
|
|
9293
|
+
return responseHeaders;
|
|
9294
|
+
};
|
|
9295
|
+
const runAfterHooks = async (ctx) => {
|
|
9296
|
+
for (const plugin of auth.plugins) {
|
|
9297
|
+
for (const hook of plugin.hooks?.after ?? []) {
|
|
9298
|
+
if (!hook.matcher(ctx)) {
|
|
9299
|
+
continue;
|
|
9300
|
+
}
|
|
9301
|
+
await hook.handler({
|
|
9302
|
+
...ctx,
|
|
9303
|
+
auth
|
|
9304
|
+
});
|
|
9305
|
+
}
|
|
9306
|
+
}
|
|
9307
|
+
return ctx;
|
|
9308
|
+
};
|
|
9309
|
+
const resolveRequestContext = async (request) => {
|
|
9310
|
+
const requestUrl = getRequestUrl(request);
|
|
9311
|
+
const resolvedBaseURL = resolveRequestBaseURL(config.baseURL, request);
|
|
9312
|
+
if (!resolvedBaseURL) {
|
|
9313
|
+
throw new Error(
|
|
9314
|
+
isDynamicBaseURLConfig2(config.baseURL) ? "Could not resolve base URL from request. Check allowedHosts/baseURL." : "Could not resolve base URL from request."
|
|
9315
|
+
);
|
|
9316
|
+
}
|
|
9317
|
+
const requestCookies = getCookies({
|
|
9318
|
+
baseURL: resolvedBaseURL,
|
|
9319
|
+
session: config.session,
|
|
9320
|
+
advanced: config.advanced
|
|
9321
|
+
});
|
|
9322
|
+
const trustedOrigins = await resolveTrustedOrigins(config, resolvedBaseURL, request);
|
|
9323
|
+
const trustedProviders = await resolveTrustedProviders(config, request);
|
|
9324
|
+
return {
|
|
9325
|
+
auth,
|
|
9326
|
+
request,
|
|
9327
|
+
url: requestUrl,
|
|
9328
|
+
path: requestUrl.pathname,
|
|
9329
|
+
basePath: normalizedBasePath,
|
|
9330
|
+
baseURL: resolvedBaseURL,
|
|
9331
|
+
origin: getOrigin(resolvedBaseURL) ?? resolvedBaseURL,
|
|
9332
|
+
headers: request.headers,
|
|
9333
|
+
cookies: requestCookies,
|
|
9334
|
+
trustedOrigins,
|
|
9335
|
+
trustedProviders,
|
|
9336
|
+
options: config,
|
|
9337
|
+
runtime: {
|
|
9338
|
+
...runtime,
|
|
9339
|
+
baseURL: resolvedBaseURL
|
|
9340
|
+
},
|
|
9341
|
+
database: auth.database,
|
|
9342
|
+
socialProviders: auth.socialProviders
|
|
9343
|
+
};
|
|
9344
|
+
};
|
|
9345
|
+
const handler = async (request) => {
|
|
9346
|
+
const requestContext = await resolveRequestContext(request);
|
|
9347
|
+
if (typeof config.handler !== "function") {
|
|
9348
|
+
return createJsonResponse(
|
|
9349
|
+
{
|
|
9350
|
+
ok: false,
|
|
9351
|
+
code: ATHENA_AUTH_BASE_ERROR_CODES.HANDLER_NOT_CONFIGURED,
|
|
9352
|
+
error: "No native auth handler was configured for this Athena auth instance.",
|
|
9353
|
+
path: requestContext.path,
|
|
9354
|
+
basePath: requestContext.basePath
|
|
9355
|
+
},
|
|
9356
|
+
{ status: 501 }
|
|
9357
|
+
);
|
|
9358
|
+
}
|
|
9359
|
+
const result = await config.handler(requestContext);
|
|
9360
|
+
if (result instanceof Response) {
|
|
9361
|
+
return result;
|
|
9362
|
+
}
|
|
9363
|
+
const response = result.response ?? (result.returned !== void 0 ? createJsonResponse(result.returned) : new Response(null, { status: 204 }));
|
|
9364
|
+
const responseHeaders = new Headers(response.headers);
|
|
9365
|
+
await runAfterHooks({
|
|
9366
|
+
path: requestContext.path,
|
|
9367
|
+
headers: request.headers,
|
|
9368
|
+
context: {
|
|
9369
|
+
responseHeaders,
|
|
9370
|
+
returned: result.returned,
|
|
9371
|
+
setSession: result.setSession,
|
|
9372
|
+
clearSession: result.clearSession,
|
|
9373
|
+
dontRememberMe: result.dontRememberMe,
|
|
9374
|
+
cookieOverrides: result.cookieOverrides
|
|
9375
|
+
}
|
|
9376
|
+
});
|
|
9377
|
+
return mergeResponseHeaders(response, responseHeaders);
|
|
9378
|
+
};
|
|
9379
|
+
const api = Object.assign(
|
|
9380
|
+
{
|
|
9381
|
+
applyResponseCookies,
|
|
9382
|
+
clearSession,
|
|
9383
|
+
createCookieContext,
|
|
9384
|
+
getCookieCache,
|
|
9385
|
+
getSessionCookie,
|
|
9386
|
+
resolveRequestContext,
|
|
9387
|
+
runAfterHooks,
|
|
9388
|
+
setSession
|
|
9389
|
+
},
|
|
9390
|
+
config.api ?? {}
|
|
9391
|
+
);
|
|
9392
|
+
const $ERROR_CODES = {
|
|
9393
|
+
...auth.plugins?.reduce((acc, plugin) => {
|
|
9394
|
+
if (plugin.$ERROR_CODES) {
|
|
9395
|
+
return {
|
|
9396
|
+
...acc,
|
|
9397
|
+
...plugin.$ERROR_CODES
|
|
9398
|
+
};
|
|
9399
|
+
}
|
|
9400
|
+
return acc;
|
|
9401
|
+
}, {}),
|
|
9402
|
+
...config.errorCodes ?? {},
|
|
9403
|
+
...ATHENA_AUTH_BASE_ERROR_CODES
|
|
9404
|
+
};
|
|
9405
|
+
Object.assign(auth, {
|
|
9406
|
+
config,
|
|
9407
|
+
options: config,
|
|
9408
|
+
runtime,
|
|
9409
|
+
database: resolvedDatabase,
|
|
9410
|
+
socialProviders: config.socialProviders ?? {},
|
|
9411
|
+
plugins: [...config.plugins ?? []],
|
|
9412
|
+
cookies,
|
|
9413
|
+
api,
|
|
9414
|
+
$ERROR_CODES,
|
|
9415
|
+
createCookieContext,
|
|
9416
|
+
setSession,
|
|
9417
|
+
clearSession,
|
|
9418
|
+
applyResponseCookies,
|
|
9419
|
+
runAfterHooks,
|
|
9420
|
+
resolveRequestContext,
|
|
9421
|
+
handler
|
|
9422
|
+
});
|
|
9423
|
+
auth.$context = Promise.all([
|
|
9424
|
+
resolveTrustedOrigins(config, staticBaseURL),
|
|
9425
|
+
resolveTrustedProviders(config)
|
|
9426
|
+
]).then(([trustedOrigins, trustedProviders]) => ({
|
|
9427
|
+
auth,
|
|
9428
|
+
options: config,
|
|
9429
|
+
runtime,
|
|
9430
|
+
basePath: normalizedBasePath,
|
|
9431
|
+
baseURL: staticBaseURL,
|
|
9432
|
+
origin: getOrigin(staticBaseURL),
|
|
9433
|
+
database: auth.database,
|
|
9434
|
+
socialProviders: auth.socialProviders,
|
|
9435
|
+
plugins: auth.plugins,
|
|
9436
|
+
cookies: auth.cookies,
|
|
9437
|
+
trustedOrigins,
|
|
9438
|
+
trustedProviders
|
|
9439
|
+
}));
|
|
9440
|
+
return auth;
|
|
9441
|
+
}
|
|
9442
|
+
|
|
9443
|
+
exports.ATHENA_AUTH_BASE_ERROR_CODES = ATHENA_AUTH_BASE_ERROR_CODES;
|
|
6865
9444
|
exports.AthenaClient = AthenaClient;
|
|
6866
9445
|
exports.AthenaError = AthenaError;
|
|
6867
9446
|
exports.AthenaErrorCategory = AthenaErrorCategory;
|
|
6868
9447
|
exports.AthenaErrorCode = AthenaErrorCode;
|
|
6869
9448
|
exports.AthenaErrorKind = AthenaErrorKind;
|
|
6870
9449
|
exports.AthenaGatewayError = AthenaGatewayError;
|
|
9450
|
+
exports.AthenaStorageError = AthenaStorageError;
|
|
9451
|
+
exports.AthenaStorageErrorCode = AthenaStorageErrorCode;
|
|
6871
9452
|
exports.Backend = Backend;
|
|
6872
9453
|
exports.DEFAULT_POSTGRES_SCHEMAS = DEFAULT_POSTGRES_SCHEMAS;
|
|
6873
9454
|
exports.assertInt = assertInt;
|
|
9455
|
+
exports.athenaAuth = athenaAuth;
|
|
6874
9456
|
exports.coerceInt = coerceInt;
|
|
9457
|
+
exports.createAthenaStorageError = createAthenaStorageError;
|
|
6875
9458
|
exports.createAuthClient = createAuthClient;
|
|
6876
9459
|
exports.createAuthReactEmailInput = createAuthReactEmailInput;
|
|
6877
9460
|
exports.createClient = createClient;
|
|
6878
9461
|
exports.createModelFormAdapter = createModelFormAdapter;
|
|
6879
9462
|
exports.createPostgresIntrospectionProvider = createPostgresIntrospectionProvider;
|
|
6880
9463
|
exports.createTypedClient = createTypedClient;
|
|
9464
|
+
exports.defineAthenaAuthConfig = defineAthenaAuthConfig;
|
|
6881
9465
|
exports.defineAuthEmailTemplate = defineAuthEmailTemplate;
|
|
6882
9466
|
exports.defineDatabase = defineDatabase;
|
|
6883
9467
|
exports.defineGeneratorConfig = defineGeneratorConfig;
|
|
@@ -6886,6 +9470,7 @@ exports.defineRegistry = defineRegistry;
|
|
|
6886
9470
|
exports.defineSchema = defineSchema;
|
|
6887
9471
|
exports.findGeneratorConfigPath = findGeneratorConfigPath;
|
|
6888
9472
|
exports.generateArtifactsFromSnapshot = generateArtifactsFromSnapshot;
|
|
9473
|
+
exports.generatorEnv = generatorEnv;
|
|
6889
9474
|
exports.identifier = identifier;
|
|
6890
9475
|
exports.isAthenaGatewayError = isAthenaGatewayError;
|
|
6891
9476
|
exports.isOk = isOk;
|
|
@@ -6902,6 +9487,7 @@ exports.resolveGeneratorProvider = resolveGeneratorProvider;
|
|
|
6902
9487
|
exports.resolvePostgresColumnType = resolvePostgresColumnType;
|
|
6903
9488
|
exports.resolveProviderSchemas = resolveProviderSchemas;
|
|
6904
9489
|
exports.runSchemaGenerator = runSchemaGenerator;
|
|
9490
|
+
exports.storageSdkManifest = storageSdkManifest;
|
|
6905
9491
|
exports.toModelFormDefaults = toModelFormDefaults;
|
|
6906
9492
|
exports.toModelPayload = toModelPayload;
|
|
6907
9493
|
exports.unwrap = unwrap;
|