@xylex-group/athena 2.8.2 → 2.10.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.
Files changed (52) hide show
  1. package/README.md +154 -64
  2. package/dist/browser.cjs +1550 -181
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.cts +8 -7
  5. package/dist/browser.d.ts +8 -7
  6. package/dist/browser.js +1540 -182
  7. package/dist/browser.js.map +1 -1
  8. package/dist/cli/index.cjs +1337 -67
  9. package/dist/cli/index.cjs.map +1 -1
  10. package/dist/cli/index.d.cts +3 -3
  11. package/dist/cli/index.d.ts +3 -3
  12. package/dist/cli/index.js +1337 -67
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/{model-form-Cx3wtvi8.d.ts → client-B7EQ_hPV.d.cts} +606 -118
  15. package/dist/{model-form-_ugfOXao.d.cts → client-BYii6dU9.d.ts} +606 -118
  16. package/dist/index.cjs +1540 -113
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +8 -7
  19. package/dist/index.d.ts +8 -7
  20. package/dist/index.js +1530 -114
  21. package/dist/index.js.map +1 -1
  22. package/dist/model-form-ByvyyvxB.d.ts +96 -0
  23. package/dist/model-form-DACdBLYG.d.cts +96 -0
  24. package/dist/{react-email-CiiSVa9F.d.cts → module-DC96HJa3.d.cts} +130 -5
  25. package/dist/{react-email-WN8UU3AL.d.ts → module-DbHlxpeR.d.ts} +130 -5
  26. package/dist/next/client.cjs +8591 -0
  27. package/dist/next/client.cjs.map +1 -0
  28. package/dist/next/client.d.cts +24 -0
  29. package/dist/next/client.d.ts +24 -0
  30. package/dist/next/client.js +8589 -0
  31. package/dist/next/client.js.map +1 -0
  32. package/dist/next/server.cjs +8709 -0
  33. package/dist/next/server.cjs.map +1 -0
  34. package/dist/next/server.d.cts +52 -0
  35. package/dist/next/server.d.ts +52 -0
  36. package/dist/next/server.js +8706 -0
  37. package/dist/next/server.js.map +1 -0
  38. package/dist/{pipeline-BtD-Uo5X.d.cts → pipeline-CmUZsXsi.d.cts} +1 -1
  39. package/dist/{pipeline-yCIZNJHE.d.ts → pipeline-DZMsPxUg.d.ts} +1 -1
  40. package/dist/react.cjs +30 -1
  41. package/dist/react.cjs.map +1 -1
  42. package/dist/react.d.cts +38 -10
  43. package/dist/react.d.ts +38 -10
  44. package/dist/react.js +30 -2
  45. package/dist/react.js.map +1 -1
  46. package/dist/shared-BMVGMnti.d.cts +35 -0
  47. package/dist/shared-DRptGBWP.d.ts +35 -0
  48. package/dist/{types-g8G6J0xE.d.cts → types-BeZIHduP.d.cts} +2 -1
  49. package/dist/{types-g8G6J0xE.d.ts → types-BeZIHduP.d.ts} +2 -1
  50. package/dist/{types-C2kiTt6-.d.ts → types-C-YvfgYh.d.cts} +26 -2
  51. package/dist/{types-89EfjLjV.d.cts → types-CRjDwmtJ.d.ts} +26 -2
  52. package/package.json +32 -14
package/dist/cli/index.js CHANGED
@@ -686,6 +686,77 @@ function resolveProviderSchemas(providerConfig) {
686
686
  return [...DEFAULT_POSTGRES_SCHEMAS];
687
687
  }
688
688
 
689
+ // src/generator/table-selection.ts
690
+ function normalizeTableSelector(value) {
691
+ const trimmed = value.trim();
692
+ return trimmed.length > 0 ? trimmed : void 0;
693
+ }
694
+ function normalizeTableSelection(value) {
695
+ if (typeof value === "string") {
696
+ return Array.from(
697
+ new Set(
698
+ value.split(",").map(normalizeTableSelector).filter((entry) => Boolean(entry))
699
+ )
700
+ );
701
+ }
702
+ if (Array.isArray(value)) {
703
+ return Array.from(
704
+ new Set(
705
+ value.map((entry) => typeof entry === "string" ? normalizeTableSelector(entry) : void 0).filter((entry) => Boolean(entry))
706
+ )
707
+ );
708
+ }
709
+ return [];
710
+ }
711
+ function matchesTableSelector(schemaName, tableName, selector) {
712
+ const separatorIndex = selector.indexOf(".");
713
+ if (separatorIndex < 0) {
714
+ return tableName === selector;
715
+ }
716
+ const selectorSchema = selector.slice(0, separatorIndex).trim();
717
+ const selectorTable = selector.slice(separatorIndex + 1).trim();
718
+ return selectorSchema === schemaName && selectorTable === tableName;
719
+ }
720
+ function shouldKeepTable(schemaName, tableName, filter) {
721
+ const included = filter.includeTables.length === 0 || filter.includeTables.some((selector) => matchesTableSelector(schemaName, tableName, selector));
722
+ if (!included) {
723
+ return false;
724
+ }
725
+ return !filter.excludeTables.some((selector) => matchesTableSelector(schemaName, tableName, selector));
726
+ }
727
+ function hasTableFilters(filter) {
728
+ return filter.includeTables.length > 0 || filter.excludeTables.length > 0;
729
+ }
730
+ function filterIntrospectionSnapshot(snapshot, filter) {
731
+ if (!hasTableFilters(filter)) {
732
+ return snapshot;
733
+ }
734
+ const schemas = {};
735
+ for (const [schemaName, schema] of Object.entries(snapshot.schemas)) {
736
+ const tables = Object.fromEntries(
737
+ Object.entries(schema.tables).filter(([tableName]) => shouldKeepTable(schemaName, tableName, filter))
738
+ );
739
+ if (Object.keys(tables).length === 0) {
740
+ continue;
741
+ }
742
+ schemas[schemaName] = {
743
+ ...schema,
744
+ tables
745
+ };
746
+ }
747
+ if (Object.keys(schemas).length === 0) {
748
+ const includeLabel = filter.includeTables.length > 0 ? ` includeTables=${filter.includeTables.join(", ")}` : "";
749
+ const excludeLabel = filter.excludeTables.length > 0 ? ` excludeTables=${filter.excludeTables.join(", ")}` : "";
750
+ throw new Error(
751
+ `Generator table filters matched no tables after schema selection.${includeLabel}${excludeLabel}`
752
+ );
753
+ }
754
+ return {
755
+ ...snapshot,
756
+ schemas
757
+ };
758
+ }
759
+
689
760
  // src/generator/config.ts
690
761
  var POSTGRES_PROTOCOLS = /* @__PURE__ */ new Set(["postgres:", "postgresql:"]);
691
762
  var DEFAULT_CONFIG_CANDIDATES = [
@@ -696,13 +767,20 @@ var DEFAULT_CONFIG_CANDIDATES = [
696
767
  ".athena.config.ts",
697
768
  ".athena.config.js"
698
769
  ];
699
- var DEFAULT_TARGETS = {
770
+ var LEGACY_DEFAULT_TARGETS = {
700
771
  model: "athena/models/{schema_kebab}/{model_kebab}.ts",
701
772
  schema: "athena/schemas/{schema_kebab}.ts",
702
773
  database: "athena/relations.ts",
703
774
  registry: "athena/config.ts"
704
775
  };
705
- var DEFAULT_OUTPUT_FORMAT = "define-model";
776
+ var ATHENA_DIRECT_TARGETS = {
777
+ model: "athena/models/{schema_kebab}/{model_kebab}.ts",
778
+ schema: "athena/schemas/{schema_kebab}.ts",
779
+ database: "athena/relations.ts",
780
+ registry: "athena/registry.generated.ts"
781
+ };
782
+ var DEFAULT_OUTPUT_FORMAT = "table-builder";
783
+ var DEFAULT_OUTPUT_PRESET = "athena-direct";
706
784
  var DEFAULT_NAMING = {
707
785
  modelType: "pascal",
708
786
  modelConst: "camel",
@@ -721,6 +799,10 @@ var DEFAULT_EXPERIMENTAL_FLAGS = {
721
799
  var DEFAULT_INTERNAL_CONFIG = {
722
800
  schemaVersion: 1
723
801
  };
802
+ var DEFAULT_FILTER_CONFIG = {
803
+ includeTables: [],
804
+ excludeTables: []
805
+ };
724
806
  var PROJECT_ENV_FILENAMES = [".env", ".env.local"];
725
807
  var DIRECT_CONNECTION_STRING_ENV_KEYS = [
726
808
  "ATHENA_GENERATOR_PG_URL",
@@ -739,10 +821,13 @@ var GATEWAY_API_KEY_ENV_KEYS = [
739
821
  ];
740
822
  var GENERATOR_SCHEMA_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMAS"];
741
823
  var OUTPUT_FORMAT_ENV_KEYS = ["ATHENA_GENERATOR_OUTPUT_FORMAT"];
824
+ var OUTPUT_PRESET_ENV_KEYS = ["ATHENA_GENERATOR_OUTPUT_PRESET"];
742
825
  var MODEL_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_TARGET"];
743
826
  var SCHEMA_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMA_TARGET"];
744
827
  var DATABASE_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_DATABASE_TARGET"];
745
828
  var REGISTRY_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_REGISTRY_TARGET"];
829
+ var TABLES_ENV_KEYS = ["ATHENA_GENERATOR_TABLES"];
830
+ var EXCLUDE_TABLES_ENV_KEYS = ["ATHENA_GENERATOR_EXCLUDE_TABLES"];
746
831
  var PLACEHOLDER_MAP_ENV_KEYS = ["ATHENA_GENERATOR_PLACEHOLDER_MAP"];
747
832
  var MODEL_TYPE_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_TYPE", "ATHENA_GENERATOR_MODEL_STYLE"];
748
833
  var MODEL_CONST_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_CONST"];
@@ -757,7 +842,12 @@ var SCYLLA_PROVIDER_CONTRACTS_ENV_KEYS = ["ATHENA_GENERATOR_SCYLLA_PROVIDER_CONT
757
842
  var ENV_ONLY_CONFIG_PATH = "[environment defaults]";
758
843
  var NAMING_STYLE_VALUES = ["preserve", "camel", "pascal", "snake", "kebab"];
759
844
  var OUTPUT_FORMAT_VALUES = ["define-model", "table-builder"];
845
+ var OUTPUT_PRESET_VALUES = ["legacy", "athena-direct"];
760
846
  var BACKEND_TYPE_VALUES = ["athena", "postgrest", "postgresql", "scylladb"];
847
+ var OUTPUT_PRESET_TARGETS = {
848
+ legacy: LEGACY_DEFAULT_TARGETS,
849
+ "athena-direct": ATHENA_DIRECT_TARGETS
850
+ };
761
851
  function normalizeRawEnvValue(rawValue) {
762
852
  if (rawValue.startsWith('"') && rawValue.endsWith('"') && rawValue.length >= 2) {
763
853
  const inner = rawValue.slice(1, -1);
@@ -964,11 +1054,19 @@ function normalizeExperimentalFlags(input) {
964
1054
  )
965
1055
  };
966
1056
  }
1057
+ function normalizeFilterConfig(input) {
1058
+ return {
1059
+ includeTables: normalizeTableSelection(input?.includeTables),
1060
+ excludeTables: normalizeTableSelection(input?.excludeTables)
1061
+ };
1062
+ }
967
1063
  function normalizeOutputConfig(output) {
1064
+ const preset = output?.preset ?? DEFAULT_OUTPUT_PRESET;
968
1065
  return {
969
1066
  format: output?.format ?? DEFAULT_OUTPUT_FORMAT,
1067
+ preset,
970
1068
  targets: {
971
- ...DEFAULT_TARGETS,
1069
+ ...OUTPUT_PRESET_TARGETS[preset],
972
1070
  ...output?.targets ?? {}
973
1071
  },
974
1072
  placeholderMap: {
@@ -1048,6 +1146,10 @@ function normalizeGeneratorConfig(input) {
1048
1146
  ...DEFAULT_NAMING,
1049
1147
  ...input.naming ?? {}
1050
1148
  },
1149
+ filter: {
1150
+ ...DEFAULT_FILTER_CONFIG,
1151
+ ...normalizeFilterConfig(input.filter)
1152
+ },
1051
1153
  features: normalizeFeatureFlags(input.features),
1052
1154
  experimental: normalizeExperimentalFlags(input.experimental),
1053
1155
  internal: {
@@ -1108,16 +1210,18 @@ function importConfigModule(moduleSpecifier) {
1108
1210
  }
1109
1211
  function buildEnvironmentOutputConfig() {
1110
1212
  const format = resolveOptionalOneOf(OUTPUT_FORMAT_ENV_KEYS, OUTPUT_FORMAT_VALUES);
1213
+ const preset = resolveOptionalOneOf(OUTPUT_PRESET_ENV_KEYS, OUTPUT_PRESET_VALUES);
1111
1214
  const modelTarget = resolveFallbackValue(MODEL_TARGET_ENV_KEYS);
1112
1215
  const schemaTarget = resolveFallbackValue(SCHEMA_TARGET_ENV_KEYS);
1113
1216
  const databaseTarget = resolveFallbackValue(DATABASE_TARGET_ENV_KEYS);
1114
1217
  const registryTarget = resolveFallbackValue(REGISTRY_TARGET_ENV_KEYS);
1115
1218
  const placeholderMap = resolveOptionalJson(PLACEHOLDER_MAP_ENV_KEYS);
1116
- if (format === void 0 && modelTarget === void 0 && schemaTarget === void 0 && databaseTarget === void 0 && registryTarget === void 0 && placeholderMap === void 0) {
1219
+ if (format === void 0 && preset === void 0 && modelTarget === void 0 && schemaTarget === void 0 && databaseTarget === void 0 && registryTarget === void 0 && placeholderMap === void 0) {
1117
1220
  return void 0;
1118
1221
  }
1119
1222
  return {
1120
1223
  format,
1224
+ preset,
1121
1225
  targets: {
1122
1226
  ...modelTarget ? { model: modelTarget } : {},
1123
1227
  ...schemaTarget ? { schema: schemaTarget } : {},
@@ -1127,6 +1231,17 @@ function buildEnvironmentOutputConfig() {
1127
1231
  placeholderMap
1128
1232
  };
1129
1233
  }
1234
+ function buildEnvironmentFilterConfig() {
1235
+ const includeTables = resolveFallbackValue(TABLES_ENV_KEYS);
1236
+ const excludeTables = resolveFallbackValue(EXCLUDE_TABLES_ENV_KEYS);
1237
+ if (includeTables === void 0 && excludeTables === void 0) {
1238
+ return void 0;
1239
+ }
1240
+ return {
1241
+ ...includeTables !== void 0 ? { includeTables } : {},
1242
+ ...excludeTables !== void 0 ? { excludeTables } : {}
1243
+ };
1244
+ }
1130
1245
  function buildEnvironmentNamingConfig() {
1131
1246
  const modelType = resolveOptionalOneOf(MODEL_TYPE_ENV_KEYS, NAMING_STYLE_VALUES);
1132
1247
  const modelConst = resolveOptionalOneOf(MODEL_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
@@ -1202,6 +1317,7 @@ function createEnvironmentGeneratorConfig() {
1202
1317
  provider,
1203
1318
  output: buildEnvironmentOutputConfig(),
1204
1319
  naming: buildEnvironmentNamingConfig(),
1320
+ filter: buildEnvironmentFilterConfig(),
1205
1321
  features: buildEnvironmentFeatureFlags(),
1206
1322
  experimental: buildEnvironmentExperimentalFlags()
1207
1323
  };
@@ -1363,7 +1479,7 @@ ${schemaEntries}
1363
1479
  content
1364
1480
  };
1365
1481
  }
1366
- function renderRegistryArtifact(registryPath, databasePath, databaseConstName, registryConstName, databaseName, generatedAt, outputFormat, schemaVersion) {
1482
+ function renderRegistryArtifact(registryPath, databasePath, databaseConstName, registryConstName, databaseName, generatedAt, outputPreset, outputFormat, schemaVersion) {
1367
1483
  const databaseImportPath = toModuleImportPath(registryPath, databasePath);
1368
1484
  const content = `import { defineRegistry } from '@xylex-group/athena'
1369
1485
  import { ${databaseConstName} } from '${databaseImportPath}'
@@ -1372,6 +1488,7 @@ export const __athena_schema_meta = {
1372
1488
  schemaVersion: ${schemaVersion},
1373
1489
  generatedAt: ${escapeStringLiteral(generatedAt)},
1374
1490
  database: ${escapeStringLiteral(databaseName)},
1491
+ outputPreset: ${escapeStringLiteral(outputPreset)},
1375
1492
  outputFormat: ${escapeStringLiteral(outputFormat)},
1376
1493
  } as const
1377
1494
 
@@ -1541,6 +1658,7 @@ function composeGeneratorArtifacts(input) {
1541
1658
  toSafeIdentifier("registry", config.naming.registryConst, "registry"),
1542
1659
  databaseName,
1543
1660
  snapshot.generatedAt,
1661
+ config.output.preset,
1544
1662
  config.output.format,
1545
1663
  config.internal.schemaVersion
1546
1664
  )
@@ -1646,7 +1764,7 @@ export const ${descriptor.tableConstName} = table(${escapeStringLiteral(descript
1646
1764
  .columns({
1647
1765
  ${columnLines}
1648
1766
  })
1649
- .primaryKey(${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")})
1767
+ ${descriptor.table.primaryKey.length > 0 ? `.primaryKey(${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")})` : ".withoutPrimaryKey()"}
1650
1768
  ${relationsAssignment ? `${relationsAssignment}` : ""}
1651
1769
  export type ${descriptor.rowTypeName} = RowOf<typeof ${descriptor.tableConstName}>
1652
1770
  export type ${descriptor.insertTypeName} = InsertOf<typeof ${descriptor.tableConstName}>
@@ -1743,11 +1861,12 @@ ${nullableLines}
1743
1861
  }
1744
1862
  function generateArtifactsFromSnapshot(snapshot, config) {
1745
1863
  const normalizedConfig = "internal" in config ? config : normalizeGeneratorConfig(config);
1864
+ const filteredSnapshot = filterIntrospectionSnapshot(snapshot, normalizedConfig.filter);
1746
1865
  if (normalizedConfig.output.format === "table-builder") {
1747
- return generateTableBuilderArtifactsFromSnapshot(snapshot, normalizedConfig);
1866
+ return generateTableBuilderArtifactsFromSnapshot(filteredSnapshot, normalizedConfig);
1748
1867
  }
1749
1868
  return composeGeneratorArtifacts({
1750
- snapshot,
1869
+ snapshot: filteredSnapshot,
1751
1870
  config: normalizedConfig,
1752
1871
  createModelDescriptor({ providerName, databaseName, schemaName, tableName, table }) {
1753
1872
  const modelConstName = toSafeIdentifier(
@@ -1777,7 +1896,7 @@ function generateArtifactsFromSnapshot(snapshot, config) {
1777
1896
  table
1778
1897
  };
1779
1898
  },
1780
- renderModelArtifact: (descriptor) => renderModelArtifact2(snapshot.database, descriptor, normalizedConfig)
1899
+ renderModelArtifact: (descriptor) => renderModelArtifact2(filteredSnapshot.database, descriptor, normalizedConfig)
1781
1900
  });
1782
1901
  }
1783
1902
 
@@ -1859,8 +1978,8 @@ function parseCookies(cookieHeader) {
1859
1978
  });
1860
1979
  return cookieMap;
1861
1980
  }
1862
- var getSessionCookie = (request, config) => {
1863
- const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
1981
+ var getSessionCookie = (request2, config) => {
1982
+ const cookies = (request2 instanceof Headers || !("headers" in request2) ? request2 : request2.headers).get("cookie");
1864
1983
  if (!cookies) {
1865
1984
  return null;
1866
1985
  }
@@ -1883,7 +2002,7 @@ var getSessionCookie = (request, config) => {
1883
2002
 
1884
2003
  // package.json
1885
2004
  var package_default = {
1886
- version: "2.8.2"
2005
+ version: "2.10.0"
1887
2006
  };
1888
2007
 
1889
2008
  // src/sdk-version.ts
@@ -1896,6 +2015,7 @@ function buildSdkHeaderValue(sdkName) {
1896
2015
  var DEFAULT_CLIENT = "railway_direct";
1897
2016
  var SDK_NAME = "xylex-group/athena";
1898
2017
  var SDK_HEADER_VALUE = buildSdkHeaderValue(SDK_NAME);
2018
+ var NO_CACHE_HEADER_VALUE = "no-cache";
1899
2019
  function parseResponseBody(rawText, contentType) {
1900
2020
  if (!rawText) {
1901
2021
  return { parsed: null, parseFailed: false };
@@ -1914,6 +2034,9 @@ function parseResponseBody(rawText, contentType) {
1914
2034
  function normalizeHeaderValue(value) {
1915
2035
  return value ? value : void 0;
1916
2036
  }
2037
+ function isCacheControlHeaderName(name) {
2038
+ return name.toLowerCase() === "cache-control";
2039
+ }
1917
2040
  function resolveHeaderValue(headers, candidates) {
1918
2041
  for (const candidate of candidates) {
1919
2042
  const direct = normalizeHeaderValue(headers[candidate]);
@@ -2072,6 +2195,7 @@ function buildRpcGetEndpoint(payload) {
2072
2195
  }
2073
2196
  function buildHeaders(config, options) {
2074
2197
  const mergedStripNulls = options?.stripNulls ?? true;
2198
+ const forceNoCache = Boolean(config.forceNoCache || options?.forceNoCache);
2075
2199
  const extraHeaders = {
2076
2200
  ...config.headers ?? {},
2077
2201
  ...options?.headers ?? {}
@@ -2125,11 +2249,15 @@ function buildHeaders(config, options) {
2125
2249
  const athenaClientKeys = ["x-athena-client", "X-Athena-Client"];
2126
2250
  Object.entries(extraHeaders).forEach(([key, value]) => {
2127
2251
  if (athenaClientKeys.includes(key)) return;
2252
+ if (forceNoCache && isCacheControlHeaderName(key)) return;
2128
2253
  const normalized = normalizeHeaderValue(value);
2129
2254
  if (normalized) {
2130
2255
  headers[key] = normalized;
2131
2256
  }
2132
2257
  });
2258
+ if (forceNoCache) {
2259
+ headers["Cache-Control"] = NO_CACHE_HEADER_VALUE;
2260
+ }
2133
2261
  return headers;
2134
2262
  }
2135
2263
  function toInvalidUrlResponse(error, endpoint, method) {
@@ -2569,6 +2697,35 @@ function quoteSelectColumnsExpression(columns) {
2569
2697
  }
2570
2698
  return tokens.map(quoteSelectToken).join(", ");
2571
2699
  }
2700
+ var ATHENA_AUTH_MAX_TEMPLATE_VARIABLES = 64;
2701
+ var ATHENA_AUTH_MAX_TEMPLATE_VARIABLE_LENGTH = 128;
2702
+ function describeTemplateVariableTarget(target) {
2703
+ const normalized = target?.trim();
2704
+ return normalized && normalized.length > 0 ? normalized : "Athena auth admin email template variables";
2705
+ }
2706
+ function assertAthenaAuthTemplateVariables(variables, target) {
2707
+ const label = describeTemplateVariableTarget(target);
2708
+ if (!Array.isArray(variables)) {
2709
+ throw new Error(`${label} must be an array of strings.`);
2710
+ }
2711
+ if (variables.length > ATHENA_AUTH_MAX_TEMPLATE_VARIABLES) {
2712
+ throw new Error(
2713
+ `${label} cannot contain more than ${ATHENA_AUTH_MAX_TEMPLATE_VARIABLES} entries.`
2714
+ );
2715
+ }
2716
+ variables.forEach((variable, index) => {
2717
+ if (typeof variable !== "string") {
2718
+ throw new Error(
2719
+ `${label} must contain only strings. Received ${typeof variable} at index ${index}.`
2720
+ );
2721
+ }
2722
+ if (variable.length > ATHENA_AUTH_MAX_TEMPLATE_VARIABLE_LENGTH) {
2723
+ throw new Error(
2724
+ `${label} cannot contain entries longer than ${ATHENA_AUTH_MAX_TEMPLATE_VARIABLE_LENGTH} characters. Received ${variable.length} characters at index ${index}.`
2725
+ );
2726
+ }
2727
+ });
2728
+ }
2572
2729
 
2573
2730
  // src/auth/react-email.ts
2574
2731
  var reactEmailRenderModulePromise;
@@ -2758,6 +2915,7 @@ async function resolveReactEmailPayloadFields(input, fields, options) {
2758
2915
  var DEFAULT_AUTH_BASE_URL = "http://localhost:3001/api/auth";
2759
2916
  var SDK_NAME2 = "xylex-group/athena-auth";
2760
2917
  var SDK_HEADER_VALUE2 = buildSdkHeaderValue(SDK_NAME2);
2918
+ var NO_CACHE_HEADER_VALUE2 = "no-cache";
2761
2919
  function normalizeBaseUrl(baseUrl) {
2762
2920
  return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
2763
2921
  }
@@ -2767,6 +2925,9 @@ function isRecord4(value) {
2767
2925
  function normalizeHeaderValue2(value) {
2768
2926
  return value ? value : void 0;
2769
2927
  }
2928
+ function isCacheControlHeaderName2(name) {
2929
+ return name.toLowerCase() === "cache-control";
2930
+ }
2770
2931
  function parseResponseBody2(rawText, contentType) {
2771
2932
  if (!rawText) {
2772
2933
  return { parsed: null, parseFailed: false };
@@ -2822,6 +2983,98 @@ function mergeCallOptions(base, override) {
2822
2983
  }
2823
2984
  };
2824
2985
  }
2986
+ function copyDefinedField(target, source, targetKey, sourceKey) {
2987
+ if (!(sourceKey in source)) {
2988
+ return;
2989
+ }
2990
+ const value = source[sourceKey];
2991
+ if (value !== void 0) {
2992
+ target[targetKey] = value;
2993
+ }
2994
+ }
2995
+ function normalizeAdminEmailTemplatePayload(payload) {
2996
+ const normalized = { ...payload };
2997
+ copyDefinedField(normalized, payload, "template_key", "templateKey");
2998
+ copyDefinedField(normalized, payload, "event_type", "eventType");
2999
+ copyDefinedField(normalized, payload, "subject_template", "subjectTemplate");
3000
+ copyDefinedField(normalized, payload, "text_template", "textTemplate");
3001
+ copyDefinedField(normalized, payload, "html_template", "htmlTemplate");
3002
+ copyDefinedField(normalized, payload, "variable_bindings", "variableBindings");
3003
+ copyDefinedField(normalized, payload, "attachment_failure_mode", "attachmentFailureMode");
3004
+ copyDefinedField(normalized, payload, "is_active", "isActive");
3005
+ return normalized;
3006
+ }
3007
+ function toReactEmailTemplateCompatibilityInput(input) {
3008
+ const payload = input;
3009
+ const compatibility = { ...payload };
3010
+ copyDefinedField(compatibility, payload, "templateKey", "template_key");
3011
+ copyDefinedField(compatibility, payload, "eventType", "event_type");
3012
+ copyDefinedField(compatibility, payload, "subjectTemplate", "subject_template");
3013
+ copyDefinedField(compatibility, payload, "textTemplate", "text_template");
3014
+ copyDefinedField(compatibility, payload, "htmlTemplate", "html_template");
3015
+ copyDefinedField(compatibility, payload, "variableBindings", "variable_bindings");
3016
+ copyDefinedField(compatibility, payload, "attachmentFailureMode", "attachment_failure_mode");
3017
+ copyDefinedField(compatibility, payload, "isActive", "is_active");
3018
+ return compatibility;
3019
+ }
3020
+ function normalizeAdminEmailTemplateSendPayload(payload) {
3021
+ const normalized = { ...payload };
3022
+ copyDefinedField(normalized, payload, "template_id", "templateId");
3023
+ copyDefinedField(normalized, payload, "recipient_email", "recipientEmail");
3024
+ copyDefinedField(normalized, payload, "render_variables", "renderVariables");
3025
+ copyDefinedField(normalized, payload, "user_id", "userId");
3026
+ copyDefinedField(normalized, payload, "organization_id", "organizationId");
3027
+ copyDefinedField(normalized, payload, "session_token", "sessionToken");
3028
+ return normalized;
3029
+ }
3030
+ function toSessionGuardFailure(sessionResult) {
3031
+ if (sessionResult.status === 401 || sessionResult.data == null) {
3032
+ return {
3033
+ ok: false,
3034
+ reason: "unauthorized",
3035
+ status: 401,
3036
+ error: sessionResult.error ?? "Unauthorized",
3037
+ sessionResult
3038
+ };
3039
+ }
3040
+ return {
3041
+ ok: false,
3042
+ reason: "upstream_error",
3043
+ status: sessionResult.status,
3044
+ error: sessionResult.error ?? "Failed to resolve current session",
3045
+ sessionResult
3046
+ };
3047
+ }
3048
+ function toPermissionGuardFailure(permissionResult, sessionResult) {
3049
+ if (permissionResult.status === 401) {
3050
+ return {
3051
+ ok: false,
3052
+ reason: "unauthorized",
3053
+ status: 401,
3054
+ error: permissionResult.error ?? "Unauthorized",
3055
+ sessionResult,
3056
+ permissionResult
3057
+ };
3058
+ }
3059
+ if (permissionResult.status === 403) {
3060
+ return {
3061
+ ok: false,
3062
+ reason: "forbidden",
3063
+ status: 403,
3064
+ error: permissionResult.error ?? "Forbidden",
3065
+ sessionResult,
3066
+ permissionResult
3067
+ };
3068
+ }
3069
+ return {
3070
+ ok: false,
3071
+ reason: "upstream_error",
3072
+ status: permissionResult.status,
3073
+ error: permissionResult.error ?? "Failed to resolve permission check",
3074
+ sessionResult,
3075
+ permissionResult
3076
+ };
3077
+ }
2825
3078
  function extractFetchOptions(input) {
2826
3079
  if (!input) {
2827
3080
  return {
@@ -2837,6 +3090,7 @@ function extractFetchOptions(input) {
2837
3090
  };
2838
3091
  }
2839
3092
  function buildHeaders2(config, options) {
3093
+ const forceNoCache = Boolean(config.forceNoCache || options?.forceNoCache);
2840
3094
  const headers = {
2841
3095
  "Content-Type": "application/json",
2842
3096
  "X-Athena-Sdk": SDK_HEADER_VALUE2
@@ -2850,16 +3104,30 @@ function buildHeaders2(config, options) {
2850
3104
  if (bearerToken) {
2851
3105
  headers.Authorization = `Bearer ${bearerToken}`;
2852
3106
  }
3107
+ const cookie = options?.cookie ?? config.cookie;
3108
+ if (cookie) {
3109
+ headers.Cookie = cookie;
3110
+ }
3111
+ const sessionToken = options?.sessionToken ?? config.sessionToken;
3112
+ if (sessionToken) {
3113
+ headers["X-Athena-Auth-Session-Token"] = sessionToken;
3114
+ }
2853
3115
  const mergedExtraHeaders = {
2854
3116
  ...config.headers ?? {},
2855
3117
  ...options?.headers ?? {}
2856
3118
  };
2857
3119
  Object.entries(mergedExtraHeaders).forEach(([key, value]) => {
3120
+ if (forceNoCache && isCacheControlHeaderName2(key)) {
3121
+ return;
3122
+ }
2858
3123
  const normalized = normalizeHeaderValue2(value);
2859
3124
  if (normalized) {
2860
3125
  headers[key] = normalized;
2861
3126
  }
2862
3127
  });
3128
+ if (forceNoCache) {
3129
+ headers["Cache-Control"] = NO_CACHE_HEADER_VALUE2;
3130
+ }
2863
3131
  return headers;
2864
3132
  }
2865
3133
  function appendQueryParam(searchParams, key, value) {
@@ -3065,7 +3333,7 @@ function createAuthClient(config = {}) {
3065
3333
  ...config,
3066
3334
  baseUrl: normalizedBaseUrl
3067
3335
  };
3068
- const request = (input, options) => {
3336
+ const request2 = (input, options) => {
3069
3337
  const method = input.method ?? (input.body !== void 0 ? "POST" : inferDefaultMethod(input.endpoint));
3070
3338
  const mergedOptions = mergeCallOptions(input.fetchOptions, options);
3071
3339
  return callAuthEndpoint(
@@ -3078,7 +3346,7 @@ function createAuthClient(config = {}) {
3078
3346
  };
3079
3347
  const postGeneric = (endpoint, input, options) => {
3080
3348
  const { payload, fetchOptions } = extractFetchOptions(input);
3081
- return request(
3349
+ return request2(
3082
3350
  {
3083
3351
  endpoint,
3084
3352
  method: "POST",
@@ -3090,7 +3358,7 @@ function createAuthClient(config = {}) {
3090
3358
  };
3091
3359
  const getGeneric = (endpoint, input, options) => {
3092
3360
  const { fetchOptions } = extractFetchOptions(input);
3093
- return request(
3361
+ return request2(
3094
3362
  {
3095
3363
  endpoint,
3096
3364
  method: "GET",
@@ -3102,7 +3370,7 @@ function createAuthClient(config = {}) {
3102
3370
  const getWithQuery = (endpoint, input, options) => {
3103
3371
  const { payload, fetchOptions } = extractFetchOptions(input);
3104
3372
  const query = payload?.query;
3105
- return request(
3373
+ return request2(
3106
3374
  {
3107
3375
  endpoint,
3108
3376
  method: "GET",
@@ -3120,11 +3388,96 @@ function createAuthClient(config = {}) {
3120
3388
  htmlField: "htmlBody",
3121
3389
  textField: "textBody"
3122
3390
  }, withReactEmailRoute(route));
3123
- const resolveAdminEmailTemplatePayload = (route, input) => resolveReactEmailPayloadFields(input, {
3391
+ const resolveAdminEmailTemplatePayload = (route, input) => resolveReactEmailPayloadFields(toReactEmailTemplateCompatibilityInput(input), {
3124
3392
  htmlField: "htmlTemplate",
3125
3393
  textField: "textTemplate",
3126
3394
  variablesField: "variables"
3127
- }, withReactEmailRoute(route));
3395
+ }, withReactEmailRoute(route)).then((payload) => {
3396
+ const normalizedPayload = normalizeAdminEmailTemplatePayload(payload);
3397
+ if ("variables" in payload && payload.variables !== void 0 && payload.variables !== null) {
3398
+ assertAthenaAuthTemplateVariables(
3399
+ payload.variables,
3400
+ `${route} variables`
3401
+ );
3402
+ }
3403
+ return normalizedPayload;
3404
+ });
3405
+ const requireSession = async (input, options) => {
3406
+ const sessionInput = input?.fetchOptions ? { fetchOptions: input.fetchOptions } : void 0;
3407
+ const sessionResult = await getGeneric(
3408
+ "/get-session",
3409
+ sessionInput,
3410
+ options
3411
+ );
3412
+ if (!sessionResult.ok || sessionResult.data == null) {
3413
+ return toSessionGuardFailure(sessionResult);
3414
+ }
3415
+ return {
3416
+ ok: true,
3417
+ session: sessionResult.data
3418
+ };
3419
+ };
3420
+ const getUser = async (input, options) => {
3421
+ const sessionResult = await getGeneric(
3422
+ "/get-session",
3423
+ input,
3424
+ options
3425
+ );
3426
+ if (!sessionResult.ok) {
3427
+ return {
3428
+ ...sessionResult,
3429
+ data: null
3430
+ };
3431
+ }
3432
+ return {
3433
+ ...sessionResult,
3434
+ data: {
3435
+ user: sessionResult.data?.user ?? null
3436
+ }
3437
+ };
3438
+ };
3439
+ const requirePermission = async (endpoint, input, options) => {
3440
+ const sessionGuard = await requireSession(
3441
+ input?.fetchOptions ? { fetchOptions: input.fetchOptions } : void 0,
3442
+ options
3443
+ );
3444
+ if (!sessionGuard.ok) {
3445
+ return sessionGuard;
3446
+ }
3447
+ const permissionResult = await postGeneric(
3448
+ endpoint,
3449
+ input,
3450
+ options
3451
+ );
3452
+ if (!permissionResult.ok) {
3453
+ return toPermissionGuardFailure(permissionResult, {
3454
+ ok: true,
3455
+ status: 200,
3456
+ data: sessionGuard.session,
3457
+ error: null,
3458
+ errorDetails: null,
3459
+ raw: sessionGuard.session
3460
+ });
3461
+ }
3462
+ if (!permissionResult.data?.success) {
3463
+ return {
3464
+ ok: false,
3465
+ reason: "forbidden",
3466
+ status: 403,
3467
+ error: permissionResult.data?.error ?? "Forbidden",
3468
+ sessionResult: {
3469
+ ok: true,
3470
+ status: 200,
3471
+ data: sessionGuard.session,
3472
+ error: null,
3473
+ errorDetails: null,
3474
+ raw: sessionGuard.session
3475
+ },
3476
+ permissionResult
3477
+ };
3478
+ }
3479
+ return sessionGuard;
3480
+ };
3128
3481
  const listUserEmailsWithFallback = async (input, options) => {
3129
3482
  const primary = await getWithQuery(
3130
3483
  "/email/list",
@@ -3286,6 +3639,7 @@ function createAuthClient(config = {}) {
3286
3639
  input,
3287
3640
  options
3288
3641
  ),
3642
+ requirePermission: (input, options) => requirePermission("/organization/has-permission", input, options),
3289
3643
  invitation: {
3290
3644
  cancel: (input, options) => executePostWithCompatibleInput(
3291
3645
  resolvedConfig,
@@ -3481,6 +3835,8 @@ function createAuthClient(config = {}) {
3481
3835
  };
3482
3836
  const auth = {
3483
3837
  getSession: (input, options) => getGeneric("/get-session", input, options),
3838
+ getUser,
3839
+ requireSession,
3484
3840
  signOut,
3485
3841
  forgetPassword: (input, options) => postGeneric("/forget-password", input, options),
3486
3842
  resetPassword: authResetPassword,
@@ -3575,6 +3931,7 @@ function createAuthClient(config = {}) {
3575
3931
  }
3576
3932
  },
3577
3933
  hasPermission: (input, options) => postGeneric("/admin/has-permission", input, options),
3934
+ requirePermission: (input, options) => requirePermission("/admin/has-permission", input, options),
3578
3935
  apiKey: {
3579
3936
  create: (input, options) => postGeneric("/admin/api-key/create", input, options)
3580
3937
  },
@@ -3619,7 +3976,15 @@ function createAuthClient(config = {}) {
3619
3976
  await resolveAdminEmailTemplatePayload("/admin/email-template/update", input),
3620
3977
  options
3621
3978
  ),
3622
- delete: (input, options) => postGeneric("/admin/email-template/delete", input, options)
3979
+ delete: (input, options) => postGeneric("/admin/email-template/delete", input, options),
3980
+ send: (input, options) => postGeneric(
3981
+ "/admin/email-template/send",
3982
+ normalizeAdminEmailTemplateSendPayload(extractFetchOptions(input).payload),
3983
+ options
3984
+ )
3985
+ },
3986
+ eventType: {
3987
+ list: (input, options) => getWithQuery("/admin/email-event-type/list", input, options)
3623
3988
  }
3624
3989
  },
3625
3990
  emailTemplate: {
@@ -3635,7 +4000,15 @@ function createAuthClient(config = {}) {
3635
4000
  "/admin/email-template/update",
3636
4001
  await resolveAdminEmailTemplatePayload("/admin/email-template/update", input),
3637
4002
  options
4003
+ ),
4004
+ send: (input, options) => postGeneric(
4005
+ "/admin/email-template/send",
4006
+ normalizeAdminEmailTemplateSendPayload(extractFetchOptions(input).payload),
4007
+ options
3638
4008
  )
4009
+ },
4010
+ emailEventType: {
4011
+ list: (input, options) => getWithQuery("/admin/email-event-type/list", input, options)
3639
4012
  }
3640
4013
  },
3641
4014
  apiKey: {
@@ -3675,7 +4048,7 @@ function createAuthClient(config = {}) {
3675
4048
  throw new Error("callback.provider requires non-empty code and state values");
3676
4049
  }
3677
4050
  const endpoint = `/callback/${encodeURIComponent(provider)}`;
3678
- return request({
4051
+ return request2({
3679
4052
  endpoint,
3680
4053
  method: "GET",
3681
4054
  query: {
@@ -3689,7 +4062,7 @@ function createAuthClient(config = {}) {
3689
4062
  };
3690
4063
  return {
3691
4064
  baseUrl: normalizedBaseUrl,
3692
- request,
4065
+ request: request2,
3693
4066
  signIn: {
3694
4067
  email: (input, options) => executePostWithCompatibleInput(
3695
4068
  resolvedConfig,
@@ -3726,6 +4099,8 @@ function createAuthClient(config = {}) {
3726
4099
  input,
3727
4100
  options
3728
4101
  ),
4102
+ getUser,
4103
+ requireSession,
3729
4104
  listSessions: (input, options) => executeGetWithCompatibleInput(
3730
4105
  resolvedConfig,
3731
4106
  { endpoint: "/list-sessions", method: "GET" },
@@ -3889,16 +4264,16 @@ function createStorageFileModule(base, config = {}) {
3889
4264
  };
3890
4265
  });
3891
4266
  input.onProgress?.(createProgressSnapshot("preparing", sources, 0, 0, 0));
3892
- const uploadUrls = uploadRequests.length === 1 ? [await base.createStorageUploadUrl(uploadRequests[0].uploadRequest, options)] : (await base.createStorageUploadUrls({ files: uploadRequests.map((request) => request.uploadRequest) }, options)).files;
4267
+ const uploadUrls = uploadRequests.length === 1 ? [await base.createStorageUploadUrl(uploadRequests[0].uploadRequest, options)] : (await base.createStorageUploadUrls({ files: uploadRequests.map((request2) => request2.uploadRequest) }, options)).files;
3893
4268
  const aggregateLoaded = new Array(uploadRequests.length).fill(0);
3894
4269
  const uploaded = [];
3895
4270
  for (let index = 0; index < uploadRequests.length; index += 1) {
3896
- const request = uploadRequests[index];
4271
+ const request2 = uploadRequests[index];
3897
4272
  const uploadUrl = uploadUrls[index];
3898
4273
  const response = await putUploadBody(
3899
4274
  uploadUrl.upload.url,
3900
4275
  uploadUrl.upload.headers ?? {},
3901
- request.source,
4276
+ request2.source,
3902
4277
  input,
3903
4278
  options,
3904
4279
  (progress) => {
@@ -3909,13 +4284,13 @@ function createStorageFileModule(base, config = {}) {
3909
4284
  uploaded.push({
3910
4285
  file: uploadUrl.file,
3911
4286
  upload: uploadUrl.upload,
3912
- source: request.source.source,
3913
- fileName: request.source.fileName,
3914
- storage_key: request.uploadRequest.storage_key,
4287
+ source: request2.source.source,
4288
+ fileName: request2.source.fileName,
4289
+ storage_key: request2.uploadRequest.storage_key,
3915
4290
  response
3916
4291
  });
3917
- aggregateLoaded[index] = request.source.sizeBytes;
3918
- input.onProgress?.(createProgressSnapshot("complete", sources, index, request.source.sizeBytes, sum(aggregateLoaded)));
4292
+ aggregateLoaded[index] = request2.source.sizeBytes;
4293
+ input.onProgress?.(createProgressSnapshot("complete", sources, index, request2.source.sizeBytes, sum(aggregateLoaded)));
3919
4294
  }
3920
4295
  return {
3921
4296
  files: uploaded,
@@ -5876,6 +6251,484 @@ function createStorageModule(gateway, runtimeOptions) {
5876
6251
  };
5877
6252
  }
5878
6253
 
6254
+ // src/chat/module.ts
6255
+ var SDK_NAME3 = "xylex-group/athena-chat";
6256
+ var SDK_HEADER_VALUE3 = buildSdkHeaderValue(SDK_NAME3);
6257
+ var NO_CACHE_HEADER_VALUE3 = "no-cache";
6258
+ var AthenaChatError = class extends Error {
6259
+ status;
6260
+ endpoint;
6261
+ method;
6262
+ requestId;
6263
+ body;
6264
+ constructor(input) {
6265
+ super(input.message);
6266
+ this.name = "AthenaChatError";
6267
+ this.status = input.status;
6268
+ this.endpoint = input.endpoint;
6269
+ this.method = input.method;
6270
+ this.requestId = input.requestId;
6271
+ this.body = input.body;
6272
+ }
6273
+ };
6274
+ function deriveRealtimeInfoUrl(wsUrl) {
6275
+ if (!wsUrl) {
6276
+ return void 0;
6277
+ }
6278
+ const parsed = new URL(normalizeWsUrl(wsUrl, "Athena chat WebSocket URL"));
6279
+ parsed.protocol = parsed.protocol === "wss:" ? "https:" : "http:";
6280
+ parsed.pathname = parsed.pathname.replace(/\/wss\/gateway$/, "/wss/info");
6281
+ return parsed.toString();
6282
+ }
6283
+ function normalizeWsUrl(value, label) {
6284
+ const normalized = value.trim();
6285
+ if (!normalized) {
6286
+ throw new Error(`${label} is required.`);
6287
+ }
6288
+ let parsed;
6289
+ try {
6290
+ parsed = new URL(normalized);
6291
+ } catch {
6292
+ throw new Error(`${label} must be a valid absolute ws(s) URL.`);
6293
+ }
6294
+ if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
6295
+ throw new Error(`${label} must use ws or wss.`);
6296
+ }
6297
+ parsed.pathname = parsed.pathname.replace(/\/+$/, "");
6298
+ return parsed.toString().replace(/\/$/, "");
6299
+ }
6300
+ function isRecord7(value) {
6301
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6302
+ }
6303
+ function normalizeHeaderValue3(value) {
6304
+ return value ? value : void 0;
6305
+ }
6306
+ function parseResponseBody4(rawText, contentType) {
6307
+ if (!rawText) {
6308
+ return { parsed: null, parseFailed: false };
6309
+ }
6310
+ const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
6311
+ const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
6312
+ if (!looksJson) {
6313
+ return { parsed: rawText, parseFailed: false };
6314
+ }
6315
+ try {
6316
+ return { parsed: JSON.parse(rawText), parseFailed: false };
6317
+ } catch {
6318
+ return { parsed: rawText, parseFailed: true };
6319
+ }
6320
+ }
6321
+ function resolveRequestId3(headers) {
6322
+ return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
6323
+ }
6324
+ function resolveErrorMessage4(payload, fallback) {
6325
+ if (isRecord7(payload)) {
6326
+ for (const candidate of [payload.error, payload.message, payload.details]) {
6327
+ if (typeof candidate === "string" && candidate.trim().length > 0) {
6328
+ return candidate.trim();
6329
+ }
6330
+ }
6331
+ }
6332
+ if (typeof payload === "string" && payload.trim().length > 0) {
6333
+ return payload.trim();
6334
+ }
6335
+ return fallback;
6336
+ }
6337
+ function encodePathSegment(value, label) {
6338
+ const normalized = value.trim();
6339
+ if (!normalized) {
6340
+ throw new Error(`${label} is required.`);
6341
+ }
6342
+ return encodeURIComponent(normalized);
6343
+ }
6344
+ function encodeQuery(query) {
6345
+ if (!query) {
6346
+ return "";
6347
+ }
6348
+ const params = new URLSearchParams();
6349
+ for (const [key, value] of Object.entries(query)) {
6350
+ if (value === void 0 || value === null) {
6351
+ continue;
6352
+ }
6353
+ if (Array.isArray(value)) {
6354
+ for (const item of value) {
6355
+ if (item !== void 0 && item !== null) {
6356
+ params.append(key, String(item));
6357
+ }
6358
+ }
6359
+ continue;
6360
+ }
6361
+ params.set(key, String(value));
6362
+ }
6363
+ const encoded = params.toString();
6364
+ return encoded ? `?${encoded}` : "";
6365
+ }
6366
+ function createSocket(factory, url, protocols) {
6367
+ try {
6368
+ return new factory(url, protocols);
6369
+ } catch (error) {
6370
+ if (error instanceof TypeError) {
6371
+ return factory(url, protocols);
6372
+ }
6373
+ throw error;
6374
+ }
6375
+ }
6376
+ function buildHeaders3(config, options) {
6377
+ const headers = {
6378
+ Accept: "application/json",
6379
+ apikey: config.apiKey,
6380
+ "x-api-key": config.apiKey,
6381
+ "X-Athena-Sdk": SDK_HEADER_VALUE3
6382
+ };
6383
+ if (config.client || options?.client) {
6384
+ headers["X-Athena-Client"] = options?.client ?? config.client ?? "";
6385
+ }
6386
+ const bearerToken = options?.bearerToken ?? config.bearerToken;
6387
+ if (typeof bearerToken === "string" && bearerToken.trim()) {
6388
+ headers.Authorization = bearerToken.startsWith("Bearer ") ? bearerToken : `Bearer ${bearerToken}`;
6389
+ }
6390
+ const cookie = options?.cookie ?? config.cookie;
6391
+ if (typeof cookie === "string" && cookie.trim()) {
6392
+ headers.Cookie = cookie;
6393
+ }
6394
+ const sessionToken = options?.sessionToken ?? config.sessionToken;
6395
+ if (typeof sessionToken === "string" && sessionToken.trim()) {
6396
+ headers["X-Athena-Auth-Session-Token"] = sessionToken;
6397
+ }
6398
+ if (config.forceNoCache || options?.forceNoCache) {
6399
+ headers["Cache-Control"] = NO_CACHE_HEADER_VALUE3;
6400
+ }
6401
+ for (const source of [config.headers, options?.headers]) {
6402
+ for (const [key, value] of Object.entries(source ?? {})) {
6403
+ const normalized = normalizeHeaderValue3(value);
6404
+ if (normalized) {
6405
+ headers[key] = normalized;
6406
+ }
6407
+ }
6408
+ }
6409
+ return headers;
6410
+ }
6411
+ function withJsonBody(init, body) {
6412
+ return {
6413
+ ...init,
6414
+ body: body === void 0 ? void 0 : JSON.stringify(body),
6415
+ headers: {
6416
+ "Content-Type": "application/json",
6417
+ ...init.headers
6418
+ }
6419
+ };
6420
+ }
6421
+ async function request(config, method, endpoint, options, body) {
6422
+ if (!config.baseUrl) {
6423
+ throw new Error(
6424
+ "Athena chat base URL is not configured. Pass createClient({ url }) for unified routing or set chat.url / chatUrl explicitly."
6425
+ );
6426
+ }
6427
+ const url = `${config.baseUrl}${endpoint}`;
6428
+ const init = {
6429
+ method,
6430
+ headers: buildHeaders3(config, options),
6431
+ signal: options?.signal
6432
+ };
6433
+ const finalInit = body === void 0 || method === "GET" ? init : withJsonBody(init, body);
6434
+ const response = await fetch(url, finalInit);
6435
+ const rawText = await response.text();
6436
+ const { parsed } = parseResponseBody4(rawText, response.headers.get("content-type"));
6437
+ if (!response.ok) {
6438
+ throw new AthenaChatError({
6439
+ message: resolveErrorMessage4(parsed, `Athena chat ${method} ${endpoint} failed with ${response.status}`),
6440
+ status: response.status,
6441
+ endpoint,
6442
+ method,
6443
+ requestId: resolveRequestId3(response.headers),
6444
+ body: parsed
6445
+ });
6446
+ }
6447
+ return parsed;
6448
+ }
6449
+ function createRealtimeConnection(config, options) {
6450
+ if (!config.wsUrl) {
6451
+ throw new Error(
6452
+ "Athena chat WebSocket URL is not configured. Pass createClient({ url }) for unified routing or set chat.wsUrl / chatWsUrl explicitly."
6453
+ );
6454
+ }
6455
+ const wsFactory = config.webSocketFactory ?? globalThis.WebSocket;
6456
+ if (!wsFactory) {
6457
+ throw new Error(
6458
+ "No WebSocket implementation is available. Provide chat.webSocketFactory in createClient(...) or run in a runtime with global WebSocket support."
6459
+ );
6460
+ }
6461
+ const socket = createSocket(wsFactory, config.wsUrl, options?.protocols);
6462
+ const send = (command) => {
6463
+ socket.send(JSON.stringify(command));
6464
+ };
6465
+ if (options?.onMessage) {
6466
+ const listener = (event) => {
6467
+ const messageEvent = event;
6468
+ const raw = messageEvent?.data;
6469
+ if (typeof raw !== "string") {
6470
+ return;
6471
+ }
6472
+ try {
6473
+ options.onMessage?.(JSON.parse(raw));
6474
+ } catch {
6475
+ options.onMessage?.({ type: "error", error: "Invalid JSON message from Athena chat realtime gateway." });
6476
+ }
6477
+ };
6478
+ if (typeof socket.addEventListener === "function") {
6479
+ socket.addEventListener("message", listener);
6480
+ } else {
6481
+ socket.onmessage = listener;
6482
+ }
6483
+ }
6484
+ const hello = (command) => {
6485
+ send({
6486
+ type: "auth.hello",
6487
+ token: command?.token,
6488
+ room_subscriptions: command?.room_subscriptions
6489
+ });
6490
+ };
6491
+ if (options?.hello) {
6492
+ const onOpen = () => hello({
6493
+ token: options.hello?.token ?? void 0,
6494
+ room_subscriptions: options.hello?.room_subscriptions ?? void 0
6495
+ });
6496
+ if (typeof socket.addEventListener === "function") {
6497
+ socket.addEventListener("open", onOpen);
6498
+ } else {
6499
+ socket.onopen = onOpen;
6500
+ }
6501
+ }
6502
+ return {
6503
+ socket,
6504
+ send,
6505
+ hello,
6506
+ subscribe(roomId, fromSeq) {
6507
+ send({
6508
+ type: "chat.subscribe",
6509
+ room_id: roomId,
6510
+ from_seq: fromSeq ?? void 0
6511
+ });
6512
+ },
6513
+ unsubscribe(roomId) {
6514
+ send({
6515
+ type: "chat.unsubscribe",
6516
+ room_id: roomId
6517
+ });
6518
+ },
6519
+ resume(rooms) {
6520
+ send({
6521
+ type: "chat.resume",
6522
+ rooms
6523
+ });
6524
+ },
6525
+ typingStart(roomId) {
6526
+ send({
6527
+ type: "chat.typing.start",
6528
+ room_id: roomId
6529
+ });
6530
+ },
6531
+ typingStop(roomId) {
6532
+ send({
6533
+ type: "chat.typing.stop",
6534
+ room_id: roomId
6535
+ });
6536
+ },
6537
+ presenceHeartbeat(activeRoomId) {
6538
+ send({
6539
+ type: "chat.presence.heartbeat",
6540
+ active_room_id: activeRoomId ?? void 0
6541
+ });
6542
+ },
6543
+ readUpTo(roomId, input) {
6544
+ send({
6545
+ type: "chat.read.up_to",
6546
+ room_id: roomId,
6547
+ message_id: input?.message_id ?? void 0,
6548
+ seq: input?.seq ?? void 0
6549
+ });
6550
+ },
6551
+ ping(at = (/* @__PURE__ */ new Date()).toISOString()) {
6552
+ send({
6553
+ type: "ping",
6554
+ at
6555
+ });
6556
+ },
6557
+ close(code, reason) {
6558
+ socket.close(code, reason);
6559
+ }
6560
+ };
6561
+ }
6562
+ function createChatModule(config) {
6563
+ const realtime = {
6564
+ info(options) {
6565
+ const realtimeInfoUrl = config.realtimeInfoUrl ?? deriveRealtimeInfoUrl(config.wsUrl);
6566
+ if (!realtimeInfoUrl) {
6567
+ throw new Error(
6568
+ "Athena chat realtime info URL is not configured. Pass createClient({ url }) for unified routing or set chat.wsUrl / chatWsUrl explicitly."
6569
+ );
6570
+ }
6571
+ return request(
6572
+ {
6573
+ ...config,
6574
+ baseUrl: realtimeInfoUrl
6575
+ },
6576
+ "GET",
6577
+ "",
6578
+ options
6579
+ );
6580
+ },
6581
+ connect(options) {
6582
+ return createRealtimeConnection(config, options);
6583
+ }
6584
+ };
6585
+ return {
6586
+ room: {
6587
+ list(query, options) {
6588
+ return request(
6589
+ config,
6590
+ "GET",
6591
+ `/rooms${encodeQuery(query)}`,
6592
+ options
6593
+ );
6594
+ },
6595
+ create(input, options) {
6596
+ return request(config, "POST", "/rooms", options, input);
6597
+ },
6598
+ get(roomId, options) {
6599
+ return request(
6600
+ config,
6601
+ "GET",
6602
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}`,
6603
+ options
6604
+ );
6605
+ },
6606
+ update(roomId, input, options) {
6607
+ return request(
6608
+ config,
6609
+ "PATCH",
6610
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}`,
6611
+ options,
6612
+ input
6613
+ );
6614
+ },
6615
+ archive(roomId, options) {
6616
+ return request(
6617
+ config,
6618
+ "POST",
6619
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/archive`,
6620
+ options
6621
+ );
6622
+ },
6623
+ readCursor: {
6624
+ upTo(roomId, input, options) {
6625
+ return request(
6626
+ config,
6627
+ "POST",
6628
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/read-cursor`,
6629
+ options,
6630
+ input ?? {}
6631
+ );
6632
+ }
6633
+ },
6634
+ member: {
6635
+ list(roomId, options) {
6636
+ return request(
6637
+ config,
6638
+ "GET",
6639
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/members`,
6640
+ options
6641
+ );
6642
+ },
6643
+ add(roomId, input, options) {
6644
+ return request(
6645
+ config,
6646
+ "POST",
6647
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/members`,
6648
+ options,
6649
+ input
6650
+ );
6651
+ },
6652
+ remove(roomId, userId, options) {
6653
+ return request(
6654
+ config,
6655
+ "DELETE",
6656
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/members/${encodePathSegment(userId, "chat user ID")}`,
6657
+ options
6658
+ );
6659
+ }
6660
+ },
6661
+ message: {
6662
+ list(roomId, query, options) {
6663
+ return request(
6664
+ config,
6665
+ "GET",
6666
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/messages${encodeQuery(query)}`,
6667
+ options
6668
+ );
6669
+ },
6670
+ send(roomId, input, options) {
6671
+ return request(
6672
+ config,
6673
+ "POST",
6674
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/messages`,
6675
+ options,
6676
+ input
6677
+ );
6678
+ },
6679
+ update(roomId, messageId, input, options) {
6680
+ return request(
6681
+ config,
6682
+ "PATCH",
6683
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/messages/${encodePathSegment(messageId, "chat message ID")}`,
6684
+ options,
6685
+ input
6686
+ );
6687
+ },
6688
+ delete(roomId, messageId, options) {
6689
+ return request(
6690
+ config,
6691
+ "DELETE",
6692
+ `/rooms/${encodePathSegment(roomId, "chat room ID")}/messages/${encodePathSegment(messageId, "chat message ID")}`,
6693
+ options
6694
+ );
6695
+ }
6696
+ }
6697
+ },
6698
+ message: {
6699
+ reaction: {
6700
+ add(messageId, input, options) {
6701
+ return request(
6702
+ config,
6703
+ "POST",
6704
+ `/messages/${encodePathSegment(messageId, "chat message ID")}/reactions`,
6705
+ options,
6706
+ input
6707
+ );
6708
+ },
6709
+ remove(messageId, emoji, options) {
6710
+ return request(
6711
+ config,
6712
+ "DELETE",
6713
+ `/messages/${encodePathSegment(messageId, "chat message ID")}/reactions/${encodePathSegment(emoji, "reaction emoji")}`,
6714
+ options
6715
+ );
6716
+ }
6717
+ },
6718
+ search(input, options) {
6719
+ return request(
6720
+ config,
6721
+ "POST",
6722
+ "/messages/search",
6723
+ options,
6724
+ input
6725
+ );
6726
+ }
6727
+ },
6728
+ realtime
6729
+ };
6730
+ }
6731
+
5879
6732
  // src/client-builder.ts
5880
6733
  var DEFAULT_BACKEND = { type: "athena" };
5881
6734
  function toBackendConfig(value) {
@@ -5910,7 +6763,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
5910
6763
  "ilike",
5911
6764
  "is"
5912
6765
  ]);
5913
- function isRecord7(value) {
6766
+ function isRecord8(value) {
5914
6767
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5915
6768
  }
5916
6769
  function isUuidString(value) {
@@ -5923,7 +6776,7 @@ function shouldUseUuidTextComparison(column, value) {
5923
6776
  return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
5924
6777
  }
5925
6778
  function isRelationSelectNode(value) {
5926
- return isRecord7(value) && isRecord7(value.select);
6779
+ return isRecord8(value) && isRecord8(value.select);
5927
6780
  }
5928
6781
  function normalizeIdentifier(value, label) {
5929
6782
  const normalized = value.trim();
@@ -5979,7 +6832,7 @@ function compileRelationToken(key, node) {
5979
6832
  return `${prefix}${relationToken}(${nested})`;
5980
6833
  }
5981
6834
  function compileSelectShape(select) {
5982
- if (!isRecord7(select)) {
6835
+ if (!isRecord8(select)) {
5983
6836
  throw new Error("findMany select must be an object");
5984
6837
  }
5985
6838
  const tokens = [];
@@ -6003,7 +6856,7 @@ function compileSelectShape(select) {
6003
6856
  return tokens.join(",");
6004
6857
  }
6005
6858
  function selectShapeUsesRelationSchema(select) {
6006
- if (!isRecord7(select)) {
6859
+ if (!isRecord8(select)) {
6007
6860
  return false;
6008
6861
  }
6009
6862
  for (const rawValue of Object.values(select)) {
@@ -6021,7 +6874,7 @@ function selectShapeUsesRelationSchema(select) {
6021
6874
  }
6022
6875
  function compileColumnWhere(column, input) {
6023
6876
  const normalizedColumn = normalizeIdentifier(column, "where column");
6024
- if (!isRecord7(input)) {
6877
+ if (!isRecord8(input)) {
6025
6878
  return [buildGatewayCondition("eq", normalizedColumn, input)];
6026
6879
  }
6027
6880
  const conditions = [];
@@ -6049,7 +6902,7 @@ function compileColumnWhere(column, input) {
6049
6902
  return conditions;
6050
6903
  }
6051
6904
  function compileBooleanExpressionTerms(clause, label) {
6052
- if (!isRecord7(clause)) {
6905
+ if (!isRecord8(clause)) {
6053
6906
  throw new Error(`findMany where.${label} clauses must be objects`);
6054
6907
  }
6055
6908
  const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
@@ -6058,7 +6911,7 @@ function compileBooleanExpressionTerms(clause, label) {
6058
6911
  }
6059
6912
  const [rawColumn, rawValue] = entries[0];
6060
6913
  const column = normalizeIdentifier(rawColumn, `where.${label} column`);
6061
- if (!isRecord7(rawValue)) {
6914
+ if (!isRecord8(rawValue)) {
6062
6915
  return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
6063
6916
  }
6064
6917
  const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
@@ -6082,7 +6935,7 @@ function compileWhere(where) {
6082
6935
  if (where === void 0) {
6083
6936
  return void 0;
6084
6937
  }
6085
- if (!isRecord7(where)) {
6938
+ if (!isRecord8(where)) {
6086
6939
  throw new Error("findMany where must be an object");
6087
6940
  }
6088
6941
  const conditions = [];
@@ -6132,7 +6985,7 @@ function compileOrderBy(orderBy) {
6132
6985
  if (orderBy === void 0) {
6133
6986
  return void 0;
6134
6987
  }
6135
- if (!isRecord7(orderBy)) {
6988
+ if (!isRecord8(orderBy)) {
6136
6989
  throw new Error("findMany orderBy must be an object");
6137
6990
  }
6138
6991
  if ("column" in orderBy) {
@@ -6307,11 +7160,11 @@ function toFindManyAstOrder(order) {
6307
7160
  ascending: order.direction !== "descending"
6308
7161
  };
6309
7162
  }
6310
- function isRecord8(value) {
7163
+ function isRecord9(value) {
6311
7164
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6312
7165
  }
6313
7166
  function normalizeFindManyAstColumnPredicate(value) {
6314
- if (!isRecord8(value)) {
7167
+ if (!isRecord9(value)) {
6315
7168
  return {
6316
7169
  eq: value
6317
7170
  };
@@ -6335,7 +7188,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
6335
7188
  return normalized;
6336
7189
  }
6337
7190
  function normalizeFindManyAstWhere(where) {
6338
- if (!where || !isRecord8(where)) {
7191
+ if (!where || !isRecord9(where)) {
6339
7192
  return where;
6340
7193
  }
6341
7194
  const normalized = {};
@@ -6349,7 +7202,7 @@ function normalizeFindManyAstWhere(where) {
6349
7202
  );
6350
7203
  continue;
6351
7204
  }
6352
- if (key === "not" && isRecord8(value)) {
7205
+ if (key === "not" && isRecord9(value)) {
6353
7206
  normalized.not = normalizeFindManyAstBooleanOperand(
6354
7207
  value
6355
7208
  );
@@ -6360,7 +7213,7 @@ function normalizeFindManyAstWhere(where) {
6360
7213
  return normalized;
6361
7214
  }
6362
7215
  function predicateRequiresUuidQueryFallback(column, value) {
6363
- if (!isRecord8(value)) {
7216
+ if (!isRecord9(value)) {
6364
7217
  return shouldUseUuidTextComparison(column, value);
6365
7218
  }
6366
7219
  const eqValue = value.eq;
@@ -6378,7 +7231,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
6378
7231
  return false;
6379
7232
  }
6380
7233
  function findManyAstWhereRequiresLegacyTransport(where) {
6381
- if (!where || !isRecord8(where)) {
7234
+ if (!where || !isRecord9(where)) {
6382
7235
  return false;
6383
7236
  }
6384
7237
  for (const [key, value] of Object.entries(where)) {
@@ -6393,7 +7246,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
6393
7246
  }
6394
7247
  continue;
6395
7248
  }
6396
- if (key === "not" && isRecord8(value)) {
7249
+ if (key === "not" && isRecord9(value)) {
6397
7250
  if (booleanOperandRequiresUuidQueryFallback(value)) {
6398
7251
  return true;
6399
7252
  }
@@ -6936,6 +7789,7 @@ function resolveAthenaModelTargetTableName(target, options = {}) {
6936
7789
  var DEFAULT_COLUMNS = "*";
6937
7790
  var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
6938
7791
  var ATHENA_NORMALIZED_ERROR_KEY = "__athenaNormalizedError";
7792
+ var SDK_NAME4 = "xylex-group/athena";
6939
7793
  function formatResult(response) {
6940
7794
  const result = {
6941
7795
  data: response.data ?? null,
@@ -7012,7 +7866,7 @@ async function executeExperimentalRead(experimental, runner) {
7012
7866
  throw error;
7013
7867
  }
7014
7868
  }
7015
- function isRecord9(value) {
7869
+ function isRecord10(value) {
7016
7870
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
7017
7871
  }
7018
7872
  function firstNonEmptyString2(...values) {
@@ -7024,8 +7878,8 @@ function firstNonEmptyString2(...values) {
7024
7878
  return void 0;
7025
7879
  }
7026
7880
  function resolveStructuredErrorPayload2(raw) {
7027
- if (!isRecord9(raw)) return null;
7028
- return isRecord9(raw.error) ? raw.error : raw;
7881
+ if (!isRecord10(raw)) return null;
7882
+ return isRecord10(raw.error) ? raw.error : raw;
7029
7883
  }
7030
7884
  function resolveStructuredErrorDetails(payload, message) {
7031
7885
  if (!payload || !("details" in payload)) {
@@ -7041,7 +7895,7 @@ function resolveStructuredErrorDetails(payload, message) {
7041
7895
  return details;
7042
7896
  }
7043
7897
  function createResultError(response, result, normalized) {
7044
- const rawRecord = isRecord9(response.raw) ? response.raw : null;
7898
+ const rawRecord = isRecord10(response.raw) ? response.raw : null;
7045
7899
  const payload = resolveStructuredErrorPayload2(response.raw);
7046
7900
  const message = firstNonEmptyString2(
7047
7901
  response.error,
@@ -7104,6 +7958,43 @@ function asAthenaJsonObject(value) {
7104
7958
  function asAthenaJsonObjectArray(values) {
7105
7959
  return values;
7106
7960
  }
7961
+ function parseArbitraryResponseBody(rawText, contentType) {
7962
+ if (!rawText) {
7963
+ return null;
7964
+ }
7965
+ const contentTypeSuggestsJson = contentType?.toLowerCase().includes("application/json") ?? false;
7966
+ const looksJson = contentTypeSuggestsJson || rawText.startsWith("{") || rawText.startsWith("[");
7967
+ if (!looksJson) {
7968
+ return rawText;
7969
+ }
7970
+ try {
7971
+ return JSON.parse(rawText);
7972
+ } catch {
7973
+ return rawText;
7974
+ }
7975
+ }
7976
+ function toRequestQueryString(query) {
7977
+ if (!query) {
7978
+ return "";
7979
+ }
7980
+ const params = new URLSearchParams();
7981
+ for (const [key, value] of Object.entries(query)) {
7982
+ if (value === void 0 || value === null) {
7983
+ continue;
7984
+ }
7985
+ if (Array.isArray(value)) {
7986
+ for (const item of value) {
7987
+ if (item !== void 0 && item !== null) {
7988
+ params.append(key, String(item));
7989
+ }
7990
+ }
7991
+ continue;
7992
+ }
7993
+ params.set(key, String(value));
7994
+ }
7995
+ const encoded = params.toString();
7996
+ return encoded ? `?${encoded}` : "";
7997
+ }
7107
7998
  function normalizeSelectColumnsInput(columns) {
7108
7999
  if (columns === void 0) {
7109
8000
  return void 0;
@@ -8403,6 +9294,59 @@ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
8403
9294
  );
8404
9295
  };
8405
9296
  }
9297
+ function normalizeOptionalString2(value) {
9298
+ if (typeof value !== "string") {
9299
+ return void 0;
9300
+ }
9301
+ const normalizedValue = value.trim();
9302
+ return normalizedValue ? normalizedValue : void 0;
9303
+ }
9304
+ function readHeaderBagValue(headers, targetKey) {
9305
+ if (!headers) {
9306
+ return void 0;
9307
+ }
9308
+ if (typeof headers.get === "function") {
9309
+ return normalizeOptionalString2(headers.get(targetKey));
9310
+ }
9311
+ const normalizedTargetKey = targetKey.toLowerCase();
9312
+ for (const [key, value] of Object.entries(headers)) {
9313
+ if (key.toLowerCase() !== normalizedTargetKey) {
9314
+ continue;
9315
+ }
9316
+ if (typeof value === "string") {
9317
+ return normalizeOptionalString2(value);
9318
+ }
9319
+ return void 0;
9320
+ }
9321
+ return void 0;
9322
+ }
9323
+ function resolveSessionContextOptions(session, options) {
9324
+ const sessionToken = normalizeOptionalString2(session?.session?.token);
9325
+ const requestCookie = readHeaderBagValue(options?.requestHeaders, "cookie") ?? readHeaderBagValue(options?.headers, "cookie");
9326
+ const authInput = options?.auth;
9327
+ const resolvedUserId = options?.userId !== void 0 ? options.userId : session?.user?.id;
9328
+ const resolvedOrganizationId = options?.organizationId !== void 0 ? options.organizationId : session?.session?.activeOrganizationId;
9329
+ const resolvedBearerToken = authInput?.bearerToken !== void 0 ? authInput.bearerToken : sessionToken;
9330
+ const resolvedSessionToken = authInput?.sessionToken !== void 0 ? authInput.sessionToken : sessionToken;
9331
+ const resolvedCookie = authInput?.cookie !== void 0 ? authInput.cookie : requestCookie;
9332
+ const auth = authInput !== void 0 || resolvedBearerToken !== void 0 || resolvedSessionToken !== void 0 || resolvedCookie !== void 0 ? {
9333
+ ...authInput ?? {},
9334
+ ...resolvedBearerToken !== void 0 ? { bearerToken: resolvedBearerToken } : {},
9335
+ ...resolvedSessionToken !== void 0 ? { sessionToken: resolvedSessionToken } : {},
9336
+ ...resolvedCookie !== void 0 ? { cookie: resolvedCookie } : {},
9337
+ headers: authInput?.headers ? { ...authInput.headers } : void 0
9338
+ } : void 0;
9339
+ if (resolvedUserId === void 0 && resolvedOrganizationId === void 0 && options?.forceNoCache === void 0 && !options?.headers && !auth) {
9340
+ return void 0;
9341
+ }
9342
+ return {
9343
+ userId: resolvedUserId,
9344
+ organizationId: resolvedOrganizationId,
9345
+ forceNoCache: options?.forceNoCache,
9346
+ headers: options?.headers ? { ...options.headers } : void 0,
9347
+ auth
9348
+ };
9349
+ }
8406
9350
  function resolveClientServiceBaseUrl(value, label) {
8407
9351
  if (value === void 0 || value === null) {
8408
9352
  return void 0;
@@ -8413,6 +9357,15 @@ function appendServicePath(baseUrl, segment) {
8413
9357
  const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(baseUrl, { label: "Athena public base URL" });
8414
9358
  return `${normalizedBaseUrl}/${segment.replace(/^\/+/, "")}`;
8415
9359
  }
9360
+ function appendRealtimeGatewayPath(baseUrl) {
9361
+ const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(baseUrl, { label: "Athena public base URL" });
9362
+ const wsUrl = new URL(normalizedBaseUrl);
9363
+ wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
9364
+ wsUrl.pathname = `${wsUrl.pathname.replace(/\/+$/, "")}/wss/gateway`;
9365
+ wsUrl.search = "";
9366
+ wsUrl.hash = "";
9367
+ return wsUrl.toString();
9368
+ }
8416
9369
  function resolveServiceUrlOverride(value, label) {
8417
9370
  return resolveClientServiceBaseUrl(value, label);
8418
9371
  }
@@ -8421,6 +9374,8 @@ function resolveServiceUrls(config) {
8421
9374
  return {
8422
9375
  dbUrl: resolveServiceUrlOverride(config.db?.url, "Athena DB base URL") ?? resolveServiceUrlOverride(config.gateway?.url, "Athena gateway base URL") ?? resolveServiceUrlOverride(config.dbUrl, "Athena DB base URL") ?? resolveServiceUrlOverride(config.gatewayUrl, "Athena gateway base URL") ?? (baseUrl ? appendServicePath(baseUrl, "db") : void 0),
8423
9376
  authUrl: resolveServiceUrlOverride(config.auth?.url, "Athena auth base URL") ?? resolveServiceUrlOverride(config.auth?.baseUrl, "Athena auth base URL") ?? resolveServiceUrlOverride(config.authUrl, "Athena auth base URL") ?? (baseUrl ? appendServicePath(baseUrl, "auth") : void 0),
9377
+ chatUrl: resolveServiceUrlOverride(config.chat?.url, "Athena chat base URL") ?? resolveServiceUrlOverride(config.chatUrl, "Athena chat base URL") ?? (baseUrl ? appendServicePath(baseUrl, "chat") : void 0),
9378
+ chatWsUrl: normalizeOptionalString2(config.chat?.wsUrl) ?? normalizeOptionalString2(config.chatWsUrl) ?? (baseUrl ? appendRealtimeGatewayPath(baseUrl) : void 0),
8424
9379
  storageUrl: resolveServiceUrlOverride(config.storage?.url, "Athena storage base URL") ?? resolveServiceUrlOverride(config.storageUrl, "Athena storage base URL") ?? (baseUrl ? appendServicePath(baseUrl, "storage") : void 0)
8425
9380
  };
8426
9381
  }
@@ -8445,6 +9400,89 @@ function resolveRequiredClientApiKey(value) {
8445
9400
  }
8446
9401
  return normalizedValue;
8447
9402
  }
9403
+ function hasHeaderIgnoreCase(headers, targetKey) {
9404
+ const normalizedTargetKey = targetKey.toLowerCase();
9405
+ return Object.keys(headers).some((key) => key.toLowerCase() === normalizedTargetKey);
9406
+ }
9407
+ function mergeClientHeaders(current, next) {
9408
+ if (!current && !next) {
9409
+ return void 0;
9410
+ }
9411
+ return {
9412
+ ...current ?? {},
9413
+ ...next ?? {}
9414
+ };
9415
+ }
9416
+ function mergeDefinedObject(current, next) {
9417
+ if (!current && !next) {
9418
+ return void 0;
9419
+ }
9420
+ const merged = {
9421
+ ...current ?? {}
9422
+ };
9423
+ const mutableMerged = merged;
9424
+ for (const [key, value] of Object.entries(next ?? {})) {
9425
+ if (value !== void 0) {
9426
+ mutableMerged[key] = value;
9427
+ }
9428
+ }
9429
+ return merged;
9430
+ }
9431
+ function mergeAuthClientOptions(current, next) {
9432
+ const merged = mergeDefinedObject(current, next);
9433
+ if (!merged) {
9434
+ return void 0;
9435
+ }
9436
+ const mergedHeaders = mergeClientHeaders(current?.headers, next?.headers);
9437
+ if (mergedHeaders) {
9438
+ merged.headers = mergedHeaders;
9439
+ }
9440
+ return merged;
9441
+ }
9442
+ function mergeServiceUrlOverrides(current, next) {
9443
+ return mergeDefinedObject(current, next);
9444
+ }
9445
+ function toClientContextOverrides(context) {
9446
+ if (!context) {
9447
+ return void 0;
9448
+ }
9449
+ return {
9450
+ userId: context.userId,
9451
+ organizationId: context.organizationId,
9452
+ forceNoCache: context.forceNoCache,
9453
+ headers: context.headers,
9454
+ auth: context.auth ? {
9455
+ ...context.auth,
9456
+ headers: context.auth.headers ? { ...context.auth.headers } : void 0
9457
+ } : void 0
9458
+ };
9459
+ }
9460
+ function mergeClientOverrideOptions(base, overrides) {
9461
+ if (!overrides) {
9462
+ return {
9463
+ ...base,
9464
+ headers: base.headers ? { ...base.headers } : void 0,
9465
+ auth: base.auth ? {
9466
+ ...base.auth,
9467
+ headers: base.auth.headers ? { ...base.auth.headers } : void 0
9468
+ } : void 0,
9469
+ db: base.db ? { ...base.db } : void 0,
9470
+ gateway: base.gateway ? { ...base.gateway } : void 0,
9471
+ chat: base.chat ? { ...base.chat } : void 0,
9472
+ storage: base.storage ? { ...base.storage } : void 0
9473
+ };
9474
+ }
9475
+ const merged = mergeDefinedObject(base, overrides) ?? { ...base };
9476
+ return {
9477
+ ...merged,
9478
+ headers: mergeClientHeaders(base.headers, overrides.headers),
9479
+ auth: mergeAuthClientOptions(base.auth, overrides.auth),
9480
+ db: mergeServiceUrlOverrides(base.db, overrides.db),
9481
+ gateway: mergeServiceUrlOverrides(base.gateway, overrides.gateway),
9482
+ chat: mergeServiceUrlOverrides(base.chat, overrides.chat),
9483
+ storage: mergeServiceUrlOverrides(base.storage, overrides.storage)
9484
+ };
9485
+ }
8448
9486
  function normalizeAuthClientConfig(auth, defaultBaseUrl) {
8449
9487
  if (!auth && defaultBaseUrl === void 0) {
8450
9488
  return void 0;
@@ -8454,6 +9492,8 @@ function normalizeAuthClientConfig(auth, defaultBaseUrl) {
8454
9492
  baseUrl,
8455
9493
  apiKey,
8456
9494
  bearerToken,
9495
+ cookie,
9496
+ sessionToken,
8457
9497
  ...rest
8458
9498
  } = auth ?? {};
8459
9499
  const normalized = {
@@ -8472,6 +9512,12 @@ function normalizeAuthClientConfig(auth, defaultBaseUrl) {
8472
9512
  if (typeof bearerToken === "string") {
8473
9513
  normalized.bearerToken = bearerToken;
8474
9514
  }
9515
+ if (typeof cookie === "string") {
9516
+ normalized.cookie = cookie;
9517
+ }
9518
+ if (typeof sessionToken === "string") {
9519
+ normalized.sessionToken = sessionToken;
9520
+ }
8475
9521
  return normalized;
8476
9522
  }
8477
9523
  function resolveCreateClientConfig(config) {
@@ -8485,31 +9531,53 @@ function resolveCreateClientConfig(config) {
8485
9531
  baseUrl: resolvedUrls.dbUrl,
8486
9532
  apiKey: resolveRequiredClientApiKey(config.key),
8487
9533
  client: resolveOptionalClientName(config.client),
9534
+ userId: config.userId,
9535
+ organizationId: config.organizationId,
9536
+ forceNoCache: config.forceNoCache,
8488
9537
  backend: toBackendConfig(config.backend),
8489
9538
  headers: config.headers,
8490
9539
  auth: config.auth,
8491
9540
  authUrl: resolvedUrls.authUrl,
9541
+ chat: config.chat,
9542
+ chatUrl: resolvedUrls.chatUrl,
9543
+ chatWsUrl: resolvedUrls.chatWsUrl,
8492
9544
  storageUrl: resolvedUrls.storageUrl,
8493
9545
  experimental: config.experimental
8494
9546
  };
8495
9547
  }
8496
- function createClientFromConfig(config) {
9548
+ function createClientFromInput(sourceConfig) {
9549
+ return createClientFromConfig(resolveCreateClientConfig(sourceConfig), sourceConfig);
9550
+ }
9551
+ function createClientFromConfig(config, sourceConfig) {
9552
+ const normalizedAuthConfig = normalizeAuthClientConfig(config.auth, config.authUrl);
8497
9553
  const gatewayHeaders = {
8498
9554
  ...config.headers ?? {}
8499
9555
  };
8500
- if (config.auth?.bearerToken && gatewayHeaders["X-Athena-Auth-Bearer-Token"] === void 0 && gatewayHeaders["x-athena-auth-bearer-token"] === void 0) {
8501
- gatewayHeaders["X-Athena-Auth-Bearer-Token"] = config.auth.bearerToken;
9556
+ if (normalizedAuthConfig?.bearerToken && !hasHeaderIgnoreCase(gatewayHeaders, "X-Athena-Auth-Bearer-Token")) {
9557
+ gatewayHeaders["X-Athena-Auth-Bearer-Token"] = normalizedAuthConfig.bearerToken;
9558
+ }
9559
+ if (normalizedAuthConfig?.cookie && !hasHeaderIgnoreCase(gatewayHeaders, "Cookie")) {
9560
+ gatewayHeaders.Cookie = normalizedAuthConfig.cookie;
9561
+ }
9562
+ if (normalizedAuthConfig?.sessionToken && !hasHeaderIgnoreCase(gatewayHeaders, "X-Athena-Auth-Session-Token")) {
9563
+ gatewayHeaders["X-Athena-Auth-Session-Token"] = normalizedAuthConfig.sessionToken;
8502
9564
  }
8503
9565
  const gateway = createAthenaGatewayClient({
8504
9566
  baseUrl: config.baseUrl,
8505
9567
  apiKey: config.apiKey,
8506
9568
  client: config.client,
9569
+ userId: config.userId,
9570
+ organizationId: config.organizationId,
9571
+ forceNoCache: config.forceNoCache,
8507
9572
  backend: config.backend,
8508
9573
  headers: gatewayHeaders
8509
9574
  });
8510
9575
  const formatGatewayResult = createResultFormatter(config.experimental);
8511
9576
  const queryTracer = createQueryTracer(config.experimental);
8512
- const auth = createAuthClient(normalizeAuthClientConfig(config.auth, config.authUrl));
9577
+ const auth = createAuthClient({
9578
+ ...normalizedAuthConfig ?? {},
9579
+ ...config.forceNoCache ? { forceNoCache: true } : {}
9580
+ });
8513
9581
  function from(tableOrModel, options) {
8514
9582
  if (isAthenaModelTarget(tableOrModel)) {
8515
9583
  if (options?.schema !== void 0) {
@@ -8557,17 +9625,160 @@ function createClientFromConfig(config) {
8557
9625
  queryTracer
8558
9626
  );
8559
9627
  const db = createDbModule({ from, rpc, query });
9628
+ const chat = createChatModule({
9629
+ baseUrl: config.chatUrl,
9630
+ apiKey: config.apiKey,
9631
+ client: config.client,
9632
+ headers: config.headers,
9633
+ bearerToken: normalizedAuthConfig?.bearerToken,
9634
+ cookie: normalizedAuthConfig?.cookie,
9635
+ sessionToken: normalizedAuthConfig?.sessionToken,
9636
+ forceNoCache: config.forceNoCache,
9637
+ wsUrl: config.chatWsUrl,
9638
+ webSocketFactory: config.chat?.webSocketFactory ?? void 0
9639
+ });
9640
+ const request2 = async (options) => {
9641
+ const method = options.method ?? "GET";
9642
+ const responseType = options.responseType ?? "json";
9643
+ const service = options.service ?? "db";
9644
+ const baseUrlByService = {
9645
+ db: config.baseUrl,
9646
+ auth: config.authUrl,
9647
+ chat: config.chatUrl,
9648
+ storage: config.storageUrl
9649
+ };
9650
+ const resolvedBaseUrl = options.url ?? baseUrlByService[service];
9651
+ if (!resolvedBaseUrl) {
9652
+ throw new Error(
9653
+ `Athena ${service} base URL is not configured. Pass createClient({ url }) for unified routing or set the service-specific URL first.`
9654
+ );
9655
+ }
9656
+ const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(resolvedBaseUrl, {
9657
+ label: `Athena ${service} base URL`
9658
+ });
9659
+ const normalizedPath = options.url ? "" : (() => {
9660
+ const path = options.path?.trim();
9661
+ if (!path) {
9662
+ throw new Error("client.request(...) requires either an absolute url or a non-empty path.");
9663
+ }
9664
+ return path.startsWith("/") ? path : `/${path}`;
9665
+ })();
9666
+ const targetUrl = options.url ? `${normalizedBaseUrl}${toRequestQueryString(options.query)}` : `${normalizedBaseUrl}${normalizedPath}${toRequestQueryString(options.query)}`;
9667
+ const headers = {
9668
+ "X-Athena-Sdk": buildSdkHeaderValue(SDK_NAME4),
9669
+ ...config.headers ?? {},
9670
+ ...options.headers ?? {}
9671
+ };
9672
+ if (service !== "auth") {
9673
+ headers.apikey = headers.apikey ?? config.apiKey;
9674
+ headers["x-api-key"] = headers["x-api-key"] ?? config.apiKey;
9675
+ if (config.client && !hasHeaderIgnoreCase(headers, "X-Athena-Client")) {
9676
+ headers["X-Athena-Client"] = config.client;
9677
+ }
9678
+ if (config.userId && !hasHeaderIgnoreCase(headers, "X-User-Id")) {
9679
+ headers["X-User-Id"] = config.userId;
9680
+ }
9681
+ if (config.organizationId && !hasHeaderIgnoreCase(headers, "X-Organization-Id")) {
9682
+ headers["X-Organization-Id"] = config.organizationId;
9683
+ }
9684
+ if (normalizedAuthConfig?.sessionToken && !hasHeaderIgnoreCase(headers, "X-Athena-Auth-Session-Token")) {
9685
+ headers["X-Athena-Auth-Session-Token"] = normalizedAuthConfig.sessionToken;
9686
+ }
9687
+ if (normalizedAuthConfig?.bearerToken && !hasHeaderIgnoreCase(headers, "X-Athena-Auth-Bearer-Token")) {
9688
+ headers["X-Athena-Auth-Bearer-Token"] = normalizedAuthConfig.bearerToken;
9689
+ }
9690
+ if (normalizedAuthConfig?.cookie && !hasHeaderIgnoreCase(headers, "Cookie")) {
9691
+ headers.Cookie = normalizedAuthConfig.cookie;
9692
+ }
9693
+ } else {
9694
+ const authApiKey = normalizedAuthConfig?.apiKey ?? config.apiKey;
9695
+ if (authApiKey && !hasHeaderIgnoreCase(headers, "x-api-key")) {
9696
+ headers.apikey = headers.apikey ?? authApiKey;
9697
+ headers["x-api-key"] = headers["x-api-key"] ?? authApiKey;
9698
+ }
9699
+ if (normalizedAuthConfig?.bearerToken && !hasHeaderIgnoreCase(headers, "Authorization")) {
9700
+ headers.Authorization = `Bearer ${normalizedAuthConfig.bearerToken}`;
9701
+ }
9702
+ if (normalizedAuthConfig?.cookie && !hasHeaderIgnoreCase(headers, "Cookie")) {
9703
+ headers.Cookie = normalizedAuthConfig.cookie;
9704
+ }
9705
+ if (normalizedAuthConfig?.sessionToken && !hasHeaderIgnoreCase(headers, "X-Athena-Auth-Session-Token")) {
9706
+ headers["X-Athena-Auth-Session-Token"] = normalizedAuthConfig.sessionToken;
9707
+ }
9708
+ }
9709
+ const shouldSendJsonBody = options.body !== void 0 && options.body !== null && !(options.body instanceof FormData) && !(options.body instanceof Blob) && !(options.body instanceof URLSearchParams) && !(options.body instanceof ArrayBuffer) && !ArrayBuffer.isView(options.body) && typeof options.body !== "string";
9710
+ if (shouldSendJsonBody && !hasHeaderIgnoreCase(headers, "Content-Type")) {
9711
+ headers["Content-Type"] = "application/json";
9712
+ }
9713
+ const response = await fetch(targetUrl, {
9714
+ method,
9715
+ headers,
9716
+ body: options.body === void 0 || options.body === null ? void 0 : shouldSendJsonBody ? JSON.stringify(options.body) : options.body,
9717
+ signal: options.signal,
9718
+ credentials: options.credentials
9719
+ });
9720
+ if (responseType === "response") {
9721
+ return {
9722
+ ok: response.ok,
9723
+ status: response.status,
9724
+ statusText: response.statusText,
9725
+ headers: response.headers,
9726
+ data: null,
9727
+ raw: response
9728
+ };
9729
+ }
9730
+ const rawText = await response.text();
9731
+ const parsed = responseType === "text" ? rawText : parseArbitraryResponseBody(rawText, response.headers.get("content-type"));
9732
+ return {
9733
+ ok: response.ok,
9734
+ status: response.status,
9735
+ statusText: response.statusText,
9736
+ headers: response.headers,
9737
+ data: parsed,
9738
+ raw: response
9739
+ };
9740
+ };
9741
+ const withContext = (context) => createClientFromInput(
9742
+ mergeClientOverrideOptions(sourceConfig, toClientContextOverrides(context))
9743
+ );
9744
+ const withSession = (session, options) => createClientFromInput(
9745
+ mergeClientOverrideOptions(
9746
+ sourceConfig,
9747
+ toClientContextOverrides(resolveSessionContextOptions(session, options))
9748
+ )
9749
+ );
9750
+ const authWithOptions = (options) => createClientFromInput(mergeClientOverrideOptions(sourceConfig, options));
8560
9751
  const sdkClient = {
8561
9752
  from,
8562
9753
  db,
8563
9754
  rpc,
8564
9755
  query,
9756
+ request: request2,
8565
9757
  verifyConnection: gateway.verifyConnection,
8566
- auth: auth.auth
9758
+ auth: auth.auth,
9759
+ chat,
9760
+ withContext,
9761
+ withSession,
9762
+ withOptions: authWithOptions
8567
9763
  };
8568
9764
  if (config.experimental?.athenaStorageBackend) {
9765
+ const storageWithContext = (context) => createClientFromInput(
9766
+ mergeClientOverrideOptions(sourceConfig, toClientContextOverrides(context))
9767
+ );
9768
+ const storageWithSession = (session, options) => createClientFromInput(
9769
+ mergeClientOverrideOptions(
9770
+ sourceConfig,
9771
+ toClientContextOverrides(resolveSessionContextOptions(session, options))
9772
+ )
9773
+ );
9774
+ const storageWithOptions = (options) => createClientFromInput(
9775
+ mergeClientOverrideOptions(sourceConfig, options)
9776
+ );
8569
9777
  const storageClient = {
8570
9778
  ...sdkClient,
9779
+ withContext: storageWithContext,
9780
+ withSession: storageWithSession,
9781
+ withOptions: storageWithOptions,
8571
9782
  storage: createStorageModule(gateway, {
8572
9783
  ...config.experimental.storage,
8573
9784
  ...config.storageUrl ? {
@@ -8582,13 +9793,13 @@ function createClientFromConfig(config) {
8582
9793
  }
8583
9794
  function createClient(configOrUrl, apiKey, options) {
8584
9795
  if (typeof configOrUrl === "string" || configOrUrl === null || configOrUrl === void 0) {
8585
- return createClientFromConfig(resolveCreateClientConfig({
9796
+ return createClientFromInput({
8586
9797
  url: configOrUrl,
8587
9798
  key: apiKey ?? "",
8588
9799
  ...options
8589
- }));
9800
+ });
8590
9801
  }
8591
- return createClientFromConfig(resolveCreateClientConfig(configOrUrl));
9802
+ return createClientFromInput(configOrUrl);
8592
9803
  }
8593
9804
 
8594
9805
  // src/schema/postgres-introspection-core.ts
@@ -9144,16 +10355,25 @@ async function fileExists(path) {
9144
10355
  }
9145
10356
  async function writeArtifacts(files, cwd) {
9146
10357
  const writtenFiles = [];
10358
+ const skippedFiles = [];
9147
10359
  for (const file of files) {
9148
10360
  const absolutePath = resolve(cwd, file.path);
9149
10361
  if (!canOverwriteArtifact(file) && await fileExists(absolutePath)) {
10362
+ skippedFiles.push({
10363
+ kind: file.kind,
10364
+ path: file.path,
10365
+ reason: "protected-existing-file"
10366
+ });
9150
10367
  continue;
9151
10368
  }
9152
10369
  await mkdir(dirname(absolutePath), { recursive: true });
9153
10370
  await writeFile(absolutePath, file.content, "utf8");
9154
10371
  writtenFiles.push(file.path);
9155
10372
  }
9156
- return writtenFiles;
10373
+ return {
10374
+ writtenFiles,
10375
+ skippedFiles
10376
+ };
9157
10377
  }
9158
10378
  async function runSchemaGenerator(options = {}) {
9159
10379
  const cwd = options.cwd ?? process.cwd();
@@ -9167,12 +10387,13 @@ async function runSchemaGenerator(options = {}) {
9167
10387
  schemas: resolveProviderSchemas(config.provider)
9168
10388
  });
9169
10389
  const generated = generateArtifactsFromSnapshot(snapshot, config);
9170
- const writtenFiles = options.dryRun ? [] : await writeArtifacts(generated.files, cwd);
10390
+ const writeResult = options.dryRun ? { writtenFiles: [], skippedFiles: [] } : await writeArtifacts(generated.files, cwd);
9171
10391
  return {
9172
10392
  ...generated,
9173
10393
  configPath,
9174
10394
  config,
9175
- writtenFiles
10395
+ writtenFiles: writeResult.writtenFiles,
10396
+ skippedFiles: writeResult.skippedFiles
9176
10397
  };
9177
10398
  }
9178
10399
 
@@ -9214,24 +10435,64 @@ function generateUsage() {
9214
10435
  " athena-js generate --config ./athena.config.ts --dry-run"
9215
10436
  ].join("\n");
9216
10437
  }
9217
- function usesSchemaScopedModelTarget(target) {
9218
- return /\{schema(?:_[a-z]+)?\}/.test(target);
10438
+ function normalizePath2(pathValue) {
10439
+ return pathValue.replace(/\\/g, "/");
10440
+ }
10441
+ function isLegacyConfigRegistryTarget(target) {
10442
+ return normalizePath2(target) === "athena/config.ts";
10443
+ }
10444
+ function isFlatSchemaTarget(target) {
10445
+ return normalizePath2(target) === "athena/schema.ts";
10446
+ }
10447
+ function formatProviderLine(result) {
10448
+ const { provider } = result.config;
10449
+ if (provider.kind === "postgres") {
10450
+ const schemaList = Array.isArray(provider.schemas) ? provider.schemas.join(",") : typeof provider.schemas === "string" ? provider.schemas : "public";
10451
+ const database = provider.database ? ` database=${provider.database}` : "";
10452
+ const backend = provider.mode === "gateway" && provider.backend ? ` backend=${provider.backend}` : "";
10453
+ return `[provider] kind=${provider.kind} mode=${provider.mode}${database}${backend} schemas=${schemaList}`;
10454
+ }
10455
+ const datacenter = provider.datacenter ? ` datacenter=${provider.datacenter}` : "";
10456
+ return `[provider] kind=${provider.kind} mode=${provider.mode} keyspace=${provider.keyspace} contactPoints=${provider.contactPoints.join(",")}${datacenter}`;
10457
+ }
10458
+ function formatFilterLine(result) {
10459
+ const { includeTables, excludeTables } = result.config.filter;
10460
+ if (includeTables.length === 0 && excludeTables.length === 0) {
10461
+ return void 0;
10462
+ }
10463
+ return `[filter] include=${includeTables.length > 0 ? includeTables.join(",") : "-"} exclude=${excludeTables.length > 0 ? excludeTables.join(",") : "-"}`;
9219
10464
  }
9220
10465
  function formatGeneratorModeLines(result) {
9221
10466
  const lines = [
9222
- `[mode] format=${result.config.output.format} modelTarget=${result.config.output.targets.model}`
10467
+ `[mode] preset=${result.config.output.preset} format=${result.config.output.format} modelTarget=${result.config.output.targets.model}`,
10468
+ formatProviderLine(result),
10469
+ `[targets] schema=${result.config.output.targets.schema} database=${result.config.output.targets.database} registry=${result.config.output.targets.registry}`
9223
10470
  ];
10471
+ const filterLine = formatFilterLine(result);
10472
+ if (filterLine) {
10473
+ lines.push(filterLine);
10474
+ }
9224
10475
  if (result.config.output.format === "define-model") {
9225
10476
  lines.push(
9226
- '[note] Zero-style table-builder files are not active. Set output.format="table-builder" or ATHENA_GENERATOR_OUTPUT_FORMAT=table-builder to emit table(...).schema(...).columns(...).primaryKey(...).'
10477
+ '[note] Legacy define-model compatibility output is active. Set output.format="table-builder" or ATHENA_GENERATOR_OUTPUT_FORMAT=table-builder to emit table(...).schema(...).columns(...).primaryKey(...).'
10478
+ );
10479
+ }
10480
+ if (result.config.output.preset === "legacy") {
10481
+ lines.push(
10482
+ '[note] Legacy preset is active. It keeps registry output on athena/config.ts for compatibility; prefer output.preset="athena-direct" for the default safe direct layout.'
9227
10483
  );
9228
10484
  }
9229
10485
  lines.push(
9230
- "[note] Table-builder generation is stable. experimental.findManyAst only affects runtime findMany(...) transport and does not enable generator table output."
10486
+ "[note] Default generator mode is preset=athena-direct + format=table-builder. experimental.findManyAst only affects runtime findMany(...) transport and does not enable generator table output."
9231
10487
  );
9232
- if (usesSchemaScopedModelTarget(result.config.output.targets.model)) {
10488
+ if (isLegacyConfigRegistryTarget(result.config.output.targets.registry)) {
10489
+ lines.push(
10490
+ '[warn] Registry target points at athena/config.ts. That file is often a handwritten runtime seam; prefer output.preset="athena-direct" or output.targets.registry="athena/registry.generated.ts" unless you intentionally need legacy compatibility.'
10491
+ );
10492
+ }
10493
+ if (isFlatSchemaTarget(result.config.output.targets.schema)) {
9233
10494
  lines.push(
9234
- '[note] Flat athena/models/*.ts output is opt-in. Set output.targets.model="athena/models/{model_kebab}.ts" or ATHENA_GENERATOR_MODEL_TARGET=athena/models/{model_kebab}.ts; multi-schema collisions are still auto-scoped by schema when needed.'
10495
+ "[warn] Schema target points at athena/schema.ts. Prefer schema-scoped output such as athena/schemas/{schema_kebab}.ts."
9235
10496
  );
9236
10497
  }
9237
10498
  return lines;
@@ -9318,6 +10579,12 @@ function formatGeneratorError(error, configPath) {
9318
10579
  }
9319
10580
  return new Error(normalizeErrorMessage(error));
9320
10581
  }
10582
+ function formatSkippedArtifactLine(artifact) {
10583
+ if (artifact.reason === "protected-existing-file") {
10584
+ return ` [skip] ${artifact.path} (existing ${artifact.kind} artifacts are protected from overwrite; delete or retarget the file to regenerate it)`;
10585
+ }
10586
+ return ` [skip] ${artifact.path}`;
10587
+ }
9321
10588
  async function runCLI(argv, runtime = {}) {
9322
10589
  const log = runtime.log ?? console.log;
9323
10590
  const runGenerator = runtime.runGenerator ?? runSchemaGenerator;
@@ -9352,6 +10619,9 @@ async function runCLI(argv, runtime = {}) {
9352
10619
  for (const filePath of result.writtenFiles) {
9353
10620
  log(` - ${filePath}`);
9354
10621
  }
10622
+ for (const artifact of result.skippedFiles) {
10623
+ log(formatSkippedArtifactLine(artifact));
10624
+ }
9355
10625
  }
9356
10626
 
9357
10627
  export { parseCommand, runCLI, usage };