@xylex-group/athena 1.9.0 → 2.1.2
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 +86 -68
- package/bin/athena-js.js +0 -0
- package/dist/browser.cjs +3319 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +25 -0
- package/dist/browser.d.ts +25 -0
- package/dist/browser.js +3276 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli/index.cjs +1839 -275
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -2
- package/dist/cli/index.d.ts +3 -2
- package/dist/cli/index.js +1840 -276
- package/dist/cli/index.js.map +1 -1
- package/dist/client-BX0NQqOn.d.ts +435 -0
- package/dist/client-dpAp-NZK.d.cts +435 -0
- package/dist/cookies.cjs +890 -0
- package/dist/cookies.cjs.map +1 -0
- package/dist/cookies.d.cts +174 -0
- package/dist/cookies.d.ts +174 -0
- package/dist/cookies.js +869 -0
- package/dist/cookies.js.map +1 -0
- package/dist/index.cjs +2724 -1777
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -641
- package/dist/index.d.ts +8 -641
- package/dist/index.js +2725 -1779
- package/dist/index.js.map +1 -1
- package/dist/model-form-2hqmoOUX.d.ts +1284 -0
- package/dist/model-form-Cy-zaO0u.d.cts +1284 -0
- package/dist/pipeline-BOPszLsL.d.ts +8 -0
- package/dist/pipeline-E3FDbs4W.d.cts +8 -0
- package/dist/react.cjs +93 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +38 -4
- package/dist/react.d.ts +38 -4
- package/dist/react.js +93 -1
- package/dist/react.js.map +1 -1
- package/dist/{types-BnzoaNRC.d.cts → types-BaBzjwXr.d.cts} +1 -1
- package/dist/{types-BnzoaNRC.d.ts → types-BaBzjwXr.d.ts} +1 -1
- package/dist/{pipeline-CQgV-Yfo.d.ts → types-CeBPrnGj.d.ts} +2 -7
- package/dist/{pipeline-C-cN0ACi.d.cts → types-CpqL-pZx.d.cts} +2 -7
- package/package.json +36 -17
- package/dist/model-form-Bm_kqCn2.d.ts +0 -92
- package/dist/model-form-DkS48fsh.d.cts +0 -92
package/dist/cli/index.cjs
CHANGED
|
@@ -4,7 +4,6 @@ var promises = require('fs/promises');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var fs = require('fs');
|
|
6
6
|
var url = require('url');
|
|
7
|
-
var pg = require('pg');
|
|
8
7
|
|
|
9
8
|
// src/generator/pipeline.ts
|
|
10
9
|
|
|
@@ -149,9 +148,13 @@ function resolvePlaceholderMap(baseTokens, outputConfig) {
|
|
|
149
148
|
const resolved = {
|
|
150
149
|
...baseTokens
|
|
151
150
|
};
|
|
151
|
+
const reservedTokenKeys = new Set(Object.keys(baseTokens));
|
|
152
152
|
const entries = Object.entries(outputConfig.placeholderMap ?? {});
|
|
153
153
|
for (let index = 0; index < entries.length; index += 1) {
|
|
154
154
|
const [key, value] = entries[index];
|
|
155
|
+
if (reservedTokenKeys.has(key)) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
155
158
|
let current = value;
|
|
156
159
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
157
160
|
const next = renderTemplate(current, resolved);
|
|
@@ -292,6 +295,295 @@ function resolvePostgresColumnType(column) {
|
|
|
292
295
|
return wrapArrayType(baseType, column.arrayDimensions);
|
|
293
296
|
}
|
|
294
297
|
|
|
298
|
+
// src/gateway/errors.ts
|
|
299
|
+
var AthenaGatewayError = class _AthenaGatewayError extends Error {
|
|
300
|
+
code;
|
|
301
|
+
status;
|
|
302
|
+
endpoint;
|
|
303
|
+
method;
|
|
304
|
+
requestId;
|
|
305
|
+
hint;
|
|
306
|
+
causeDetail;
|
|
307
|
+
constructor(input) {
|
|
308
|
+
super(input.message);
|
|
309
|
+
this.name = "AthenaGatewayError";
|
|
310
|
+
this.code = input.code;
|
|
311
|
+
this.status = input.status ?? 0;
|
|
312
|
+
this.endpoint = input.endpoint;
|
|
313
|
+
this.method = input.method;
|
|
314
|
+
this.requestId = input.requestId;
|
|
315
|
+
this.hint = input.hint;
|
|
316
|
+
this.causeDetail = input.cause;
|
|
317
|
+
}
|
|
318
|
+
toDetails() {
|
|
319
|
+
return {
|
|
320
|
+
code: this.code,
|
|
321
|
+
message: this.message,
|
|
322
|
+
status: this.status,
|
|
323
|
+
endpoint: this.endpoint,
|
|
324
|
+
method: this.method,
|
|
325
|
+
requestId: this.requestId,
|
|
326
|
+
hint: this.hint,
|
|
327
|
+
cause: this.causeDetail
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
static fromResponse(response, fallback) {
|
|
331
|
+
const details = response.errorDetails;
|
|
332
|
+
if (details) {
|
|
333
|
+
return new _AthenaGatewayError({
|
|
334
|
+
code: details.code,
|
|
335
|
+
message: details.message,
|
|
336
|
+
status: details.status,
|
|
337
|
+
endpoint: details.endpoint ?? fallback.endpoint,
|
|
338
|
+
method: details.method ?? fallback.method,
|
|
339
|
+
requestId: details.requestId ?? fallback.requestId,
|
|
340
|
+
hint: details.hint,
|
|
341
|
+
cause: details.cause
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return new _AthenaGatewayError({
|
|
345
|
+
code: "HTTP_ERROR",
|
|
346
|
+
message: response.error ?? "Gateway request failed",
|
|
347
|
+
status: response.status,
|
|
348
|
+
endpoint: fallback.endpoint,
|
|
349
|
+
method: fallback.method,
|
|
350
|
+
requestId: fallback.requestId
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
function isAthenaGatewayError(error) {
|
|
355
|
+
return error instanceof AthenaGatewayError;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/auxiliaries.ts
|
|
359
|
+
var AthenaErrorCode = {
|
|
360
|
+
UniqueViolation: "UNIQUE_VIOLATION",
|
|
361
|
+
NotFound: "NOT_FOUND",
|
|
362
|
+
ValidationFailed: "VALIDATION_FAILED",
|
|
363
|
+
AuthUnauthorized: "AUTH_UNAUTHORIZED",
|
|
364
|
+
AuthForbidden: "AUTH_FORBIDDEN",
|
|
365
|
+
RateLimited: "RATE_LIMITED",
|
|
366
|
+
NetworkUnavailable: "NETWORK_UNAVAILABLE",
|
|
367
|
+
TransientFailure: "TRANSIENT_FAILURE",
|
|
368
|
+
HttpFailure: "HTTP_FAILURE",
|
|
369
|
+
Unknown: "UNKNOWN"
|
|
370
|
+
};
|
|
371
|
+
var AthenaErrorCategory = {
|
|
372
|
+
Transport: "transport",
|
|
373
|
+
Client: "client",
|
|
374
|
+
Server: "server",
|
|
375
|
+
Database: "database",
|
|
376
|
+
Unknown: "unknown"
|
|
377
|
+
};
|
|
378
|
+
function parseBooleanFlag(rawValue, fallback) {
|
|
379
|
+
if (!rawValue) return fallback;
|
|
380
|
+
const normalized = rawValue.trim().toLowerCase();
|
|
381
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") {
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
return fallback;
|
|
388
|
+
}
|
|
389
|
+
function isRecord(value) {
|
|
390
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
391
|
+
}
|
|
392
|
+
function isAthenaErrorKind(value) {
|
|
393
|
+
return value === "unique_violation" || value === "not_found" || value === "validation" || value === "auth" || value === "rate_limit" || value === "transient" || value === "unknown";
|
|
394
|
+
}
|
|
395
|
+
function isAthenaErrorCode(value) {
|
|
396
|
+
return value === "UNIQUE_VIOLATION" || value === "NOT_FOUND" || value === "VALIDATION_FAILED" || value === "AUTH_UNAUTHORIZED" || value === "AUTH_FORBIDDEN" || value === "RATE_LIMITED" || value === "NETWORK_UNAVAILABLE" || value === "TRANSIENT_FAILURE" || value === "HTTP_FAILURE" || value === "UNKNOWN";
|
|
397
|
+
}
|
|
398
|
+
function isAthenaErrorCategory(value) {
|
|
399
|
+
return value === "transport" || value === "client" || value === "server" || value === "database" || value === "unknown";
|
|
400
|
+
}
|
|
401
|
+
function isNormalizedAthenaError(value) {
|
|
402
|
+
return isRecord(value) && isAthenaErrorKind(value.kind) && isAthenaErrorCode(value.code) && isAthenaErrorCategory(value.category) && typeof value.retryable === "boolean" && typeof value.message === "string" && "raw" in value;
|
|
403
|
+
}
|
|
404
|
+
function withContextOverrides(normalized, context) {
|
|
405
|
+
if (!context?.table && !context?.operation) {
|
|
406
|
+
return normalized;
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
...normalized,
|
|
410
|
+
table: context.table ?? normalized.table,
|
|
411
|
+
operation: context.operation ?? normalized.operation
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function resolveAttachedNormalizedError(resultOrError) {
|
|
415
|
+
if (!isRecord(resultOrError)) return void 0;
|
|
416
|
+
if (!("__athenaNormalizedError" in resultOrError)) return void 0;
|
|
417
|
+
const candidate = resultOrError.__athenaNormalizedError;
|
|
418
|
+
return isNormalizedAthenaError(candidate) ? candidate : void 0;
|
|
419
|
+
}
|
|
420
|
+
function isAthenaResultLike(value) {
|
|
421
|
+
return isRecord(value) && "status" in value && "error" in value && "data" in value && typeof value.status === "number";
|
|
422
|
+
}
|
|
423
|
+
function operationFromDetails(details) {
|
|
424
|
+
if (!details?.endpoint) return void 0;
|
|
425
|
+
if (details.endpoint === "/gateway/fetch" || details.endpoint === "/gateway/query") return "select";
|
|
426
|
+
if (details.endpoint === "/gateway/insert") return "insert";
|
|
427
|
+
if (details.endpoint === "/gateway/update") return "update";
|
|
428
|
+
if (details.endpoint === "/gateway/delete") return "delete";
|
|
429
|
+
if (details.endpoint === "/gateway/rpc" || details.endpoint.startsWith("/rpc/")) return "rpc";
|
|
430
|
+
return void 0;
|
|
431
|
+
}
|
|
432
|
+
function matchRegex(input, patterns) {
|
|
433
|
+
for (const pattern of patterns) {
|
|
434
|
+
const match = pattern.exec(input);
|
|
435
|
+
if (match?.[1]) return match[1];
|
|
436
|
+
}
|
|
437
|
+
return void 0;
|
|
438
|
+
}
|
|
439
|
+
function extractConstraint(message) {
|
|
440
|
+
return matchRegex(message, [
|
|
441
|
+
/unique constraint\s+["'`]([^"'`]+)["'`]/i,
|
|
442
|
+
/constraint\s+["'`]([^"'`]+)["'`]/i
|
|
443
|
+
]);
|
|
444
|
+
}
|
|
445
|
+
function extractTable(message) {
|
|
446
|
+
return matchRegex(message, [
|
|
447
|
+
/(?:table|relation)\s+["'`]([^"'`]+)["'`]/i,
|
|
448
|
+
/on\s+table\s+([a-zA-Z0-9_.]+)/i
|
|
449
|
+
]);
|
|
450
|
+
}
|
|
451
|
+
function classifyKind(status, code, message) {
|
|
452
|
+
const lower = message.toLowerCase();
|
|
453
|
+
const hasUniquePattern = lower.includes("unique constraint") || lower.includes("duplicate key") || lower.includes("already exists") || lower.includes("duplicate");
|
|
454
|
+
const hasNotFoundPattern = lower.includes("not found") || lower.includes("no rows");
|
|
455
|
+
const hasValidationPattern = lower.includes("validation") || lower.includes("invalid") || lower.includes("malformed");
|
|
456
|
+
const hasAuthPattern = lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("auth");
|
|
457
|
+
const hasRateLimitPattern = lower.includes("rate limit") || lower.includes("too many requests");
|
|
458
|
+
const hasTransientPattern = lower.includes("timeout") || lower.includes("temporar") || lower.includes("connection reset") || lower.includes("socket") || lower.includes("deadlock");
|
|
459
|
+
if (status === 409 || hasUniquePattern) return "unique_violation";
|
|
460
|
+
if (status === 404 || hasNotFoundPattern) return "not_found";
|
|
461
|
+
if (status === 401 || status === 403 || hasAuthPattern) return "auth";
|
|
462
|
+
if (status === 429 || hasRateLimitPattern) return "rate_limit";
|
|
463
|
+
if (status === 400 || status === 422 || hasValidationPattern) return "validation";
|
|
464
|
+
if (code === "NETWORK_ERROR" || status === 0 || status !== void 0 && status >= 500 || hasTransientPattern) {
|
|
465
|
+
return "transient";
|
|
466
|
+
}
|
|
467
|
+
return "unknown";
|
|
468
|
+
}
|
|
469
|
+
function toAthenaErrorCode(kind, status, gatewayCode) {
|
|
470
|
+
if (gatewayCode === "NETWORK_ERROR" || kind === "transient" && status === 0) {
|
|
471
|
+
return AthenaErrorCode.NetworkUnavailable;
|
|
472
|
+
}
|
|
473
|
+
switch (kind) {
|
|
474
|
+
case "unique_violation":
|
|
475
|
+
return AthenaErrorCode.UniqueViolation;
|
|
476
|
+
case "not_found":
|
|
477
|
+
return AthenaErrorCode.NotFound;
|
|
478
|
+
case "validation":
|
|
479
|
+
return AthenaErrorCode.ValidationFailed;
|
|
480
|
+
case "rate_limit":
|
|
481
|
+
return AthenaErrorCode.RateLimited;
|
|
482
|
+
case "auth":
|
|
483
|
+
if (status === 403) {
|
|
484
|
+
return AthenaErrorCode.AuthForbidden;
|
|
485
|
+
}
|
|
486
|
+
return AthenaErrorCode.AuthUnauthorized;
|
|
487
|
+
case "transient":
|
|
488
|
+
return status !== void 0 && status >= 500 ? AthenaErrorCode.HttpFailure : AthenaErrorCode.TransientFailure;
|
|
489
|
+
case "unknown":
|
|
490
|
+
default:
|
|
491
|
+
return status !== void 0 && status >= 400 ? AthenaErrorCode.HttpFailure : AthenaErrorCode.Unknown;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function toAthenaErrorCategory(kind, status) {
|
|
495
|
+
if (kind === "transient" && (status === 0 || status === void 0)) {
|
|
496
|
+
return AthenaErrorCategory.Transport;
|
|
497
|
+
}
|
|
498
|
+
if (kind === "unique_violation") return AthenaErrorCategory.Database;
|
|
499
|
+
if (kind === "validation" || kind === "auth" || kind === "not_found") return AthenaErrorCategory.Client;
|
|
500
|
+
if (kind === "rate_limit" || kind === "transient") return AthenaErrorCategory.Server;
|
|
501
|
+
return AthenaErrorCategory.Unknown;
|
|
502
|
+
}
|
|
503
|
+
function isRetryable(kind, status) {
|
|
504
|
+
if (kind === "rate_limit" || kind === "transient") return true;
|
|
505
|
+
return status !== void 0 && status >= 500;
|
|
506
|
+
}
|
|
507
|
+
function normalizeAthenaError(resultOrError, context) {
|
|
508
|
+
const attached = resolveAttachedNormalizedError(resultOrError);
|
|
509
|
+
if (attached) {
|
|
510
|
+
return withContextOverrides(attached, context);
|
|
511
|
+
}
|
|
512
|
+
if (isAthenaResultLike(resultOrError)) {
|
|
513
|
+
const details = resultOrError.errorDetails;
|
|
514
|
+
const message2 = resultOrError.error ?? details?.message ?? `Athena ${context?.operation ?? operationFromDetails(details) ?? "request"} failed`;
|
|
515
|
+
const operation = context?.operation ?? operationFromDetails(details);
|
|
516
|
+
const table = context?.table ?? extractTable(message2);
|
|
517
|
+
const constraint = extractConstraint(message2);
|
|
518
|
+
const kind2 = classifyKind(resultOrError.status, details?.code, message2);
|
|
519
|
+
const code = toAthenaErrorCode(kind2, resultOrError.status, details?.code);
|
|
520
|
+
const category = toAthenaErrorCategory(kind2, resultOrError.status);
|
|
521
|
+
return {
|
|
522
|
+
kind: kind2,
|
|
523
|
+
code,
|
|
524
|
+
category,
|
|
525
|
+
retryable: isRetryable(kind2, resultOrError.status),
|
|
526
|
+
status: resultOrError.status,
|
|
527
|
+
constraint,
|
|
528
|
+
table,
|
|
529
|
+
operation,
|
|
530
|
+
message: message2,
|
|
531
|
+
raw: resultOrError.raw
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
if (isAthenaGatewayError(resultOrError)) {
|
|
535
|
+
const details = resultOrError.toDetails();
|
|
536
|
+
const operation = context?.operation ?? operationFromDetails(details);
|
|
537
|
+
const table = context?.table ?? extractTable(resultOrError.message);
|
|
538
|
+
const constraint = extractConstraint(resultOrError.message);
|
|
539
|
+
const kind2 = classifyKind(resultOrError.status, resultOrError.code, resultOrError.message);
|
|
540
|
+
const code = toAthenaErrorCode(kind2, resultOrError.status, resultOrError.code);
|
|
541
|
+
const category = toAthenaErrorCategory(kind2, resultOrError.status);
|
|
542
|
+
return {
|
|
543
|
+
kind: kind2,
|
|
544
|
+
code,
|
|
545
|
+
category,
|
|
546
|
+
retryable: isRetryable(kind2, resultOrError.status),
|
|
547
|
+
status: resultOrError.status,
|
|
548
|
+
constraint,
|
|
549
|
+
table,
|
|
550
|
+
operation,
|
|
551
|
+
message: resultOrError.message,
|
|
552
|
+
raw: resultOrError
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
if (resultOrError instanceof Error) {
|
|
556
|
+
const maybeStatus = isRecord(resultOrError) && typeof resultOrError.status === "number" ? resultOrError.status : void 0;
|
|
557
|
+
const kind2 = classifyKind(maybeStatus, void 0, resultOrError.message);
|
|
558
|
+
return {
|
|
559
|
+
kind: kind2,
|
|
560
|
+
code: toAthenaErrorCode(kind2, maybeStatus),
|
|
561
|
+
category: toAthenaErrorCategory(kind2, maybeStatus),
|
|
562
|
+
retryable: isRetryable(kind2, maybeStatus),
|
|
563
|
+
status: maybeStatus,
|
|
564
|
+
constraint: extractConstraint(resultOrError.message),
|
|
565
|
+
table: context?.table ?? extractTable(resultOrError.message),
|
|
566
|
+
operation: context?.operation,
|
|
567
|
+
message: resultOrError.message,
|
|
568
|
+
raw: resultOrError
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
const message = typeof resultOrError === "string" ? resultOrError : "Unknown Athena error";
|
|
572
|
+
const kind = classifyKind(void 0, void 0, message);
|
|
573
|
+
return {
|
|
574
|
+
kind,
|
|
575
|
+
code: toAthenaErrorCode(kind, void 0),
|
|
576
|
+
category: toAthenaErrorCategory(kind, void 0),
|
|
577
|
+
retryable: isRetryable(kind, void 0),
|
|
578
|
+
status: void 0,
|
|
579
|
+
constraint: extractConstraint(message),
|
|
580
|
+
table: context?.table ?? extractTable(message),
|
|
581
|
+
operation: context?.operation,
|
|
582
|
+
message,
|
|
583
|
+
raw: resultOrError
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
295
587
|
// src/generator/schema-selection.ts
|
|
296
588
|
var DEFAULT_POSTGRES_SCHEMAS = ["public"];
|
|
297
589
|
function collectSchemaNames(input) {
|
|
@@ -322,6 +614,7 @@ function resolveProviderSchemas(providerConfig) {
|
|
|
322
614
|
}
|
|
323
615
|
|
|
324
616
|
// src/generator/config.ts
|
|
617
|
+
var POSTGRES_PROTOCOLS = /* @__PURE__ */ new Set(["postgres:", "postgresql:"]);
|
|
325
618
|
var DEFAULT_CONFIG_CANDIDATES = [
|
|
326
619
|
"athena.config.ts",
|
|
327
620
|
"athena.config.js",
|
|
@@ -351,6 +644,184 @@ var DEFAULT_EXPERIMENTAL_FLAGS = {
|
|
|
351
644
|
postgresGatewayIntrospection: false,
|
|
352
645
|
scyllaProviderContracts: true
|
|
353
646
|
};
|
|
647
|
+
var PROJECT_ENV_FILENAMES = [".env", ".env.local"];
|
|
648
|
+
var DIRECT_CONNECTION_STRING_ENV_KEYS = [
|
|
649
|
+
"ATHENA_GENERATOR_PG_URL",
|
|
650
|
+
"DATABASE_URL",
|
|
651
|
+
"PG_URL",
|
|
652
|
+
"POSTGRES_URL",
|
|
653
|
+
"POSTGRESQL_URL"
|
|
654
|
+
];
|
|
655
|
+
var POSTGRES_DATABASE_ENV_KEYS = ["ATHENA_GENERATOR_DB", "ATHENA_DATABASE", "PGDATABASE"];
|
|
656
|
+
var POSTGRES_PASSWORD_ENV_KEYS = ["ATHENA_GENERATOR_PG_PASSWORD", "PGPASSWORD"];
|
|
657
|
+
var GATEWAY_URL_ENV_KEYS = ["ATHENA_URL", "ATHENA_GATEWAY_URL", "ATHENA_GENERATOR_URL"];
|
|
658
|
+
var GATEWAY_API_KEY_ENV_KEYS = [
|
|
659
|
+
"ATHENA_API_KEY",
|
|
660
|
+
"ATHENA_GATEWAY_API_KEY",
|
|
661
|
+
"ATHENA_GENERATOR_API_KEY"
|
|
662
|
+
];
|
|
663
|
+
function normalizeRawEnvValue(rawValue) {
|
|
664
|
+
if (rawValue.startsWith('"') && rawValue.endsWith('"') && rawValue.length >= 2) {
|
|
665
|
+
const inner = rawValue.slice(1, -1);
|
|
666
|
+
return inner.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
667
|
+
}
|
|
668
|
+
if (rawValue.startsWith("'") && rawValue.endsWith("'") && rawValue.length >= 2) {
|
|
669
|
+
return rawValue.slice(1, -1);
|
|
670
|
+
}
|
|
671
|
+
const commentIndex = rawValue.search(/\s+#/);
|
|
672
|
+
const withoutComment = commentIndex >= 0 ? rawValue.slice(0, commentIndex) : rawValue;
|
|
673
|
+
return withoutComment.trim();
|
|
674
|
+
}
|
|
675
|
+
function parseEnvLine(line) {
|
|
676
|
+
const trimmed = line.trim();
|
|
677
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
678
|
+
return void 0;
|
|
679
|
+
}
|
|
680
|
+
const match = trimmed.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
|
|
681
|
+
if (!match) {
|
|
682
|
+
return void 0;
|
|
683
|
+
}
|
|
684
|
+
const [, key, rawValue] = match;
|
|
685
|
+
return [key, normalizeRawEnvValue(rawValue.trim())];
|
|
686
|
+
}
|
|
687
|
+
function readProjectEnvEntries(cwd) {
|
|
688
|
+
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
689
|
+
const filenames = [
|
|
690
|
+
...PROJECT_ENV_FILENAMES,
|
|
691
|
+
...nodeEnv ? [`.env.${nodeEnv}`, `.env.${nodeEnv}.local`] : []
|
|
692
|
+
];
|
|
693
|
+
const entries = /* @__PURE__ */ new Map();
|
|
694
|
+
for (const filename of filenames) {
|
|
695
|
+
const absolutePath = path.resolve(cwd, filename);
|
|
696
|
+
if (!fs.existsSync(absolutePath)) {
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
const content = fs.readFileSync(absolutePath, "utf8");
|
|
700
|
+
const lines = content.split(/\r?\n/g);
|
|
701
|
+
for (const line of lines) {
|
|
702
|
+
const parsed = parseEnvLine(line);
|
|
703
|
+
if (!parsed) {
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
const [key, value] = parsed;
|
|
707
|
+
entries.set(key, value);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return entries;
|
|
711
|
+
}
|
|
712
|
+
function applyProjectEnv(cwd) {
|
|
713
|
+
const envEntries = readProjectEnvEntries(cwd);
|
|
714
|
+
if (envEntries.size === 0) {
|
|
715
|
+
return () => {
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
const initialKeys = new Set(
|
|
719
|
+
Object.keys(process.env).filter((key) => process.env[key] !== void 0)
|
|
720
|
+
);
|
|
721
|
+
const staged = /* @__PURE__ */ new Map();
|
|
722
|
+
for (const [key, value] of envEntries.entries()) {
|
|
723
|
+
if (initialKeys.has(key)) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
staged.set(key, value);
|
|
727
|
+
}
|
|
728
|
+
for (const [key, value] of staged.entries()) {
|
|
729
|
+
process.env[key] = value;
|
|
730
|
+
}
|
|
731
|
+
return () => {
|
|
732
|
+
for (const key of staged.keys()) {
|
|
733
|
+
delete process.env[key];
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
function readEnvStringValue(key) {
|
|
738
|
+
const value = process.env[key];
|
|
739
|
+
if (typeof value !== "string") {
|
|
740
|
+
return void 0;
|
|
741
|
+
}
|
|
742
|
+
const trimmed = value.trim();
|
|
743
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
744
|
+
}
|
|
745
|
+
function resolveFallbackValue(fallbackKeys) {
|
|
746
|
+
for (const key of fallbackKeys) {
|
|
747
|
+
const value = readEnvStringValue(key);
|
|
748
|
+
if (value) {
|
|
749
|
+
return value;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return void 0;
|
|
753
|
+
}
|
|
754
|
+
function normalizeOptionalString(value, fallbackKeys) {
|
|
755
|
+
if (typeof value === "string") {
|
|
756
|
+
const trimmed = value.trim();
|
|
757
|
+
if (trimmed.length > 0) {
|
|
758
|
+
return trimmed;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return resolveFallbackValue(fallbackKeys);
|
|
762
|
+
}
|
|
763
|
+
function normalizeRequiredString(value, fieldLabel, fallbackKeys) {
|
|
764
|
+
const resolved = normalizeOptionalString(value, fallbackKeys);
|
|
765
|
+
if (resolved) {
|
|
766
|
+
return resolved;
|
|
767
|
+
}
|
|
768
|
+
throw new Error(
|
|
769
|
+
`Generator config is missing ${fieldLabel}. Set ${fieldLabel} directly or provide one of: ${fallbackKeys.join(", ")}.`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
function applyPostgresPasswordFallback(connectionString) {
|
|
773
|
+
let parsedUrl;
|
|
774
|
+
try {
|
|
775
|
+
parsedUrl = new URL(connectionString);
|
|
776
|
+
} catch {
|
|
777
|
+
return connectionString;
|
|
778
|
+
}
|
|
779
|
+
if (!POSTGRES_PROTOCOLS.has(parsedUrl.protocol)) {
|
|
780
|
+
return connectionString;
|
|
781
|
+
}
|
|
782
|
+
if (!parsedUrl.username || parsedUrl.password) {
|
|
783
|
+
return connectionString;
|
|
784
|
+
}
|
|
785
|
+
const fallbackPassword = resolveFallbackValue(POSTGRES_PASSWORD_ENV_KEYS);
|
|
786
|
+
if (!fallbackPassword) {
|
|
787
|
+
return connectionString;
|
|
788
|
+
}
|
|
789
|
+
parsedUrl.password = fallbackPassword;
|
|
790
|
+
return parsedUrl.toString();
|
|
791
|
+
}
|
|
792
|
+
function normalizeBooleanFlag(rawValue, fallback) {
|
|
793
|
+
if (typeof rawValue === "boolean") {
|
|
794
|
+
return rawValue;
|
|
795
|
+
}
|
|
796
|
+
if (typeof rawValue === "string") {
|
|
797
|
+
return parseBooleanFlag(rawValue, fallback);
|
|
798
|
+
}
|
|
799
|
+
return fallback;
|
|
800
|
+
}
|
|
801
|
+
function normalizeFeatureFlags(input) {
|
|
802
|
+
return {
|
|
803
|
+
emitRelations: normalizeBooleanFlag(
|
|
804
|
+
input?.emitRelations,
|
|
805
|
+
DEFAULT_FEATURES.emitRelations
|
|
806
|
+
),
|
|
807
|
+
emitRegistry: normalizeBooleanFlag(
|
|
808
|
+
input?.emitRegistry,
|
|
809
|
+
DEFAULT_FEATURES.emitRegistry
|
|
810
|
+
)
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
function normalizeExperimentalFlags(input) {
|
|
814
|
+
return {
|
|
815
|
+
postgresGatewayIntrospection: normalizeBooleanFlag(
|
|
816
|
+
input?.postgresGatewayIntrospection,
|
|
817
|
+
DEFAULT_EXPERIMENTAL_FLAGS.postgresGatewayIntrospection
|
|
818
|
+
),
|
|
819
|
+
scyllaProviderContracts: normalizeBooleanFlag(
|
|
820
|
+
input?.scyllaProviderContracts,
|
|
821
|
+
DEFAULT_EXPERIMENTAL_FLAGS.scyllaProviderContracts
|
|
822
|
+
)
|
|
823
|
+
};
|
|
824
|
+
}
|
|
354
825
|
function normalizeOutputConfig(output) {
|
|
355
826
|
return {
|
|
356
827
|
targets: {
|
|
@@ -363,9 +834,41 @@ function normalizeOutputConfig(output) {
|
|
|
363
834
|
};
|
|
364
835
|
}
|
|
365
836
|
function normalizeProviderConfig(provider) {
|
|
366
|
-
if (provider.kind === "postgres") {
|
|
837
|
+
if (provider.kind === "postgres" && provider.mode === "direct") {
|
|
838
|
+
const connectionString = normalizeRequiredString(
|
|
839
|
+
provider.connectionString,
|
|
840
|
+
"provider.connectionString",
|
|
841
|
+
DIRECT_CONNECTION_STRING_ENV_KEYS
|
|
842
|
+
);
|
|
843
|
+
const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS);
|
|
844
|
+
return {
|
|
845
|
+
...provider,
|
|
846
|
+
connectionString: applyPostgresPasswordFallback(connectionString),
|
|
847
|
+
database,
|
|
848
|
+
schemas: normalizeSchemaSelection(provider.schemas)
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
if (provider.kind === "postgres" && provider.mode === "gateway") {
|
|
852
|
+
const gatewayUrl = normalizeRequiredString(
|
|
853
|
+
provider.gatewayUrl,
|
|
854
|
+
"provider.gatewayUrl",
|
|
855
|
+
GATEWAY_URL_ENV_KEYS
|
|
856
|
+
);
|
|
857
|
+
const apiKey = normalizeRequiredString(
|
|
858
|
+
provider.apiKey,
|
|
859
|
+
"provider.apiKey",
|
|
860
|
+
GATEWAY_API_KEY_ENV_KEYS
|
|
861
|
+
);
|
|
862
|
+
const database = normalizeRequiredString(
|
|
863
|
+
provider.database,
|
|
864
|
+
"provider.database",
|
|
865
|
+
POSTGRES_DATABASE_ENV_KEYS
|
|
866
|
+
);
|
|
367
867
|
return {
|
|
368
868
|
...provider,
|
|
869
|
+
gatewayUrl,
|
|
870
|
+
apiKey,
|
|
871
|
+
database,
|
|
369
872
|
schemas: normalizeSchemaSelection(provider.schemas)
|
|
370
873
|
};
|
|
371
874
|
}
|
|
@@ -386,14 +889,8 @@ function normalizeGeneratorConfig(input) {
|
|
|
386
889
|
...DEFAULT_NAMING,
|
|
387
890
|
...input.naming ?? {}
|
|
388
891
|
},
|
|
389
|
-
features:
|
|
390
|
-
|
|
391
|
-
...input.features ?? {}
|
|
392
|
-
},
|
|
393
|
-
experimental: {
|
|
394
|
-
...DEFAULT_EXPERIMENTAL_FLAGS,
|
|
395
|
-
...input.experimental ?? {}
|
|
396
|
-
}
|
|
892
|
+
features: normalizeFeatureFlags(input.features),
|
|
893
|
+
experimental: normalizeExperimentalFlags(input.experimental)
|
|
397
894
|
};
|
|
398
895
|
}
|
|
399
896
|
function findGeneratorConfigPath(cwd = process.cwd()) {
|
|
@@ -430,6 +927,11 @@ function extractConfigExport(module) {
|
|
|
430
927
|
if (moduleExports && typeof moduleExports === "object") {
|
|
431
928
|
queue.push(moduleExports);
|
|
432
929
|
}
|
|
930
|
+
for (const value of Object.values(record)) {
|
|
931
|
+
if (value && typeof value === "object") {
|
|
932
|
+
queue.push(value);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
433
935
|
}
|
|
434
936
|
throw new Error(
|
|
435
937
|
"Generator config file must export a config object as default export or `config`."
|
|
@@ -444,19 +946,24 @@ function importConfigModule(moduleSpecifier) {
|
|
|
444
946
|
}
|
|
445
947
|
async function loadGeneratorConfig(options = {}) {
|
|
446
948
|
const cwd = options.cwd ?? process.cwd();
|
|
949
|
+
const restoreProjectEnv = applyProjectEnv(cwd);
|
|
447
950
|
const resolvedPath = options.configPath ? path.resolve(cwd, options.configPath) : findGeneratorConfigPath(cwd);
|
|
448
951
|
if (!resolvedPath) {
|
|
449
952
|
throw new Error(
|
|
450
953
|
`No generator config found in ${cwd}. Expected one of: ${DEFAULT_CONFIG_CANDIDATES.join(", ")}`
|
|
451
954
|
);
|
|
452
955
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
956
|
+
try {
|
|
957
|
+
const moduleUrl = url.pathToFileURL(resolvedPath);
|
|
958
|
+
const module = await importConfigModule(`${moduleUrl.href}?cacheBust=${Date.now()}`);
|
|
959
|
+
const rawConfig = extractConfigExport(module);
|
|
960
|
+
return {
|
|
961
|
+
configPath: resolvedPath,
|
|
962
|
+
config: normalizeGeneratorConfig(rawConfig)
|
|
963
|
+
};
|
|
964
|
+
} finally {
|
|
965
|
+
restoreProjectEnv();
|
|
966
|
+
}
|
|
460
967
|
}
|
|
461
968
|
|
|
462
969
|
// src/generator/renderer.ts
|
|
@@ -598,13 +1105,65 @@ function assertNoDuplicatePaths(files) {
|
|
|
598
1105
|
[
|
|
599
1106
|
`Generator output collision detected for path: ${file.path}`,
|
|
600
1107
|
`Collision: ${existing.kind} and ${file.kind}.`,
|
|
601
|
-
"
|
|
1108
|
+
"Use explicit placeholders such as {model}, {model_kebab}, {schema}, or {schema_kebab} in output targets so each artifact resolves to a unique path."
|
|
602
1109
|
].join(" ")
|
|
603
1110
|
);
|
|
604
1111
|
}
|
|
605
1112
|
seen.set(file.path, file);
|
|
606
1113
|
}
|
|
607
1114
|
}
|
|
1115
|
+
function addSchemaSegmentToPath(pathValue, schemaName) {
|
|
1116
|
+
const normalizedPath = normalizePath(pathValue);
|
|
1117
|
+
const parsedPath = path.posix.parse(normalizedPath);
|
|
1118
|
+
const schemaSegment = applyNamingStyle(schemaName, "kebab");
|
|
1119
|
+
if (!schemaSegment) {
|
|
1120
|
+
return normalizedPath;
|
|
1121
|
+
}
|
|
1122
|
+
const dir = parsedPath.dir.length > 0 ? `${parsedPath.dir}/${schemaSegment}` : schemaSegment;
|
|
1123
|
+
return normalizePath(path.posix.join(dir, parsedPath.base));
|
|
1124
|
+
}
|
|
1125
|
+
function scopeDuplicateDescriptorPathsBySchema(descriptors) {
|
|
1126
|
+
const nextDescriptors = descriptors.map((descriptor) => ({ ...descriptor }));
|
|
1127
|
+
const duplicates = /* @__PURE__ */ new Map();
|
|
1128
|
+
for (let index = 0; index < nextDescriptors.length; index += 1) {
|
|
1129
|
+
const descriptor = nextDescriptors[index];
|
|
1130
|
+
const indexes = duplicates.get(descriptor.filePath) ?? [];
|
|
1131
|
+
indexes.push(index);
|
|
1132
|
+
duplicates.set(descriptor.filePath, indexes);
|
|
1133
|
+
}
|
|
1134
|
+
let appliedSchemaScoping = false;
|
|
1135
|
+
for (const indexes of duplicates.values()) {
|
|
1136
|
+
if (indexes.length <= 1) {
|
|
1137
|
+
continue;
|
|
1138
|
+
}
|
|
1139
|
+
const schemaNames = new Set(indexes.map((index) => nextDescriptors[index].schemaName));
|
|
1140
|
+
if (schemaNames.size <= 1) {
|
|
1141
|
+
continue;
|
|
1142
|
+
}
|
|
1143
|
+
for (const index of indexes) {
|
|
1144
|
+
const descriptor = nextDescriptors[index];
|
|
1145
|
+
descriptor.filePath = addSchemaSegmentToPath(descriptor.filePath, descriptor.schemaName);
|
|
1146
|
+
}
|
|
1147
|
+
appliedSchemaScoping = true;
|
|
1148
|
+
}
|
|
1149
|
+
if (!appliedSchemaScoping) {
|
|
1150
|
+
return nextDescriptors;
|
|
1151
|
+
}
|
|
1152
|
+
const normalizedPaths = /* @__PURE__ */ new Set();
|
|
1153
|
+
for (const descriptor of nextDescriptors) {
|
|
1154
|
+
if (normalizedPaths.has(descriptor.filePath)) {
|
|
1155
|
+
throw new Error(
|
|
1156
|
+
[
|
|
1157
|
+
`Generator output collision detected for path: ${descriptor.filePath}`,
|
|
1158
|
+
"Automatic schema path scoping was applied but collisions remain.",
|
|
1159
|
+
"Add explicit placeholders such as {model}, {model_kebab}, {schema}, or {schema_kebab} to your output targets."
|
|
1160
|
+
].join(" ")
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
normalizedPaths.add(descriptor.filePath);
|
|
1164
|
+
}
|
|
1165
|
+
return nextDescriptors;
|
|
1166
|
+
}
|
|
608
1167
|
var ArtifactComposer = class {
|
|
609
1168
|
constructor(snapshot, config) {
|
|
610
1169
|
this.snapshot = snapshot;
|
|
@@ -643,7 +1202,8 @@ var ArtifactComposer = class {
|
|
|
643
1202
|
});
|
|
644
1203
|
}
|
|
645
1204
|
}
|
|
646
|
-
const
|
|
1205
|
+
const scopedModelDescriptors = scopeDuplicateDescriptorPathsBySchema(modelDescriptors);
|
|
1206
|
+
let schemaDescriptors = Object.keys(this.snapshot.schemas).sort().map((schemaName) => {
|
|
647
1207
|
const schemaPath = normalizePath(
|
|
648
1208
|
renderOutputPath(this.config.output.targets.schema, {
|
|
649
1209
|
provider: providerName,
|
|
@@ -661,9 +1221,10 @@ var ArtifactComposer = class {
|
|
|
661
1221
|
this.config.naming.schemaConst,
|
|
662
1222
|
"schema"
|
|
663
1223
|
),
|
|
664
|
-
models:
|
|
1224
|
+
models: scopedModelDescriptors.filter((model) => model.schemaName === schemaName)
|
|
665
1225
|
};
|
|
666
1226
|
});
|
|
1227
|
+
schemaDescriptors = scopeDuplicateDescriptorPathsBySchema(schemaDescriptors);
|
|
667
1228
|
const databasePath = normalizePath(
|
|
668
1229
|
renderOutputPath(this.config.output.targets.database, {
|
|
669
1230
|
provider: providerName,
|
|
@@ -683,7 +1244,7 @@ var ArtifactComposer = class {
|
|
|
683
1244
|
schemas: schemaDescriptors
|
|
684
1245
|
};
|
|
685
1246
|
const files = [];
|
|
686
|
-
for (const modelDescriptor of
|
|
1247
|
+
for (const modelDescriptor of scopedModelDescriptors) {
|
|
687
1248
|
files.push(renderModelArtifact(this.snapshot, modelDescriptor, this.config));
|
|
688
1249
|
}
|
|
689
1250
|
for (const schemaDescriptor of schemaDescriptors) {
|
|
@@ -722,63 +1283,6 @@ function generateArtifactsFromSnapshot(snapshot, config) {
|
|
|
722
1283
|
return new ArtifactComposer(snapshot, normalizedConfig).compose();
|
|
723
1284
|
}
|
|
724
1285
|
|
|
725
|
-
// src/gateway/errors.ts
|
|
726
|
-
var AthenaGatewayError = class _AthenaGatewayError extends Error {
|
|
727
|
-
code;
|
|
728
|
-
status;
|
|
729
|
-
endpoint;
|
|
730
|
-
method;
|
|
731
|
-
requestId;
|
|
732
|
-
hint;
|
|
733
|
-
causeDetail;
|
|
734
|
-
constructor(input) {
|
|
735
|
-
super(input.message);
|
|
736
|
-
this.name = "AthenaGatewayError";
|
|
737
|
-
this.code = input.code;
|
|
738
|
-
this.status = input.status ?? 0;
|
|
739
|
-
this.endpoint = input.endpoint;
|
|
740
|
-
this.method = input.method;
|
|
741
|
-
this.requestId = input.requestId;
|
|
742
|
-
this.hint = input.hint;
|
|
743
|
-
this.causeDetail = input.cause;
|
|
744
|
-
}
|
|
745
|
-
toDetails() {
|
|
746
|
-
return {
|
|
747
|
-
code: this.code,
|
|
748
|
-
message: this.message,
|
|
749
|
-
status: this.status,
|
|
750
|
-
endpoint: this.endpoint,
|
|
751
|
-
method: this.method,
|
|
752
|
-
requestId: this.requestId,
|
|
753
|
-
hint: this.hint,
|
|
754
|
-
cause: this.causeDetail
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
static fromResponse(response, fallback) {
|
|
758
|
-
const details = response.errorDetails;
|
|
759
|
-
if (details) {
|
|
760
|
-
return new _AthenaGatewayError({
|
|
761
|
-
code: details.code,
|
|
762
|
-
message: details.message,
|
|
763
|
-
status: details.status,
|
|
764
|
-
endpoint: details.endpoint ?? fallback.endpoint,
|
|
765
|
-
method: details.method ?? fallback.method,
|
|
766
|
-
requestId: details.requestId ?? fallback.requestId,
|
|
767
|
-
hint: details.hint,
|
|
768
|
-
cause: details.cause
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
return new _AthenaGatewayError({
|
|
772
|
-
code: "HTTP_ERROR",
|
|
773
|
-
message: response.error ?? "Gateway request failed",
|
|
774
|
-
status: response.status,
|
|
775
|
-
endpoint: fallback.endpoint,
|
|
776
|
-
method: fallback.method,
|
|
777
|
-
requestId: fallback.requestId
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
};
|
|
781
|
-
|
|
782
1286
|
// src/gateway/client.ts
|
|
783
1287
|
var DEFAULT_BASE_URL = "https://athena-db.com";
|
|
784
1288
|
var DEFAULT_CLIENT = "railway_direct";
|
|
@@ -804,14 +1308,14 @@ function parseResponseBody(rawText, contentType) {
|
|
|
804
1308
|
function normalizeHeaderValue(value) {
|
|
805
1309
|
return value ? value : void 0;
|
|
806
1310
|
}
|
|
807
|
-
function
|
|
1311
|
+
function isRecord2(value) {
|
|
808
1312
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
809
1313
|
}
|
|
810
1314
|
function resolveRequestId(headers) {
|
|
811
1315
|
return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
|
|
812
1316
|
}
|
|
813
1317
|
function resolveErrorMessage(payload, fallback) {
|
|
814
|
-
if (
|
|
1318
|
+
if (isRecord2(payload)) {
|
|
815
1319
|
const messageCandidates = [payload.error, payload.message, payload.details];
|
|
816
1320
|
for (const candidate of messageCandidates) {
|
|
817
1321
|
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
@@ -1001,7 +1505,7 @@ async function callAthena(config, endpoint, method, payload, options) {
|
|
|
1001
1505
|
};
|
|
1002
1506
|
}
|
|
1003
1507
|
const parsed = parsedBody.parsed;
|
|
1004
|
-
const parsedPayload =
|
|
1508
|
+
const parsedPayload = isRecord2(parsed) ? parsed : null;
|
|
1005
1509
|
if (!response.ok) {
|
|
1006
1510
|
const httpError = new AthenaGatewayError({
|
|
1007
1511
|
code: "HTTP_ERROR",
|
|
@@ -1084,126 +1588,1196 @@ function createAthenaGatewayClient(config = {}) {
|
|
|
1084
1588
|
}
|
|
1085
1589
|
};
|
|
1086
1590
|
}
|
|
1087
|
-
|
|
1088
|
-
// src/sql-identifiers.ts
|
|
1089
|
-
var SIMPLE_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1090
|
-
var COMPOSITE_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
1091
|
-
var ALIAS_PATTERN = /^([A-Za-z_][A-Za-z0-9_.]*)\s+(?:as\s+)?([A-Za-z_][A-Za-z0-9_]*)$/i;
|
|
1092
|
-
function quoteIdentifierSegment(identifier) {
|
|
1093
|
-
return `"${identifier.replace(/"/g, '""')}"`;
|
|
1591
|
+
|
|
1592
|
+
// src/sql-identifiers.ts
|
|
1593
|
+
var SIMPLE_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1594
|
+
var COMPOSITE_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
1595
|
+
var ALIAS_PATTERN = /^([A-Za-z_][A-Za-z0-9_.]*)\s+(?:as\s+)?([A-Za-z_][A-Za-z0-9_]*)$/i;
|
|
1596
|
+
function quoteIdentifierSegment(identifier) {
|
|
1597
|
+
return `"${identifier.replace(/"/g, '""')}"`;
|
|
1598
|
+
}
|
|
1599
|
+
function quoteQualifiedIdentifier(identifier) {
|
|
1600
|
+
return identifier.split(".").map((segment) => quoteIdentifierSegment(segment)).join(".");
|
|
1601
|
+
}
|
|
1602
|
+
function quoteSelectToken(token) {
|
|
1603
|
+
if (token === "*") return token;
|
|
1604
|
+
if (COMPOSITE_IDENTIFIER_PATTERN.test(token)) {
|
|
1605
|
+
return quoteQualifiedIdentifier(token);
|
|
1606
|
+
}
|
|
1607
|
+
const aliasMatch = ALIAS_PATTERN.exec(token);
|
|
1608
|
+
if (!aliasMatch) {
|
|
1609
|
+
return token;
|
|
1610
|
+
}
|
|
1611
|
+
const [, baseIdentifier, aliasIdentifier] = aliasMatch;
|
|
1612
|
+
if (!COMPOSITE_IDENTIFIER_PATTERN.test(baseIdentifier) || !SIMPLE_IDENTIFIER_PATTERN.test(aliasIdentifier)) {
|
|
1613
|
+
return token;
|
|
1614
|
+
}
|
|
1615
|
+
return `${quoteQualifiedIdentifier(baseIdentifier)} AS ${quoteIdentifierSegment(aliasIdentifier)}`;
|
|
1616
|
+
}
|
|
1617
|
+
function canAutoQuoteToken(token) {
|
|
1618
|
+
if (token === "*") return true;
|
|
1619
|
+
if (COMPOSITE_IDENTIFIER_PATTERN.test(token)) return true;
|
|
1620
|
+
const aliasMatch = ALIAS_PATTERN.exec(token);
|
|
1621
|
+
if (!aliasMatch) return false;
|
|
1622
|
+
const [, baseIdentifier, aliasIdentifier] = aliasMatch;
|
|
1623
|
+
return COMPOSITE_IDENTIFIER_PATTERN.test(baseIdentifier) && SIMPLE_IDENTIFIER_PATTERN.test(aliasIdentifier);
|
|
1624
|
+
}
|
|
1625
|
+
function splitTopLevelCommaSeparated(input) {
|
|
1626
|
+
const parts = [];
|
|
1627
|
+
let buffer = "";
|
|
1628
|
+
let singleQuoted = false;
|
|
1629
|
+
let doubleQuoted = false;
|
|
1630
|
+
let depth = 0;
|
|
1631
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
1632
|
+
const char = input[index];
|
|
1633
|
+
const next = index + 1 < input.length ? input[index + 1] : "";
|
|
1634
|
+
if (singleQuoted) {
|
|
1635
|
+
buffer += char;
|
|
1636
|
+
if (char === "'" && next === "'") {
|
|
1637
|
+
buffer += next;
|
|
1638
|
+
index += 1;
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
if (char === "'") {
|
|
1642
|
+
singleQuoted = false;
|
|
1643
|
+
}
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
if (doubleQuoted) {
|
|
1647
|
+
buffer += char;
|
|
1648
|
+
if (char === '"' && next === '"') {
|
|
1649
|
+
buffer += next;
|
|
1650
|
+
index += 1;
|
|
1651
|
+
continue;
|
|
1652
|
+
}
|
|
1653
|
+
if (char === '"') {
|
|
1654
|
+
doubleQuoted = false;
|
|
1655
|
+
}
|
|
1656
|
+
continue;
|
|
1657
|
+
}
|
|
1658
|
+
if (char === "'") {
|
|
1659
|
+
singleQuoted = true;
|
|
1660
|
+
buffer += char;
|
|
1661
|
+
continue;
|
|
1662
|
+
}
|
|
1663
|
+
if (char === '"') {
|
|
1664
|
+
doubleQuoted = true;
|
|
1665
|
+
buffer += char;
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
if (char === "(") {
|
|
1669
|
+
depth += 1;
|
|
1670
|
+
buffer += char;
|
|
1671
|
+
continue;
|
|
1672
|
+
}
|
|
1673
|
+
if (char === ")") {
|
|
1674
|
+
depth -= 1;
|
|
1675
|
+
if (depth < 0) return null;
|
|
1676
|
+
buffer += char;
|
|
1677
|
+
continue;
|
|
1678
|
+
}
|
|
1679
|
+
if (char === "," && depth === 0) {
|
|
1680
|
+
parts.push(buffer.trim());
|
|
1681
|
+
buffer = "";
|
|
1682
|
+
continue;
|
|
1683
|
+
}
|
|
1684
|
+
buffer += char;
|
|
1685
|
+
}
|
|
1686
|
+
if (singleQuoted || doubleQuoted || depth !== 0) {
|
|
1687
|
+
return null;
|
|
1688
|
+
}
|
|
1689
|
+
if (buffer.trim().length > 0) {
|
|
1690
|
+
parts.push(buffer.trim());
|
|
1691
|
+
}
|
|
1692
|
+
return parts;
|
|
1693
|
+
}
|
|
1694
|
+
function quoteSelectColumnsExpression(columns) {
|
|
1695
|
+
const trimmed = columns.trim();
|
|
1696
|
+
if (!trimmed || trimmed === "*") return trimmed || "*";
|
|
1697
|
+
const tokens = splitTopLevelCommaSeparated(trimmed);
|
|
1698
|
+
if (!tokens || tokens.length === 0) {
|
|
1699
|
+
return trimmed;
|
|
1700
|
+
}
|
|
1701
|
+
if (!tokens.every(canAutoQuoteToken)) {
|
|
1702
|
+
return trimmed;
|
|
1703
|
+
}
|
|
1704
|
+
return tokens.map(quoteSelectToken).join(", ");
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// src/auth/client.ts
|
|
1708
|
+
var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
|
|
1709
|
+
var FALLBACK_SDK_VERSION2 = "1.0.0";
|
|
1710
|
+
var SDK_NAME2 = "xylex-group/athena-auth";
|
|
1711
|
+
var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
|
|
1712
|
+
var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
|
|
1713
|
+
function normalizeBaseUrl(baseUrl) {
|
|
1714
|
+
return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
|
|
1715
|
+
}
|
|
1716
|
+
function isRecord3(value) {
|
|
1717
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1718
|
+
}
|
|
1719
|
+
function normalizeHeaderValue2(value) {
|
|
1720
|
+
return value ? value : void 0;
|
|
1721
|
+
}
|
|
1722
|
+
function parseResponseBody2(rawText, contentType) {
|
|
1723
|
+
if (!rawText) {
|
|
1724
|
+
return { parsed: null, parseFailed: false };
|
|
1725
|
+
}
|
|
1726
|
+
const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
|
|
1727
|
+
const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
|
|
1728
|
+
if (!looksJson) {
|
|
1729
|
+
return { parsed: rawText, parseFailed: false };
|
|
1730
|
+
}
|
|
1731
|
+
try {
|
|
1732
|
+
return { parsed: JSON.parse(rawText), parseFailed: false };
|
|
1733
|
+
} catch {
|
|
1734
|
+
return { parsed: rawText, parseFailed: true };
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
function resolveRequestId2(headers) {
|
|
1738
|
+
return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
|
|
1739
|
+
}
|
|
1740
|
+
function resolveErrorMessage2(payload, fallback) {
|
|
1741
|
+
if (isRecord3(payload)) {
|
|
1742
|
+
const messageCandidates = [payload.error, payload.message, payload.details];
|
|
1743
|
+
for (const candidate of messageCandidates) {
|
|
1744
|
+
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
1745
|
+
return candidate.trim();
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
if (typeof payload === "string" && payload.trim().length > 0) {
|
|
1750
|
+
return payload.trim();
|
|
1751
|
+
}
|
|
1752
|
+
return fallback;
|
|
1753
|
+
}
|
|
1754
|
+
function toErrorDetails(input) {
|
|
1755
|
+
return {
|
|
1756
|
+
code: input.code,
|
|
1757
|
+
message: input.message,
|
|
1758
|
+
status: input.status,
|
|
1759
|
+
endpoint: input.endpoint,
|
|
1760
|
+
method: input.method,
|
|
1761
|
+
requestId: input.requestId,
|
|
1762
|
+
hint: input.hint,
|
|
1763
|
+
cause: input.cause
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
function mergeCallOptions(base, override) {
|
|
1767
|
+
if (!base && !override) return void 0;
|
|
1768
|
+
return {
|
|
1769
|
+
...base,
|
|
1770
|
+
...override,
|
|
1771
|
+
headers: {
|
|
1772
|
+
...base?.headers ?? {},
|
|
1773
|
+
...override?.headers ?? {}
|
|
1774
|
+
}
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
function extractFetchOptions(input) {
|
|
1778
|
+
if (!input) {
|
|
1779
|
+
return {
|
|
1780
|
+
payload: void 0,
|
|
1781
|
+
fetchOptions: void 0
|
|
1782
|
+
};
|
|
1783
|
+
}
|
|
1784
|
+
const { fetchOptions, ...rest } = input;
|
|
1785
|
+
const hasPayloadKeys = Object.keys(rest).length > 0;
|
|
1786
|
+
return {
|
|
1787
|
+
payload: hasPayloadKeys ? rest : void 0,
|
|
1788
|
+
fetchOptions
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
function buildHeaders2(config, options) {
|
|
1792
|
+
const headers = {
|
|
1793
|
+
"Content-Type": "application/json",
|
|
1794
|
+
"X-Athena-Sdk": SDK_HEADER_VALUE2
|
|
1795
|
+
};
|
|
1796
|
+
const apiKey = options?.apiKey ?? config.apiKey;
|
|
1797
|
+
if (apiKey) {
|
|
1798
|
+
headers.apikey = apiKey;
|
|
1799
|
+
headers["x-api-key"] = apiKey;
|
|
1800
|
+
}
|
|
1801
|
+
const bearerToken = options?.bearerToken ?? config.bearerToken;
|
|
1802
|
+
if (bearerToken) {
|
|
1803
|
+
headers.Authorization = `Bearer ${bearerToken}`;
|
|
1804
|
+
}
|
|
1805
|
+
const mergedExtraHeaders = {
|
|
1806
|
+
...config.headers ?? {},
|
|
1807
|
+
...options?.headers ?? {}
|
|
1808
|
+
};
|
|
1809
|
+
Object.entries(mergedExtraHeaders).forEach(([key, value]) => {
|
|
1810
|
+
const normalized = normalizeHeaderValue2(value);
|
|
1811
|
+
if (normalized) {
|
|
1812
|
+
headers[key] = normalized;
|
|
1813
|
+
}
|
|
1814
|
+
});
|
|
1815
|
+
return headers;
|
|
1816
|
+
}
|
|
1817
|
+
function appendQueryParam(searchParams, key, value) {
|
|
1818
|
+
if (value === void 0 || value === null) return;
|
|
1819
|
+
if (Array.isArray(value)) {
|
|
1820
|
+
value.forEach((item) => {
|
|
1821
|
+
searchParams.append(key, String(item));
|
|
1822
|
+
});
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
searchParams.append(key, String(value));
|
|
1826
|
+
}
|
|
1827
|
+
function buildRequestUrl(baseUrl, endpoint, query) {
|
|
1828
|
+
const url = `${baseUrl}${endpoint}`;
|
|
1829
|
+
if (!query || Object.keys(query).length === 0) return url;
|
|
1830
|
+
const searchParams = new URLSearchParams();
|
|
1831
|
+
Object.entries(query).forEach(([key, value]) => appendQueryParam(searchParams, key, value));
|
|
1832
|
+
const queryText = searchParams.toString();
|
|
1833
|
+
return queryText ? `${url}?${queryText}` : url;
|
|
1834
|
+
}
|
|
1835
|
+
function inferDefaultMethod(endpoint) {
|
|
1836
|
+
if (endpoint.startsWith("/reset-password/")) {
|
|
1837
|
+
return "GET";
|
|
1838
|
+
}
|
|
1839
|
+
switch (endpoint) {
|
|
1840
|
+
case "/get-session":
|
|
1841
|
+
case "/list-sessions":
|
|
1842
|
+
case "/verify-email":
|
|
1843
|
+
case "/change-email/verify":
|
|
1844
|
+
case "/delete-user/verify":
|
|
1845
|
+
case "/email-list":
|
|
1846
|
+
case "/email/list":
|
|
1847
|
+
case "/delete-user/callback":
|
|
1848
|
+
case "/list-accounts":
|
|
1849
|
+
case "/passkey/generate-register-options":
|
|
1850
|
+
case "/passkey/list-user-passkeys":
|
|
1851
|
+
case "/.well-known/webauthn":
|
|
1852
|
+
case "/admin/list-users":
|
|
1853
|
+
case "/admin/athena-client/list":
|
|
1854
|
+
case "/admin/audit-log/list":
|
|
1855
|
+
case "/admin/email/get":
|
|
1856
|
+
case "/admin/email-failure/list":
|
|
1857
|
+
case "/admin/email-failure/get":
|
|
1858
|
+
case "/admin/email-template/get":
|
|
1859
|
+
case "/admin/email-template/list":
|
|
1860
|
+
case "/admin/email/list":
|
|
1861
|
+
case "/api-key/get":
|
|
1862
|
+
case "/api-key/list":
|
|
1863
|
+
case "/organization/get-full-organization":
|
|
1864
|
+
case "/organization/list":
|
|
1865
|
+
case "/organization/get-invitation":
|
|
1866
|
+
case "/organization/list-invitations":
|
|
1867
|
+
case "/organization/list-user-invitations":
|
|
1868
|
+
case "/organization/list-members":
|
|
1869
|
+
case "/organization/get-active-member":
|
|
1870
|
+
case "/health":
|
|
1871
|
+
case "/ok":
|
|
1872
|
+
case "/error":
|
|
1873
|
+
return "GET";
|
|
1874
|
+
default:
|
|
1875
|
+
return "POST";
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
async function callAuthEndpoint(config, context, body, query, options) {
|
|
1879
|
+
const baseUrl = normalizeBaseUrl(options?.baseUrl ?? config.baseUrl);
|
|
1880
|
+
const url = buildRequestUrl(baseUrl, context.endpoint, query);
|
|
1881
|
+
const headers = buildHeaders2(config, options);
|
|
1882
|
+
const credentials = options?.credentials ?? config.credentials ?? "include";
|
|
1883
|
+
const requestInit = {
|
|
1884
|
+
method: context.method,
|
|
1885
|
+
headers,
|
|
1886
|
+
credentials,
|
|
1887
|
+
signal: options?.signal
|
|
1888
|
+
};
|
|
1889
|
+
if (context.method !== "GET") {
|
|
1890
|
+
requestInit.body = JSON.stringify(body ?? {});
|
|
1891
|
+
}
|
|
1892
|
+
const fetcher = config.fetch ?? globalThis.fetch;
|
|
1893
|
+
if (!fetcher) {
|
|
1894
|
+
const details = toErrorDetails({
|
|
1895
|
+
code: "UNKNOWN_ERROR",
|
|
1896
|
+
message: "No fetch implementation available for auth client",
|
|
1897
|
+
status: 0,
|
|
1898
|
+
endpoint: context.endpoint,
|
|
1899
|
+
method: context.method,
|
|
1900
|
+
hint: "Use Node 18+ or provide `fetch` via createClient(..., { auth: { fetch } }) or createAuthClient({ fetch })"
|
|
1901
|
+
});
|
|
1902
|
+
return {
|
|
1903
|
+
ok: false,
|
|
1904
|
+
status: 0,
|
|
1905
|
+
data: null,
|
|
1906
|
+
error: details.message,
|
|
1907
|
+
errorDetails: details,
|
|
1908
|
+
raw: null
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
try {
|
|
1912
|
+
const response = await fetcher(url, requestInit);
|
|
1913
|
+
const rawText = await response.text();
|
|
1914
|
+
const requestId = resolveRequestId2(response.headers);
|
|
1915
|
+
const parsedBody = parseResponseBody2(rawText ?? "", response.headers.get("content-type"));
|
|
1916
|
+
if (parsedBody.parseFailed) {
|
|
1917
|
+
const details = toErrorDetails({
|
|
1918
|
+
code: "INVALID_JSON",
|
|
1919
|
+
message: "Auth server returned malformed JSON",
|
|
1920
|
+
status: response.status,
|
|
1921
|
+
endpoint: context.endpoint,
|
|
1922
|
+
method: context.method,
|
|
1923
|
+
requestId,
|
|
1924
|
+
hint: "Verify the auth endpoint response body is valid JSON.",
|
|
1925
|
+
cause: rawText.slice(0, 300)
|
|
1926
|
+
});
|
|
1927
|
+
return {
|
|
1928
|
+
ok: false,
|
|
1929
|
+
status: response.status,
|
|
1930
|
+
data: null,
|
|
1931
|
+
error: details.message,
|
|
1932
|
+
errorDetails: details,
|
|
1933
|
+
raw: parsedBody.parsed
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
const parsed = parsedBody.parsed;
|
|
1937
|
+
if (!response.ok) {
|
|
1938
|
+
const details = toErrorDetails({
|
|
1939
|
+
code: "HTTP_ERROR",
|
|
1940
|
+
message: resolveErrorMessage2(
|
|
1941
|
+
parsed,
|
|
1942
|
+
`Auth endpoint ${context.method} ${context.endpoint} failed with status ${response.status}`
|
|
1943
|
+
),
|
|
1944
|
+
status: response.status,
|
|
1945
|
+
endpoint: context.endpoint,
|
|
1946
|
+
method: context.method,
|
|
1947
|
+
requestId
|
|
1948
|
+
});
|
|
1949
|
+
return {
|
|
1950
|
+
ok: false,
|
|
1951
|
+
status: response.status,
|
|
1952
|
+
data: null,
|
|
1953
|
+
error: details.message,
|
|
1954
|
+
errorDetails: details,
|
|
1955
|
+
raw: parsed
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
return {
|
|
1959
|
+
ok: true,
|
|
1960
|
+
status: response.status,
|
|
1961
|
+
data: parsed ?? null,
|
|
1962
|
+
error: null,
|
|
1963
|
+
errorDetails: null,
|
|
1964
|
+
raw: parsed
|
|
1965
|
+
};
|
|
1966
|
+
} catch (callError) {
|
|
1967
|
+
const message = callError instanceof Error ? callError.message : String(callError);
|
|
1968
|
+
const details = toErrorDetails({
|
|
1969
|
+
code: "NETWORK_ERROR",
|
|
1970
|
+
message: `Network error while calling ${context.method} ${context.endpoint}: ${message}`,
|
|
1971
|
+
status: 0,
|
|
1972
|
+
endpoint: context.endpoint,
|
|
1973
|
+
method: context.method,
|
|
1974
|
+
cause: message,
|
|
1975
|
+
hint: "Check auth server URL, DNS, and network reachability."
|
|
1976
|
+
});
|
|
1977
|
+
return {
|
|
1978
|
+
ok: false,
|
|
1979
|
+
status: 0,
|
|
1980
|
+
data: null,
|
|
1981
|
+
error: details.message,
|
|
1982
|
+
errorDetails: details,
|
|
1983
|
+
raw: null
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
function executePostWithCompatibleInput(config, context, input, options) {
|
|
1988
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
1989
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
1990
|
+
return callAuthEndpoint(config, context, payload ?? {}, void 0, mergedOptions);
|
|
1094
1991
|
}
|
|
1095
|
-
function
|
|
1096
|
-
|
|
1992
|
+
function executePostWithOptionalInput(config, context, input, options) {
|
|
1993
|
+
const { fetchOptions } = extractFetchOptions(input);
|
|
1994
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
1995
|
+
return callAuthEndpoint(config, context, {}, void 0, mergedOptions);
|
|
1097
1996
|
}
|
|
1098
|
-
function
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
}
|
|
1103
|
-
const aliasMatch = ALIAS_PATTERN.exec(token);
|
|
1104
|
-
if (!aliasMatch) {
|
|
1105
|
-
return token;
|
|
1106
|
-
}
|
|
1107
|
-
const [, baseIdentifier, aliasIdentifier] = aliasMatch;
|
|
1108
|
-
if (!COMPOSITE_IDENTIFIER_PATTERN.test(baseIdentifier) || !SIMPLE_IDENTIFIER_PATTERN.test(aliasIdentifier)) {
|
|
1109
|
-
return token;
|
|
1110
|
-
}
|
|
1111
|
-
return `${quoteQualifiedIdentifier(baseIdentifier)} AS ${quoteIdentifierSegment(aliasIdentifier)}`;
|
|
1997
|
+
function executeGetWithCompatibleInput(config, context, input, options) {
|
|
1998
|
+
const { fetchOptions } = extractFetchOptions(input);
|
|
1999
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
2000
|
+
return callAuthEndpoint(config, context, void 0, void 0, mergedOptions);
|
|
1112
2001
|
}
|
|
1113
|
-
function
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
2002
|
+
function executeGetWithQueryCompatibleInput(config, context, input, options) {
|
|
2003
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2004
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
2005
|
+
const query = payload?.query;
|
|
2006
|
+
return callAuthEndpoint(
|
|
2007
|
+
config,
|
|
2008
|
+
context,
|
|
2009
|
+
void 0,
|
|
2010
|
+
query,
|
|
2011
|
+
mergedOptions
|
|
2012
|
+
);
|
|
1120
2013
|
}
|
|
1121
|
-
function
|
|
1122
|
-
const
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
const
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
2014
|
+
function createAuthClient(config = {}) {
|
|
2015
|
+
const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
|
|
2016
|
+
const resolvedConfig = {
|
|
2017
|
+
...config,
|
|
2018
|
+
baseUrl: normalizedBaseUrl
|
|
2019
|
+
};
|
|
2020
|
+
const request = (input, options) => {
|
|
2021
|
+
const method = input.method ?? (input.body !== void 0 ? "POST" : inferDefaultMethod(input.endpoint));
|
|
2022
|
+
const mergedOptions = mergeCallOptions(input.fetchOptions, options);
|
|
2023
|
+
return callAuthEndpoint(
|
|
2024
|
+
resolvedConfig,
|
|
2025
|
+
{ endpoint: input.endpoint, method },
|
|
2026
|
+
input.body,
|
|
2027
|
+
input.query,
|
|
2028
|
+
mergedOptions
|
|
2029
|
+
);
|
|
2030
|
+
};
|
|
2031
|
+
const postGeneric = (endpoint, input, options) => {
|
|
2032
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2033
|
+
return request(
|
|
2034
|
+
{
|
|
2035
|
+
endpoint,
|
|
2036
|
+
method: "POST",
|
|
2037
|
+
body: payload ?? {},
|
|
2038
|
+
fetchOptions
|
|
2039
|
+
},
|
|
2040
|
+
options
|
|
2041
|
+
);
|
|
2042
|
+
};
|
|
2043
|
+
const getGeneric = (endpoint, input, options) => {
|
|
2044
|
+
const { fetchOptions } = extractFetchOptions(input);
|
|
2045
|
+
return request(
|
|
2046
|
+
{
|
|
2047
|
+
endpoint,
|
|
2048
|
+
method: "GET",
|
|
2049
|
+
fetchOptions
|
|
2050
|
+
},
|
|
2051
|
+
options
|
|
2052
|
+
);
|
|
2053
|
+
};
|
|
2054
|
+
const getWithQuery = (endpoint, input, options) => {
|
|
2055
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2056
|
+
const query = payload?.query;
|
|
2057
|
+
return request(
|
|
2058
|
+
{
|
|
2059
|
+
endpoint,
|
|
2060
|
+
method: "GET",
|
|
2061
|
+
query,
|
|
2062
|
+
fetchOptions
|
|
2063
|
+
},
|
|
2064
|
+
options
|
|
2065
|
+
);
|
|
2066
|
+
};
|
|
2067
|
+
const listUserEmailsWithFallback = async (input, options) => {
|
|
2068
|
+
const primary = await getWithQuery(
|
|
2069
|
+
"/email/list",
|
|
2070
|
+
input,
|
|
2071
|
+
options
|
|
2072
|
+
);
|
|
2073
|
+
if (primary.ok || primary.status !== 404 || primary.errorDetails?.code !== "HTTP_ERROR") {
|
|
2074
|
+
return primary;
|
|
2075
|
+
}
|
|
2076
|
+
return getWithQuery(
|
|
2077
|
+
"/email-list",
|
|
2078
|
+
input,
|
|
2079
|
+
options
|
|
2080
|
+
);
|
|
2081
|
+
};
|
|
2082
|
+
const healthWithFallback = async (input, options) => {
|
|
2083
|
+
const primary = await getGeneric("/health", input, options);
|
|
2084
|
+
if (primary.ok || primary.status !== 404 || primary.errorDetails?.code !== "HTTP_ERROR") {
|
|
2085
|
+
return primary;
|
|
2086
|
+
}
|
|
2087
|
+
const fallback = await getGeneric("/ok", input, options);
|
|
2088
|
+
if (!fallback.ok) {
|
|
2089
|
+
return {
|
|
2090
|
+
...fallback,
|
|
2091
|
+
data: null
|
|
2092
|
+
};
|
|
2093
|
+
}
|
|
2094
|
+
const fallbackStatus = isRecord3(fallback.data) && typeof fallback.data.ok === "boolean" ? fallback.data.ok ? "ok" : "error" : "ok";
|
|
2095
|
+
return {
|
|
2096
|
+
...fallback,
|
|
2097
|
+
data: {
|
|
2098
|
+
status: fallbackStatus
|
|
1136
2099
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
2100
|
+
};
|
|
2101
|
+
};
|
|
2102
|
+
const signOut = (input, options) => executePostWithOptionalInput(
|
|
2103
|
+
resolvedConfig,
|
|
2104
|
+
{ endpoint: "/sign-out", method: "POST" },
|
|
2105
|
+
input,
|
|
2106
|
+
options
|
|
2107
|
+
);
|
|
2108
|
+
const revokeSessions = (input, options) => executePostWithOptionalInput(
|
|
2109
|
+
resolvedConfig,
|
|
2110
|
+
{ endpoint: "/revoke-sessions", method: "POST" },
|
|
2111
|
+
input,
|
|
2112
|
+
options
|
|
2113
|
+
);
|
|
2114
|
+
const revokeOtherSessions = (input, options) => executePostWithOptionalInput(
|
|
2115
|
+
resolvedConfig,
|
|
2116
|
+
{ endpoint: "/revoke-other-sessions", method: "POST" },
|
|
2117
|
+
input,
|
|
2118
|
+
options
|
|
2119
|
+
);
|
|
2120
|
+
const revokeSession = (input, options) => executePostWithCompatibleInput(
|
|
2121
|
+
resolvedConfig,
|
|
2122
|
+
{ endpoint: "/revoke-session", method: "POST" },
|
|
2123
|
+
input,
|
|
2124
|
+
options
|
|
2125
|
+
);
|
|
2126
|
+
const deleteUser = (input, options) => {
|
|
2127
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2128
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
2129
|
+
return callAuthEndpoint(
|
|
2130
|
+
resolvedConfig,
|
|
2131
|
+
{ endpoint: "/delete-user", method: "POST" },
|
|
2132
|
+
payload ?? {},
|
|
2133
|
+
void 0,
|
|
2134
|
+
mergedOptions
|
|
2135
|
+
);
|
|
2136
|
+
};
|
|
2137
|
+
const deleteUserCallback = (input, options) => {
|
|
2138
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2139
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
2140
|
+
const query = payload ?? {};
|
|
2141
|
+
return callAuthEndpoint(
|
|
2142
|
+
resolvedConfig,
|
|
2143
|
+
{ endpoint: "/delete-user/callback", method: "GET" },
|
|
2144
|
+
void 0,
|
|
2145
|
+
{
|
|
2146
|
+
token: query.token,
|
|
2147
|
+
callbackURL: query.callbackURL
|
|
2148
|
+
},
|
|
2149
|
+
mergedOptions
|
|
2150
|
+
);
|
|
2151
|
+
};
|
|
2152
|
+
const resolveResetPasswordToken = (input, options) => {
|
|
2153
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2154
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
2155
|
+
const query = payload;
|
|
2156
|
+
const token = query?.token?.trim();
|
|
2157
|
+
if (!token) {
|
|
2158
|
+
throw new Error("resolveResetPasswordToken requires a non-empty token");
|
|
2159
|
+
}
|
|
2160
|
+
const endpoint = `/reset-password/${encodeURIComponent(token)}`;
|
|
2161
|
+
return callAuthEndpoint(
|
|
2162
|
+
resolvedConfig,
|
|
2163
|
+
{ endpoint, method: "GET" },
|
|
2164
|
+
void 0,
|
|
2165
|
+
query?.callbackURL ? { callbackURL: query.callbackURL } : void 0,
|
|
2166
|
+
mergedOptions
|
|
2167
|
+
);
|
|
2168
|
+
};
|
|
2169
|
+
const organization = {
|
|
2170
|
+
create: (input, options) => executePostWithCompatibleInput(
|
|
2171
|
+
resolvedConfig,
|
|
2172
|
+
{ endpoint: "/organization/create", method: "POST" },
|
|
2173
|
+
input,
|
|
2174
|
+
options
|
|
2175
|
+
),
|
|
2176
|
+
update: (input, options) => executePostWithCompatibleInput(
|
|
2177
|
+
resolvedConfig,
|
|
2178
|
+
{ endpoint: "/organization/update", method: "POST" },
|
|
2179
|
+
input,
|
|
2180
|
+
options
|
|
2181
|
+
),
|
|
2182
|
+
delete: (input, options) => executePostWithCompatibleInput(
|
|
2183
|
+
resolvedConfig,
|
|
2184
|
+
{ endpoint: "/organization/delete", method: "POST" },
|
|
2185
|
+
input,
|
|
2186
|
+
options
|
|
2187
|
+
),
|
|
2188
|
+
setActive: (input, options) => executePostWithCompatibleInput(
|
|
2189
|
+
resolvedConfig,
|
|
2190
|
+
{ endpoint: "/organization/set-active", method: "POST" },
|
|
2191
|
+
input,
|
|
2192
|
+
options
|
|
2193
|
+
),
|
|
2194
|
+
list: (input, options) => getGeneric(
|
|
2195
|
+
"/organization/list",
|
|
2196
|
+
input,
|
|
2197
|
+
options
|
|
2198
|
+
),
|
|
2199
|
+
getFull: (input, options) => executeGetWithQueryCompatibleInput(
|
|
2200
|
+
resolvedConfig,
|
|
2201
|
+
{ endpoint: "/organization/get-full-organization", method: "GET" },
|
|
2202
|
+
input,
|
|
2203
|
+
options
|
|
2204
|
+
),
|
|
2205
|
+
checkSlug: (input, options) => executePostWithCompatibleInput(
|
|
2206
|
+
resolvedConfig,
|
|
2207
|
+
{ endpoint: "/organization/check-slug", method: "POST" },
|
|
2208
|
+
input,
|
|
2209
|
+
options
|
|
2210
|
+
),
|
|
2211
|
+
leave: (input, options) => executePostWithCompatibleInput(
|
|
2212
|
+
resolvedConfig,
|
|
2213
|
+
{ endpoint: "/organization/leave", method: "POST" },
|
|
2214
|
+
input,
|
|
2215
|
+
options
|
|
2216
|
+
),
|
|
2217
|
+
listUserInvitations: (input, options) => executeGetWithQueryCompatibleInput(
|
|
2218
|
+
resolvedConfig,
|
|
2219
|
+
{ endpoint: "/organization/list-user-invitations", method: "GET" },
|
|
2220
|
+
input,
|
|
2221
|
+
options
|
|
2222
|
+
),
|
|
2223
|
+
hasPermission: (input, options) => postGeneric(
|
|
2224
|
+
"/organization/has-permission",
|
|
2225
|
+
input,
|
|
2226
|
+
options
|
|
2227
|
+
),
|
|
2228
|
+
invitation: {
|
|
2229
|
+
cancel: (input, options) => executePostWithCompatibleInput(
|
|
2230
|
+
resolvedConfig,
|
|
2231
|
+
{ endpoint: "/organization/cancel-invitation", method: "POST" },
|
|
2232
|
+
input,
|
|
2233
|
+
options
|
|
2234
|
+
),
|
|
2235
|
+
accept: (input, options) => executePostWithCompatibleInput(
|
|
2236
|
+
resolvedConfig,
|
|
2237
|
+
{ endpoint: "/organization/accept-invitation", method: "POST" },
|
|
2238
|
+
input,
|
|
2239
|
+
options
|
|
2240
|
+
),
|
|
2241
|
+
get: (input, options) => executeGetWithQueryCompatibleInput(
|
|
2242
|
+
resolvedConfig,
|
|
2243
|
+
{ endpoint: "/organization/get-invitation", method: "GET" },
|
|
2244
|
+
input,
|
|
2245
|
+
options
|
|
2246
|
+
),
|
|
2247
|
+
reject: (input, options) => executePostWithCompatibleInput(
|
|
2248
|
+
resolvedConfig,
|
|
2249
|
+
{ endpoint: "/organization/reject-invitation", method: "POST" },
|
|
2250
|
+
input,
|
|
2251
|
+
options
|
|
2252
|
+
),
|
|
2253
|
+
list: (input, options) => executeGetWithQueryCompatibleInput(
|
|
2254
|
+
resolvedConfig,
|
|
2255
|
+
{ endpoint: "/organization/list-invitations", method: "GET" },
|
|
2256
|
+
input,
|
|
2257
|
+
options
|
|
2258
|
+
)
|
|
2259
|
+
},
|
|
2260
|
+
member: {
|
|
2261
|
+
remove: (input, options) => executePostWithCompatibleInput(
|
|
2262
|
+
resolvedConfig,
|
|
2263
|
+
{ endpoint: "/organization/remove-member", method: "POST" },
|
|
2264
|
+
input,
|
|
2265
|
+
options
|
|
2266
|
+
),
|
|
2267
|
+
updateRole: (input, options) => executePostWithCompatibleInput(
|
|
2268
|
+
resolvedConfig,
|
|
2269
|
+
{ endpoint: "/organization/update-member-role", method: "POST" },
|
|
2270
|
+
input,
|
|
2271
|
+
options
|
|
2272
|
+
),
|
|
2273
|
+
invite: (input, options) => executePostWithCompatibleInput(
|
|
2274
|
+
resolvedConfig,
|
|
2275
|
+
{ endpoint: "/organization/invite-member", method: "POST" },
|
|
2276
|
+
input,
|
|
2277
|
+
options
|
|
2278
|
+
),
|
|
2279
|
+
getActive: (input, options) => executeGetWithCompatibleInput(
|
|
2280
|
+
resolvedConfig,
|
|
2281
|
+
{ endpoint: "/organization/get-active-member", method: "GET" },
|
|
2282
|
+
input,
|
|
2283
|
+
options
|
|
2284
|
+
),
|
|
2285
|
+
list: (input, options) => executeGetWithQueryCompatibleInput(
|
|
2286
|
+
resolvedConfig,
|
|
2287
|
+
{ endpoint: "/organization/list-members", method: "GET" },
|
|
2288
|
+
input,
|
|
2289
|
+
options
|
|
2290
|
+
)
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
2293
|
+
const authResetPassword = Object.assign(
|
|
2294
|
+
(input, options) => executePostWithCompatibleInput(
|
|
2295
|
+
resolvedConfig,
|
|
2296
|
+
{ endpoint: "/reset-password", method: "POST" },
|
|
2297
|
+
input,
|
|
2298
|
+
options
|
|
2299
|
+
),
|
|
2300
|
+
{
|
|
2301
|
+
token: resolveResetPasswordToken
|
|
2302
|
+
}
|
|
2303
|
+
);
|
|
2304
|
+
const sessionRevokeBinding = (input, options) => {
|
|
2305
|
+
if (Array.isArray(input)) {
|
|
2306
|
+
if (input.length === 0) {
|
|
2307
|
+
throw new Error("session.revoke requires at least one session token");
|
|
1139
2308
|
}
|
|
1140
|
-
|
|
2309
|
+
if (input.length === 1) {
|
|
2310
|
+
return revokeSession(input[0], options);
|
|
2311
|
+
}
|
|
2312
|
+
return revokeSessions(void 0, options);
|
|
1141
2313
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
2314
|
+
const parsed = input;
|
|
2315
|
+
const tokens = Array.isArray(parsed.tokens) ? parsed.tokens.filter((token2) => token2.trim().length > 0) : void 0;
|
|
2316
|
+
if (tokens && tokens.length > 1) {
|
|
2317
|
+
return revokeSessions(
|
|
2318
|
+
parsed.fetchOptions ? { fetchOptions: parsed.fetchOptions } : void 0,
|
|
2319
|
+
options
|
|
2320
|
+
);
|
|
2321
|
+
}
|
|
2322
|
+
if (tokens && tokens.length === 1) {
|
|
2323
|
+
return revokeSession(
|
|
2324
|
+
{ token: tokens[0], fetchOptions: parsed.fetchOptions },
|
|
2325
|
+
options
|
|
2326
|
+
);
|
|
2327
|
+
}
|
|
2328
|
+
const token = parsed.token?.trim();
|
|
2329
|
+
if (!token) {
|
|
2330
|
+
throw new Error("session.revoke requires a non-empty token or a non-empty token list");
|
|
2331
|
+
}
|
|
2332
|
+
return revokeSession(
|
|
2333
|
+
{
|
|
2334
|
+
token,
|
|
2335
|
+
fetchOptions: parsed.fetchOptions
|
|
2336
|
+
},
|
|
2337
|
+
options
|
|
2338
|
+
);
|
|
2339
|
+
};
|
|
2340
|
+
const adminUserSessionRevokeBinding = (input, options) => {
|
|
2341
|
+
const requireUserId = (userId) => {
|
|
2342
|
+
const trimmed = String(userId ?? "").trim();
|
|
2343
|
+
if (!trimmed) {
|
|
2344
|
+
throw new Error("admin.user.session.revoke requires a non-empty userId");
|
|
1148
2345
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
2346
|
+
return trimmed;
|
|
2347
|
+
};
|
|
2348
|
+
const requireSinglePluralUserId = (sessions2) => {
|
|
2349
|
+
const uniqueUserIds = [...new Set(sessions2.map((session) => requireUserId(session.userId)))];
|
|
2350
|
+
if (uniqueUserIds.length !== 1) {
|
|
2351
|
+
throw new Error("admin.user.session.revoke requires the same userId across plural payloads");
|
|
1151
2352
|
}
|
|
1152
|
-
|
|
2353
|
+
return { userId: uniqueUserIds[0] };
|
|
2354
|
+
};
|
|
2355
|
+
if (Array.isArray(input)) {
|
|
2356
|
+
if (input.length === 0) {
|
|
2357
|
+
throw new Error("admin.user.session.revoke requires at least one payload item");
|
|
2358
|
+
}
|
|
2359
|
+
if (input.length === 1) {
|
|
2360
|
+
return postGeneric(
|
|
2361
|
+
"/admin/revoke-user-session",
|
|
2362
|
+
{
|
|
2363
|
+
...input[0],
|
|
2364
|
+
userId: requireUserId(input[0].userId)
|
|
2365
|
+
},
|
|
2366
|
+
options
|
|
2367
|
+
);
|
|
2368
|
+
}
|
|
2369
|
+
return postGeneric(
|
|
2370
|
+
"/admin/revoke-user-sessions",
|
|
2371
|
+
requireSinglePluralUserId(input),
|
|
2372
|
+
options
|
|
2373
|
+
);
|
|
1153
2374
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
2375
|
+
const parsed = input;
|
|
2376
|
+
const sessions = parsed.sessions;
|
|
2377
|
+
if (sessions && sessions.length === 0) {
|
|
2378
|
+
throw new Error("admin.user.session.revoke requires at least one payload item");
|
|
1158
2379
|
}
|
|
1159
|
-
if (
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
2380
|
+
if (sessions && sessions.length === 1) {
|
|
2381
|
+
return postGeneric(
|
|
2382
|
+
"/admin/revoke-user-session",
|
|
2383
|
+
{
|
|
2384
|
+
...sessions[0],
|
|
2385
|
+
userId: requireUserId(sessions[0].userId),
|
|
2386
|
+
fetchOptions: parsed.fetchOptions
|
|
2387
|
+
},
|
|
2388
|
+
options
|
|
2389
|
+
);
|
|
1163
2390
|
}
|
|
1164
|
-
if (
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
2391
|
+
if (sessions && sessions.length > 1) {
|
|
2392
|
+
return postGeneric(
|
|
2393
|
+
"/admin/revoke-user-sessions",
|
|
2394
|
+
{
|
|
2395
|
+
...requireSinglePluralUserId(sessions),
|
|
2396
|
+
fetchOptions: parsed.fetchOptions
|
|
2397
|
+
},
|
|
2398
|
+
options
|
|
2399
|
+
);
|
|
1168
2400
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
2401
|
+
const normalizedUserId = requireUserId(parsed.userId);
|
|
2402
|
+
if (!parsed.sessionToken) {
|
|
2403
|
+
return postGeneric(
|
|
2404
|
+
"/admin/revoke-user-sessions",
|
|
2405
|
+
{
|
|
2406
|
+
userId: normalizedUserId,
|
|
2407
|
+
fetchOptions: parsed.fetchOptions
|
|
2408
|
+
},
|
|
2409
|
+
options
|
|
2410
|
+
);
|
|
1174
2411
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
2412
|
+
return postGeneric(
|
|
2413
|
+
"/admin/revoke-user-session",
|
|
2414
|
+
{
|
|
2415
|
+
...parsed,
|
|
2416
|
+
userId: normalizedUserId
|
|
2417
|
+
},
|
|
2418
|
+
options
|
|
2419
|
+
);
|
|
2420
|
+
};
|
|
2421
|
+
const auth = {
|
|
2422
|
+
getSession: (input, options) => getGeneric("/get-session", input, options),
|
|
2423
|
+
signOut,
|
|
2424
|
+
forgetPassword: (input, options) => postGeneric("/forget-password", input, options),
|
|
2425
|
+
resetPassword: authResetPassword,
|
|
2426
|
+
setPassword: (input, options) => postGeneric("/set-password", input, options),
|
|
2427
|
+
verifyEmail: (input, options) => {
|
|
2428
|
+
const queryInput = {
|
|
2429
|
+
query: {
|
|
2430
|
+
token: input.token,
|
|
2431
|
+
callbackURL: input.callbackURL
|
|
2432
|
+
},
|
|
2433
|
+
fetchOptions: input.fetchOptions
|
|
2434
|
+
};
|
|
2435
|
+
return getWithQuery(
|
|
2436
|
+
"/verify-email",
|
|
2437
|
+
queryInput,
|
|
2438
|
+
options
|
|
2439
|
+
);
|
|
2440
|
+
},
|
|
2441
|
+
sendVerificationEmail: (input, options) => postGeneric("/send-verification-email", input, options),
|
|
2442
|
+
changeEmail: (input, options) => postGeneric("/change-email", input, options),
|
|
2443
|
+
changeEmailVerify: (input, options) => getWithQuery("/change-email/verify", input, options),
|
|
2444
|
+
deleteUserVerify: (input, options) => getWithQuery("/delete-user/verify", input, options),
|
|
2445
|
+
changePassword: (input, options) => postGeneric("/change-password", input, options),
|
|
2446
|
+
user: {
|
|
2447
|
+
update: (input, options) => postGeneric("/update-user", input, options),
|
|
2448
|
+
delete: (input, options) => postGeneric("/delete-user", input, options),
|
|
2449
|
+
email: {
|
|
2450
|
+
list: listUserEmailsWithFallback
|
|
2451
|
+
}
|
|
2452
|
+
},
|
|
2453
|
+
session: {
|
|
2454
|
+
list: (input, options) => getGeneric("/list-sessions", input, options),
|
|
2455
|
+
revoke: sessionRevokeBinding,
|
|
2456
|
+
revokeOther: revokeOtherSessions
|
|
2457
|
+
},
|
|
2458
|
+
social: {
|
|
2459
|
+
link: (input, options) => postGeneric("/link-social", input, options)
|
|
2460
|
+
},
|
|
2461
|
+
account: {
|
|
2462
|
+
list: (input, options) => getGeneric("/list-accounts", input, options),
|
|
2463
|
+
unlink: (input, options) => postGeneric("/unlink-account", input, options)
|
|
2464
|
+
},
|
|
2465
|
+
deleteUser: {
|
|
2466
|
+
callback: deleteUserCallback
|
|
2467
|
+
},
|
|
2468
|
+
refreshToken: (input, options) => postGeneric("/refresh-token", input, options),
|
|
2469
|
+
getAccessToken: (input, options) => postGeneric("/get-access-token", input, options),
|
|
2470
|
+
health: healthWithFallback,
|
|
2471
|
+
ok: (input, options) => getGeneric("/ok", input, options),
|
|
2472
|
+
error: (input, options) => getGeneric("/error", input, options),
|
|
2473
|
+
twoFactor: {
|
|
2474
|
+
getTotpUri: (input, options) => postGeneric("/two-factor/get-totp-uri", input, options),
|
|
2475
|
+
verifyTotp: (input, options) => postGeneric("/two-factor/verify-totp", input, options),
|
|
2476
|
+
sendOtp: (input, options) => postGeneric("/two-factor/send-otp", input, options),
|
|
2477
|
+
verifyOtp: (input, options) => postGeneric("/two-factor/verify-otp", input, options),
|
|
2478
|
+
verifyBackupCode: (input, options) => postGeneric("/two-factor/verify-backup-code", input, options),
|
|
2479
|
+
generateBackupCodes: (input, options) => executePostWithCompatibleInput(
|
|
2480
|
+
resolvedConfig,
|
|
2481
|
+
{ endpoint: "/two-factor/generate-backup-codes", method: "POST" },
|
|
2482
|
+
input,
|
|
2483
|
+
options
|
|
2484
|
+
),
|
|
2485
|
+
enable: (input, options) => postGeneric("/two-factor/enable", input, options),
|
|
2486
|
+
disable: (input, options) => postGeneric("/two-factor/disable", input, options)
|
|
2487
|
+
},
|
|
2488
|
+
passkey: {
|
|
2489
|
+
generateRegisterOptions: (input, options) => getGeneric("/passkey/generate-register-options", input, options),
|
|
2490
|
+
generateAuthenticateOptions: (input, options) => postGeneric("/passkey/generate-authenticate-options", input, options),
|
|
2491
|
+
verifyRegistration: (input, options) => postGeneric("/passkey/verify-registration", input, options),
|
|
2492
|
+
verifyAuthentication: (input, options) => postGeneric("/passkey/verify-authentication", input, options),
|
|
2493
|
+
listUserPasskeys: (input, options) => getGeneric("/passkey/list-user-passkeys", input, options),
|
|
2494
|
+
deletePasskey: (input, options) => postGeneric("/passkey/delete-passkey", input, options),
|
|
2495
|
+
updatePasskey: (input, options) => postGeneric("/passkey/update-passkey", input, options),
|
|
2496
|
+
getRelatedOrigins: (input, options) => getGeneric("/.well-known/webauthn", input, options)
|
|
2497
|
+
},
|
|
2498
|
+
admin: {
|
|
2499
|
+
role: {
|
|
2500
|
+
set: (input, options) => postGeneric("/admin/set-role", input, options)
|
|
2501
|
+
},
|
|
2502
|
+
user: {
|
|
2503
|
+
list: (input, options) => getWithQuery("/admin/list-users", input, options),
|
|
2504
|
+
create: (input, options) => postGeneric("/admin/create-user", input, options),
|
|
2505
|
+
unban: (input, options) => postGeneric("/admin/unban-user", input, options),
|
|
2506
|
+
ban: (input, options) => postGeneric("/admin/ban-user", input, options),
|
|
2507
|
+
impersonate: (input, options) => postGeneric("/admin/impersonate-user", input, options),
|
|
2508
|
+
stopImpersonating: (input, options) => postGeneric("/admin/stop-impersonating", input, options),
|
|
2509
|
+
remove: (input, options) => postGeneric("/admin/remove-user", input, options),
|
|
2510
|
+
setPassword: (input, options) => postGeneric("/admin/set-user-password", input, options),
|
|
2511
|
+
session: {
|
|
2512
|
+
list: (input, options) => postGeneric("/admin/list-user-sessions", input, options),
|
|
2513
|
+
revoke: adminUserSessionRevokeBinding
|
|
2514
|
+
}
|
|
2515
|
+
},
|
|
2516
|
+
hasPermission: (input, options) => postGeneric("/admin/has-permission", input, options),
|
|
2517
|
+
apiKey: {
|
|
2518
|
+
create: (input, options) => postGeneric("/admin/api-key/create", input, options)
|
|
2519
|
+
},
|
|
2520
|
+
athenaClient: {
|
|
2521
|
+
create: (input, options) => postGeneric("/admin/athena-client/create", input, options),
|
|
2522
|
+
list: (input, options) => getWithQuery("/admin/athena-client/list", input, options)
|
|
2523
|
+
},
|
|
2524
|
+
auditLog: {
|
|
2525
|
+
list: (input, options) => getWithQuery("/admin/audit-log/list", input, options)
|
|
2526
|
+
},
|
|
2527
|
+
email: {
|
|
2528
|
+
list: (input, options) => getWithQuery("/admin/email/list", input, options),
|
|
2529
|
+
get: (input, options) => getWithQuery("/admin/email/get", input, options),
|
|
2530
|
+
create: (input, options) => postGeneric("/admin/email/create", input, options),
|
|
2531
|
+
update: (input, options) => postGeneric("/admin/email/update", input, options),
|
|
2532
|
+
delete: (input, options) => postGeneric("/admin/email/delete", input, options),
|
|
2533
|
+
failure: {
|
|
2534
|
+
list: (input, options) => getWithQuery("/admin/email-failure/list", input, options),
|
|
2535
|
+
get: (input, options) => getWithQuery("/admin/email-failure/get", input, options),
|
|
2536
|
+
create: (input, options) => postGeneric("/admin/email-failure/create", input, options),
|
|
2537
|
+
update: (input, options) => postGeneric("/admin/email-failure/update", input, options),
|
|
2538
|
+
delete: (input, options) => postGeneric("/admin/email-failure/delete", input, options)
|
|
2539
|
+
},
|
|
2540
|
+
template: {
|
|
2541
|
+
list: (input, options) => getWithQuery("/admin/email-template/list", input, options),
|
|
2542
|
+
get: (input, options) => getWithQuery("/admin/email-template/get", input, options),
|
|
2543
|
+
create: (input, options) => postGeneric("/admin/email-template/create", input, options),
|
|
2544
|
+
update: (input, options) => postGeneric("/admin/email-template/update", input, options),
|
|
2545
|
+
delete: (input, options) => postGeneric("/admin/email-template/delete", input, options)
|
|
2546
|
+
}
|
|
2547
|
+
},
|
|
2548
|
+
emailTemplate: {
|
|
2549
|
+
get: (input, options) => getWithQuery("/admin/email-template/get", input, options),
|
|
2550
|
+
create: (input, options) => postGeneric("/admin/email-template/create", input, options),
|
|
2551
|
+
delete: (input, options) => postGeneric("/admin/email-template/delete", input, options),
|
|
2552
|
+
list: (input, options) => getWithQuery("/admin/email-template/list", input, options),
|
|
2553
|
+
update: (input, options) => postGeneric("/admin/email-template/update", input, options)
|
|
2554
|
+
}
|
|
2555
|
+
},
|
|
2556
|
+
apiKey: {
|
|
2557
|
+
create: (input, options) => postGeneric("/api-key/create", input, options),
|
|
2558
|
+
get: (input, options) => getWithQuery("/api-key/get", input, options),
|
|
2559
|
+
update: (input, options) => postGeneric("/api-key/update", input, options),
|
|
2560
|
+
delete: (input, options) => postGeneric("/api-key/delete", input, options),
|
|
2561
|
+
list: (input, options) => getWithQuery("/api-key/list", input, options),
|
|
2562
|
+
verify: (input, options) => postGeneric("/api-key/verify", input, options),
|
|
2563
|
+
deleteAllExpired: (input, options) => executePostWithOptionalInput(
|
|
2564
|
+
resolvedConfig,
|
|
2565
|
+
{ endpoint: "/api-key/delete-all-expired-api-keys", method: "POST" },
|
|
2566
|
+
input,
|
|
2567
|
+
options
|
|
2568
|
+
)
|
|
2569
|
+
},
|
|
2570
|
+
signIn: {
|
|
2571
|
+
email: (input, options) => postGeneric("/sign-in/email", input, options),
|
|
2572
|
+
username: (input, options) => postGeneric("/sign-in/username", input, options),
|
|
2573
|
+
social: (input, options) => postGeneric("/sign-in/social", input, options)
|
|
2574
|
+
},
|
|
2575
|
+
signUp: {
|
|
2576
|
+
email: (input, options) => postGeneric("/sign-up/email", input, options)
|
|
2577
|
+
},
|
|
2578
|
+
organization,
|
|
2579
|
+
callback: {
|
|
2580
|
+
provider: (input, options) => {
|
|
2581
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2582
|
+
const parsed = payload;
|
|
2583
|
+
const provider = String(parsed?.provider ?? "").trim();
|
|
2584
|
+
if (!provider) {
|
|
2585
|
+
throw new Error("callback.provider requires a non-empty provider value");
|
|
2586
|
+
}
|
|
2587
|
+
const code = String(parsed?.code ?? "").trim();
|
|
2588
|
+
const state = String(parsed?.state ?? "").trim();
|
|
2589
|
+
if (!code || !state) {
|
|
2590
|
+
throw new Error("callback.provider requires non-empty code and state values");
|
|
2591
|
+
}
|
|
2592
|
+
const endpoint = `/callback/${encodeURIComponent(provider)}`;
|
|
2593
|
+
return request({
|
|
2594
|
+
endpoint,
|
|
2595
|
+
method: "GET",
|
|
2596
|
+
query: {
|
|
2597
|
+
code,
|
|
2598
|
+
state
|
|
2599
|
+
},
|
|
2600
|
+
fetchOptions
|
|
2601
|
+
}, options);
|
|
2602
|
+
}
|
|
1179
2603
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
2604
|
+
};
|
|
2605
|
+
return {
|
|
2606
|
+
baseUrl: normalizedBaseUrl,
|
|
2607
|
+
request,
|
|
2608
|
+
signIn: {
|
|
2609
|
+
email: (input, options) => executePostWithCompatibleInput(
|
|
2610
|
+
resolvedConfig,
|
|
2611
|
+
{ endpoint: "/sign-in/email", method: "POST" },
|
|
2612
|
+
input,
|
|
2613
|
+
options
|
|
2614
|
+
),
|
|
2615
|
+
username: (input, options) => executePostWithCompatibleInput(
|
|
2616
|
+
resolvedConfig,
|
|
2617
|
+
{ endpoint: "/sign-in/username", method: "POST" },
|
|
2618
|
+
input,
|
|
2619
|
+
options
|
|
2620
|
+
),
|
|
2621
|
+
social: (input, options) => executePostWithCompatibleInput(
|
|
2622
|
+
resolvedConfig,
|
|
2623
|
+
{ endpoint: "/sign-in/social", method: "POST" },
|
|
2624
|
+
input,
|
|
2625
|
+
options
|
|
2626
|
+
)
|
|
2627
|
+
},
|
|
2628
|
+
signUp: {
|
|
2629
|
+
email: (input, options) => executePostWithCompatibleInput(
|
|
2630
|
+
resolvedConfig,
|
|
2631
|
+
{ endpoint: "/sign-up/email", method: "POST" },
|
|
2632
|
+
input,
|
|
2633
|
+
options
|
|
2634
|
+
)
|
|
2635
|
+
},
|
|
2636
|
+
signOut,
|
|
2637
|
+
logout: signOut,
|
|
2638
|
+
getSession: (input, options) => executeGetWithCompatibleInput(
|
|
2639
|
+
resolvedConfig,
|
|
2640
|
+
{ endpoint: "/get-session", method: "GET" },
|
|
2641
|
+
input,
|
|
2642
|
+
options
|
|
2643
|
+
),
|
|
2644
|
+
listSessions: (input, options) => executeGetWithCompatibleInput(
|
|
2645
|
+
resolvedConfig,
|
|
2646
|
+
{ endpoint: "/list-sessions", method: "GET" },
|
|
2647
|
+
input,
|
|
2648
|
+
options
|
|
2649
|
+
),
|
|
2650
|
+
revokeSession,
|
|
2651
|
+
clearSession: revokeSession,
|
|
2652
|
+
revokeSessions,
|
|
2653
|
+
clearSessions: revokeSessions,
|
|
2654
|
+
revokeOtherSessions,
|
|
2655
|
+
clearOtherSessions: revokeOtherSessions,
|
|
2656
|
+
forgetPassword: (input, options) => executePostWithCompatibleInput(
|
|
2657
|
+
resolvedConfig,
|
|
2658
|
+
{ endpoint: "/forget-password", method: "POST" },
|
|
2659
|
+
input,
|
|
2660
|
+
options
|
|
2661
|
+
),
|
|
2662
|
+
resetPassword: (input, options) => executePostWithCompatibleInput(
|
|
2663
|
+
resolvedConfig,
|
|
2664
|
+
{ endpoint: "/reset-password", method: "POST" },
|
|
2665
|
+
input,
|
|
2666
|
+
options
|
|
2667
|
+
),
|
|
2668
|
+
resolveResetPasswordToken,
|
|
2669
|
+
verifyEmail: (input, options) => {
|
|
2670
|
+
const { payload, fetchOptions } = extractFetchOptions(input);
|
|
2671
|
+
const mergedOptions = mergeCallOptions(fetchOptions, options);
|
|
2672
|
+
const query = payload;
|
|
2673
|
+
return callAuthEndpoint(
|
|
2674
|
+
resolvedConfig,
|
|
2675
|
+
{ endpoint: "/verify-email", method: "GET" },
|
|
2676
|
+
void 0,
|
|
2677
|
+
query ? {
|
|
2678
|
+
token: query.token,
|
|
2679
|
+
callbackURL: query.callbackURL
|
|
2680
|
+
} : void 0,
|
|
2681
|
+
mergedOptions
|
|
2682
|
+
);
|
|
2683
|
+
},
|
|
2684
|
+
sendVerificationEmail: (input, options) => executePostWithCompatibleInput(
|
|
2685
|
+
resolvedConfig,
|
|
2686
|
+
{ endpoint: "/send-verification-email", method: "POST" },
|
|
2687
|
+
input,
|
|
2688
|
+
options
|
|
2689
|
+
),
|
|
2690
|
+
changeEmail: (input, options) => executePostWithCompatibleInput(
|
|
2691
|
+
resolvedConfig,
|
|
2692
|
+
{ endpoint: "/change-email", method: "POST" },
|
|
2693
|
+
input,
|
|
2694
|
+
options
|
|
2695
|
+
),
|
|
2696
|
+
changePassword: (input, options) => executePostWithCompatibleInput(
|
|
2697
|
+
resolvedConfig,
|
|
2698
|
+
{ endpoint: "/change-password", method: "POST" },
|
|
2699
|
+
input,
|
|
2700
|
+
options
|
|
2701
|
+
),
|
|
2702
|
+
updateUser: (input, options) => executePostWithCompatibleInput(
|
|
2703
|
+
resolvedConfig,
|
|
2704
|
+
{ endpoint: "/update-user", method: "POST" },
|
|
2705
|
+
input,
|
|
2706
|
+
options
|
|
2707
|
+
),
|
|
2708
|
+
deleteUser,
|
|
2709
|
+
deleteUserCallback,
|
|
2710
|
+
linkSocial: (input, options) => executePostWithCompatibleInput(
|
|
2711
|
+
resolvedConfig,
|
|
2712
|
+
{ endpoint: "/link-social", method: "POST" },
|
|
2713
|
+
input,
|
|
2714
|
+
options
|
|
2715
|
+
),
|
|
2716
|
+
listAccounts: (input, options) => executeGetWithCompatibleInput(
|
|
2717
|
+
resolvedConfig,
|
|
2718
|
+
{ endpoint: "/list-accounts", method: "GET" },
|
|
2719
|
+
input,
|
|
2720
|
+
options
|
|
2721
|
+
),
|
|
2722
|
+
unlinkAccount: (input, options) => executePostWithCompatibleInput(
|
|
2723
|
+
resolvedConfig,
|
|
2724
|
+
{ endpoint: "/unlink-account", method: "POST" },
|
|
2725
|
+
input,
|
|
2726
|
+
options
|
|
2727
|
+
),
|
|
2728
|
+
refreshToken: (input, options) => executePostWithCompatibleInput(
|
|
2729
|
+
resolvedConfig,
|
|
2730
|
+
{ endpoint: "/refresh-token", method: "POST" },
|
|
2731
|
+
input,
|
|
2732
|
+
options
|
|
2733
|
+
),
|
|
2734
|
+
getAccessToken: (input, options) => executePostWithCompatibleInput(
|
|
2735
|
+
resolvedConfig,
|
|
2736
|
+
{ endpoint: "/get-access-token", method: "POST" },
|
|
2737
|
+
input,
|
|
2738
|
+
options
|
|
2739
|
+
),
|
|
2740
|
+
organization,
|
|
2741
|
+
auth
|
|
2742
|
+
};
|
|
1189
2743
|
}
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
const
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
2744
|
+
|
|
2745
|
+
// src/db/module.ts
|
|
2746
|
+
function createDbModule(input) {
|
|
2747
|
+
const db = {
|
|
2748
|
+
from(table) {
|
|
2749
|
+
return input.from(table);
|
|
2750
|
+
},
|
|
2751
|
+
select(table, columns, options) {
|
|
2752
|
+
return input.from(table).select(columns, options);
|
|
2753
|
+
},
|
|
2754
|
+
insert(table, values, options) {
|
|
2755
|
+
return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
|
|
2756
|
+
},
|
|
2757
|
+
upsert(table, values, options) {
|
|
2758
|
+
return Array.isArray(values) ? input.from(table).upsert(values, options) : input.from(table).upsert(values, options);
|
|
2759
|
+
},
|
|
2760
|
+
update(table, values, options) {
|
|
2761
|
+
return input.from(table).update(values, options);
|
|
2762
|
+
},
|
|
2763
|
+
delete(table, options) {
|
|
2764
|
+
return input.from(table).delete(options);
|
|
2765
|
+
},
|
|
2766
|
+
rpc(fn, args, options) {
|
|
2767
|
+
return input.rpc(fn, args, options);
|
|
2768
|
+
},
|
|
2769
|
+
query(query, options) {
|
|
2770
|
+
return input.query(query, options);
|
|
2771
|
+
}
|
|
2772
|
+
};
|
|
2773
|
+
return db;
|
|
1201
2774
|
}
|
|
1202
2775
|
|
|
1203
2776
|
// src/client.ts
|
|
1204
2777
|
var DEFAULT_COLUMNS = "*";
|
|
1205
2778
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1206
2779
|
var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
|
|
2780
|
+
var ATHENA_NORMALIZED_ERROR_KEY = "__athenaNormalizedError";
|
|
1207
2781
|
function formatResult(response) {
|
|
1208
2782
|
const result = {
|
|
1209
2783
|
data: response.data ?? null,
|
|
@@ -1217,6 +2791,28 @@ function formatResult(response) {
|
|
|
1217
2791
|
}
|
|
1218
2792
|
return result;
|
|
1219
2793
|
}
|
|
2794
|
+
function attachNormalizedError(result, normalizedError) {
|
|
2795
|
+
Object.defineProperty(result, ATHENA_NORMALIZED_ERROR_KEY, {
|
|
2796
|
+
value: normalizedError,
|
|
2797
|
+
enumerable: false,
|
|
2798
|
+
configurable: true,
|
|
2799
|
+
writable: false
|
|
2800
|
+
});
|
|
2801
|
+
}
|
|
2802
|
+
function createResultFormatter(experimental) {
|
|
2803
|
+
if (!experimental?.enableErrorNormalization) {
|
|
2804
|
+
return formatResult;
|
|
2805
|
+
}
|
|
2806
|
+
return (response, context) => {
|
|
2807
|
+
const result = formatResult(response);
|
|
2808
|
+
if (result.error == null) {
|
|
2809
|
+
return result;
|
|
2810
|
+
}
|
|
2811
|
+
const normalizedError = normalizeAthenaError(result, context);
|
|
2812
|
+
attachNormalizedError(result, normalizedError);
|
|
2813
|
+
return result;
|
|
2814
|
+
};
|
|
2815
|
+
}
|
|
1220
2816
|
function toSingleResult(response) {
|
|
1221
2817
|
const payload = response.data;
|
|
1222
2818
|
const singleData = Array.isArray(payload) ? payload.length ? payload[0] : null : payload ?? null;
|
|
@@ -1591,7 +3187,7 @@ function createRpcFilterMethods(filters, self) {
|
|
|
1591
3187
|
}
|
|
1592
3188
|
};
|
|
1593
3189
|
}
|
|
1594
|
-
function createRpcBuilder(functionName, args, baseOptions, client) {
|
|
3190
|
+
function createRpcBuilder(functionName, args, baseOptions, client, formatGatewayResult) {
|
|
1595
3191
|
const state = {
|
|
1596
3192
|
filters: []
|
|
1597
3193
|
};
|
|
@@ -1613,7 +3209,7 @@ function createRpcBuilder(functionName, args, baseOptions, client) {
|
|
|
1613
3209
|
order: state.order
|
|
1614
3210
|
};
|
|
1615
3211
|
const response = await client.rpcGateway(payload, mergedOptions);
|
|
1616
|
-
return
|
|
3212
|
+
return formatGatewayResult(response, { operation: "rpc" });
|
|
1617
3213
|
};
|
|
1618
3214
|
const run = (columns, options) => {
|
|
1619
3215
|
const payloadColumns = columns ?? selectedColumns;
|
|
@@ -1667,7 +3263,7 @@ function createRpcBuilder(functionName, args, baseOptions, client) {
|
|
|
1667
3263
|
});
|
|
1668
3264
|
return builder;
|
|
1669
3265
|
}
|
|
1670
|
-
function createTableBuilder(tableName, client) {
|
|
3266
|
+
function createTableBuilder(tableName, client, formatGatewayResult) {
|
|
1671
3267
|
const state = {
|
|
1672
3268
|
conditions: []
|
|
1673
3269
|
};
|
|
@@ -1724,7 +3320,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1724
3320
|
});
|
|
1725
3321
|
if (query) {
|
|
1726
3322
|
const queryResponse = await client.queryGateway({ query }, options);
|
|
1727
|
-
return
|
|
3323
|
+
return formatGatewayResult(queryResponse, { table: resolvedTableName, operation: "select" });
|
|
1728
3324
|
}
|
|
1729
3325
|
}
|
|
1730
3326
|
const payload = {
|
|
@@ -1742,7 +3338,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1742
3338
|
head: options?.head
|
|
1743
3339
|
};
|
|
1744
3340
|
const response = await client.fetchGateway(payload, options);
|
|
1745
|
-
return
|
|
3341
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "select" });
|
|
1746
3342
|
};
|
|
1747
3343
|
const createSelectChain = (columns, options) => {
|
|
1748
3344
|
const chain = {};
|
|
@@ -1797,7 +3393,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1797
3393
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1798
3394
|
}
|
|
1799
3395
|
const response = await client.insertGateway(payload, mergedOptions);
|
|
1800
|
-
return
|
|
3396
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
1801
3397
|
};
|
|
1802
3398
|
return createMutationQuery(executeInsertMany);
|
|
1803
3399
|
}
|
|
@@ -1815,7 +3411,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1815
3411
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1816
3412
|
}
|
|
1817
3413
|
const response = await client.insertGateway(payload, mergedOptions);
|
|
1818
|
-
return
|
|
3414
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
1819
3415
|
};
|
|
1820
3416
|
return createMutationQuery(executeInsertOne);
|
|
1821
3417
|
},
|
|
@@ -1837,7 +3433,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1837
3433
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1838
3434
|
}
|
|
1839
3435
|
const response = await client.insertGateway(payload, mergedOptions);
|
|
1840
|
-
return
|
|
3436
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
1841
3437
|
};
|
|
1842
3438
|
return createMutationQuery(executeUpsertMany);
|
|
1843
3439
|
}
|
|
@@ -1857,7 +3453,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1857
3453
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
1858
3454
|
}
|
|
1859
3455
|
const response = await client.insertGateway(payload, mergedOptions);
|
|
1860
|
-
return
|
|
3456
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "insert" });
|
|
1861
3457
|
};
|
|
1862
3458
|
return createMutationQuery(executeUpsertOne);
|
|
1863
3459
|
},
|
|
@@ -1878,7 +3474,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1878
3474
|
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
1879
3475
|
if (columns) payload.columns = columns;
|
|
1880
3476
|
const response = await client.updateGateway(payload, mergedOptions);
|
|
1881
|
-
return
|
|
3477
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "update" });
|
|
1882
3478
|
};
|
|
1883
3479
|
const mutation = createMutationQuery(executeUpdate, null);
|
|
1884
3480
|
const updateChain = {};
|
|
@@ -1906,7 +3502,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1906
3502
|
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
1907
3503
|
if (columns) payload.columns = columns;
|
|
1908
3504
|
const response = await client.deleteGateway(payload, mergedOptions);
|
|
1909
|
-
return
|
|
3505
|
+
return formatGatewayResult(response, { table: resolvedTableName, operation: "delete" });
|
|
1910
3506
|
};
|
|
1911
3507
|
return createMutationQuery(executeDelete, null);
|
|
1912
3508
|
},
|
|
@@ -1920,14 +3516,14 @@ function createTableBuilder(tableName, client) {
|
|
|
1920
3516
|
});
|
|
1921
3517
|
return builder;
|
|
1922
3518
|
}
|
|
1923
|
-
function createQueryBuilder(client) {
|
|
3519
|
+
function createQueryBuilder(client, formatGatewayResult) {
|
|
1924
3520
|
return async function query(query, options) {
|
|
1925
3521
|
const normalizedQuery = query.trim();
|
|
1926
3522
|
if (!normalizedQuery) {
|
|
1927
3523
|
throw new Error("query requires a non-empty string");
|
|
1928
3524
|
}
|
|
1929
3525
|
const response = await client.queryGateway({ query: normalizedQuery }, options);
|
|
1930
|
-
return
|
|
3526
|
+
return formatGatewayResult(response, { operation: "query" });
|
|
1931
3527
|
};
|
|
1932
3528
|
}
|
|
1933
3529
|
function createClientFromConfig(config) {
|
|
@@ -1938,23 +3534,30 @@ function createClientFromConfig(config) {
|
|
|
1938
3534
|
backend: config.backend,
|
|
1939
3535
|
headers: config.headers
|
|
1940
3536
|
});
|
|
3537
|
+
const formatGatewayResult = createResultFormatter(config.experimental);
|
|
3538
|
+
const auth = createAuthClient(config.auth);
|
|
3539
|
+
const from = (table) => createTableBuilder(table, gateway, formatGatewayResult);
|
|
3540
|
+
const rpc = (fn, args, options) => {
|
|
3541
|
+
const normalizedFn = fn.trim();
|
|
3542
|
+
if (!normalizedFn) {
|
|
3543
|
+
throw new Error("rpc requires a function name");
|
|
3544
|
+
}
|
|
3545
|
+
return createRpcBuilder(
|
|
3546
|
+
normalizedFn,
|
|
3547
|
+
args,
|
|
3548
|
+
options,
|
|
3549
|
+
gateway,
|
|
3550
|
+
formatGatewayResult
|
|
3551
|
+
);
|
|
3552
|
+
};
|
|
3553
|
+
const query = createQueryBuilder(gateway, formatGatewayResult);
|
|
3554
|
+
const db = createDbModule({ from, rpc, query });
|
|
1941
3555
|
return {
|
|
1942
|
-
from
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
if (!normalizedFn) {
|
|
1948
|
-
throw new Error("rpc requires a function name");
|
|
1949
|
-
}
|
|
1950
|
-
return createRpcBuilder(
|
|
1951
|
-
normalizedFn,
|
|
1952
|
-
args,
|
|
1953
|
-
options,
|
|
1954
|
-
gateway
|
|
1955
|
-
);
|
|
1956
|
-
},
|
|
1957
|
-
query: createQueryBuilder(gateway)
|
|
3556
|
+
from,
|
|
3557
|
+
db,
|
|
3558
|
+
rpc,
|
|
3559
|
+
query,
|
|
3560
|
+
auth: auth.auth
|
|
1958
3561
|
};
|
|
1959
3562
|
}
|
|
1960
3563
|
var DEFAULT_BACKEND = { type: "athena" };
|
|
@@ -1962,73 +3565,16 @@ function toBackendConfig(b) {
|
|
|
1962
3565
|
if (!b) return DEFAULT_BACKEND;
|
|
1963
3566
|
return typeof b === "string" ? { type: b } : b;
|
|
1964
3567
|
}
|
|
1965
|
-
var AthenaClientBuilderImpl = class {
|
|
1966
|
-
baseUrl;
|
|
1967
|
-
apiKey;
|
|
1968
|
-
backendConfig = DEFAULT_BACKEND;
|
|
1969
|
-
clientName;
|
|
1970
|
-
defaultHeaders;
|
|
1971
|
-
isHealthTrackingEnabled = false;
|
|
1972
|
-
url(url) {
|
|
1973
|
-
this.baseUrl = url;
|
|
1974
|
-
return this;
|
|
1975
|
-
}
|
|
1976
|
-
key(apiKey) {
|
|
1977
|
-
this.apiKey = apiKey;
|
|
1978
|
-
return this;
|
|
1979
|
-
}
|
|
1980
|
-
backend(backend) {
|
|
1981
|
-
this.backendConfig = toBackendConfig(backend);
|
|
1982
|
-
return this;
|
|
1983
|
-
}
|
|
1984
|
-
client(clientName) {
|
|
1985
|
-
this.clientName = clientName;
|
|
1986
|
-
return this;
|
|
1987
|
-
}
|
|
1988
|
-
headers(headers) {
|
|
1989
|
-
this.defaultHeaders = headers;
|
|
1990
|
-
return this;
|
|
1991
|
-
}
|
|
1992
|
-
healthTracking(enabled) {
|
|
1993
|
-
this.isHealthTrackingEnabled = enabled;
|
|
1994
|
-
return this;
|
|
1995
|
-
}
|
|
1996
|
-
build() {
|
|
1997
|
-
if (!this.baseUrl || !this.apiKey) {
|
|
1998
|
-
throw new Error("AthenaClient requires url and key; call .url() and .key() before .build()");
|
|
1999
|
-
}
|
|
2000
|
-
return createClientFromConfig({
|
|
2001
|
-
baseUrl: this.baseUrl,
|
|
2002
|
-
apiKey: this.apiKey,
|
|
2003
|
-
client: this.clientName,
|
|
2004
|
-
backend: this.backendConfig,
|
|
2005
|
-
headers: this.defaultHeaders,
|
|
2006
|
-
healthTracking: this.isHealthTrackingEnabled
|
|
2007
|
-
});
|
|
2008
|
-
}
|
|
2009
|
-
};
|
|
2010
|
-
var AthenaClient = class _AthenaClient {
|
|
2011
|
-
/** Create a fluent builder for a strongly-typed Athena SDK client. */
|
|
2012
|
-
static builder() {
|
|
2013
|
-
return new AthenaClientBuilderImpl();
|
|
2014
|
-
}
|
|
2015
|
-
/** Build a client from process environment variables. */
|
|
2016
|
-
static fromEnvironment() {
|
|
2017
|
-
const url = process.env.ATHENA_URL ?? process.env.ATHENA_GATEWAY_URL;
|
|
2018
|
-
const key = process.env.ATHENA_API_KEY ?? process.env.ATHENA_GATEWAY_API_KEY;
|
|
2019
|
-
if (!url || !key) {
|
|
2020
|
-
throw new Error(
|
|
2021
|
-
"ATHENA_URL and ATHENA_API_KEY (or ATHENA_GATEWAY_URL and ATHENA_GATEWAY_API_KEY) are required"
|
|
2022
|
-
);
|
|
2023
|
-
}
|
|
2024
|
-
return _AthenaClient.builder().url(url).key(key).build();
|
|
2025
|
-
}
|
|
2026
|
-
};
|
|
2027
3568
|
function createClient(url, apiKey, options) {
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
3569
|
+
return createClientFromConfig({
|
|
3570
|
+
baseUrl: url,
|
|
3571
|
+
apiKey,
|
|
3572
|
+
client: options?.client,
|
|
3573
|
+
backend: toBackendConfig(options?.backend),
|
|
3574
|
+
headers: options?.headers,
|
|
3575
|
+
auth: options?.auth,
|
|
3576
|
+
experimental: options?.experimental
|
|
3577
|
+
});
|
|
2032
3578
|
}
|
|
2033
3579
|
|
|
2034
3580
|
// src/schema/postgres-introspection-core.ts
|
|
@@ -2378,6 +3924,23 @@ var PostgresCatalogSnapshotAssembler = class {
|
|
|
2378
3924
|
table.relations[key] = relation;
|
|
2379
3925
|
}
|
|
2380
3926
|
};
|
|
3927
|
+
|
|
3928
|
+
// src/schema/postgres-provider.ts
|
|
3929
|
+
var pgPoolConstructorPromise;
|
|
3930
|
+
async function loadPgPoolConstructor() {
|
|
3931
|
+
if (!pgPoolConstructorPromise) {
|
|
3932
|
+
pgPoolConstructorPromise = import('pg').then((module) => {
|
|
3933
|
+
const poolConstructor = module.Pool ?? module.default?.Pool;
|
|
3934
|
+
if (!poolConstructor) {
|
|
3935
|
+
throw new Error(
|
|
3936
|
+
'@xylex-group/athena: Unable to load the PostgreSQL driver. Ensure "pg" is installed and this API runs in a Node.js server runtime.'
|
|
3937
|
+
);
|
|
3938
|
+
}
|
|
3939
|
+
return poolConstructor;
|
|
3940
|
+
});
|
|
3941
|
+
}
|
|
3942
|
+
return pgPoolConstructorPromise;
|
|
3943
|
+
}
|
|
2381
3944
|
var PgCatalogClient = class {
|
|
2382
3945
|
constructor(pool) {
|
|
2383
3946
|
this.pool = pool;
|
|
@@ -2417,7 +3980,8 @@ var PostgresIntrospectionProvider = class {
|
|
|
2417
3980
|
}
|
|
2418
3981
|
async inspect(options) {
|
|
2419
3982
|
const schemas = options?.schemas && options.schemas.length > 0 ? normalizePostgresCatalogSchemas(options.schemas) : this.schemas;
|
|
2420
|
-
const
|
|
3983
|
+
const PoolConstructor = await loadPgPoolConstructor();
|
|
3984
|
+
const pool = new PoolConstructor({
|
|
2421
3985
|
connectionString: this.connectionString
|
|
2422
3986
|
});
|
|
2423
3987
|
const catalogClient = new PgCatalogClient(pool);
|