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