@xylex-group/athena 1.6.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -532,6 +532,12 @@ function mergeOptions(...options) {
532
532
  return { ...acc, ...next };
533
533
  }, void 0);
534
534
  }
535
+ function asAthenaJsonObject(value) {
536
+ return value;
537
+ }
538
+ function asAthenaJsonObjectArray(values) {
539
+ return values;
540
+ }
535
541
  function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS) {
536
542
  let selectedColumns = defaultColumns === null ? void 0 : defaultColumns;
537
543
  let selectedOptions;
@@ -620,6 +626,22 @@ function buildSelectColumnsClause(columns) {
620
626
  }
621
627
  return quoteSelectColumnsExpression(columns);
622
628
  }
629
+ function resolveTableNameForCall(tableName, schema) {
630
+ if (!schema) return tableName;
631
+ const normalizedSchema = schema.trim();
632
+ if (!normalizedSchema) {
633
+ throw new Error("schema option must be a non-empty string");
634
+ }
635
+ if (tableName.includes(".")) {
636
+ if (tableName.startsWith(`${normalizedSchema}.`)) {
637
+ return tableName;
638
+ }
639
+ throw new Error(
640
+ `schema option "${normalizedSchema}" conflicts with schema-qualified table "${tableName}"`
641
+ );
642
+ }
643
+ return `${normalizedSchema}.${tableName}`;
644
+ }
623
645
  function conditionToSqlClause(condition) {
624
646
  if (!condition.column) return null;
625
647
  const column = withCast(quoteQualifiedIdentifier(condition.column), condition.column_cast);
@@ -699,23 +721,27 @@ function buildTypedSelectQuery(input) {
699
721
  function createFilterMethods(state, addCondition, self) {
700
722
  return {
701
723
  eq(column, value) {
702
- if (shouldUseUuidTextComparison(column, value)) {
703
- addCondition("eq", column, value, { columnCast: "text" });
724
+ const columnName = String(column);
725
+ if (shouldUseUuidTextComparison(columnName, value)) {
726
+ addCondition("eq", columnName, value, { columnCast: "text" });
704
727
  } else {
705
- addCondition("eq", column, value);
728
+ addCondition("eq", columnName, value);
706
729
  }
707
730
  return self;
708
731
  },
709
732
  eqCast(column, value, cast) {
710
- addCondition("eq", column, value, { valueCast: cast });
733
+ addCondition("eq", String(column), value, { valueCast: cast });
711
734
  return self;
712
735
  },
713
736
  eqUuid(column, value) {
714
- addCondition("eq", column, value, { valueCast: "uuid" });
737
+ addCondition("eq", String(column), value, { valueCast: "uuid" });
715
738
  return self;
716
739
  },
717
740
  match(filters) {
718
741
  Object.entries(filters).forEach(([column, value]) => {
742
+ if (value === void 0) {
743
+ return;
744
+ }
719
745
  if (shouldUseUuidTextComparison(column, value)) {
720
746
  addCondition("eq", column, value, { columnCast: "text" });
721
747
  } else {
@@ -751,60 +777,61 @@ function createFilterMethods(state, addCondition, self) {
751
777
  },
752
778
  order(column, options) {
753
779
  state.order = {
754
- field: column,
780
+ field: String(column),
755
781
  direction: options?.ascending === false ? "descending" : "ascending"
756
782
  };
757
783
  return self;
758
784
  },
759
785
  gt(column, value) {
760
- addCondition("gt", column, value);
786
+ addCondition("gt", String(column), value);
761
787
  return self;
762
788
  },
763
789
  gte(column, value) {
764
- addCondition("gte", column, value);
790
+ addCondition("gte", String(column), value);
765
791
  return self;
766
792
  },
767
793
  lt(column, value) {
768
- addCondition("lt", column, value);
794
+ addCondition("lt", String(column), value);
769
795
  return self;
770
796
  },
771
797
  lte(column, value) {
772
- addCondition("lte", column, value);
798
+ addCondition("lte", String(column), value);
773
799
  return self;
774
800
  },
775
801
  neq(column, value) {
776
- addCondition("neq", column, value);
802
+ addCondition("neq", String(column), value);
777
803
  return self;
778
804
  },
779
805
  like(column, value) {
780
- addCondition("like", column, value);
806
+ addCondition("like", String(column), value);
781
807
  return self;
782
808
  },
783
809
  ilike(column, value) {
784
- addCondition("ilike", column, value);
810
+ addCondition("ilike", String(column), value);
785
811
  return self;
786
812
  },
787
813
  is(column, value) {
788
- addCondition("is", column, value);
814
+ addCondition("is", String(column), value);
789
815
  return self;
790
816
  },
791
817
  in(column, values) {
792
- addCondition("in", column, values);
818
+ addCondition("in", String(column), values);
793
819
  return self;
794
820
  },
795
821
  contains(column, values) {
796
- addCondition("contains", column, values);
822
+ addCondition("contains", String(column), values);
797
823
  return self;
798
824
  },
799
825
  containedBy(column, values) {
800
- addCondition("containedBy", column, values);
826
+ addCondition("containedBy", String(column), values);
801
827
  return self;
802
828
  },
803
829
  not(columnOrExpression, operator, value) {
830
+ const expression = String(columnOrExpression);
804
831
  if (operator != null && value !== void 0) {
805
- addCondition("not", void 0, `${columnOrExpression}.${operator}.${stringifyFilterValue(value)}`);
832
+ addCondition("not", void 0, `${expression}.${operator}.${stringifyFilterValue(value)}`);
806
833
  } else {
807
- addCondition("not", void 0, columnOrExpression);
834
+ addCondition("not", void 0, expression);
808
835
  }
809
836
  return self;
810
837
  },
@@ -974,15 +1001,20 @@ function createTableBuilder(tableName, client) {
974
1001
  state.conditions.push(condition);
975
1002
  };
976
1003
  const builder = {};
977
- const filterMethods = createFilterMethods(state, addCondition, builder);
1004
+ const filterMethods = createFilterMethods(
1005
+ state,
1006
+ addCondition,
1007
+ builder
1008
+ );
978
1009
  const runSelect = async (columns = DEFAULT_COLUMNS, options) => {
1010
+ const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
979
1011
  const conditions = state.conditions.length ? state.conditions.map((condition) => ({ ...condition })) : void 0;
980
1012
  const hasTypedEqualityComparison = conditions?.some(
981
1013
  (condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
982
1014
  ) ?? false;
983
1015
  if (hasTypedEqualityComparison && !options?.head && !options?.count && conditions) {
984
1016
  const query = buildTypedSelectQuery({
985
- tableName,
1017
+ tableName: resolvedTableName,
986
1018
  columns,
987
1019
  conditions,
988
1020
  limit: state.limit,
@@ -997,7 +1029,7 @@ function createTableBuilder(tableName, client) {
997
1029
  }
998
1030
  }
999
1031
  const payload = {
1000
- table_name: tableName,
1032
+ table_name: resolvedTableName,
1001
1033
  columns,
1002
1034
  conditions,
1003
1035
  limit: state.limit,
@@ -1054,9 +1086,10 @@ function createTableBuilder(tableName, client) {
1054
1086
  if (Array.isArray(values)) {
1055
1087
  const executeInsertMany = async (columns, selectOptions) => {
1056
1088
  const mergedOptions = mergeOptions(options, selectOptions);
1089
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1057
1090
  const payload = {
1058
- table_name: tableName,
1059
- insert_body: values
1091
+ table_name: resolvedTableName,
1092
+ insert_body: asAthenaJsonObjectArray(values)
1060
1093
  };
1061
1094
  if (columns) payload.columns = columns;
1062
1095
  if (mergedOptions?.count) payload.count = mergedOptions.count;
@@ -1071,9 +1104,10 @@ function createTableBuilder(tableName, client) {
1071
1104
  }
1072
1105
  const executeInsertOne = async (columns, selectOptions) => {
1073
1106
  const mergedOptions = mergeOptions(options, selectOptions);
1107
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1074
1108
  const payload = {
1075
- table_name: tableName,
1076
- insert_body: values
1109
+ table_name: resolvedTableName,
1110
+ insert_body: asAthenaJsonObject(values)
1077
1111
  };
1078
1112
  if (columns) payload.columns = columns;
1079
1113
  if (mergedOptions?.count) payload.count = mergedOptions.count;
@@ -1090,10 +1124,11 @@ function createTableBuilder(tableName, client) {
1090
1124
  if (Array.isArray(values)) {
1091
1125
  const executeUpsertMany = async (columns, selectOptions) => {
1092
1126
  const mergedOptions = mergeOptions(options, selectOptions);
1127
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1093
1128
  const payload = {
1094
- table_name: tableName,
1095
- insert_body: values,
1096
- update_body: options?.updateBody ? options.updateBody : void 0
1129
+ table_name: resolvedTableName,
1130
+ insert_body: asAthenaJsonObjectArray(values),
1131
+ update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
1097
1132
  };
1098
1133
  if (columns) payload.columns = columns;
1099
1134
  if (options?.onConflict) payload.on_conflict = options.onConflict;
@@ -1109,10 +1144,11 @@ function createTableBuilder(tableName, client) {
1109
1144
  }
1110
1145
  const executeUpsertOne = async (columns, selectOptions) => {
1111
1146
  const mergedOptions = mergeOptions(options, selectOptions);
1147
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1112
1148
  const payload = {
1113
- table_name: tableName,
1114
- insert_body: values,
1115
- update_body: options?.updateBody ? options.updateBody : void 0
1149
+ table_name: resolvedTableName,
1150
+ insert_body: asAthenaJsonObject(values),
1151
+ update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
1116
1152
  };
1117
1153
  if (columns) payload.columns = columns;
1118
1154
  if (options?.onConflict) payload.on_conflict = options.onConflict;
@@ -1130,9 +1166,10 @@ function createTableBuilder(tableName, client) {
1130
1166
  const executeUpdate = async (columns, selectOptions) => {
1131
1167
  const filters = state.conditions.length ? [...state.conditions] : void 0;
1132
1168
  const mergedOptions = mergeOptions(options, selectOptions);
1169
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1133
1170
  const payload = {
1134
- table_name: tableName,
1135
- set: values,
1171
+ table_name: resolvedTableName,
1172
+ set: asAthenaJsonObject(values),
1136
1173
  conditions: filters,
1137
1174
  strip_nulls: mergedOptions?.stripNulls ?? true
1138
1175
  };
@@ -1158,8 +1195,9 @@ function createTableBuilder(tableName, client) {
1158
1195
  }
1159
1196
  const executeDelete = async (columns, selectOptions) => {
1160
1197
  const mergedOptions = mergeOptions(options, selectOptions);
1198
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1161
1199
  const payload = {
1162
- table_name: tableName,
1200
+ table_name: resolvedTableName,
1163
1201
  resource_id: resourceId,
1164
1202
  conditions: filters
1165
1203
  };
@@ -2018,8 +2056,21 @@ function coerceStringArray(value) {
2018
2056
  }
2019
2057
  return [];
2020
2058
  }
2059
+ function normalizePostgresCatalogSchemas(schemas) {
2060
+ const normalized = [];
2061
+ const seen = /* @__PURE__ */ new Set();
2062
+ for (const value of schemas ?? []) {
2063
+ const schema = value.trim();
2064
+ if (!schema || seen.has(schema)) {
2065
+ continue;
2066
+ }
2067
+ seen.add(schema);
2068
+ normalized.push(schema);
2069
+ }
2070
+ return normalized.length > 0 ? normalized : ["public"];
2071
+ }
2021
2072
  function buildSchemaArrayLiteral(schemas) {
2022
- const normalized = schemas.length > 0 ? schemas : ["public"];
2073
+ const normalized = normalizePostgresCatalogSchemas(schemas);
2023
2074
  const literals = normalized.map((schema) => `'${escapeSqlLiteral(schema)}'`).join(", ");
2024
2075
  return `ARRAY[${literals}]`;
2025
2076
  }
@@ -2220,12 +2271,14 @@ var PostgresIntrospectionProvider = class {
2220
2271
  backend = "postgresql";
2221
2272
  connectionString;
2222
2273
  database;
2274
+ schemas;
2223
2275
  constructor(options) {
2224
2276
  this.connectionString = options.connectionString;
2225
2277
  this.database = options.database ?? "postgres";
2278
+ this.schemas = normalizePostgresCatalogSchemas(options.schemas);
2226
2279
  }
2227
2280
  async inspect(options) {
2228
- const schemas = options?.schemas && options.schemas.length > 0 ? options.schemas : ["public"];
2281
+ const schemas = options?.schemas && options.schemas.length > 0 ? normalizePostgresCatalogSchemas(options.schemas) : this.schemas;
2229
2282
  const pool = new Pool({
2230
2283
  connectionString: this.connectionString
2231
2284
  });
@@ -2256,6 +2309,98 @@ var PostgresIntrospectionProvider = class {
2256
2309
  function createPostgresIntrospectionProvider(options) {
2257
2310
  return new PostgresIntrospectionProvider(options);
2258
2311
  }
2312
+
2313
+ // src/schema/model-form.ts
2314
+ function resolveNullishValue(mode) {
2315
+ if (mode === "undefined") return void 0;
2316
+ if (mode === "null") return null;
2317
+ return "";
2318
+ }
2319
+ function isRecord3(value) {
2320
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2321
+ }
2322
+ function isNullableColumn(model, key) {
2323
+ const nullable = model.meta.nullable;
2324
+ return nullable?.[key] === true;
2325
+ }
2326
+ function toModelFormDefaults(model, values, options) {
2327
+ const source = values;
2328
+ if (!isRecord3(source)) {
2329
+ return {};
2330
+ }
2331
+ const mode = options?.nullishMode ?? "empty-string";
2332
+ const nullishValue = resolveNullishValue(mode);
2333
+ const result = {};
2334
+ for (const [key, value] of Object.entries(source)) {
2335
+ if (value === null && isNullableColumn(model, key)) {
2336
+ result[key] = nullishValue;
2337
+ continue;
2338
+ }
2339
+ result[key] = value;
2340
+ }
2341
+ return result;
2342
+ }
2343
+ function toModelPayload(model, formValues, options) {
2344
+ const emptyStringAsNull = options?.emptyStringAsNull ?? true;
2345
+ const stripUndefined = options?.stripUndefined ?? true;
2346
+ const result = {};
2347
+ for (const [key, rawValue] of Object.entries(formValues)) {
2348
+ if (rawValue === void 0 && stripUndefined) {
2349
+ continue;
2350
+ }
2351
+ if (emptyStringAsNull && rawValue === "" && isNullableColumn(model, key)) {
2352
+ result[key] = null;
2353
+ continue;
2354
+ }
2355
+ result[key] = rawValue;
2356
+ }
2357
+ return result;
2358
+ }
2359
+ function createModelFormAdapter(model) {
2360
+ return {
2361
+ model,
2362
+ toDefaults(values, options) {
2363
+ return toModelFormDefaults(model, values, options);
2364
+ },
2365
+ toInsert(values, options) {
2366
+ return toModelPayload(model, values, options);
2367
+ },
2368
+ toUpdate(values, options) {
2369
+ return toModelPayload(model, values, options);
2370
+ }
2371
+ };
2372
+ }
2373
+
2374
+ // src/generator/schema-selection.ts
2375
+ var DEFAULT_POSTGRES_SCHEMAS = ["public"];
2376
+ function collectSchemaNames(input) {
2377
+ if (!input) {
2378
+ return [];
2379
+ }
2380
+ const values = typeof input === "string" ? [input] : input;
2381
+ return values.flatMap((value) => String(value).split(","));
2382
+ }
2383
+ function normalizeSchemaSelection(input) {
2384
+ const schemas = [];
2385
+ const seen = /* @__PURE__ */ new Set();
2386
+ for (const value of collectSchemaNames(input)) {
2387
+ const schema = value.trim();
2388
+ if (!schema || seen.has(schema)) {
2389
+ continue;
2390
+ }
2391
+ seen.add(schema);
2392
+ schemas.push(schema);
2393
+ }
2394
+ return schemas.length > 0 ? schemas : [...DEFAULT_POSTGRES_SCHEMAS];
2395
+ }
2396
+ function resolveProviderSchemas(providerConfig) {
2397
+ if (providerConfig.kind === "postgres") {
2398
+ return normalizeSchemaSelection(providerConfig.schemas);
2399
+ }
2400
+ return [...DEFAULT_POSTGRES_SCHEMAS];
2401
+ }
2402
+
2403
+ // src/generator/config.ts
2259
2404
  var DEFAULT_CONFIG_CANDIDATES = [
2260
2405
  "athena.config.ts",
2261
2406
  "athena.config.js",
@@ -2265,8 +2410,8 @@ var DEFAULT_CONFIG_CANDIDATES = [
2265
2410
  ".athena.config.js"
2266
2411
  ];
2267
2412
  var DEFAULT_TARGETS = {
2268
- model: "athena/models/{model_kebab}.ts",
2269
- schema: "athena/schema.ts",
2413
+ model: "athena/models/{schema_kebab}/{model_kebab}.ts",
2414
+ schema: "athena/schemas/{schema_kebab}.ts",
2270
2415
  database: "athena/relations.ts",
2271
2416
  registry: "athena/config.ts"
2272
2417
  };
@@ -2296,6 +2441,15 @@ function normalizeOutputConfig(output) {
2296
2441
  }
2297
2442
  };
2298
2443
  }
2444
+ function normalizeProviderConfig(provider) {
2445
+ if (provider.kind === "postgres") {
2446
+ return {
2447
+ ...provider,
2448
+ schemas: normalizeSchemaSelection(provider.schemas)
2449
+ };
2450
+ }
2451
+ return provider;
2452
+ }
2299
2453
  function isAthenaGeneratorConfig(value) {
2300
2454
  if (!value || typeof value !== "object") {
2301
2455
  return false;
@@ -2305,7 +2459,7 @@ function isAthenaGeneratorConfig(value) {
2305
2459
  }
2306
2460
  function normalizeGeneratorConfig(input) {
2307
2461
  return {
2308
- provider: input.provider,
2462
+ provider: normalizeProviderConfig(input.provider),
2309
2463
  output: normalizeOutputConfig(input.output),
2310
2464
  naming: {
2311
2465
  ...DEFAULT_NAMING,
@@ -2802,12 +2956,19 @@ export const ${registryConstName} = defineRegistry({
2802
2956
  };
2803
2957
  }
2804
2958
  function assertNoDuplicatePaths(files) {
2805
- const seen = /* @__PURE__ */ new Set();
2959
+ const seen = /* @__PURE__ */ new Map();
2806
2960
  for (const file of files) {
2807
- if (seen.has(file.path)) {
2808
- throw new Error(`Generator output collision detected for path: ${file.path}`);
2961
+ const existing = seen.get(file.path);
2962
+ if (existing) {
2963
+ throw new Error(
2964
+ [
2965
+ `Generator output collision detected for path: ${file.path}`,
2966
+ `Collision: ${existing.kind} and ${file.kind}.`,
2967
+ "When syncing multiple schemas, include a schema placeholder such as {schema} or {schema_kebab} in model/schema output targets."
2968
+ ].join(" ")
2969
+ );
2809
2970
  }
2810
- seen.add(file.path);
2971
+ seen.set(file.path, file);
2811
2972
  }
2812
2973
  }
2813
2974
  var ArtifactComposer = class {
@@ -2967,11 +3128,13 @@ var AthenaGatewayPostgresIntrospectionProvider = class {
2967
3128
  type: this.config.backend ?? "postgresql"
2968
3129
  }
2969
3130
  });
3131
+ this.schemas = normalizeSchemaSelection(this.config.schemas);
2970
3132
  }
2971
3133
  backend = "postgresql";
2972
3134
  client;
3135
+ schemas;
2973
3136
  async inspect(options) {
2974
- const schemas = options?.schemas && options.schemas.length > 0 ? options.schemas : this.config.schemas && this.config.schemas.length > 0 ? this.config.schemas : ["public"];
3137
+ const schemas = options?.schemas && options.schemas.length > 0 ? normalizeSchemaSelection(options.schemas) : this.schemas;
2975
3138
  const catalogClient = new AthenaGatewayCatalogClient(this.client);
2976
3139
  const queries = buildGatewayCatalogQueries(schemas);
2977
3140
  const [columnRows, enumMap, primaryKeyRows, foreignKeyRows] = await Promise.all([
@@ -3007,7 +3170,8 @@ var ScyllaIntrospectionProvider = class {
3007
3170
  function createPostgresProvider(config) {
3008
3171
  return createPostgresIntrospectionProvider({
3009
3172
  connectionString: config.connectionString,
3010
- database: config.database
3173
+ database: config.database,
3174
+ schemas: normalizeSchemaSelection(config.schemas)
3011
3175
  });
3012
3176
  }
3013
3177
  function resolveGeneratorProvider(providerConfig, experimentalFlags) {
@@ -3027,12 +3191,6 @@ function resolveGeneratorProvider(providerConfig, experimentalFlags) {
3027
3191
  }
3028
3192
  throw new Error(`Unsupported generator provider kind: ${providerConfig.kind ?? "unknown"}`);
3029
3193
  }
3030
- function extractProviderSchemas(providerConfig) {
3031
- if (!("schemas" in providerConfig) || !providerConfig.schemas || providerConfig.schemas.length === 0) {
3032
- return void 0;
3033
- }
3034
- return providerConfig.schemas;
3035
- }
3036
3194
  async function writeArtifacts(files, cwd) {
3037
3195
  const writtenFiles = [];
3038
3196
  for (const file of files) {
@@ -3052,7 +3210,7 @@ async function runSchemaGenerator(options = {}) {
3052
3210
  const { configPath, config } = await loadGeneratorConfig(configOptions);
3053
3211
  const provider = options.provider ?? resolveGeneratorProvider(config.provider, config.experimental);
3054
3212
  const snapshot = await provider.inspect({
3055
- schemas: extractProviderSchemas(config.provider)
3213
+ schemas: resolveProviderSchemas(config.provider)
3056
3214
  });
3057
3215
  const generated = generateArtifactsFromSnapshot(snapshot, config);
3058
3216
  const writtenFiles = options.dryRun ? [] : await writeArtifacts(generated.files, cwd);
@@ -3063,6 +3221,497 @@ async function runSchemaGenerator(options = {}) {
3063
3221
  };
3064
3222
  }
3065
3223
 
3066
- export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, assertInt, coerceInt, createClient, createPostgresIntrospectionProvider, createTypedClient, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeGeneratorConfig, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, runSchemaGenerator, unwrap, unwrapOne, unwrapRows, withRetry };
3224
+ // src/auth/client.ts
3225
+ var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
3226
+ var FALLBACK_SDK_VERSION2 = "1.0.0";
3227
+ var SDK_NAME2 = "xylex-group/athena-auth";
3228
+ var SDK_VERSION2 = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION2;
3229
+ var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
3230
+ function normalizeBaseUrl(baseUrl) {
3231
+ return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
3232
+ }
3233
+ function isRecord4(value) {
3234
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3235
+ }
3236
+ function normalizeHeaderValue2(value) {
3237
+ return value ? value : void 0;
3238
+ }
3239
+ function parseResponseBody2(rawText, contentType) {
3240
+ if (!rawText) {
3241
+ return { parsed: null, parseFailed: false };
3242
+ }
3243
+ const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
3244
+ const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
3245
+ if (!looksJson) {
3246
+ return { parsed: rawText, parseFailed: false };
3247
+ }
3248
+ try {
3249
+ return { parsed: JSON.parse(rawText), parseFailed: false };
3250
+ } catch {
3251
+ return { parsed: rawText, parseFailed: true };
3252
+ }
3253
+ }
3254
+ function resolveRequestId2(headers) {
3255
+ return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
3256
+ }
3257
+ function resolveErrorMessage2(payload, fallback) {
3258
+ if (isRecord4(payload)) {
3259
+ const messageCandidates = [payload.error, payload.message, payload.details];
3260
+ for (const candidate of messageCandidates) {
3261
+ if (typeof candidate === "string" && candidate.trim().length > 0) {
3262
+ return candidate.trim();
3263
+ }
3264
+ }
3265
+ }
3266
+ if (typeof payload === "string" && payload.trim().length > 0) {
3267
+ return payload.trim();
3268
+ }
3269
+ return fallback;
3270
+ }
3271
+ function toErrorDetails(input) {
3272
+ return {
3273
+ code: input.code,
3274
+ message: input.message,
3275
+ status: input.status,
3276
+ endpoint: input.endpoint,
3277
+ method: input.method,
3278
+ requestId: input.requestId,
3279
+ hint: input.hint,
3280
+ cause: input.cause
3281
+ };
3282
+ }
3283
+ function mergeCallOptions(base, override) {
3284
+ if (!base && !override) return void 0;
3285
+ return {
3286
+ ...base,
3287
+ ...override,
3288
+ headers: {
3289
+ ...base?.headers ?? {},
3290
+ ...override?.headers ?? {}
3291
+ }
3292
+ };
3293
+ }
3294
+ function extractFetchOptions(input) {
3295
+ if (!input) {
3296
+ return {
3297
+ payload: void 0,
3298
+ fetchOptions: void 0
3299
+ };
3300
+ }
3301
+ const { fetchOptions, ...rest } = input;
3302
+ const hasPayloadKeys = Object.keys(rest).length > 0;
3303
+ return {
3304
+ payload: hasPayloadKeys ? rest : void 0,
3305
+ fetchOptions
3306
+ };
3307
+ }
3308
+ function buildHeaders2(config, options) {
3309
+ const headers = {
3310
+ "Content-Type": "application/json",
3311
+ "X-Athena-Sdk": SDK_HEADER_VALUE2
3312
+ };
3313
+ const apiKey = options?.apiKey ?? config.apiKey;
3314
+ if (apiKey) {
3315
+ headers.apikey = apiKey;
3316
+ headers["x-api-key"] = apiKey;
3317
+ }
3318
+ const bearerToken = options?.bearerToken ?? config.bearerToken;
3319
+ if (bearerToken) {
3320
+ headers.Authorization = `Bearer ${bearerToken}`;
3321
+ }
3322
+ const mergedExtraHeaders = {
3323
+ ...config.headers ?? {},
3324
+ ...options?.headers ?? {}
3325
+ };
3326
+ Object.entries(mergedExtraHeaders).forEach(([key, value]) => {
3327
+ const normalized = normalizeHeaderValue2(value);
3328
+ if (normalized) {
3329
+ headers[key] = normalized;
3330
+ }
3331
+ });
3332
+ return headers;
3333
+ }
3334
+ function appendQueryParam(searchParams, key, value) {
3335
+ if (value === void 0 || value === null) return;
3336
+ if (Array.isArray(value)) {
3337
+ value.forEach((item) => {
3338
+ searchParams.append(key, String(item));
3339
+ });
3340
+ return;
3341
+ }
3342
+ searchParams.append(key, String(value));
3343
+ }
3344
+ function buildRequestUrl(baseUrl, endpoint, query) {
3345
+ const url = `${baseUrl}${endpoint}`;
3346
+ if (!query || Object.keys(query).length === 0) return url;
3347
+ const searchParams = new URLSearchParams();
3348
+ Object.entries(query).forEach(([key, value]) => appendQueryParam(searchParams, key, value));
3349
+ const queryText = searchParams.toString();
3350
+ return queryText ? `${url}?${queryText}` : url;
3351
+ }
3352
+ function inferDefaultMethod(endpoint) {
3353
+ if (endpoint.startsWith("/reset-password/")) {
3354
+ return "GET";
3355
+ }
3356
+ switch (endpoint) {
3357
+ case "/get-session":
3358
+ case "/list-sessions":
3359
+ case "/verify-email":
3360
+ case "/delete-user/callback":
3361
+ case "/list-accounts":
3362
+ case "/ok":
3363
+ case "/error":
3364
+ return "GET";
3365
+ default:
3366
+ return "POST";
3367
+ }
3368
+ }
3369
+ async function callAuthEndpoint(config, context, body, query, options) {
3370
+ const baseUrl = normalizeBaseUrl(options?.baseUrl ?? config.baseUrl);
3371
+ const url = buildRequestUrl(baseUrl, context.endpoint, query);
3372
+ const headers = buildHeaders2(config, options);
3373
+ const credentials = options?.credentials ?? config.credentials ?? "include";
3374
+ const requestInit = {
3375
+ method: context.method,
3376
+ headers,
3377
+ credentials,
3378
+ signal: options?.signal
3379
+ };
3380
+ if (context.method !== "GET") {
3381
+ requestInit.body = JSON.stringify(body ?? {});
3382
+ }
3383
+ const fetcher = config.fetch ?? globalThis.fetch;
3384
+ if (!fetcher) {
3385
+ const details = toErrorDetails({
3386
+ code: "UNKNOWN_ERROR",
3387
+ message: "No fetch implementation available for auth client",
3388
+ status: 0,
3389
+ endpoint: context.endpoint,
3390
+ method: context.method,
3391
+ hint: "Use Node 18+ or provide `fetch` in createAuthClient({ fetch })"
3392
+ });
3393
+ return {
3394
+ ok: false,
3395
+ status: 0,
3396
+ data: null,
3397
+ error: details.message,
3398
+ errorDetails: details,
3399
+ raw: null
3400
+ };
3401
+ }
3402
+ try {
3403
+ const response = await fetcher(url, requestInit);
3404
+ const rawText = await response.text();
3405
+ const requestId = resolveRequestId2(response.headers);
3406
+ const parsedBody = parseResponseBody2(rawText ?? "", response.headers.get("content-type"));
3407
+ if (parsedBody.parseFailed) {
3408
+ const details = toErrorDetails({
3409
+ code: "INVALID_JSON",
3410
+ message: "Auth server returned malformed JSON",
3411
+ status: response.status,
3412
+ endpoint: context.endpoint,
3413
+ method: context.method,
3414
+ requestId,
3415
+ hint: "Verify the auth endpoint response body is valid JSON.",
3416
+ cause: rawText.slice(0, 300)
3417
+ });
3418
+ return {
3419
+ ok: false,
3420
+ status: response.status,
3421
+ data: null,
3422
+ error: details.message,
3423
+ errorDetails: details,
3424
+ raw: parsedBody.parsed
3425
+ };
3426
+ }
3427
+ const parsed = parsedBody.parsed;
3428
+ if (!response.ok) {
3429
+ const details = toErrorDetails({
3430
+ code: "HTTP_ERROR",
3431
+ message: resolveErrorMessage2(
3432
+ parsed,
3433
+ `Auth endpoint ${context.method} ${context.endpoint} failed with status ${response.status}`
3434
+ ),
3435
+ status: response.status,
3436
+ endpoint: context.endpoint,
3437
+ method: context.method,
3438
+ requestId
3439
+ });
3440
+ return {
3441
+ ok: false,
3442
+ status: response.status,
3443
+ data: null,
3444
+ error: details.message,
3445
+ errorDetails: details,
3446
+ raw: parsed
3447
+ };
3448
+ }
3449
+ return {
3450
+ ok: true,
3451
+ status: response.status,
3452
+ data: parsed ?? null,
3453
+ error: null,
3454
+ errorDetails: null,
3455
+ raw: parsed
3456
+ };
3457
+ } catch (callError) {
3458
+ const message = callError instanceof Error ? callError.message : String(callError);
3459
+ const details = toErrorDetails({
3460
+ code: "NETWORK_ERROR",
3461
+ message: `Network error while calling ${context.method} ${context.endpoint}: ${message}`,
3462
+ status: 0,
3463
+ endpoint: context.endpoint,
3464
+ method: context.method,
3465
+ cause: message,
3466
+ hint: "Check auth server URL, DNS, and network reachability."
3467
+ });
3468
+ return {
3469
+ ok: false,
3470
+ status: 0,
3471
+ data: null,
3472
+ error: details.message,
3473
+ errorDetails: details,
3474
+ raw: null
3475
+ };
3476
+ }
3477
+ }
3478
+ function executePostWithCompatibleInput(config, context, input, options) {
3479
+ const { payload, fetchOptions } = extractFetchOptions(input);
3480
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3481
+ return callAuthEndpoint(config, context, payload ?? {}, void 0, mergedOptions);
3482
+ }
3483
+ function executePostWithOptionalInput(config, context, input, options) {
3484
+ const { fetchOptions } = extractFetchOptions(input);
3485
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3486
+ return callAuthEndpoint(config, context, {}, void 0, mergedOptions);
3487
+ }
3488
+ function executeGetWithCompatibleInput(config, context, input, options) {
3489
+ const { fetchOptions } = extractFetchOptions(input);
3490
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3491
+ return callAuthEndpoint(config, context, void 0, void 0, mergedOptions);
3492
+ }
3493
+ function createAuthClient(config = {}) {
3494
+ const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
3495
+ const resolvedConfig = {
3496
+ ...config,
3497
+ baseUrl: normalizedBaseUrl
3498
+ };
3499
+ const request = (input, options) => {
3500
+ const method = input.method ?? (input.body !== void 0 ? "POST" : inferDefaultMethod(input.endpoint));
3501
+ const mergedOptions = mergeCallOptions(input.fetchOptions, options);
3502
+ return callAuthEndpoint(
3503
+ resolvedConfig,
3504
+ { endpoint: input.endpoint, method },
3505
+ input.body,
3506
+ input.query,
3507
+ mergedOptions
3508
+ );
3509
+ };
3510
+ const signOut = (input, options) => executePostWithOptionalInput(
3511
+ resolvedConfig,
3512
+ { endpoint: "/sign-out", method: "POST" },
3513
+ input,
3514
+ options
3515
+ );
3516
+ const revokeSessions = (input, options) => executePostWithOptionalInput(
3517
+ resolvedConfig,
3518
+ { endpoint: "/revoke-sessions", method: "POST" },
3519
+ input,
3520
+ options
3521
+ );
3522
+ const revokeOtherSessions = (input, options) => executePostWithOptionalInput(
3523
+ resolvedConfig,
3524
+ { endpoint: "/revoke-other-sessions", method: "POST" },
3525
+ input,
3526
+ options
3527
+ );
3528
+ const revokeSession = (input, options) => executePostWithCompatibleInput(
3529
+ resolvedConfig,
3530
+ { endpoint: "/revoke-session", method: "POST" },
3531
+ input,
3532
+ options
3533
+ );
3534
+ const deleteUser = (input, options) => {
3535
+ const { payload, fetchOptions } = extractFetchOptions(input);
3536
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3537
+ return callAuthEndpoint(
3538
+ resolvedConfig,
3539
+ { endpoint: "/delete-user", method: "POST" },
3540
+ payload ?? {},
3541
+ void 0,
3542
+ mergedOptions
3543
+ );
3544
+ };
3545
+ const deleteUserCallback = (input, options) => {
3546
+ const { payload, fetchOptions } = extractFetchOptions(input);
3547
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3548
+ const query = payload ?? {};
3549
+ return callAuthEndpoint(
3550
+ resolvedConfig,
3551
+ { endpoint: "/delete-user/callback", method: "GET" },
3552
+ void 0,
3553
+ {
3554
+ token: query.token,
3555
+ callbackURL: query.callbackURL
3556
+ },
3557
+ mergedOptions
3558
+ );
3559
+ };
3560
+ const resolveResetPasswordToken = (input, options) => {
3561
+ const { payload, fetchOptions } = extractFetchOptions(input);
3562
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3563
+ const query = payload;
3564
+ const token = query?.token?.trim();
3565
+ if (!token) {
3566
+ throw new Error("resolveResetPasswordToken requires a non-empty token");
3567
+ }
3568
+ const endpoint = `/reset-password/${encodeURIComponent(token)}`;
3569
+ return callAuthEndpoint(
3570
+ resolvedConfig,
3571
+ { endpoint, method: "GET" },
3572
+ void 0,
3573
+ query?.callbackURL ? { callbackURL: query.callbackURL } : void 0,
3574
+ mergedOptions
3575
+ );
3576
+ };
3577
+ return {
3578
+ baseUrl: normalizedBaseUrl,
3579
+ request,
3580
+ signIn: {
3581
+ email: (input, options) => executePostWithCompatibleInput(
3582
+ resolvedConfig,
3583
+ { endpoint: "/sign-in/email", method: "POST" },
3584
+ input,
3585
+ options
3586
+ ),
3587
+ username: (input, options) => executePostWithCompatibleInput(
3588
+ resolvedConfig,
3589
+ { endpoint: "/sign-in/username", method: "POST" },
3590
+ input,
3591
+ options
3592
+ ),
3593
+ social: (input, options) => executePostWithCompatibleInput(
3594
+ resolvedConfig,
3595
+ { endpoint: "/sign-in/social", method: "POST" },
3596
+ input,
3597
+ options
3598
+ )
3599
+ },
3600
+ signUp: {
3601
+ email: (input, options) => executePostWithCompatibleInput(
3602
+ resolvedConfig,
3603
+ { endpoint: "/sign-up/email", method: "POST" },
3604
+ input,
3605
+ options
3606
+ )
3607
+ },
3608
+ signOut,
3609
+ logout: signOut,
3610
+ getSession: (input, options) => executeGetWithCompatibleInput(
3611
+ resolvedConfig,
3612
+ { endpoint: "/get-session", method: "GET" },
3613
+ input,
3614
+ options
3615
+ ),
3616
+ listSessions: (input, options) => executeGetWithCompatibleInput(
3617
+ resolvedConfig,
3618
+ { endpoint: "/list-sessions", method: "GET" },
3619
+ input,
3620
+ options
3621
+ ),
3622
+ revokeSession,
3623
+ clearSession: revokeSession,
3624
+ revokeSessions,
3625
+ clearSessions: revokeSessions,
3626
+ revokeOtherSessions,
3627
+ clearOtherSessions: revokeOtherSessions,
3628
+ forgetPassword: (input, options) => executePostWithCompatibleInput(
3629
+ resolvedConfig,
3630
+ { endpoint: "/forget-password", method: "POST" },
3631
+ input,
3632
+ options
3633
+ ),
3634
+ resetPassword: (input, options) => executePostWithCompatibleInput(
3635
+ resolvedConfig,
3636
+ { endpoint: "/reset-password", method: "POST" },
3637
+ input,
3638
+ options
3639
+ ),
3640
+ resolveResetPasswordToken,
3641
+ verifyEmail: (input, options) => {
3642
+ const { payload, fetchOptions } = extractFetchOptions(input);
3643
+ const mergedOptions = mergeCallOptions(fetchOptions, options);
3644
+ const query = payload;
3645
+ return callAuthEndpoint(
3646
+ resolvedConfig,
3647
+ { endpoint: "/verify-email", method: "GET" },
3648
+ void 0,
3649
+ query ? {
3650
+ token: query.token,
3651
+ callbackURL: query.callbackURL
3652
+ } : void 0,
3653
+ mergedOptions
3654
+ );
3655
+ },
3656
+ sendVerificationEmail: (input, options) => executePostWithCompatibleInput(
3657
+ resolvedConfig,
3658
+ { endpoint: "/send-verification-email", method: "POST" },
3659
+ input,
3660
+ options
3661
+ ),
3662
+ changeEmail: (input, options) => executePostWithCompatibleInput(
3663
+ resolvedConfig,
3664
+ { endpoint: "/change-email", method: "POST" },
3665
+ input,
3666
+ options
3667
+ ),
3668
+ changePassword: (input, options) => executePostWithCompatibleInput(
3669
+ resolvedConfig,
3670
+ { endpoint: "/change-password", method: "POST" },
3671
+ input,
3672
+ options
3673
+ ),
3674
+ updateUser: (input, options) => executePostWithCompatibleInput(
3675
+ resolvedConfig,
3676
+ { endpoint: "/update-user", method: "POST" },
3677
+ input,
3678
+ options
3679
+ ),
3680
+ deleteUser,
3681
+ deleteUserCallback,
3682
+ linkSocial: (input, options) => executePostWithCompatibleInput(
3683
+ resolvedConfig,
3684
+ { endpoint: "/link-social", method: "POST" },
3685
+ input,
3686
+ options
3687
+ ),
3688
+ listAccounts: (input, options) => executeGetWithCompatibleInput(
3689
+ resolvedConfig,
3690
+ { endpoint: "/list-accounts", method: "GET" },
3691
+ input,
3692
+ options
3693
+ ),
3694
+ unlinkAccount: (input, options) => executePostWithCompatibleInput(
3695
+ resolvedConfig,
3696
+ { endpoint: "/unlink-account", method: "POST" },
3697
+ input,
3698
+ options
3699
+ ),
3700
+ refreshToken: (input, options) => executePostWithCompatibleInput(
3701
+ resolvedConfig,
3702
+ { endpoint: "/refresh-token", method: "POST" },
3703
+ input,
3704
+ options
3705
+ ),
3706
+ getAccessToken: (input, options) => executePostWithCompatibleInput(
3707
+ resolvedConfig,
3708
+ { endpoint: "/get-access-token", method: "POST" },
3709
+ input,
3710
+ options
3711
+ )
3712
+ };
3713
+ }
3714
+
3715
+ export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeGeneratorConfig, normalizeSchemaSelection, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, withRetry };
3067
3716
  //# sourceMappingURL=index.js.map
3068
3717
  //# sourceMappingURL=index.js.map