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