@xylex-group/athena 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -532,6 +532,12 @@ function mergeOptions(...options) {
532
532
  return { ...acc, ...next };
533
533
  }, void 0);
534
534
  }
535
+ function asAthenaJsonObject(value) {
536
+ return value;
537
+ }
538
+ function asAthenaJsonObjectArray(values) {
539
+ return values;
540
+ }
535
541
  function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS) {
536
542
  let selectedColumns = defaultColumns === null ? void 0 : defaultColumns;
537
543
  let selectedOptions;
@@ -620,6 +626,22 @@ function buildSelectColumnsClause(columns) {
620
626
  }
621
627
  return quoteSelectColumnsExpression(columns);
622
628
  }
629
+ function resolveTableNameForCall(tableName, schema) {
630
+ if (!schema) return tableName;
631
+ const normalizedSchema = schema.trim();
632
+ if (!normalizedSchema) {
633
+ throw new Error("schema option must be a non-empty string");
634
+ }
635
+ if (tableName.includes(".")) {
636
+ if (tableName.startsWith(`${normalizedSchema}.`)) {
637
+ return tableName;
638
+ }
639
+ throw new Error(
640
+ `schema option "${normalizedSchema}" conflicts with schema-qualified table "${tableName}"`
641
+ );
642
+ }
643
+ return `${normalizedSchema}.${tableName}`;
644
+ }
623
645
  function conditionToSqlClause(condition) {
624
646
  if (!condition.column) return null;
625
647
  const column = withCast(quoteQualifiedIdentifier(condition.column), condition.column_cast);
@@ -699,23 +721,27 @@ function buildTypedSelectQuery(input) {
699
721
  function createFilterMethods(state, addCondition, self) {
700
722
  return {
701
723
  eq(column, value) {
702
- if (shouldUseUuidTextComparison(column, value)) {
703
- addCondition("eq", column, value, { columnCast: "text" });
724
+ const columnName = String(column);
725
+ if (shouldUseUuidTextComparison(columnName, value)) {
726
+ addCondition("eq", columnName, value, { columnCast: "text" });
704
727
  } else {
705
- addCondition("eq", column, value);
728
+ addCondition("eq", columnName, value);
706
729
  }
707
730
  return self;
708
731
  },
709
732
  eqCast(column, value, cast) {
710
- addCondition("eq", column, value, { valueCast: cast });
733
+ addCondition("eq", String(column), value, { valueCast: cast });
711
734
  return self;
712
735
  },
713
736
  eqUuid(column, value) {
714
- addCondition("eq", column, value, { valueCast: "uuid" });
737
+ addCondition("eq", String(column), value, { valueCast: "uuid" });
715
738
  return self;
716
739
  },
717
740
  match(filters) {
718
741
  Object.entries(filters).forEach(([column, value]) => {
742
+ if (value === void 0) {
743
+ return;
744
+ }
719
745
  if (shouldUseUuidTextComparison(column, value)) {
720
746
  addCondition("eq", column, value, { columnCast: "text" });
721
747
  } else {
@@ -751,60 +777,61 @@ function createFilterMethods(state, addCondition, self) {
751
777
  },
752
778
  order(column, options) {
753
779
  state.order = {
754
- field: column,
780
+ field: String(column),
755
781
  direction: options?.ascending === false ? "descending" : "ascending"
756
782
  };
757
783
  return self;
758
784
  },
759
785
  gt(column, value) {
760
- addCondition("gt", column, value);
786
+ addCondition("gt", String(column), value);
761
787
  return self;
762
788
  },
763
789
  gte(column, value) {
764
- addCondition("gte", column, value);
790
+ addCondition("gte", String(column), value);
765
791
  return self;
766
792
  },
767
793
  lt(column, value) {
768
- addCondition("lt", column, value);
794
+ addCondition("lt", String(column), value);
769
795
  return self;
770
796
  },
771
797
  lte(column, value) {
772
- addCondition("lte", column, value);
798
+ addCondition("lte", String(column), value);
773
799
  return self;
774
800
  },
775
801
  neq(column, value) {
776
- addCondition("neq", column, value);
802
+ addCondition("neq", String(column), value);
777
803
  return self;
778
804
  },
779
805
  like(column, value) {
780
- addCondition("like", column, value);
806
+ addCondition("like", String(column), value);
781
807
  return self;
782
808
  },
783
809
  ilike(column, value) {
784
- addCondition("ilike", column, value);
810
+ addCondition("ilike", String(column), value);
785
811
  return self;
786
812
  },
787
813
  is(column, value) {
788
- addCondition("is", column, value);
814
+ addCondition("is", String(column), value);
789
815
  return self;
790
816
  },
791
817
  in(column, values) {
792
- addCondition("in", column, values);
818
+ addCondition("in", String(column), values);
793
819
  return self;
794
820
  },
795
821
  contains(column, values) {
796
- addCondition("contains", column, values);
822
+ addCondition("contains", String(column), values);
797
823
  return self;
798
824
  },
799
825
  containedBy(column, values) {
800
- addCondition("containedBy", column, values);
826
+ addCondition("containedBy", String(column), values);
801
827
  return self;
802
828
  },
803
829
  not(columnOrExpression, operator, value) {
830
+ const expression = String(columnOrExpression);
804
831
  if (operator != null && value !== void 0) {
805
- addCondition("not", void 0, `${columnOrExpression}.${operator}.${stringifyFilterValue(value)}`);
832
+ addCondition("not", void 0, `${expression}.${operator}.${stringifyFilterValue(value)}`);
806
833
  } else {
807
- addCondition("not", void 0, columnOrExpression);
834
+ addCondition("not", void 0, expression);
808
835
  }
809
836
  return self;
810
837
  },
@@ -974,15 +1001,20 @@ function createTableBuilder(tableName, client) {
974
1001
  state.conditions.push(condition);
975
1002
  };
976
1003
  const builder = {};
977
- const filterMethods = createFilterMethods(state, addCondition, builder);
1004
+ const filterMethods = createFilterMethods(
1005
+ state,
1006
+ addCondition,
1007
+ builder
1008
+ );
978
1009
  const runSelect = async (columns = DEFAULT_COLUMNS, options) => {
1010
+ const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
979
1011
  const conditions = state.conditions.length ? state.conditions.map((condition) => ({ ...condition })) : void 0;
980
1012
  const hasTypedEqualityComparison = conditions?.some(
981
1013
  (condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
982
1014
  ) ?? false;
983
1015
  if (hasTypedEqualityComparison && !options?.head && !options?.count && conditions) {
984
1016
  const query = buildTypedSelectQuery({
985
- tableName,
1017
+ tableName: resolvedTableName,
986
1018
  columns,
987
1019
  conditions,
988
1020
  limit: state.limit,
@@ -997,7 +1029,7 @@ function createTableBuilder(tableName, client) {
997
1029
  }
998
1030
  }
999
1031
  const payload = {
1000
- table_name: tableName,
1032
+ table_name: resolvedTableName,
1001
1033
  columns,
1002
1034
  conditions,
1003
1035
  limit: state.limit,
@@ -1054,9 +1086,10 @@ function createTableBuilder(tableName, client) {
1054
1086
  if (Array.isArray(values)) {
1055
1087
  const executeInsertMany = async (columns, selectOptions) => {
1056
1088
  const mergedOptions = mergeOptions(options, selectOptions);
1089
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1057
1090
  const payload = {
1058
- table_name: tableName,
1059
- insert_body: values
1091
+ table_name: resolvedTableName,
1092
+ insert_body: asAthenaJsonObjectArray(values)
1060
1093
  };
1061
1094
  if (columns) payload.columns = columns;
1062
1095
  if (mergedOptions?.count) payload.count = mergedOptions.count;
@@ -1071,9 +1104,10 @@ function createTableBuilder(tableName, client) {
1071
1104
  }
1072
1105
  const executeInsertOne = async (columns, selectOptions) => {
1073
1106
  const mergedOptions = mergeOptions(options, selectOptions);
1107
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1074
1108
  const payload = {
1075
- table_name: tableName,
1076
- insert_body: values
1109
+ table_name: resolvedTableName,
1110
+ insert_body: asAthenaJsonObject(values)
1077
1111
  };
1078
1112
  if (columns) payload.columns = columns;
1079
1113
  if (mergedOptions?.count) payload.count = mergedOptions.count;
@@ -1090,10 +1124,11 @@ function createTableBuilder(tableName, client) {
1090
1124
  if (Array.isArray(values)) {
1091
1125
  const executeUpsertMany = async (columns, selectOptions) => {
1092
1126
  const mergedOptions = mergeOptions(options, selectOptions);
1127
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1093
1128
  const payload = {
1094
- table_name: tableName,
1095
- insert_body: values,
1096
- update_body: options?.updateBody ? options.updateBody : void 0
1129
+ table_name: resolvedTableName,
1130
+ insert_body: asAthenaJsonObjectArray(values),
1131
+ update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
1097
1132
  };
1098
1133
  if (columns) payload.columns = columns;
1099
1134
  if (options?.onConflict) payload.on_conflict = options.onConflict;
@@ -1109,10 +1144,11 @@ function createTableBuilder(tableName, client) {
1109
1144
  }
1110
1145
  const executeUpsertOne = async (columns, selectOptions) => {
1111
1146
  const mergedOptions = mergeOptions(options, selectOptions);
1147
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1112
1148
  const payload = {
1113
- table_name: tableName,
1114
- insert_body: values,
1115
- update_body: options?.updateBody ? options.updateBody : void 0
1149
+ table_name: resolvedTableName,
1150
+ insert_body: asAthenaJsonObject(values),
1151
+ update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
1116
1152
  };
1117
1153
  if (columns) payload.columns = columns;
1118
1154
  if (options?.onConflict) payload.on_conflict = options.onConflict;
@@ -1130,9 +1166,10 @@ function createTableBuilder(tableName, client) {
1130
1166
  const executeUpdate = async (columns, selectOptions) => {
1131
1167
  const filters = state.conditions.length ? [...state.conditions] : void 0;
1132
1168
  const mergedOptions = mergeOptions(options, selectOptions);
1169
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1133
1170
  const payload = {
1134
- table_name: tableName,
1135
- set: values,
1171
+ table_name: resolvedTableName,
1172
+ set: asAthenaJsonObject(values),
1136
1173
  conditions: filters,
1137
1174
  strip_nulls: mergedOptions?.stripNulls ?? true
1138
1175
  };
@@ -1158,8 +1195,9 @@ function createTableBuilder(tableName, client) {
1158
1195
  }
1159
1196
  const executeDelete = async (columns, selectOptions) => {
1160
1197
  const mergedOptions = mergeOptions(options, selectOptions);
1198
+ const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
1161
1199
  const payload = {
1162
- table_name: tableName,
1200
+ table_name: resolvedTableName,
1163
1201
  resource_id: resourceId,
1164
1202
  conditions: filters
1165
1203
  };
@@ -2272,6 +2310,67 @@ function createPostgresIntrospectionProvider(options) {
2272
2310
  return new PostgresIntrospectionProvider(options);
2273
2311
  }
2274
2312
 
2313
+ // src/schema/model-form.ts
2314
+ function resolveNullishValue(mode) {
2315
+ if (mode === "undefined") return void 0;
2316
+ if (mode === "null") return null;
2317
+ return "";
2318
+ }
2319
+ function isRecord3(value) {
2320
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
2321
+ }
2322
+ function isNullableColumn(model, key) {
2323
+ const nullable = model.meta.nullable;
2324
+ return nullable?.[key] === true;
2325
+ }
2326
+ function toModelFormDefaults(model, values, options) {
2327
+ const source = values;
2328
+ if (!isRecord3(source)) {
2329
+ return {};
2330
+ }
2331
+ const mode = options?.nullishMode ?? "empty-string";
2332
+ const nullishValue = resolveNullishValue(mode);
2333
+ const result = {};
2334
+ for (const [key, value] of Object.entries(source)) {
2335
+ if (value === null && isNullableColumn(model, key)) {
2336
+ result[key] = nullishValue;
2337
+ continue;
2338
+ }
2339
+ result[key] = value;
2340
+ }
2341
+ return result;
2342
+ }
2343
+ function toModelPayload(model, formValues, options) {
2344
+ const emptyStringAsNull = options?.emptyStringAsNull ?? true;
2345
+ const stripUndefined = options?.stripUndefined ?? true;
2346
+ const result = {};
2347
+ for (const [key, rawValue] of Object.entries(formValues)) {
2348
+ if (rawValue === void 0 && stripUndefined) {
2349
+ continue;
2350
+ }
2351
+ if (emptyStringAsNull && rawValue === "" && isNullableColumn(model, key)) {
2352
+ result[key] = null;
2353
+ continue;
2354
+ }
2355
+ result[key] = rawValue;
2356
+ }
2357
+ return result;
2358
+ }
2359
+ function createModelFormAdapter(model) {
2360
+ return {
2361
+ model,
2362
+ toDefaults(values, options) {
2363
+ return toModelFormDefaults(model, values, options);
2364
+ },
2365
+ toInsert(values, options) {
2366
+ return toModelPayload(model, values, options);
2367
+ },
2368
+ toUpdate(values, options) {
2369
+ return toModelPayload(model, values, options);
2370
+ }
2371
+ };
2372
+ }
2373
+
2275
2374
  // src/generator/schema-selection.ts
2276
2375
  var DEFAULT_POSTGRES_SCHEMAS = ["public"];
2277
2376
  function collectSchemaNames(input) {
@@ -3131,7 +3230,7 @@ var SDK_HEADER_VALUE2 = `${SDK_NAME2} ${SDK_VERSION2}`;
3131
3230
  function normalizeBaseUrl(baseUrl) {
3132
3231
  return (baseUrl ?? DEFAULT_AUTH_BASE_URL).replace(/\/$/, "");
3133
3232
  }
3134
- function isRecord3(value) {
3233
+ function isRecord4(value) {
3135
3234
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3136
3235
  }
3137
3236
  function normalizeHeaderValue2(value) {
@@ -3156,7 +3255,7 @@ function resolveRequestId2(headers) {
3156
3255
  return headers.get("x-request-id") ?? headers.get("x-correlation-id") ?? headers.get("x-athena-request-id") ?? void 0;
3157
3256
  }
3158
3257
  function resolveErrorMessage2(payload, fallback) {
3159
- if (isRecord3(payload)) {
3258
+ if (isRecord4(payload)) {
3160
3259
  const messageCandidates = [payload.error, payload.message, payload.details];
3161
3260
  for (const candidate of messageCandidates) {
3162
3261
  if (typeof candidate === "string" && candidate.trim().length > 0) {
@@ -3613,6 +3712,6 @@ function createAuthClient(config = {}) {
3613
3712
  };
3614
3713
  }
3615
3714
 
3616
- export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createClient, createPostgresIntrospectionProvider, createTypedClient, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeGeneratorConfig, normalizeSchemaSelection, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, unwrap, unwrapOne, unwrapRows, withRetry };
3715
+ export { AthenaClient, AthenaError, AthenaErrorCategory, AthenaErrorCode, AthenaErrorKind, AthenaGatewayError, Backend, DEFAULT_POSTGRES_SCHEMAS, assertInt, coerceInt, createAuthClient, createClient, createModelFormAdapter, createPostgresIntrospectionProvider, createTypedClient, defineDatabase, defineGeneratorConfig, defineModel, defineRegistry, defineSchema, findGeneratorConfigPath, generateArtifactsFromSnapshot, identifier, isAthenaGatewayError, isOk, loadGeneratorConfig, normalizeAthenaError, normalizeGeneratorConfig, normalizeSchemaSelection, requireAffected, requireSuccess, resolveGeneratorProvider, resolvePostgresColumnType, resolveProviderSchemas, runSchemaGenerator, toModelFormDefaults, toModelPayload, unwrap, unwrapOne, unwrapRows, withRetry };
3617
3716
  //# sourceMappingURL=index.js.map
3618
3717
  //# sourceMappingURL=index.js.map