@xylex-group/athena 2.6.0 → 2.8.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/README.md +210 -17
- package/dist/browser.cjs +2102 -527
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +8 -7
- package/dist/browser.d.ts +8 -7
- package/dist/browser.js +2096 -528
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +2116 -559
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -3
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +2116 -559
- package/dist/cli/index.js.map +1 -1
- package/dist/cookies.cjs +10 -3
- package/dist/cookies.cjs.map +1 -1
- package/dist/cookies.js +10 -3
- package/dist/cookies.js.map +1 -1
- package/dist/index.cjs +2694 -748
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +2688 -749
- package/dist/index.js.map +1 -1
- package/dist/model-form-DMed05gE.d.cts +3037 -0
- package/dist/model-form-DXPlOnlI.d.ts +3037 -0
- package/dist/{pipeline-Ce3pTw5h.d.ts → pipeline-CkMnhwPI.d.ts} +1 -1
- package/dist/{pipeline-D1ZYeoH7.d.cts → pipeline-D4sJRKqN.d.cts} +1 -1
- package/dist/react-email-DZhDDlEl.d.cts +417 -0
- package/dist/react-email-Lrz9A-BW.d.ts +417 -0
- package/dist/react.cjs +178 -71
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +22 -5
- package/dist/react.d.ts +22 -5
- package/dist/react.js +92 -5
- package/dist/react.js.map +1 -1
- package/dist/{types-CUuo4NDi.d.cts → types-BzY6fETM.d.ts} +47 -5
- package/dist/{types-DapchQY5.d.ts → types-CAtTGGoz.d.cts} +47 -5
- package/dist/{types-DSX6AT5B.d.cts → types-vikz9YIO.d.cts} +23 -1
- package/dist/{types-DSX6AT5B.d.ts → types-vikz9YIO.d.ts} +23 -1
- package/package.json +194 -193
- package/dist/model-form-BaHWi3gm.d.cts +0 -1383
- package/dist/model-form-Dh6gWjL0.d.ts +0 -1383
- package/dist/react-email-B8O1Jeff.d.cts +0 -1230
- package/dist/react-email-CDEF0jij.d.ts +0 -1230
package/dist/cli/index.js
CHANGED
|
@@ -129,59 +129,6 @@ function escapeStringLiteral(value) {
|
|
|
129
129
|
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// src/generator/placeholders.ts
|
|
133
|
-
function createStyleTokens(prefix, value) {
|
|
134
|
-
return {
|
|
135
|
-
[prefix]: value,
|
|
136
|
-
[`${prefix}_camel`]: applyNamingStyle(value, "camel"),
|
|
137
|
-
[`${prefix}_pascal`]: applyNamingStyle(value, "pascal"),
|
|
138
|
-
[`${prefix}_snake`]: applyNamingStyle(value, "snake"),
|
|
139
|
-
[`${prefix}_kebab`]: applyNamingStyle(value, "kebab")
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
function renderTemplate(template, tokenMap) {
|
|
143
|
-
return template.replace(/\{([A-Za-z0-9_]+)\}/g, (_match, token) => {
|
|
144
|
-
if (!(token in tokenMap)) {
|
|
145
|
-
throw new Error(`Unknown placeholder token "${token}" in template "${template}"`);
|
|
146
|
-
}
|
|
147
|
-
return tokenMap[token];
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
function resolvePlaceholderMap(baseTokens, outputConfig) {
|
|
151
|
-
const resolved = {
|
|
152
|
-
...baseTokens
|
|
153
|
-
};
|
|
154
|
-
const reservedTokenKeys = new Set(Object.keys(baseTokens));
|
|
155
|
-
const entries = Object.entries(outputConfig.placeholderMap ?? {});
|
|
156
|
-
for (let index = 0; index < entries.length; index += 1) {
|
|
157
|
-
const [key, value] = entries[index];
|
|
158
|
-
if (reservedTokenKeys.has(key)) {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
let current = value;
|
|
162
|
-
for (let depth = 0; depth < 8; depth += 1) {
|
|
163
|
-
const next = renderTemplate(current, resolved);
|
|
164
|
-
if (next === current) {
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
current = next;
|
|
168
|
-
}
|
|
169
|
-
resolved[key] = current;
|
|
170
|
-
}
|
|
171
|
-
return resolved;
|
|
172
|
-
}
|
|
173
|
-
function renderOutputPath(template, context, outputConfig) {
|
|
174
|
-
const baseTokens = {
|
|
175
|
-
provider: context.provider,
|
|
176
|
-
kind: context.kind,
|
|
177
|
-
...createStyleTokens("database", context.database),
|
|
178
|
-
...createStyleTokens("schema", context.schema),
|
|
179
|
-
...createStyleTokens("model", context.model)
|
|
180
|
-
};
|
|
181
|
-
const tokens = resolvePlaceholderMap(baseTokens, outputConfig);
|
|
182
|
-
return renderTemplate(template, tokens);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
132
|
// src/generator/postgres-type-mapping.ts
|
|
186
133
|
var NUMBER_TYPES = /* @__PURE__ */ new Set([
|
|
187
134
|
"int2",
|
|
@@ -755,6 +702,7 @@ var DEFAULT_TARGETS = {
|
|
|
755
702
|
database: "athena/relations.ts",
|
|
756
703
|
registry: "athena/config.ts"
|
|
757
704
|
};
|
|
705
|
+
var DEFAULT_OUTPUT_FORMAT = "define-model";
|
|
758
706
|
var DEFAULT_NAMING = {
|
|
759
707
|
modelType: "pascal",
|
|
760
708
|
modelConst: "camel",
|
|
@@ -770,6 +718,9 @@ var DEFAULT_EXPERIMENTAL_FLAGS = {
|
|
|
770
718
|
postgresGatewayIntrospection: false,
|
|
771
719
|
scyllaProviderContracts: true
|
|
772
720
|
};
|
|
721
|
+
var DEFAULT_INTERNAL_CONFIG = {
|
|
722
|
+
schemaVersion: 1
|
|
723
|
+
};
|
|
773
724
|
var PROJECT_ENV_FILENAMES = [".env", ".env.local"];
|
|
774
725
|
var DIRECT_CONNECTION_STRING_ENV_KEYS = [
|
|
775
726
|
"ATHENA_GENERATOR_PG_URL",
|
|
@@ -786,6 +737,27 @@ var GATEWAY_API_KEY_ENV_KEYS = [
|
|
|
786
737
|
"ATHENA_GATEWAY_API_KEY",
|
|
787
738
|
"ATHENA_GENERATOR_API_KEY"
|
|
788
739
|
];
|
|
740
|
+
var GENERATOR_SCHEMA_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMAS"];
|
|
741
|
+
var OUTPUT_FORMAT_ENV_KEYS = ["ATHENA_GENERATOR_OUTPUT_FORMAT"];
|
|
742
|
+
var MODEL_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_TARGET"];
|
|
743
|
+
var SCHEMA_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMA_TARGET"];
|
|
744
|
+
var DATABASE_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_DATABASE_TARGET"];
|
|
745
|
+
var REGISTRY_TARGET_ENV_KEYS = ["ATHENA_GENERATOR_REGISTRY_TARGET"];
|
|
746
|
+
var PLACEHOLDER_MAP_ENV_KEYS = ["ATHENA_GENERATOR_PLACEHOLDER_MAP"];
|
|
747
|
+
var MODEL_TYPE_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_TYPE", "ATHENA_GENERATOR_MODEL_STYLE"];
|
|
748
|
+
var MODEL_CONST_ENV_KEYS = ["ATHENA_GENERATOR_MODEL_CONST"];
|
|
749
|
+
var SCHEMA_CONST_ENV_KEYS = ["ATHENA_GENERATOR_SCHEMA_CONST"];
|
|
750
|
+
var DATABASE_CONST_ENV_KEYS = ["ATHENA_GENERATOR_DATABASE_CONST"];
|
|
751
|
+
var REGISTRY_CONST_ENV_KEYS = ["ATHENA_GENERATOR_REGISTRY_CONST"];
|
|
752
|
+
var EMIT_RELATIONS_ENV_KEYS = ["ATHENA_GENERATOR_EMIT_RELATIONS"];
|
|
753
|
+
var EMIT_REGISTRY_ENV_KEYS = ["ATHENA_GENERATOR_EMIT_REGISTRY"];
|
|
754
|
+
var GATEWAY_BACKEND_ENV_KEYS = ["ATHENA_GENERATOR_BACKEND"];
|
|
755
|
+
var GATEWAY_EXPERIMENTAL_ENV_KEYS = ["ATHENA_GENERATOR_GATEWAY_EXPERIMENTAL"];
|
|
756
|
+
var SCYLLA_PROVIDER_CONTRACTS_ENV_KEYS = ["ATHENA_GENERATOR_SCYLLA_PROVIDER_CONTRACTS"];
|
|
757
|
+
var ENV_ONLY_CONFIG_PATH = "[environment defaults]";
|
|
758
|
+
var NAMING_STYLE_VALUES = ["preserve", "camel", "pascal", "snake", "kebab"];
|
|
759
|
+
var OUTPUT_FORMAT_VALUES = ["define-model", "table-builder"];
|
|
760
|
+
var BACKEND_TYPE_VALUES = ["athena", "postgrest", "postgresql", "scylladb"];
|
|
789
761
|
function normalizeRawEnvValue(rawValue) {
|
|
790
762
|
if (rawValue.startsWith('"') && rawValue.endsWith('"') && rawValue.length >= 2) {
|
|
791
763
|
const inner = rawValue.slice(1, -1);
|
|
@@ -877,6 +849,50 @@ function resolveFallbackValue(fallbackKeys) {
|
|
|
877
849
|
}
|
|
878
850
|
return void 0;
|
|
879
851
|
}
|
|
852
|
+
function normalizeOneOfValue(rawValue, allowedValues, envKeys) {
|
|
853
|
+
if (!rawValue) {
|
|
854
|
+
return void 0;
|
|
855
|
+
}
|
|
856
|
+
if (allowedValues.includes(rawValue)) {
|
|
857
|
+
return rawValue;
|
|
858
|
+
}
|
|
859
|
+
throw new Error(
|
|
860
|
+
`Generator config env vars ${envKeys.join(", ")} must resolve to one of: ${allowedValues.join(", ")}. Received: ${rawValue}.`
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
function resolveOptionalOneOf(envKeys, allowedValues) {
|
|
864
|
+
return normalizeOneOfValue(resolveFallbackValue(envKeys), allowedValues, envKeys);
|
|
865
|
+
}
|
|
866
|
+
function resolveOptionalBoolean(envKeys) {
|
|
867
|
+
const rawValue = resolveFallbackValue(envKeys);
|
|
868
|
+
return rawValue === void 0 ? void 0 : parseBooleanFlag2(rawValue, false);
|
|
869
|
+
}
|
|
870
|
+
function resolveOptionalJson(envKeys) {
|
|
871
|
+
const rawValue = resolveFallbackValue(envKeys);
|
|
872
|
+
if (rawValue === void 0) {
|
|
873
|
+
return void 0;
|
|
874
|
+
}
|
|
875
|
+
try {
|
|
876
|
+
return JSON.parse(rawValue);
|
|
877
|
+
} catch (error) {
|
|
878
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
879
|
+
throw new Error(
|
|
880
|
+
`Generator config env vars ${envKeys.join(", ")} must contain valid JSON. ${message}`
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
function deriveDatabaseNameFromConnectionString(connectionString) {
|
|
885
|
+
try {
|
|
886
|
+
const parsedUrl = new URL(connectionString);
|
|
887
|
+
if (!POSTGRES_PROTOCOLS.has(parsedUrl.protocol)) {
|
|
888
|
+
return void 0;
|
|
889
|
+
}
|
|
890
|
+
const pathname = parsedUrl.pathname.replace(/^\/+/, "").trim();
|
|
891
|
+
return pathname.length > 0 ? decodeURIComponent(pathname) : void 0;
|
|
892
|
+
} catch {
|
|
893
|
+
return void 0;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
880
896
|
function normalizeOptionalString(value, fallbackKeys) {
|
|
881
897
|
if (typeof value === "string") {
|
|
882
898
|
const trimmed = value.trim();
|
|
@@ -950,12 +966,13 @@ function normalizeExperimentalFlags(input) {
|
|
|
950
966
|
}
|
|
951
967
|
function normalizeOutputConfig(output) {
|
|
952
968
|
return {
|
|
969
|
+
format: output?.format ?? DEFAULT_OUTPUT_FORMAT,
|
|
953
970
|
targets: {
|
|
954
971
|
...DEFAULT_TARGETS,
|
|
955
|
-
...output
|
|
972
|
+
...output?.targets ?? {}
|
|
956
973
|
},
|
|
957
974
|
placeholderMap: {
|
|
958
|
-
...output
|
|
975
|
+
...output?.placeholderMap ?? {}
|
|
959
976
|
}
|
|
960
977
|
};
|
|
961
978
|
}
|
|
@@ -966,7 +983,7 @@ function normalizeProviderConfig(provider) {
|
|
|
966
983
|
"provider.connectionString",
|
|
967
984
|
DIRECT_CONNECTION_STRING_ENV_KEYS
|
|
968
985
|
);
|
|
969
|
-
const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS);
|
|
986
|
+
const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS) ?? deriveDatabaseNameFromConnectionString(connectionString);
|
|
970
987
|
return {
|
|
971
988
|
...provider,
|
|
972
989
|
connectionString: applyPostgresPasswordFallback(connectionString),
|
|
@@ -985,11 +1002,7 @@ function normalizeProviderConfig(provider) {
|
|
|
985
1002
|
"provider.apiKey",
|
|
986
1003
|
GATEWAY_API_KEY_ENV_KEYS
|
|
987
1004
|
);
|
|
988
|
-
const database =
|
|
989
|
-
provider.database,
|
|
990
|
-
"provider.database",
|
|
991
|
-
POSTGRES_DATABASE_ENV_KEYS
|
|
992
|
-
);
|
|
1005
|
+
const database = normalizeOptionalString(provider.database, POSTGRES_DATABASE_ENV_KEYS) ?? "postgres";
|
|
993
1006
|
return {
|
|
994
1007
|
...provider,
|
|
995
1008
|
gatewayUrl,
|
|
@@ -998,6 +1011,26 @@ function normalizeProviderConfig(provider) {
|
|
|
998
1011
|
schemas: normalizeSchemaSelection(provider.schemas)
|
|
999
1012
|
};
|
|
1000
1013
|
}
|
|
1014
|
+
if (provider.kind === "scylla" && provider.mode === "direct") {
|
|
1015
|
+
if (!provider.contactPoints?.length) {
|
|
1016
|
+
throw new Error(
|
|
1017
|
+
"Generator config is missing provider.contactPoints for scylla direct mode."
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
const keyspace = normalizeOptionalString(provider.keyspace, []);
|
|
1021
|
+
if (!keyspace) {
|
|
1022
|
+
throw new Error(
|
|
1023
|
+
"Generator config is missing provider.keyspace for scylla direct mode."
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
return {
|
|
1027
|
+
kind: "scylla",
|
|
1028
|
+
mode: "direct",
|
|
1029
|
+
contactPoints: provider.contactPoints.slice(),
|
|
1030
|
+
keyspace,
|
|
1031
|
+
datacenter: normalizeOptionalString(provider.datacenter, [])
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1001
1034
|
return provider;
|
|
1002
1035
|
}
|
|
1003
1036
|
function isAthenaGeneratorConfig(value) {
|
|
@@ -1005,7 +1038,7 @@ function isAthenaGeneratorConfig(value) {
|
|
|
1005
1038
|
return false;
|
|
1006
1039
|
}
|
|
1007
1040
|
const record = value;
|
|
1008
|
-
return Boolean(record.provider && typeof record.provider === "object") &&
|
|
1041
|
+
return Boolean(record.provider && typeof record.provider === "object") && (record.output === void 0 || typeof record.output === "object");
|
|
1009
1042
|
}
|
|
1010
1043
|
function normalizeGeneratorConfig(input) {
|
|
1011
1044
|
return {
|
|
@@ -1016,7 +1049,10 @@ function normalizeGeneratorConfig(input) {
|
|
|
1016
1049
|
...input.naming ?? {}
|
|
1017
1050
|
},
|
|
1018
1051
|
features: normalizeFeatureFlags(input.features),
|
|
1019
|
-
experimental: normalizeExperimentalFlags(input.experimental)
|
|
1052
|
+
experimental: normalizeExperimentalFlags(input.experimental),
|
|
1053
|
+
internal: {
|
|
1054
|
+
...DEFAULT_INTERNAL_CONFIG
|
|
1055
|
+
}
|
|
1020
1056
|
};
|
|
1021
1057
|
}
|
|
1022
1058
|
function findGeneratorConfigPath(cwd = process.cwd()) {
|
|
@@ -1070,16 +1106,123 @@ function importConfigModule(moduleSpecifier) {
|
|
|
1070
1106
|
);
|
|
1071
1107
|
return runtimeImport(moduleSpecifier);
|
|
1072
1108
|
}
|
|
1109
|
+
function buildEnvironmentOutputConfig() {
|
|
1110
|
+
const format = resolveOptionalOneOf(OUTPUT_FORMAT_ENV_KEYS, OUTPUT_FORMAT_VALUES);
|
|
1111
|
+
const modelTarget = resolveFallbackValue(MODEL_TARGET_ENV_KEYS);
|
|
1112
|
+
const schemaTarget = resolveFallbackValue(SCHEMA_TARGET_ENV_KEYS);
|
|
1113
|
+
const databaseTarget = resolveFallbackValue(DATABASE_TARGET_ENV_KEYS);
|
|
1114
|
+
const registryTarget = resolveFallbackValue(REGISTRY_TARGET_ENV_KEYS);
|
|
1115
|
+
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) {
|
|
1117
|
+
return void 0;
|
|
1118
|
+
}
|
|
1119
|
+
return {
|
|
1120
|
+
format,
|
|
1121
|
+
targets: {
|
|
1122
|
+
...modelTarget ? { model: modelTarget } : {},
|
|
1123
|
+
...schemaTarget ? { schema: schemaTarget } : {},
|
|
1124
|
+
...databaseTarget ? { database: databaseTarget } : {},
|
|
1125
|
+
...registryTarget ? { registry: registryTarget } : {}
|
|
1126
|
+
},
|
|
1127
|
+
placeholderMap
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
function buildEnvironmentNamingConfig() {
|
|
1131
|
+
const modelType = resolveOptionalOneOf(MODEL_TYPE_ENV_KEYS, NAMING_STYLE_VALUES);
|
|
1132
|
+
const modelConst = resolveOptionalOneOf(MODEL_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
|
|
1133
|
+
const schemaConst = resolveOptionalOneOf(SCHEMA_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
|
|
1134
|
+
const databaseConst = resolveOptionalOneOf(DATABASE_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
|
|
1135
|
+
const registryConst = resolveOptionalOneOf(REGISTRY_CONST_ENV_KEYS, NAMING_STYLE_VALUES);
|
|
1136
|
+
if (modelType === void 0 && modelConst === void 0 && schemaConst === void 0 && databaseConst === void 0 && registryConst === void 0) {
|
|
1137
|
+
return void 0;
|
|
1138
|
+
}
|
|
1139
|
+
return {
|
|
1140
|
+
...modelType ? { modelType } : {},
|
|
1141
|
+
...modelConst ? { modelConst } : {},
|
|
1142
|
+
...schemaConst ? { schemaConst } : {},
|
|
1143
|
+
...databaseConst ? { databaseConst } : {},
|
|
1144
|
+
...registryConst ? { registryConst } : {}
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
function buildEnvironmentFeatureFlags() {
|
|
1148
|
+
const emitRelations = resolveOptionalBoolean(EMIT_RELATIONS_ENV_KEYS);
|
|
1149
|
+
const emitRegistry = resolveOptionalBoolean(EMIT_REGISTRY_ENV_KEYS);
|
|
1150
|
+
if (emitRelations === void 0 && emitRegistry === void 0) {
|
|
1151
|
+
return void 0;
|
|
1152
|
+
}
|
|
1153
|
+
return {
|
|
1154
|
+
...emitRelations !== void 0 ? { emitRelations } : {},
|
|
1155
|
+
...emitRegistry !== void 0 ? { emitRegistry } : {}
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
function buildEnvironmentExperimentalFlags() {
|
|
1159
|
+
const postgresGatewayIntrospection = resolveOptionalBoolean(GATEWAY_EXPERIMENTAL_ENV_KEYS);
|
|
1160
|
+
const scyllaProviderContracts = resolveOptionalBoolean(SCYLLA_PROVIDER_CONTRACTS_ENV_KEYS);
|
|
1161
|
+
if (postgresGatewayIntrospection === void 0 && scyllaProviderContracts === void 0) {
|
|
1162
|
+
return void 0;
|
|
1163
|
+
}
|
|
1164
|
+
return {
|
|
1165
|
+
...postgresGatewayIntrospection !== void 0 ? { postgresGatewayIntrospection } : {},
|
|
1166
|
+
...scyllaProviderContracts !== void 0 ? { scyllaProviderContracts } : {}
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
function buildEnvironmentProviderConfig() {
|
|
1170
|
+
const directConnectionString = resolveFallbackValue(DIRECT_CONNECTION_STRING_ENV_KEYS);
|
|
1171
|
+
if (directConnectionString) {
|
|
1172
|
+
return {
|
|
1173
|
+
kind: "postgres",
|
|
1174
|
+
mode: "direct",
|
|
1175
|
+
connectionString: directConnectionString,
|
|
1176
|
+
database: normalizeOptionalString(void 0, POSTGRES_DATABASE_ENV_KEYS),
|
|
1177
|
+
schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS))
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
const gatewayUrl = resolveFallbackValue(GATEWAY_URL_ENV_KEYS);
|
|
1181
|
+
const apiKey = resolveFallbackValue(GATEWAY_API_KEY_ENV_KEYS);
|
|
1182
|
+
if (gatewayUrl && apiKey) {
|
|
1183
|
+
const backend = resolveOptionalOneOf(GATEWAY_BACKEND_ENV_KEYS, BACKEND_TYPE_VALUES);
|
|
1184
|
+
return {
|
|
1185
|
+
kind: "postgres",
|
|
1186
|
+
mode: "gateway",
|
|
1187
|
+
gatewayUrl,
|
|
1188
|
+
apiKey,
|
|
1189
|
+
database: normalizeOptionalString(void 0, POSTGRES_DATABASE_ENV_KEYS),
|
|
1190
|
+
schemas: normalizeSchemaSelection(resolveFallbackValue(GENERATOR_SCHEMA_ENV_KEYS)),
|
|
1191
|
+
backend
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
return void 0;
|
|
1195
|
+
}
|
|
1196
|
+
function createEnvironmentGeneratorConfig() {
|
|
1197
|
+
const provider = buildEnvironmentProviderConfig();
|
|
1198
|
+
if (!provider) {
|
|
1199
|
+
return void 0;
|
|
1200
|
+
}
|
|
1201
|
+
return {
|
|
1202
|
+
provider,
|
|
1203
|
+
output: buildEnvironmentOutputConfig(),
|
|
1204
|
+
naming: buildEnvironmentNamingConfig(),
|
|
1205
|
+
features: buildEnvironmentFeatureFlags(),
|
|
1206
|
+
experimental: buildEnvironmentExperimentalFlags()
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1073
1209
|
async function loadGeneratorConfig(options = {}) {
|
|
1074
1210
|
const cwd = options.cwd ?? process.cwd();
|
|
1075
1211
|
const restoreProjectEnv = applyProjectEnv(cwd);
|
|
1076
|
-
const resolvedPath = options.configPath ? resolve(cwd, options.configPath) : findGeneratorConfigPath(cwd);
|
|
1077
|
-
if (!resolvedPath) {
|
|
1078
|
-
throw new Error(
|
|
1079
|
-
`No generator config found in ${cwd}. Expected one of: ${DEFAULT_CONFIG_CANDIDATES.join(", ")}`
|
|
1080
|
-
);
|
|
1081
|
-
}
|
|
1082
1212
|
try {
|
|
1213
|
+
const resolvedPath = options.configPath ? resolve(cwd, options.configPath) : findGeneratorConfigPath(cwd);
|
|
1214
|
+
if (!resolvedPath) {
|
|
1215
|
+
const environmentConfig = createEnvironmentGeneratorConfig();
|
|
1216
|
+
if (environmentConfig) {
|
|
1217
|
+
return {
|
|
1218
|
+
configPath: ENV_ONLY_CONFIG_PATH,
|
|
1219
|
+
config: normalizeGeneratorConfig(environmentConfig)
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
throw new Error(
|
|
1223
|
+
`No generator config found in ${cwd}. Expected one of: ${DEFAULT_CONFIG_CANDIDATES.join(", ")}. To run without a config file, set DATABASE_URL (direct mode) or ATHENA_URL + ATHENA_API_KEY (gateway mode).`
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1083
1226
|
const moduleUrl = pathToFileURL(resolvedPath);
|
|
1084
1227
|
const module = await importConfigModule(`${moduleUrl.href}?cacheBust=${Date.now()}`);
|
|
1085
1228
|
const rawConfig = extractConfigExport(module);
|
|
@@ -1092,7 +1235,60 @@ async function loadGeneratorConfig(options = {}) {
|
|
|
1092
1235
|
}
|
|
1093
1236
|
}
|
|
1094
1237
|
|
|
1095
|
-
// src/generator/
|
|
1238
|
+
// src/generator/placeholders.ts
|
|
1239
|
+
function createStyleTokens(prefix, value) {
|
|
1240
|
+
return {
|
|
1241
|
+
[prefix]: value,
|
|
1242
|
+
[`${prefix}_camel`]: applyNamingStyle(value, "camel"),
|
|
1243
|
+
[`${prefix}_pascal`]: applyNamingStyle(value, "pascal"),
|
|
1244
|
+
[`${prefix}_snake`]: applyNamingStyle(value, "snake"),
|
|
1245
|
+
[`${prefix}_kebab`]: applyNamingStyle(value, "kebab")
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
function renderTemplate(template, tokenMap) {
|
|
1249
|
+
return template.replace(/\{([A-Za-z0-9_]+)\}/g, (_match, token) => {
|
|
1250
|
+
if (!(token in tokenMap)) {
|
|
1251
|
+
throw new Error(`Unknown placeholder token "${token}" in template "${template}"`);
|
|
1252
|
+
}
|
|
1253
|
+
return tokenMap[token];
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
function resolvePlaceholderMap(baseTokens, outputConfig) {
|
|
1257
|
+
const resolved = {
|
|
1258
|
+
...baseTokens
|
|
1259
|
+
};
|
|
1260
|
+
const reservedTokenKeys = new Set(Object.keys(baseTokens));
|
|
1261
|
+
const entries = Object.entries(outputConfig.placeholderMap ?? {});
|
|
1262
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
1263
|
+
const [key, value] = entries[index];
|
|
1264
|
+
if (reservedTokenKeys.has(key)) {
|
|
1265
|
+
continue;
|
|
1266
|
+
}
|
|
1267
|
+
let current = value;
|
|
1268
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
1269
|
+
const next = renderTemplate(current, resolved);
|
|
1270
|
+
if (next === current) {
|
|
1271
|
+
break;
|
|
1272
|
+
}
|
|
1273
|
+
current = next;
|
|
1274
|
+
}
|
|
1275
|
+
resolved[key] = current;
|
|
1276
|
+
}
|
|
1277
|
+
return resolved;
|
|
1278
|
+
}
|
|
1279
|
+
function renderOutputPath(template, context, outputConfig) {
|
|
1280
|
+
const baseTokens = {
|
|
1281
|
+
provider: context.provider,
|
|
1282
|
+
kind: context.kind,
|
|
1283
|
+
...createStyleTokens("database", context.database),
|
|
1284
|
+
...createStyleTokens("schema", context.schema),
|
|
1285
|
+
...createStyleTokens("model", context.model)
|
|
1286
|
+
};
|
|
1287
|
+
const tokens = resolvePlaceholderMap(baseTokens, outputConfig);
|
|
1288
|
+
return renderTemplate(template, tokens);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/generator/render-shared.ts
|
|
1096
1292
|
function normalizePath(pathValue) {
|
|
1097
1293
|
return pathValue.replace(/\\/g, "/");
|
|
1098
1294
|
}
|
|
@@ -1105,11 +1301,13 @@ function toModuleImportPath(fromFile, targetFile) {
|
|
|
1105
1301
|
);
|
|
1106
1302
|
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
1107
1303
|
}
|
|
1304
|
+
function resolveOutputPath(target, tokens, config) {
|
|
1305
|
+
return normalizePath(renderOutputPath(target, tokens, config.output));
|
|
1306
|
+
}
|
|
1108
1307
|
function renderObjectKey(key) {
|
|
1109
|
-
|
|
1110
|
-
return escaped.startsWith("'") ? escaped : escaped;
|
|
1308
|
+
return escapeTypePropertyName(key);
|
|
1111
1309
|
}
|
|
1112
|
-
function
|
|
1310
|
+
function renderRelationLiteral(relation) {
|
|
1113
1311
|
const through = relation.through ? `,
|
|
1114
1312
|
through: {
|
|
1115
1313
|
schema: ${escapeStringLiteral(relation.through.schema)},
|
|
@@ -1125,54 +1323,12 @@ function renderRelation(relation) {
|
|
|
1125
1323
|
targetColumns: [${relation.targetColumns.map((value) => escapeStringLiteral(value)).join(", ")}]${through}
|
|
1126
1324
|
}`;
|
|
1127
1325
|
}
|
|
1128
|
-
function renderModelArtifact(snapshot, descriptor, config) {
|
|
1129
|
-
const columnLines = Object.values(descriptor.table.columns).map((column) => {
|
|
1130
|
-
const propertyName = escapeTypePropertyName(column.name);
|
|
1131
|
-
const baseType = resolvePostgresColumnType(column);
|
|
1132
|
-
const isOptional = column.isNullable;
|
|
1133
|
-
const typeWithNullability = column.isNullable ? `${baseType} | null` : baseType;
|
|
1134
|
-
return ` ${propertyName}${isOptional ? "?" : ""}: ${typeWithNullability}`;
|
|
1135
|
-
}).join("\n");
|
|
1136
|
-
const nullableLines = Object.values(descriptor.table.columns).map((column) => ` ${renderObjectKey(column.name)}: ${column.isNullable ? "true" : "false"}`).join(",\n");
|
|
1137
|
-
const relationEntries = Object.entries(descriptor.table.relations);
|
|
1138
|
-
const relationBlock = config.features.emitRelations && relationEntries.length > 0 ? `,
|
|
1139
|
-
relations: {
|
|
1140
|
-
${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelation(relationValue)}`).join(",\n")}
|
|
1141
|
-
}` : "";
|
|
1142
|
-
const content = `import { defineModel } from '@xylex-group/athena'
|
|
1143
|
-
|
|
1144
|
-
export interface ${descriptor.rowTypeName} {
|
|
1145
|
-
${columnLines}
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
export type ${descriptor.insertTypeName} = Partial<${descriptor.rowTypeName}>
|
|
1149
|
-
export type ${descriptor.updateTypeName} = Partial<${descriptor.insertTypeName}>
|
|
1150
|
-
|
|
1151
|
-
export const ${descriptor.modelConstName} = defineModel<${descriptor.rowTypeName}, ${descriptor.insertTypeName}, ${descriptor.updateTypeName}>({
|
|
1152
|
-
meta: {
|
|
1153
|
-
database: ${escapeStringLiteral(snapshot.database)},
|
|
1154
|
-
schema: ${escapeStringLiteral(descriptor.schemaName)},
|
|
1155
|
-
model: ${escapeStringLiteral(descriptor.tableName)},
|
|
1156
|
-
tableName: ${escapeStringLiteral(`${descriptor.schemaName}.${descriptor.tableName}`)},
|
|
1157
|
-
primaryKey: [${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")}],
|
|
1158
|
-
nullable: {
|
|
1159
|
-
${nullableLines}
|
|
1160
|
-
}${relationBlock}
|
|
1161
|
-
}
|
|
1162
|
-
})
|
|
1163
|
-
`;
|
|
1164
|
-
return {
|
|
1165
|
-
kind: "model",
|
|
1166
|
-
path: descriptor.filePath,
|
|
1167
|
-
content
|
|
1168
|
-
};
|
|
1169
|
-
}
|
|
1170
1326
|
function renderSchemaArtifact(descriptor) {
|
|
1171
1327
|
const importLines = descriptor.models.map((modelDescriptor) => {
|
|
1172
1328
|
const importPath = toModuleImportPath(descriptor.filePath, modelDescriptor.filePath);
|
|
1173
|
-
return `import { ${modelDescriptor.
|
|
1329
|
+
return `import { ${modelDescriptor.exportConstName} } from '${importPath}'`;
|
|
1174
1330
|
}).join("\n");
|
|
1175
|
-
const modelEntries = descriptor.models.map((modelDescriptor) => ` ${renderObjectKey(modelDescriptor.tableName)}: ${modelDescriptor.
|
|
1331
|
+
const modelEntries = descriptor.models.map((modelDescriptor) => ` ${renderObjectKey(modelDescriptor.tableName)}: ${modelDescriptor.exportConstName}`).join(",\n");
|
|
1176
1332
|
const content = `import { defineSchema } from '@xylex-group/athena'
|
|
1177
1333
|
${importLines ? `
|
|
1178
1334
|
${importLines}
|
|
@@ -1207,11 +1363,18 @@ ${schemaEntries}
|
|
|
1207
1363
|
content
|
|
1208
1364
|
};
|
|
1209
1365
|
}
|
|
1210
|
-
function renderRegistryArtifact(registryPath, databasePath, databaseConstName, registryConstName, databaseName) {
|
|
1366
|
+
function renderRegistryArtifact(registryPath, databasePath, databaseConstName, registryConstName, databaseName, generatedAt, outputFormat, schemaVersion) {
|
|
1211
1367
|
const databaseImportPath = toModuleImportPath(registryPath, databasePath);
|
|
1212
1368
|
const content = `import { defineRegistry } from '@xylex-group/athena'
|
|
1213
1369
|
import { ${databaseConstName} } from '${databaseImportPath}'
|
|
1214
1370
|
|
|
1371
|
+
export const __athena_schema_meta = {
|
|
1372
|
+
schemaVersion: ${schemaVersion},
|
|
1373
|
+
generatedAt: ${escapeStringLiteral(generatedAt)},
|
|
1374
|
+
database: ${escapeStringLiteral(databaseName)},
|
|
1375
|
+
outputFormat: ${escapeStringLiteral(outputFormat)},
|
|
1376
|
+
} as const
|
|
1377
|
+
|
|
1215
1378
|
export const ${registryConstName} = defineRegistry({
|
|
1216
1379
|
${renderObjectKey(databaseName)}: ${databaseConstName}
|
|
1217
1380
|
})
|
|
@@ -1290,123 +1453,332 @@ function scopeDuplicateDescriptorPathsBySchema(descriptors) {
|
|
|
1290
1453
|
}
|
|
1291
1454
|
return nextDescriptors;
|
|
1292
1455
|
}
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
const
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
const table = schema.tables[tableName];
|
|
1306
|
-
const rowTypeName = `${toSafeIdentifier(`${schemaName} ${tableName}`, this.config.naming.modelType, "Model")}Row`;
|
|
1307
|
-
const insertTypeName = `${toSafeIdentifier(`${schemaName} ${tableName}`, this.config.naming.modelType, "Model")}Insert`;
|
|
1308
|
-
const updateTypeName = `${toSafeIdentifier(`${schemaName} ${tableName}`, this.config.naming.modelType, "Model")}Update`;
|
|
1309
|
-
const modelConstName = `${toSafeIdentifier(`${schemaName} ${tableName} model`, this.config.naming.modelConst, "model")}`;
|
|
1310
|
-
const modelPath = normalizePath(
|
|
1311
|
-
renderOutputPath(this.config.output.targets.model, {
|
|
1312
|
-
provider: providerName,
|
|
1313
|
-
kind: "model",
|
|
1314
|
-
database: databaseName,
|
|
1315
|
-
schema: schemaName,
|
|
1316
|
-
model: tableName
|
|
1317
|
-
}, this.config.output)
|
|
1318
|
-
);
|
|
1319
|
-
modelDescriptors.push({
|
|
1456
|
+
function composeGeneratorArtifacts(input) {
|
|
1457
|
+
const { snapshot, config, createModelDescriptor, renderModelArtifact: renderModelArtifact3 } = input;
|
|
1458
|
+
const providerName = snapshot.backend;
|
|
1459
|
+
const databaseName = snapshot.database;
|
|
1460
|
+
const modelDescriptors = [];
|
|
1461
|
+
for (const schemaName of Object.keys(snapshot.schemas).sort()) {
|
|
1462
|
+
const schema = snapshot.schemas[schemaName];
|
|
1463
|
+
for (const tableName of Object.keys(schema.tables).sort()) {
|
|
1464
|
+
modelDescriptors.push(
|
|
1465
|
+
createModelDescriptor({
|
|
1466
|
+
providerName,
|
|
1467
|
+
databaseName,
|
|
1320
1468
|
schemaName,
|
|
1321
1469
|
tableName,
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
insertTypeName,
|
|
1325
|
-
updateTypeName,
|
|
1326
|
-
modelConstName,
|
|
1327
|
-
table
|
|
1328
|
-
});
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
const scopedModelDescriptors = scopeDuplicateDescriptorPathsBySchema(modelDescriptors);
|
|
1332
|
-
let schemaDescriptors = Object.keys(this.snapshot.schemas).sort().map((schemaName) => {
|
|
1333
|
-
const schemaPath = normalizePath(
|
|
1334
|
-
renderOutputPath(this.config.output.targets.schema, {
|
|
1335
|
-
provider: providerName,
|
|
1336
|
-
kind: "schema",
|
|
1337
|
-
database: databaseName,
|
|
1338
|
-
schema: schemaName,
|
|
1339
|
-
model: "index"
|
|
1340
|
-
}, this.config.output)
|
|
1470
|
+
table: schema.tables[tableName]
|
|
1471
|
+
})
|
|
1341
1472
|
);
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
models: scopedModelDescriptors.filter((model) => model.schemaName === schemaName)
|
|
1351
|
-
};
|
|
1352
|
-
});
|
|
1353
|
-
schemaDescriptors = scopeDuplicateDescriptorPathsBySchema(schemaDescriptors);
|
|
1354
|
-
const databasePath = normalizePath(
|
|
1355
|
-
renderOutputPath(this.config.output.targets.database, {
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
const scopedModelDescriptors = scopeDuplicateDescriptorPathsBySchema(modelDescriptors);
|
|
1476
|
+
let schemaDescriptors = Object.keys(snapshot.schemas).sort().map((schemaName) => ({
|
|
1477
|
+
schemaName,
|
|
1478
|
+
filePath: resolveOutputPath(
|
|
1479
|
+
config.output.targets.schema,
|
|
1480
|
+
{
|
|
1356
1481
|
provider: providerName,
|
|
1357
|
-
kind: "
|
|
1482
|
+
kind: "schema",
|
|
1358
1483
|
database: databaseName,
|
|
1359
|
-
schema:
|
|
1484
|
+
schema: schemaName,
|
|
1360
1485
|
model: "index"
|
|
1361
|
-
},
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
databaseDescriptor.databaseConstName,
|
|
1395
|
-
toSafeIdentifier("registry", this.config.naming.registryConst, "registry"),
|
|
1396
|
-
databaseName
|
|
1397
|
-
)
|
|
1398
|
-
);
|
|
1399
|
-
}
|
|
1400
|
-
assertNoDuplicatePaths(files);
|
|
1401
|
-
return {
|
|
1402
|
-
snapshot: this.snapshot,
|
|
1403
|
-
files
|
|
1404
|
-
};
|
|
1486
|
+
},
|
|
1487
|
+
config
|
|
1488
|
+
),
|
|
1489
|
+
schemaConstName: toSafeIdentifier(
|
|
1490
|
+
`${schemaName} schema`,
|
|
1491
|
+
config.naming.schemaConst,
|
|
1492
|
+
"schema"
|
|
1493
|
+
),
|
|
1494
|
+
models: scopedModelDescriptors.filter((model) => model.schemaName === schemaName)
|
|
1495
|
+
}));
|
|
1496
|
+
schemaDescriptors = scopeDuplicateDescriptorPathsBySchema(schemaDescriptors);
|
|
1497
|
+
const databaseDescriptor = {
|
|
1498
|
+
filePath: resolveOutputPath(
|
|
1499
|
+
config.output.targets.database,
|
|
1500
|
+
{
|
|
1501
|
+
provider: providerName,
|
|
1502
|
+
kind: "database",
|
|
1503
|
+
database: databaseName,
|
|
1504
|
+
schema: "index",
|
|
1505
|
+
model: "index"
|
|
1506
|
+
},
|
|
1507
|
+
config
|
|
1508
|
+
),
|
|
1509
|
+
databaseConstName: toSafeIdentifier(
|
|
1510
|
+
`${databaseName} database`,
|
|
1511
|
+
config.naming.databaseConst,
|
|
1512
|
+
"database"
|
|
1513
|
+
),
|
|
1514
|
+
schemas: schemaDescriptors
|
|
1515
|
+
};
|
|
1516
|
+
const files = [];
|
|
1517
|
+
for (const modelDescriptor of scopedModelDescriptors) {
|
|
1518
|
+
files.push(renderModelArtifact3(modelDescriptor));
|
|
1405
1519
|
}
|
|
1406
|
-
|
|
1520
|
+
for (const schemaDescriptor of schemaDescriptors) {
|
|
1521
|
+
files.push(renderSchemaArtifact(schemaDescriptor));
|
|
1522
|
+
}
|
|
1523
|
+
files.push(renderDatabaseArtifact(databaseDescriptor));
|
|
1524
|
+
if (config.features.emitRegistry) {
|
|
1525
|
+
const registryPath = resolveOutputPath(
|
|
1526
|
+
config.output.targets.registry,
|
|
1527
|
+
{
|
|
1528
|
+
provider: providerName,
|
|
1529
|
+
kind: "registry",
|
|
1530
|
+
database: databaseName,
|
|
1531
|
+
schema: "index",
|
|
1532
|
+
model: "index"
|
|
1533
|
+
},
|
|
1534
|
+
config
|
|
1535
|
+
);
|
|
1536
|
+
files.push(
|
|
1537
|
+
renderRegistryArtifact(
|
|
1538
|
+
registryPath,
|
|
1539
|
+
databaseDescriptor.filePath,
|
|
1540
|
+
databaseDescriptor.databaseConstName,
|
|
1541
|
+
toSafeIdentifier("registry", config.naming.registryConst, "registry"),
|
|
1542
|
+
databaseName,
|
|
1543
|
+
snapshot.generatedAt,
|
|
1544
|
+
config.output.format,
|
|
1545
|
+
config.internal.schemaVersion
|
|
1546
|
+
)
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
assertNoDuplicatePaths(files);
|
|
1550
|
+
return {
|
|
1551
|
+
snapshot,
|
|
1552
|
+
files
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
// src/generator/table-builder-renderer.ts
|
|
1557
|
+
var SAFE_NUMBER_TYPES = /* @__PURE__ */ new Set([
|
|
1558
|
+
"int2",
|
|
1559
|
+
"int4",
|
|
1560
|
+
"float4",
|
|
1561
|
+
"float8",
|
|
1562
|
+
"smallint",
|
|
1563
|
+
"integer",
|
|
1564
|
+
"real",
|
|
1565
|
+
"double precision"
|
|
1566
|
+
]);
|
|
1567
|
+
var JSON_TYPES = /* @__PURE__ */ new Set(["json", "jsonb"]);
|
|
1568
|
+
var BOOLEAN_TYPES = /* @__PURE__ */ new Set(["bool", "boolean"]);
|
|
1569
|
+
var STRING_TYPES = /* @__PURE__ */ new Set([
|
|
1570
|
+
"int8",
|
|
1571
|
+
"bigint",
|
|
1572
|
+
"serial8",
|
|
1573
|
+
"bigserial",
|
|
1574
|
+
"numeric",
|
|
1575
|
+
"decimal",
|
|
1576
|
+
"money",
|
|
1577
|
+
"bytea"
|
|
1578
|
+
]);
|
|
1579
|
+
function normalizeTypeLabel2(column) {
|
|
1580
|
+
const preferred = (column.udtName || column.dataType).toLowerCase().trim();
|
|
1581
|
+
if (column.arrayDimensions > 0 && preferred.startsWith("_")) {
|
|
1582
|
+
return preferred.slice(1);
|
|
1583
|
+
}
|
|
1584
|
+
return preferred;
|
|
1585
|
+
}
|
|
1586
|
+
function renderColumnBuilder(column) {
|
|
1587
|
+
const label = normalizeTypeLabel2(column);
|
|
1588
|
+
let helper;
|
|
1589
|
+
let expression;
|
|
1590
|
+
if (column.typeKind === "enum" && column.enumValues && column.enumValues.length > 0) {
|
|
1591
|
+
helper = "enumeration";
|
|
1592
|
+
expression = `enumeration([${column.enumValues.map((value) => escapeStringLiteral(value)).join(", ")}] as const)`;
|
|
1593
|
+
} else if (column.arrayDimensions > 0 || JSON_TYPES.has(label) || column.typeKind === "composite") {
|
|
1594
|
+
helper = "json";
|
|
1595
|
+
expression = `json<${resolvePostgresColumnType(column)}>()`;
|
|
1596
|
+
} else if (BOOLEAN_TYPES.has(label)) {
|
|
1597
|
+
helper = "boolean";
|
|
1598
|
+
expression = "boolean()";
|
|
1599
|
+
} else if (SAFE_NUMBER_TYPES.has(label)) {
|
|
1600
|
+
helper = "number";
|
|
1601
|
+
expression = "number()";
|
|
1602
|
+
} else if (STRING_TYPES.has(label)) {
|
|
1603
|
+
helper = "string";
|
|
1604
|
+
expression = "string()";
|
|
1605
|
+
} else {
|
|
1606
|
+
helper = "string";
|
|
1607
|
+
expression = "string()";
|
|
1608
|
+
}
|
|
1609
|
+
if (column.isNullable) {
|
|
1610
|
+
expression = `${expression}.optional()`;
|
|
1611
|
+
}
|
|
1612
|
+
if (column.hasDefault) {
|
|
1613
|
+
expression = `${expression}.defaulted()`;
|
|
1614
|
+
}
|
|
1615
|
+
if (column.isGenerated) {
|
|
1616
|
+
expression = `${expression}.generated()`;
|
|
1617
|
+
}
|
|
1618
|
+
return { helper, expression };
|
|
1619
|
+
}
|
|
1620
|
+
function renderModelArtifact(descriptor, config) {
|
|
1621
|
+
const helperImports = /* @__PURE__ */ new Set(["table"]);
|
|
1622
|
+
const columnLines = Object.entries(descriptor.table.columns).map(([columnName, column]) => {
|
|
1623
|
+
const propertyName = escapeTypePropertyName(columnName);
|
|
1624
|
+
const rendered = renderColumnBuilder(column);
|
|
1625
|
+
helperImports.add(rendered.helper);
|
|
1626
|
+
return ` ${propertyName}: ${rendered.expression}`;
|
|
1627
|
+
}).join(",\n");
|
|
1628
|
+
const helperImportLine = Array.from(helperImports).sort().join(", ");
|
|
1629
|
+
const rowSchemaConstName = `${descriptor.tableConstName}_row_schema`;
|
|
1630
|
+
const insertSchemaConstName = `${descriptor.tableConstName}_insert_schema`;
|
|
1631
|
+
const updateSchemaConstName = `${descriptor.tableConstName}_update_schema`;
|
|
1632
|
+
const formSchemaConstName = `${descriptor.tableConstName}_form_schema`;
|
|
1633
|
+
const relationEntries = Object.entries(descriptor.table.relations);
|
|
1634
|
+
const relationsAssignment = config.features.emitRelations && relationEntries.length > 0 ? `
|
|
1635
|
+
Object.assign(${descriptor.tableConstName}.meta, {
|
|
1636
|
+
relations: {
|
|
1637
|
+
${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
|
|
1638
|
+
}
|
|
1639
|
+
})
|
|
1640
|
+
` : "";
|
|
1641
|
+
const content = `import { ${helperImportLine} } from '@xylex-group/athena'
|
|
1642
|
+
import type { FormValuesOf, InsertOf, RowOf, UpdateOf } from '@xylex-group/athena'
|
|
1643
|
+
|
|
1644
|
+
export const ${descriptor.tableConstName} = table(${escapeStringLiteral(descriptor.tableName)})
|
|
1645
|
+
.schema(${escapeStringLiteral(descriptor.schemaName)})
|
|
1646
|
+
.columns({
|
|
1647
|
+
${columnLines}
|
|
1648
|
+
})
|
|
1649
|
+
.primaryKey(${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")})
|
|
1650
|
+
${relationsAssignment ? `${relationsAssignment}` : ""}
|
|
1651
|
+
export type ${descriptor.rowTypeName} = RowOf<typeof ${descriptor.tableConstName}>
|
|
1652
|
+
export type ${descriptor.insertTypeName} = InsertOf<typeof ${descriptor.tableConstName}>
|
|
1653
|
+
export type ${descriptor.updateTypeName} = UpdateOf<typeof ${descriptor.tableConstName}>
|
|
1654
|
+
export type ${descriptor.formValuesTypeName} = FormValuesOf<typeof ${descriptor.tableConstName}>
|
|
1655
|
+
|
|
1656
|
+
export const ${rowSchemaConstName} = ${descriptor.tableConstName}.schemas.row
|
|
1657
|
+
export const ${insertSchemaConstName} = ${descriptor.tableConstName}.schemas.insert
|
|
1658
|
+
export const ${updateSchemaConstName} = ${descriptor.tableConstName}.schemas.update
|
|
1659
|
+
export const ${formSchemaConstName} = ${descriptor.tableConstName}.schemas.form
|
|
1660
|
+
`;
|
|
1661
|
+
return {
|
|
1662
|
+
kind: "model",
|
|
1663
|
+
path: descriptor.filePath,
|
|
1664
|
+
content
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
function generateTableBuilderArtifactsFromSnapshot(snapshot, config) {
|
|
1668
|
+
const normalizedConfig = "internal" in config ? config : normalizeGeneratorConfig(config);
|
|
1669
|
+
return composeGeneratorArtifacts({
|
|
1670
|
+
snapshot,
|
|
1671
|
+
config: normalizedConfig,
|
|
1672
|
+
createModelDescriptor({ providerName, databaseName, schemaName, tableName, table }) {
|
|
1673
|
+
const tableConstName = toSafeIdentifier(tableName, "preserve", "table");
|
|
1674
|
+
return {
|
|
1675
|
+
schemaName,
|
|
1676
|
+
tableName,
|
|
1677
|
+
filePath: resolveOutputPath(
|
|
1678
|
+
normalizedConfig.output.targets.model,
|
|
1679
|
+
{
|
|
1680
|
+
provider: providerName,
|
|
1681
|
+
kind: "model",
|
|
1682
|
+
database: databaseName,
|
|
1683
|
+
schema: schemaName,
|
|
1684
|
+
model: tableName
|
|
1685
|
+
},
|
|
1686
|
+
normalizedConfig
|
|
1687
|
+
),
|
|
1688
|
+
rowTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Row`,
|
|
1689
|
+
insertTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Insert`,
|
|
1690
|
+
updateTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Update`,
|
|
1691
|
+
formValuesTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}FormValues`,
|
|
1692
|
+
tableConstName,
|
|
1693
|
+
exportConstName: tableConstName,
|
|
1694
|
+
table
|
|
1695
|
+
};
|
|
1696
|
+
},
|
|
1697
|
+
renderModelArtifact: (descriptor) => renderModelArtifact(descriptor, normalizedConfig)
|
|
1698
|
+
});
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
// src/generator/renderer.ts
|
|
1702
|
+
function renderModelArtifact2(databaseName, descriptor, config) {
|
|
1703
|
+
const columnLines = Object.values(descriptor.table.columns).map((column) => {
|
|
1704
|
+
const propertyName = escapeTypePropertyName(column.name);
|
|
1705
|
+
const baseType = resolvePostgresColumnType(column);
|
|
1706
|
+
const isOptional = column.isNullable;
|
|
1707
|
+
const typeWithNullability = column.isNullable ? `${baseType} | null` : baseType;
|
|
1708
|
+
return ` ${propertyName}${isOptional ? "?" : ""}: ${typeWithNullability}`;
|
|
1709
|
+
}).join("\n");
|
|
1710
|
+
const nullableLines = Object.values(descriptor.table.columns).map((column) => ` ${renderObjectKey(column.name)}: ${column.isNullable ? "true" : "false"}`).join(",\n");
|
|
1711
|
+
const relationEntries = Object.entries(descriptor.table.relations);
|
|
1712
|
+
const relationBlock = config.features.emitRelations && relationEntries.length > 0 ? `,
|
|
1713
|
+
relations: {
|
|
1714
|
+
${relationEntries.map(([relationKey2, relationValue]) => ` ${renderObjectKey(relationKey2)}: ${renderRelationLiteral(relationValue)}`).join(",\n")}
|
|
1715
|
+
}` : "";
|
|
1716
|
+
const content = `import { defineModel } from '@xylex-group/athena'
|
|
1717
|
+
|
|
1718
|
+
export interface ${descriptor.rowTypeName} {
|
|
1719
|
+
${columnLines}
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
export type ${descriptor.insertTypeName} = Partial<${descriptor.rowTypeName}>
|
|
1723
|
+
export type ${descriptor.updateTypeName} = Partial<${descriptor.insertTypeName}>
|
|
1724
|
+
|
|
1725
|
+
export const ${descriptor.modelConstName} = defineModel<${descriptor.rowTypeName}, ${descriptor.insertTypeName}, ${descriptor.updateTypeName}>({
|
|
1726
|
+
meta: {
|
|
1727
|
+
database: ${escapeStringLiteral(databaseName)},
|
|
1728
|
+
schema: ${escapeStringLiteral(descriptor.schemaName)},
|
|
1729
|
+
model: ${escapeStringLiteral(descriptor.tableName)},
|
|
1730
|
+
tableName: ${escapeStringLiteral(`${descriptor.schemaName}.${descriptor.tableName}`)},
|
|
1731
|
+
primaryKey: [${descriptor.table.primaryKey.map((value) => escapeStringLiteral(value)).join(", ")}],
|
|
1732
|
+
nullable: {
|
|
1733
|
+
${nullableLines}
|
|
1734
|
+
}${relationBlock}
|
|
1735
|
+
}
|
|
1736
|
+
})
|
|
1737
|
+
`;
|
|
1738
|
+
return {
|
|
1739
|
+
kind: "model",
|
|
1740
|
+
path: descriptor.filePath,
|
|
1741
|
+
content
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1407
1744
|
function generateArtifactsFromSnapshot(snapshot, config) {
|
|
1408
|
-
const normalizedConfig = "
|
|
1409
|
-
|
|
1745
|
+
const normalizedConfig = "internal" in config ? config : normalizeGeneratorConfig(config);
|
|
1746
|
+
if (normalizedConfig.output.format === "table-builder") {
|
|
1747
|
+
return generateTableBuilderArtifactsFromSnapshot(snapshot, normalizedConfig);
|
|
1748
|
+
}
|
|
1749
|
+
return composeGeneratorArtifacts({
|
|
1750
|
+
snapshot,
|
|
1751
|
+
config: normalizedConfig,
|
|
1752
|
+
createModelDescriptor({ providerName, databaseName, schemaName, tableName, table }) {
|
|
1753
|
+
const modelConstName = toSafeIdentifier(
|
|
1754
|
+
`${schemaName} ${tableName} model`,
|
|
1755
|
+
normalizedConfig.naming.modelConst,
|
|
1756
|
+
"model"
|
|
1757
|
+
);
|
|
1758
|
+
return {
|
|
1759
|
+
schemaName,
|
|
1760
|
+
tableName,
|
|
1761
|
+
filePath: resolveOutputPath(
|
|
1762
|
+
normalizedConfig.output.targets.model,
|
|
1763
|
+
{
|
|
1764
|
+
provider: providerName,
|
|
1765
|
+
kind: "model",
|
|
1766
|
+
database: databaseName,
|
|
1767
|
+
schema: schemaName,
|
|
1768
|
+
model: tableName
|
|
1769
|
+
},
|
|
1770
|
+
normalizedConfig
|
|
1771
|
+
),
|
|
1772
|
+
rowTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Row`,
|
|
1773
|
+
insertTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Insert`,
|
|
1774
|
+
updateTypeName: `${toSafeIdentifier(`${schemaName} ${tableName}`, normalizedConfig.naming.modelType, "Model")}Update`,
|
|
1775
|
+
modelConstName,
|
|
1776
|
+
exportConstName: modelConstName,
|
|
1777
|
+
table
|
|
1778
|
+
};
|
|
1779
|
+
},
|
|
1780
|
+
renderModelArtifact: (descriptor) => renderModelArtifact2(snapshot.database, descriptor, normalizedConfig)
|
|
1781
|
+
});
|
|
1410
1782
|
}
|
|
1411
1783
|
|
|
1412
1784
|
// src/gateway/url.ts
|
|
@@ -1495,16 +1867,23 @@ var getSessionCookie = (request, config) => {
|
|
|
1495
1867
|
const { cookieName = "session_token", cookiePrefix = "athena-auth" } = {};
|
|
1496
1868
|
const parsedCookie = parseCookies(cookies);
|
|
1497
1869
|
const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
|
|
1498
|
-
const
|
|
1499
|
-
|
|
1500
|
-
|
|
1870
|
+
const candidateCookieNames = Array.from(/* @__PURE__ */ new Set([
|
|
1871
|
+
cookieName,
|
|
1872
|
+
cookieName.replace(/_/g, "-"),
|
|
1873
|
+
cookieName.replace(/-/g, "_")
|
|
1874
|
+
])).filter(Boolean);
|
|
1875
|
+
for (const candidateName of candidateCookieNames) {
|
|
1876
|
+
const sessionToken = getCookie(`${cookiePrefix}.${candidateName}`) || getCookie(`${cookiePrefix}-${candidateName}`);
|
|
1877
|
+
if (sessionToken) {
|
|
1878
|
+
return sessionToken;
|
|
1879
|
+
}
|
|
1501
1880
|
}
|
|
1502
1881
|
return null;
|
|
1503
1882
|
};
|
|
1504
1883
|
|
|
1505
1884
|
// package.json
|
|
1506
1885
|
var package_default = {
|
|
1507
|
-
version: "2.
|
|
1886
|
+
version: "2.8.0"
|
|
1508
1887
|
};
|
|
1509
1888
|
|
|
1510
1889
|
// src/sdk-version.ts
|
|
@@ -3451,11 +3830,12 @@ function createAuthClient(config = {}) {
|
|
|
3451
3830
|
// src/db/module.ts
|
|
3452
3831
|
function createDbModule(input) {
|
|
3453
3832
|
const db = {
|
|
3454
|
-
from
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3833
|
+
from: input.from,
|
|
3834
|
+
select(table, first, second) {
|
|
3835
|
+
if (first && typeof first === "object" && !Array.isArray(first)) {
|
|
3836
|
+
return input.from(table).select(void 0, first);
|
|
3837
|
+
}
|
|
3838
|
+
return input.from(table).select(first, second);
|
|
3459
3839
|
},
|
|
3460
3840
|
insert(table, values, options) {
|
|
3461
3841
|
return Array.isArray(values) ? input.from(table).insert(values, options) : input.from(table).insert(values, options);
|
|
@@ -3479,6 +3859,344 @@ function createDbModule(input) {
|
|
|
3479
3859
|
return db;
|
|
3480
3860
|
}
|
|
3481
3861
|
|
|
3862
|
+
// src/storage/file.ts
|
|
3863
|
+
function createStorageFileModule(base, config = {}) {
|
|
3864
|
+
const upload = async (input, options) => {
|
|
3865
|
+
const sources = normalizeUploadSources(input);
|
|
3866
|
+
validateUploadConstraints(sources, input);
|
|
3867
|
+
const uploadRequests = sources.map((source, index) => {
|
|
3868
|
+
const storageKey = resolveUploadStorageKey(input, source, index, options, config);
|
|
3869
|
+
return {
|
|
3870
|
+
source,
|
|
3871
|
+
uploadRequest: {
|
|
3872
|
+
s3_id: input.s3_id,
|
|
3873
|
+
bucket: input.bucket,
|
|
3874
|
+
storage_key: storageKey,
|
|
3875
|
+
name: input.name ?? source.fileName,
|
|
3876
|
+
original_name: input.original_name ?? source.fileName,
|
|
3877
|
+
resource_id: input.resource_id ?? input.resourceId,
|
|
3878
|
+
mime_type: input.mime_type ?? source.contentType,
|
|
3879
|
+
content_type: input.content_type ?? source.contentType,
|
|
3880
|
+
size_bytes: source.sizeBytes,
|
|
3881
|
+
public: input.public,
|
|
3882
|
+
metadata: input.metadata
|
|
3883
|
+
}
|
|
3884
|
+
};
|
|
3885
|
+
});
|
|
3886
|
+
input.onProgress?.(createProgressSnapshot("preparing", sources, 0, 0, 0));
|
|
3887
|
+
const uploadUrls = uploadRequests.length === 1 ? [await base.createStorageUploadUrl(uploadRequests[0].uploadRequest, options)] : (await base.createStorageUploadUrls({ files: uploadRequests.map((request) => request.uploadRequest) }, options)).files;
|
|
3888
|
+
const aggregateLoaded = new Array(uploadRequests.length).fill(0);
|
|
3889
|
+
const uploaded = [];
|
|
3890
|
+
for (let index = 0; index < uploadRequests.length; index += 1) {
|
|
3891
|
+
const request = uploadRequests[index];
|
|
3892
|
+
const uploadUrl = uploadUrls[index];
|
|
3893
|
+
const response = await putUploadBody(uploadUrl.upload.url, request.source, input, options, (progress) => {
|
|
3894
|
+
aggregateLoaded[index] = progress.loaded;
|
|
3895
|
+
input.onProgress?.(createProgressSnapshot("uploading", sources, index, progress.loaded, sum(aggregateLoaded)));
|
|
3896
|
+
});
|
|
3897
|
+
uploaded.push({
|
|
3898
|
+
file: uploadUrl.file,
|
|
3899
|
+
upload: uploadUrl.upload,
|
|
3900
|
+
source: request.source.source,
|
|
3901
|
+
fileName: request.source.fileName,
|
|
3902
|
+
storage_key: request.uploadRequest.storage_key,
|
|
3903
|
+
response
|
|
3904
|
+
});
|
|
3905
|
+
aggregateLoaded[index] = request.source.sizeBytes;
|
|
3906
|
+
input.onProgress?.(createProgressSnapshot("complete", sources, index, request.source.sizeBytes, sum(aggregateLoaded)));
|
|
3907
|
+
}
|
|
3908
|
+
return {
|
|
3909
|
+
files: uploaded,
|
|
3910
|
+
count: uploaded.length
|
|
3911
|
+
};
|
|
3912
|
+
};
|
|
3913
|
+
const download = ((input, queryOrOptions, maybeOptions) => {
|
|
3914
|
+
const { fileIds, query, options } = normalizeDownloadArgs(input, queryOrOptions, maybeOptions);
|
|
3915
|
+
const downloads = fileIds.map((fileId) => base.getStorageFileProxy(fileId, query, options));
|
|
3916
|
+
return Array.isArray(input) || isRecord5(input) && Array.isArray(input.fileIds) ? Promise.all(downloads) : downloads[0];
|
|
3917
|
+
});
|
|
3918
|
+
const deleteFile = ((input, options) => {
|
|
3919
|
+
if (Array.isArray(input)) {
|
|
3920
|
+
return Promise.all(input.map((fileId) => base.deleteStorageFile(fileId, options)));
|
|
3921
|
+
}
|
|
3922
|
+
return base.deleteStorageFile(input, options);
|
|
3923
|
+
});
|
|
3924
|
+
return {
|
|
3925
|
+
upload,
|
|
3926
|
+
download,
|
|
3927
|
+
list(input, options) {
|
|
3928
|
+
const prefix = resolveStoragePath(input.prefix ?? "", input, options, config);
|
|
3929
|
+
return base.listStorageFiles(
|
|
3930
|
+
{
|
|
3931
|
+
s3_id: input.s3_id,
|
|
3932
|
+
prefix
|
|
3933
|
+
},
|
|
3934
|
+
options
|
|
3935
|
+
);
|
|
3936
|
+
},
|
|
3937
|
+
delete: deleteFile
|
|
3938
|
+
};
|
|
3939
|
+
}
|
|
3940
|
+
function resolveStoragePath(path, input, options, config = {}) {
|
|
3941
|
+
const context = createPathContext(input, options, config);
|
|
3942
|
+
const prefixPath = input.prefixPath ?? config.prefixPath;
|
|
3943
|
+
const prefix = typeof prefixPath === "function" ? prefixPath(context) : prefixPath;
|
|
3944
|
+
return joinStoragePath(renderStorageTemplate(prefix ?? "", context), renderStorageTemplate(path, context));
|
|
3945
|
+
}
|
|
3946
|
+
function resolveUploadStorageKey(input, source, index, options, config) {
|
|
3947
|
+
const explicitKey = input.storage_key ?? input.storageKey;
|
|
3948
|
+
const keyTemplate = input.storageKeyTemplate;
|
|
3949
|
+
const fallbackName = source.fileName;
|
|
3950
|
+
const context = createPathContext(input, options, config);
|
|
3951
|
+
const key = keyTemplate ? renderStorageTemplate(keyTemplate, {
|
|
3952
|
+
...context,
|
|
3953
|
+
vars: {
|
|
3954
|
+
...context.vars,
|
|
3955
|
+
index,
|
|
3956
|
+
fileName: source.fileName,
|
|
3957
|
+
name: source.fileName
|
|
3958
|
+
}
|
|
3959
|
+
}) : explicitKey ?? fallbackName;
|
|
3960
|
+
return resolveStoragePath(key, input, options, config);
|
|
3961
|
+
}
|
|
3962
|
+
function normalizeUploadSources(input) {
|
|
3963
|
+
const files = toArray(input.files);
|
|
3964
|
+
if (files.length === 0) {
|
|
3965
|
+
throw new Error("athena.storage.file.upload requires at least one file");
|
|
3966
|
+
}
|
|
3967
|
+
return files.map((source, index) => {
|
|
3968
|
+
const fileName = input.fileName ?? sourceName(source) ?? `file-${index + 1}`;
|
|
3969
|
+
const sizeBytes = sourceSize(source);
|
|
3970
|
+
const contentType = input.content_type ?? input.mime_type ?? sourceContentType(source);
|
|
3971
|
+
return {
|
|
3972
|
+
source,
|
|
3973
|
+
fileName,
|
|
3974
|
+
sizeBytes,
|
|
3975
|
+
contentType
|
|
3976
|
+
};
|
|
3977
|
+
});
|
|
3978
|
+
}
|
|
3979
|
+
function validateUploadConstraints(sources, input) {
|
|
3980
|
+
const maxFiles = input.maxFiles ?? 1;
|
|
3981
|
+
if (sources.length > maxFiles) {
|
|
3982
|
+
throw new Error(`athena.storage.file.upload accepts at most ${maxFiles} file${maxFiles === 1 ? "" : "s"} for this call`);
|
|
3983
|
+
}
|
|
3984
|
+
const maxFileSizeBytes = input.maxFileSizeBytes ?? (input.maxFileSizeMb === void 0 ? void 0 : Math.floor(input.maxFileSizeMb * 1024 * 1024));
|
|
3985
|
+
if (maxFileSizeBytes !== void 0) {
|
|
3986
|
+
const tooLarge = sources.find((source) => source.sizeBytes > maxFileSizeBytes);
|
|
3987
|
+
if (tooLarge) {
|
|
3988
|
+
throw new Error(`athena.storage.file.upload rejected ${tooLarge.fileName}: file exceeds ${maxFileSizeBytes} bytes`);
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
const allowedExtensions = normalizeExtensions(input.allowedExtensions ?? input.extensions);
|
|
3992
|
+
if (allowedExtensions.size > 0) {
|
|
3993
|
+
const invalid = sources.find((source) => !allowedExtensions.has(fileExtension(source.fileName)));
|
|
3994
|
+
if (invalid) {
|
|
3995
|
+
throw new Error(`athena.storage.file.upload rejected ${invalid.fileName}: extension is not allowed`);
|
|
3996
|
+
}
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
async function putUploadBody(url, source, input, options, onProgress) {
|
|
4000
|
+
const headers = new Headers(input.uploadHeaders);
|
|
4001
|
+
if (source.contentType && !headers.has("Content-Type")) {
|
|
4002
|
+
headers.set("Content-Type", source.contentType);
|
|
4003
|
+
}
|
|
4004
|
+
if (typeof XMLHttpRequest !== "undefined") {
|
|
4005
|
+
return putUploadBodyWithXhr(url, source, headers, options, onProgress);
|
|
4006
|
+
}
|
|
4007
|
+
onProgress({ loaded: 0 });
|
|
4008
|
+
const response = await fetch(url, {
|
|
4009
|
+
method: "PUT",
|
|
4010
|
+
headers,
|
|
4011
|
+
body: source.source,
|
|
4012
|
+
signal: options?.signal
|
|
4013
|
+
});
|
|
4014
|
+
if (!response.ok) {
|
|
4015
|
+
throw new Error(`athena.storage.file.upload failed with status ${response.status}`);
|
|
4016
|
+
}
|
|
4017
|
+
onProgress({ loaded: source.sizeBytes });
|
|
4018
|
+
return response;
|
|
4019
|
+
}
|
|
4020
|
+
function putUploadBodyWithXhr(url, source, headers, options, onProgress) {
|
|
4021
|
+
const Xhr = XMLHttpRequest;
|
|
4022
|
+
if (Xhr === void 0) {
|
|
4023
|
+
return Promise.reject(new Error("athena.storage.file.upload requires XMLHttpRequest in this runtime"));
|
|
4024
|
+
}
|
|
4025
|
+
return new Promise((resolve3, reject) => {
|
|
4026
|
+
const xhr = new Xhr();
|
|
4027
|
+
const abort = () => xhr.abort();
|
|
4028
|
+
xhr.open("PUT", url);
|
|
4029
|
+
headers.forEach((value, key) => xhr.setRequestHeader(key, value));
|
|
4030
|
+
xhr.upload.onprogress = (event) => {
|
|
4031
|
+
onProgress({ loaded: event.loaded });
|
|
4032
|
+
};
|
|
4033
|
+
xhr.onload = () => {
|
|
4034
|
+
if (options?.signal) {
|
|
4035
|
+
options.signal.removeEventListener("abort", abort);
|
|
4036
|
+
}
|
|
4037
|
+
if (xhr.status < 200 || xhr.status >= 300) {
|
|
4038
|
+
reject(new Error(`athena.storage.file.upload failed with status ${xhr.status}`));
|
|
4039
|
+
return;
|
|
4040
|
+
}
|
|
4041
|
+
onProgress({ loaded: source.sizeBytes });
|
|
4042
|
+
resolve3(new Response(xhr.response, {
|
|
4043
|
+
status: xhr.status,
|
|
4044
|
+
statusText: xhr.statusText,
|
|
4045
|
+
headers: parseXhrHeaders(xhr.getAllResponseHeaders())
|
|
4046
|
+
}));
|
|
4047
|
+
};
|
|
4048
|
+
xhr.onerror = () => {
|
|
4049
|
+
if (options?.signal) {
|
|
4050
|
+
options.signal.removeEventListener("abort", abort);
|
|
4051
|
+
}
|
|
4052
|
+
reject(new Error("athena.storage.file.upload failed with a network error"));
|
|
4053
|
+
};
|
|
4054
|
+
xhr.onabort = () => {
|
|
4055
|
+
if (options?.signal) {
|
|
4056
|
+
options.signal.removeEventListener("abort", abort);
|
|
4057
|
+
}
|
|
4058
|
+
reject(new DOMException("Upload aborted", "AbortError"));
|
|
4059
|
+
};
|
|
4060
|
+
if (options?.signal) {
|
|
4061
|
+
if (options.signal.aborted) {
|
|
4062
|
+
abort();
|
|
4063
|
+
return;
|
|
4064
|
+
}
|
|
4065
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
4066
|
+
}
|
|
4067
|
+
xhr.send(source.source);
|
|
4068
|
+
});
|
|
4069
|
+
}
|
|
4070
|
+
function normalizeDownloadArgs(input, queryOrOptions, maybeOptions) {
|
|
4071
|
+
if (typeof input === "string") {
|
|
4072
|
+
return { fileIds: [input], query: queryOrOptions, options: maybeOptions };
|
|
4073
|
+
}
|
|
4074
|
+
if (Array.isArray(input)) {
|
|
4075
|
+
return { fileIds: [...input], query: queryOrOptions, options: maybeOptions };
|
|
4076
|
+
}
|
|
4077
|
+
const downloadInput = input;
|
|
4078
|
+
const { fileId, fileIds, ...query } = downloadInput;
|
|
4079
|
+
return {
|
|
4080
|
+
fileIds: fileIds ? [...fileIds] : fileId ? [fileId] : [],
|
|
4081
|
+
query,
|
|
4082
|
+
options: queryOrOptions
|
|
4083
|
+
};
|
|
4084
|
+
}
|
|
4085
|
+
function createPathContext(input, options, config) {
|
|
4086
|
+
const organizationId = input.organizationId ?? input.organization_id ?? options?.organizationId ?? void 0;
|
|
4087
|
+
const userId = input.userId ?? input.user_id ?? options?.userId ?? void 0;
|
|
4088
|
+
const resourceId = input.resourceId ?? input.resource_id ?? void 0;
|
|
4089
|
+
const vars = {
|
|
4090
|
+
...config.vars ?? {},
|
|
4091
|
+
...input.vars ?? {}
|
|
4092
|
+
};
|
|
4093
|
+
if (organizationId !== void 0) {
|
|
4094
|
+
vars.organizationId = organizationId;
|
|
4095
|
+
vars.organization_id = organizationId;
|
|
4096
|
+
}
|
|
4097
|
+
if (userId !== void 0) {
|
|
4098
|
+
vars.userId = userId;
|
|
4099
|
+
vars.user_id = userId;
|
|
4100
|
+
}
|
|
4101
|
+
if (resourceId !== void 0) {
|
|
4102
|
+
vars.resourceId = resourceId;
|
|
4103
|
+
vars.resource_id = resourceId;
|
|
4104
|
+
}
|
|
4105
|
+
return {
|
|
4106
|
+
vars,
|
|
4107
|
+
env: {
|
|
4108
|
+
...readProcessEnv(),
|
|
4109
|
+
...config.env ?? {},
|
|
4110
|
+
...input.env ?? {}
|
|
4111
|
+
},
|
|
4112
|
+
organizationId,
|
|
4113
|
+
organization_id: organizationId,
|
|
4114
|
+
userId,
|
|
4115
|
+
user_id: userId,
|
|
4116
|
+
resourceId,
|
|
4117
|
+
resource_id: resourceId
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
function renderStorageTemplate(template, context) {
|
|
4121
|
+
return template.replace(/\$\{([^}]+)\}|\{([^}]+)\}/g, (_match, shellToken, braceToken) => {
|
|
4122
|
+
const token = (shellToken ?? braceToken ?? "").trim();
|
|
4123
|
+
if (!token) return "";
|
|
4124
|
+
const value = resolveTemplateToken(token, context);
|
|
4125
|
+
return value === void 0 || value === null ? "" : String(value);
|
|
4126
|
+
});
|
|
4127
|
+
}
|
|
4128
|
+
function resolveTemplateToken(token, context) {
|
|
4129
|
+
if (token.startsWith("env.")) {
|
|
4130
|
+
return context.env[token.slice(4)];
|
|
4131
|
+
}
|
|
4132
|
+
if (token in context.vars) {
|
|
4133
|
+
return context.vars[token];
|
|
4134
|
+
}
|
|
4135
|
+
return context.env[token];
|
|
4136
|
+
}
|
|
4137
|
+
function joinStoragePath(...parts) {
|
|
4138
|
+
return parts.map((part) => part.trim().replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
|
|
4139
|
+
}
|
|
4140
|
+
function toArray(files) {
|
|
4141
|
+
if (isUploadSource(files)) return [files];
|
|
4142
|
+
return Array.from(files);
|
|
4143
|
+
}
|
|
4144
|
+
function isUploadSource(value) {
|
|
4145
|
+
return value instanceof Blob || value instanceof ArrayBuffer || value instanceof Uint8Array;
|
|
4146
|
+
}
|
|
4147
|
+
function sourceName(source) {
|
|
4148
|
+
return isRecord5(source) && typeof source.name === "string" && source.name.trim() ? source.name.trim() : void 0;
|
|
4149
|
+
}
|
|
4150
|
+
function sourceSize(source) {
|
|
4151
|
+
if (source instanceof Blob) return source.size;
|
|
4152
|
+
return source.byteLength;
|
|
4153
|
+
}
|
|
4154
|
+
function sourceContentType(source) {
|
|
4155
|
+
return source instanceof Blob && source.type.trim() ? source.type.trim() : void 0;
|
|
4156
|
+
}
|
|
4157
|
+
function normalizeExtensions(extensions) {
|
|
4158
|
+
return new Set((extensions ?? []).map((extension) => extension.replace(/^\./, "").toLowerCase()).filter(Boolean));
|
|
4159
|
+
}
|
|
4160
|
+
function fileExtension(fileName) {
|
|
4161
|
+
const lastDot = fileName.lastIndexOf(".");
|
|
4162
|
+
return lastDot === -1 ? "" : fileName.slice(lastDot + 1).toLowerCase();
|
|
4163
|
+
}
|
|
4164
|
+
function createProgressSnapshot(phase, sources, fileIndex, loaded, aggregateLoaded) {
|
|
4165
|
+
const total = sources[fileIndex]?.sizeBytes ?? 0;
|
|
4166
|
+
const aggregateTotal = sources.reduce((totalBytes, source) => totalBytes + source.sizeBytes, 0);
|
|
4167
|
+
return {
|
|
4168
|
+
phase,
|
|
4169
|
+
fileIndex,
|
|
4170
|
+
fileCount: sources.length,
|
|
4171
|
+
fileName: sources[fileIndex]?.fileName ?? "",
|
|
4172
|
+
loaded,
|
|
4173
|
+
total,
|
|
4174
|
+
percent: total > 0 ? Math.round(loaded / total * 100) : 100,
|
|
4175
|
+
aggregateLoaded,
|
|
4176
|
+
aggregateTotal,
|
|
4177
|
+
aggregatePercent: aggregateTotal > 0 ? Math.round(aggregateLoaded / aggregateTotal * 100) : 100
|
|
4178
|
+
};
|
|
4179
|
+
}
|
|
4180
|
+
function sum(values) {
|
|
4181
|
+
return values.reduce((total, value) => total + value, 0);
|
|
4182
|
+
}
|
|
4183
|
+
function parseXhrHeaders(raw) {
|
|
4184
|
+
const headers = new Headers();
|
|
4185
|
+
for (const line of raw.trim().split(/[\r\n]+/)) {
|
|
4186
|
+
const index = line.indexOf(":");
|
|
4187
|
+
if (index === -1) continue;
|
|
4188
|
+
headers.set(line.slice(0, index).trim(), line.slice(index + 1).trim());
|
|
4189
|
+
}
|
|
4190
|
+
return headers;
|
|
4191
|
+
}
|
|
4192
|
+
function readProcessEnv() {
|
|
4193
|
+
const processLike = globalThis.process;
|
|
4194
|
+
return processLike?.env ?? {};
|
|
4195
|
+
}
|
|
4196
|
+
function isRecord5(value) {
|
|
4197
|
+
return Boolean(value) && typeof value === "object";
|
|
4198
|
+
}
|
|
4199
|
+
|
|
3482
4200
|
// src/storage/module.ts
|
|
3483
4201
|
var storageSdkManifest = {
|
|
3484
4202
|
methods: [
|
|
@@ -3673,7 +4391,7 @@ var AthenaStorageError = class extends Error {
|
|
|
3673
4391
|
};
|
|
3674
4392
|
}
|
|
3675
4393
|
};
|
|
3676
|
-
function
|
|
4394
|
+
function isRecord6(value) {
|
|
3677
4395
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3678
4396
|
}
|
|
3679
4397
|
function causeToString(cause) {
|
|
@@ -3784,11 +4502,20 @@ function appendQuery(path, query) {
|
|
|
3784
4502
|
function storagePath(path) {
|
|
3785
4503
|
return path;
|
|
3786
4504
|
}
|
|
4505
|
+
function resolveStorageEndpointPath(endpoint, runtimeOptions) {
|
|
4506
|
+
if (!runtimeOptions?.stripBasePath) {
|
|
4507
|
+
return endpoint;
|
|
4508
|
+
}
|
|
4509
|
+
const [pathname, queryText] = String(endpoint).split("?", 2);
|
|
4510
|
+
const trimmedPathname = pathname.startsWith("/storage/") ? pathname.slice("/storage".length) : pathname === "/storage" ? "/" : pathname;
|
|
4511
|
+
const resolvedPath = trimmedPathname.startsWith("/") ? trimmedPathname : `/${trimmedPathname}`;
|
|
4512
|
+
return storagePath(queryText ? `${resolvedPath}?${queryText}` : resolvedPath);
|
|
4513
|
+
}
|
|
3787
4514
|
function withPathParam(path, name, value) {
|
|
3788
4515
|
return path.replace(`{${name}}`, encodeURIComponent(value));
|
|
3789
4516
|
}
|
|
3790
4517
|
function resolveErrorMessage3(payload, fallback) {
|
|
3791
|
-
if (
|
|
4518
|
+
if (isRecord6(payload)) {
|
|
3792
4519
|
const message = payload.message ?? payload.error ?? payload.details;
|
|
3793
4520
|
if (typeof message === "string" && message.trim()) {
|
|
3794
4521
|
return message.trim();
|
|
@@ -3800,12 +4527,12 @@ function resolveErrorMessage3(payload, fallback) {
|
|
|
3800
4527
|
return fallback;
|
|
3801
4528
|
}
|
|
3802
4529
|
function resolveErrorHint2(payload) {
|
|
3803
|
-
if (!
|
|
4530
|
+
if (!isRecord6(payload)) return void 0;
|
|
3804
4531
|
const hint = payload.hint ?? payload.suggestion;
|
|
3805
4532
|
return typeof hint === "string" && hint.trim() ? hint.trim() : void 0;
|
|
3806
4533
|
}
|
|
3807
4534
|
function resolveErrorCause(payload) {
|
|
3808
|
-
if (!
|
|
4535
|
+
if (!isRecord6(payload)) return void 0;
|
|
3809
4536
|
const cause = payload.cause ?? payload.reason;
|
|
3810
4537
|
return typeof cause === "string" && cause.trim() ? cause.trim() : void 0;
|
|
3811
4538
|
}
|
|
@@ -3822,8 +4549,8 @@ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload,
|
|
|
3822
4549
|
let url;
|
|
3823
4550
|
let headers;
|
|
3824
4551
|
try {
|
|
3825
|
-
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
|
|
3826
|
-
url = buildAthenaGatewayUrl(baseUrl, endpoint);
|
|
4552
|
+
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : runtimeOptions?.baseUrl ? normalizeAthenaGatewayBaseUrl(runtimeOptions.baseUrl) : gateway.baseUrl;
|
|
4553
|
+
url = buildAthenaGatewayUrl(baseUrl, resolveStorageEndpointPath(endpoint, runtimeOptions));
|
|
3827
4554
|
headers = gateway.buildHeaders(options);
|
|
3828
4555
|
} catch (error) {
|
|
3829
4556
|
return rejectStorageError(
|
|
@@ -3924,7 +4651,7 @@ async function callStorageEndpoint(gateway, endpoint, method, envelope, payload,
|
|
|
3924
4651
|
);
|
|
3925
4652
|
}
|
|
3926
4653
|
if (envelope === "athena") {
|
|
3927
|
-
if (!
|
|
4654
|
+
if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
|
|
3928
4655
|
return rejectStorageError(
|
|
3929
4656
|
{
|
|
3930
4657
|
code: "INVALID_ATHENA_ENVELOPE",
|
|
@@ -3947,8 +4674,8 @@ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, run
|
|
|
3947
4674
|
let url;
|
|
3948
4675
|
let headers;
|
|
3949
4676
|
try {
|
|
3950
|
-
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : gateway.baseUrl;
|
|
3951
|
-
url = buildAthenaGatewayUrl(baseUrl, endpoint);
|
|
4677
|
+
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : runtimeOptions?.baseUrl ? normalizeAthenaGatewayBaseUrl(runtimeOptions.baseUrl) : gateway.baseUrl;
|
|
4678
|
+
url = buildAthenaGatewayUrl(baseUrl, resolveStorageEndpointPath(endpoint, runtimeOptions));
|
|
3952
4679
|
headers = gateway.buildHeaders(options);
|
|
3953
4680
|
} catch (error) {
|
|
3954
4681
|
return rejectStorageError(
|
|
@@ -4032,129 +4759,515 @@ async function callStorageBinaryEndpoint(gateway, endpoint, method, options, run
|
|
|
4032
4759
|
runtimeOptions
|
|
4033
4760
|
);
|
|
4034
4761
|
}
|
|
4035
|
-
function
|
|
4762
|
+
function isBlobBody(body) {
|
|
4763
|
+
return typeof Blob !== "undefined" && body instanceof Blob;
|
|
4764
|
+
}
|
|
4765
|
+
function isReadableStreamBody(body) {
|
|
4766
|
+
return typeof ReadableStream !== "undefined" && body instanceof ReadableStream;
|
|
4767
|
+
}
|
|
4768
|
+
async function putPresignedUploadBody(uploadUrl, uploadHeaders, body, options) {
|
|
4769
|
+
const headers = new Headers(uploadHeaders);
|
|
4770
|
+
Object.entries(options?.headers ?? {}).forEach(([key, value]) => headers.set(key, value));
|
|
4771
|
+
if (!headers.has("Content-Type") && isBlobBody(body) && body.type) {
|
|
4772
|
+
headers.set("Content-Type", body.type);
|
|
4773
|
+
}
|
|
4774
|
+
const init = {
|
|
4775
|
+
method: "PUT",
|
|
4776
|
+
headers,
|
|
4777
|
+
body,
|
|
4778
|
+
signal: options?.signal
|
|
4779
|
+
};
|
|
4780
|
+
if (isReadableStreamBody(body)) {
|
|
4781
|
+
init.duplex = "half";
|
|
4782
|
+
}
|
|
4783
|
+
return fetch(uploadUrl, init);
|
|
4784
|
+
}
|
|
4785
|
+
function attachManagedUpload(upload) {
|
|
4786
|
+
const headers = {};
|
|
4036
4787
|
return {
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4788
|
+
...upload,
|
|
4789
|
+
method: "PUT",
|
|
4790
|
+
headers,
|
|
4791
|
+
expiresAt: upload.expires_at,
|
|
4792
|
+
put(body, options) {
|
|
4793
|
+
return putPresignedUploadBody(upload.url, headers, body, options);
|
|
4794
|
+
}
|
|
4795
|
+
};
|
|
4796
|
+
}
|
|
4797
|
+
function attachUploadHelper(response) {
|
|
4798
|
+
return {
|
|
4799
|
+
...response,
|
|
4800
|
+
upload: attachManagedUpload(response.upload)
|
|
4801
|
+
};
|
|
4802
|
+
}
|
|
4803
|
+
function attachUploadHelpers(response) {
|
|
4804
|
+
return {
|
|
4805
|
+
files: response.files.map(attachUploadHelper)
|
|
4806
|
+
};
|
|
4807
|
+
}
|
|
4808
|
+
function normalizeUploadUrlRequest(input) {
|
|
4809
|
+
const s3_id = input.s3_id ?? input.s3Id;
|
|
4810
|
+
const storage_key = input.storage_key ?? input.storageKey;
|
|
4811
|
+
if (!s3_id?.trim()) {
|
|
4812
|
+
throw new Error("athena.storage.file.upload requires s3_id or s3Id");
|
|
4813
|
+
}
|
|
4814
|
+
if (!storage_key?.trim()) {
|
|
4815
|
+
throw new Error("athena.storage.file.upload requires storage_key or storageKey");
|
|
4816
|
+
}
|
|
4817
|
+
const fileName = input.fileName?.trim();
|
|
4818
|
+
const originalName = input.originalName?.trim();
|
|
4819
|
+
return {
|
|
4820
|
+
s3_id,
|
|
4821
|
+
bucket: input.bucket,
|
|
4822
|
+
storage_key,
|
|
4823
|
+
name: input.name ?? fileName,
|
|
4824
|
+
original_name: input.original_name ?? originalName ?? fileName,
|
|
4825
|
+
resource_id: input.resource_id ?? input.resourceId,
|
|
4826
|
+
mime_type: input.mime_type ?? input.mimeType,
|
|
4827
|
+
content_type: input.content_type ?? input.contentType,
|
|
4828
|
+
size_bytes: input.size_bytes ?? input.sizeBytes,
|
|
4829
|
+
file_id: input.file_id ?? input.fileId,
|
|
4830
|
+
public: input.public,
|
|
4831
|
+
visibility: input.visibility,
|
|
4832
|
+
metadata: input.metadata
|
|
4833
|
+
};
|
|
4834
|
+
}
|
|
4835
|
+
async function callStorageUploadBinaryEndpoint(gateway, endpoint, body, options, runtimeOptions) {
|
|
4836
|
+
let url;
|
|
4837
|
+
let headers;
|
|
4838
|
+
try {
|
|
4839
|
+
const baseUrl = options?.baseUrl ? normalizeAthenaGatewayBaseUrl(options.baseUrl) : runtimeOptions?.baseUrl ? normalizeAthenaGatewayBaseUrl(runtimeOptions.baseUrl) : gateway.baseUrl;
|
|
4840
|
+
url = buildAthenaGatewayUrl(baseUrl, resolveStorageEndpointPath(endpoint, runtimeOptions));
|
|
4841
|
+
headers = gateway.buildHeaders(options);
|
|
4842
|
+
} catch (error) {
|
|
4843
|
+
return rejectStorageError(
|
|
4844
|
+
{
|
|
4845
|
+
code: storageCodeFromUnknown(error),
|
|
4846
|
+
message: error instanceof Error ? error.message : `Athena storage PUT ${endpoint} failed before sending the request`,
|
|
4847
|
+
status: isAthenaGatewayError(error) ? error.status : 0,
|
|
4848
|
+
endpoint,
|
|
4849
|
+
method: "PUT",
|
|
4850
|
+
raw: error,
|
|
4851
|
+
requestId: isAthenaGatewayError(error) ? error.requestId : void 0,
|
|
4852
|
+
hint: isAthenaGatewayError(error) ? error.hint : void 0,
|
|
4853
|
+
cause: error
|
|
4854
|
+
},
|
|
4855
|
+
options,
|
|
4856
|
+
runtimeOptions
|
|
4857
|
+
);
|
|
4858
|
+
}
|
|
4859
|
+
delete headers["Content-Type"];
|
|
4860
|
+
delete headers["content-type"];
|
|
4861
|
+
if (isBlobBody(body) && body.type) {
|
|
4862
|
+
headers["Content-Type"] = body.type;
|
|
4863
|
+
}
|
|
4864
|
+
const requestInit = {
|
|
4865
|
+
method: "PUT",
|
|
4866
|
+
headers,
|
|
4867
|
+
body,
|
|
4868
|
+
signal: options?.signal
|
|
4869
|
+
};
|
|
4870
|
+
if (isReadableStreamBody(body)) {
|
|
4871
|
+
requestInit.duplex = "half";
|
|
4872
|
+
}
|
|
4873
|
+
let response;
|
|
4874
|
+
try {
|
|
4875
|
+
response = await fetch(url, requestInit);
|
|
4876
|
+
} catch (error) {
|
|
4877
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4878
|
+
return rejectStorageError(
|
|
4879
|
+
{
|
|
4880
|
+
code: "NETWORK_ERROR",
|
|
4881
|
+
message: `Network error while calling Athena storage PUT ${endpoint}: ${message}`,
|
|
4882
|
+
status: 0,
|
|
4883
|
+
endpoint,
|
|
4884
|
+
method: "PUT",
|
|
4885
|
+
cause: error
|
|
4886
|
+
},
|
|
4887
|
+
options,
|
|
4888
|
+
runtimeOptions
|
|
4889
|
+
);
|
|
4890
|
+
}
|
|
4891
|
+
let rawText;
|
|
4892
|
+
try {
|
|
4893
|
+
rawText = await response.text();
|
|
4894
|
+
} catch (error) {
|
|
4895
|
+
return rejectStorageError(
|
|
4896
|
+
{
|
|
4897
|
+
code: "NETWORK_ERROR",
|
|
4898
|
+
message: `Athena storage PUT ${endpoint} response body could not be read`,
|
|
4899
|
+
status: response.status,
|
|
4900
|
+
endpoint,
|
|
4901
|
+
method: "PUT",
|
|
4902
|
+
requestId: headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]),
|
|
4903
|
+
cause: error
|
|
4904
|
+
},
|
|
4905
|
+
options,
|
|
4906
|
+
runtimeOptions
|
|
4907
|
+
);
|
|
4908
|
+
}
|
|
4909
|
+
const parsedBody = parseResponseBody3(rawText ?? "", response.headers.get("content-type"));
|
|
4910
|
+
const requestId = headerValue(response.headers, ["x-athena-request-id", "x-request-id", "request-id"]);
|
|
4911
|
+
if (parsedBody.parseFailed) {
|
|
4912
|
+
return rejectStorageError(
|
|
4913
|
+
{
|
|
4914
|
+
code: "INVALID_JSON",
|
|
4915
|
+
message: `Athena storage PUT ${endpoint} returned malformed JSON`,
|
|
4916
|
+
status: response.status,
|
|
4917
|
+
endpoint,
|
|
4918
|
+
method: "PUT",
|
|
4919
|
+
requestId,
|
|
4920
|
+
raw: parsedBody.parsed
|
|
4921
|
+
},
|
|
4922
|
+
options,
|
|
4923
|
+
runtimeOptions
|
|
4924
|
+
);
|
|
4925
|
+
}
|
|
4926
|
+
if (!response.ok) {
|
|
4927
|
+
return rejectStorageError(
|
|
4928
|
+
{
|
|
4929
|
+
code: "HTTP_ERROR",
|
|
4930
|
+
message: resolveErrorMessage3(
|
|
4931
|
+
parsedBody.parsed,
|
|
4932
|
+
`Athena storage PUT ${endpoint} failed with status ${response.status}`
|
|
4933
|
+
),
|
|
4934
|
+
status: response.status,
|
|
4935
|
+
endpoint,
|
|
4936
|
+
method: "PUT",
|
|
4937
|
+
requestId,
|
|
4938
|
+
hint: resolveErrorHint2(parsedBody.parsed),
|
|
4939
|
+
cause: resolveErrorCause(parsedBody.parsed),
|
|
4940
|
+
raw: parsedBody.parsed
|
|
4941
|
+
},
|
|
4942
|
+
options,
|
|
4943
|
+
runtimeOptions
|
|
4944
|
+
);
|
|
4945
|
+
}
|
|
4946
|
+
if (!isRecord6(parsedBody.parsed) || !("data" in parsedBody.parsed)) {
|
|
4947
|
+
return rejectStorageError(
|
|
4948
|
+
{
|
|
4949
|
+
code: "INVALID_ATHENA_ENVELOPE",
|
|
4950
|
+
message: `Athena storage PUT ${endpoint} returned an invalid Athena envelope`,
|
|
4951
|
+
status: response.status,
|
|
4952
|
+
endpoint,
|
|
4953
|
+
method: "PUT",
|
|
4954
|
+
requestId,
|
|
4955
|
+
raw: parsedBody.parsed
|
|
4956
|
+
},
|
|
4957
|
+
options,
|
|
4958
|
+
runtimeOptions
|
|
4959
|
+
);
|
|
4960
|
+
}
|
|
4961
|
+
return parsedBody.parsed.data;
|
|
4962
|
+
}
|
|
4963
|
+
function createStorageModule(gateway, runtimeOptions) {
|
|
4964
|
+
const resolvedRuntimeOptions = runtimeOptions;
|
|
4965
|
+
const callRaw = (path, method, payload, options) => callStorageEndpoint(
|
|
4966
|
+
gateway,
|
|
4967
|
+
storagePath(path),
|
|
4968
|
+
method,
|
|
4969
|
+
"raw",
|
|
4970
|
+
payload,
|
|
4971
|
+
options,
|
|
4972
|
+
resolvedRuntimeOptions
|
|
4973
|
+
);
|
|
4974
|
+
const callAthena2 = (path, method, payload, options) => callStorageEndpoint(
|
|
4975
|
+
gateway,
|
|
4976
|
+
storagePath(path),
|
|
4977
|
+
method,
|
|
4978
|
+
"athena",
|
|
4979
|
+
payload,
|
|
4980
|
+
options,
|
|
4981
|
+
resolvedRuntimeOptions
|
|
4982
|
+
);
|
|
4983
|
+
const base = {
|
|
4984
|
+
listStorageCatalogs(options) {
|
|
4985
|
+
return callRaw("/storage/catalogs", "GET", void 0, options);
|
|
4986
|
+
},
|
|
4987
|
+
createStorageCatalog(input, options) {
|
|
4988
|
+
return callRaw("/storage/catalogs", "POST", input, options);
|
|
4989
|
+
},
|
|
4990
|
+
updateStorageCatalog(id, input, options) {
|
|
4991
|
+
return callRaw(withPathParam("/storage/catalogs/{id}", "id", id), "PATCH", input, options);
|
|
4992
|
+
},
|
|
4993
|
+
deleteStorageCatalog(id, options) {
|
|
4994
|
+
return callRaw(withPathParam("/storage/catalogs/{id}", "id", id), "DELETE", void 0, options);
|
|
4064
4995
|
},
|
|
4065
4996
|
listStorageCredentials(options) {
|
|
4066
|
-
return
|
|
4997
|
+
return callRaw("/storage/credentials", "GET", void 0, options);
|
|
4067
4998
|
},
|
|
4068
4999
|
createStorageUploadUrl(input, options) {
|
|
4069
|
-
return
|
|
4070
|
-
gateway,
|
|
4071
|
-
storagePath("/storage/files/upload-url"),
|
|
4072
|
-
"POST",
|
|
4073
|
-
"athena",
|
|
4074
|
-
input,
|
|
4075
|
-
options,
|
|
4076
|
-
runtimeOptions
|
|
4077
|
-
);
|
|
5000
|
+
return callAthena2("/storage/files/upload-url", "POST", input, options);
|
|
4078
5001
|
},
|
|
4079
5002
|
createStorageUploadUrls(input, options) {
|
|
4080
|
-
return
|
|
4081
|
-
gateway,
|
|
4082
|
-
storagePath("/storage/files/upload-urls"),
|
|
4083
|
-
"POST",
|
|
4084
|
-
"athena",
|
|
4085
|
-
input,
|
|
4086
|
-
options,
|
|
4087
|
-
runtimeOptions
|
|
4088
|
-
);
|
|
5003
|
+
return callAthena2("/storage/files/upload-urls", "POST", input, options);
|
|
4089
5004
|
},
|
|
4090
5005
|
listStorageFiles(input, options) {
|
|
4091
|
-
return
|
|
5006
|
+
return callAthena2("/storage/files/list", "POST", input, options);
|
|
4092
5007
|
},
|
|
4093
5008
|
getStorageFile(fileId, options) {
|
|
4094
|
-
return
|
|
4095
|
-
gateway,
|
|
4096
|
-
storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
|
|
4097
|
-
"GET",
|
|
4098
|
-
"athena",
|
|
4099
|
-
void 0,
|
|
4100
|
-
options,
|
|
4101
|
-
runtimeOptions
|
|
4102
|
-
);
|
|
5009
|
+
return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "GET", void 0, options);
|
|
4103
5010
|
},
|
|
4104
5011
|
getStorageFileUrl(fileId, query, options) {
|
|
4105
5012
|
const path = appendQuery(
|
|
4106
5013
|
withPathParam("/storage/files/{file_id}/url", "file_id", fileId),
|
|
4107
5014
|
query
|
|
4108
5015
|
);
|
|
4109
|
-
return
|
|
5016
|
+
return callAthena2(path, "GET", void 0, options);
|
|
4110
5017
|
},
|
|
4111
5018
|
getStorageFileProxy(fileId, query, options) {
|
|
4112
5019
|
const path = appendQuery(
|
|
4113
5020
|
withPathParam("/storage/files/{file_id}/proxy", "file_id", fileId),
|
|
4114
5021
|
query
|
|
4115
5022
|
);
|
|
4116
|
-
return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options,
|
|
5023
|
+
return callStorageBinaryEndpoint(gateway, storagePath(path), "GET", options, resolvedRuntimeOptions);
|
|
4117
5024
|
},
|
|
4118
5025
|
updateStorageFile(fileId, input, options) {
|
|
4119
|
-
return
|
|
4120
|
-
gateway,
|
|
4121
|
-
storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
|
|
4122
|
-
"PATCH",
|
|
4123
|
-
"athena",
|
|
4124
|
-
input,
|
|
4125
|
-
options,
|
|
4126
|
-
runtimeOptions
|
|
4127
|
-
);
|
|
5026
|
+
return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "PATCH", input, options);
|
|
4128
5027
|
},
|
|
4129
5028
|
deleteStorageFile(fileId, options) {
|
|
4130
|
-
return
|
|
4131
|
-
gateway,
|
|
4132
|
-
storagePath(withPathParam("/storage/files/{file_id}", "file_id", fileId)),
|
|
4133
|
-
"DELETE",
|
|
4134
|
-
"athena",
|
|
4135
|
-
void 0,
|
|
4136
|
-
options,
|
|
4137
|
-
runtimeOptions
|
|
4138
|
-
);
|
|
5029
|
+
return callAthena2(withPathParam("/storage/files/{file_id}", "file_id", fileId), "DELETE", void 0, options);
|
|
4139
5030
|
},
|
|
4140
5031
|
setStorageFileVisibility(fileId, input, options) {
|
|
4141
|
-
return
|
|
5032
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/visibility", "file_id", fileId), "PATCH", input, options);
|
|
5033
|
+
},
|
|
5034
|
+
deleteStorageFolder(input, options) {
|
|
5035
|
+
return callAthena2("/storage/folders/delete", "POST", input, options);
|
|
5036
|
+
},
|
|
5037
|
+
moveStorageFolder(input, options) {
|
|
5038
|
+
return callAthena2("/storage/folders/move", "POST", input, options);
|
|
5039
|
+
}
|
|
5040
|
+
};
|
|
5041
|
+
const fileFacade = createStorageFileModule(base, runtimeOptions);
|
|
5042
|
+
const fileUpload = ((input, options) => {
|
|
5043
|
+
if (isRecord6(input) && "files" in input) {
|
|
5044
|
+
return fileFacade.upload(input, options);
|
|
5045
|
+
}
|
|
5046
|
+
return base.createStorageUploadUrl(
|
|
5047
|
+
normalizeUploadUrlRequest(input),
|
|
5048
|
+
options
|
|
5049
|
+
).then(attachUploadHelper);
|
|
5050
|
+
});
|
|
5051
|
+
const fileDelete = ((input, options) => fileFacade.delete(input, options));
|
|
5052
|
+
const file = {
|
|
5053
|
+
...fileFacade,
|
|
5054
|
+
upload: fileUpload,
|
|
5055
|
+
uploadMany(input, options) {
|
|
5056
|
+
return base.createStorageUploadUrls(
|
|
5057
|
+
{ files: input.files.map(normalizeUploadUrlRequest) },
|
|
5058
|
+
options
|
|
5059
|
+
).then(attachUploadHelpers);
|
|
5060
|
+
},
|
|
5061
|
+
confirmUpload(fileId, input, options) {
|
|
5062
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/confirm-upload", "file_id", fileId), "POST", input ?? {}, options);
|
|
5063
|
+
},
|
|
5064
|
+
uploadBinary(fileId, body, options) {
|
|
5065
|
+
return callStorageUploadBinaryEndpoint(
|
|
4142
5066
|
gateway,
|
|
4143
|
-
storagePath(withPathParam("/storage/files/{file_id}/
|
|
4144
|
-
|
|
4145
|
-
"athena",
|
|
4146
|
-
input,
|
|
5067
|
+
storagePath(withPathParam("/storage/files/{file_id}/upload", "file_id", fileId)),
|
|
5068
|
+
body,
|
|
4147
5069
|
options,
|
|
4148
|
-
|
|
5070
|
+
resolvedRuntimeOptions
|
|
4149
5071
|
);
|
|
4150
5072
|
},
|
|
4151
|
-
|
|
4152
|
-
return
|
|
5073
|
+
search(input, options) {
|
|
5074
|
+
return callAthena2("/storage/files/search", "POST", input, options);
|
|
4153
5075
|
},
|
|
4154
|
-
|
|
4155
|
-
return
|
|
5076
|
+
get(fileId, options) {
|
|
5077
|
+
return base.getStorageFile(fileId, options);
|
|
5078
|
+
},
|
|
5079
|
+
update(fileId, input, options) {
|
|
5080
|
+
return base.updateStorageFile(fileId, input, options);
|
|
5081
|
+
},
|
|
5082
|
+
delete: fileDelete,
|
|
5083
|
+
deleteMany(input, options) {
|
|
5084
|
+
return callAthena2("/storage/files/delete-many", "POST", input, options);
|
|
5085
|
+
},
|
|
5086
|
+
updateMany(input, options) {
|
|
5087
|
+
return callAthena2("/storage/files/update-many", "POST", input, options);
|
|
5088
|
+
},
|
|
5089
|
+
restore(fileId, options) {
|
|
5090
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/restore", "file_id", fileId), "POST", {}, options);
|
|
5091
|
+
},
|
|
5092
|
+
purge(fileId, options) {
|
|
5093
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/purge", "file_id", fileId), "DELETE", void 0, options);
|
|
5094
|
+
},
|
|
5095
|
+
copy(fileId, input, options) {
|
|
5096
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/copy", "file_id", fileId), "POST", input, options);
|
|
5097
|
+
},
|
|
5098
|
+
url(fileId, query, options) {
|
|
5099
|
+
return base.getStorageFileUrl(fileId, query, options);
|
|
5100
|
+
},
|
|
5101
|
+
publicUrl(fileId, options) {
|
|
5102
|
+
return callAthena2(withPathParam("/storage/files/{file_id}/public-url", "file_id", fileId), "GET", void 0, options);
|
|
5103
|
+
},
|
|
5104
|
+
proxy(fileId, query, options) {
|
|
5105
|
+
return base.getStorageFileProxy(fileId, query, options);
|
|
5106
|
+
},
|
|
5107
|
+
visibility: {
|
|
5108
|
+
set(fileId, input, options) {
|
|
5109
|
+
return base.setStorageFileVisibility(fileId, input, options);
|
|
5110
|
+
},
|
|
5111
|
+
setMany(input, options) {
|
|
5112
|
+
return callAthena2("/storage/files/visibility-many", "POST", input, options);
|
|
5113
|
+
}
|
|
5114
|
+
}
|
|
5115
|
+
};
|
|
5116
|
+
const credentials = {
|
|
5117
|
+
list(options) {
|
|
5118
|
+
return base.listStorageCredentials(options);
|
|
5119
|
+
}
|
|
5120
|
+
};
|
|
5121
|
+
const catalog = {
|
|
5122
|
+
list(options) {
|
|
5123
|
+
return base.listStorageCatalogs(options);
|
|
5124
|
+
},
|
|
5125
|
+
create(input, options) {
|
|
5126
|
+
return base.createStorageCatalog(input, options);
|
|
5127
|
+
},
|
|
5128
|
+
update(id, input, options) {
|
|
5129
|
+
return base.updateStorageCatalog(id, input, options);
|
|
5130
|
+
},
|
|
5131
|
+
delete(id, options) {
|
|
5132
|
+
return base.deleteStorageCatalog(id, options);
|
|
5133
|
+
}
|
|
5134
|
+
};
|
|
5135
|
+
const folder = {
|
|
5136
|
+
list(input, options) {
|
|
5137
|
+
return callAthena2("/storage/folders/list", "POST", input, options);
|
|
5138
|
+
},
|
|
5139
|
+
tree(input, options) {
|
|
5140
|
+
return callAthena2("/storage/folders/tree", "POST", input, options);
|
|
5141
|
+
},
|
|
5142
|
+
delete(input, options) {
|
|
5143
|
+
return base.deleteStorageFolder(input, options);
|
|
5144
|
+
},
|
|
5145
|
+
move(input, options) {
|
|
5146
|
+
return base.moveStorageFolder(input, options);
|
|
5147
|
+
}
|
|
5148
|
+
};
|
|
5149
|
+
const permission = {
|
|
5150
|
+
list(input, options) {
|
|
5151
|
+
return callAthena2("/storage/permissions/list", "POST", input, options);
|
|
5152
|
+
},
|
|
5153
|
+
grant(input, options) {
|
|
5154
|
+
return callAthena2("/storage/permissions/grant", "POST", input, options);
|
|
5155
|
+
},
|
|
5156
|
+
revoke(input, options) {
|
|
5157
|
+
return callAthena2("/storage/permissions/revoke", "POST", input, options);
|
|
5158
|
+
},
|
|
5159
|
+
check(input, options) {
|
|
5160
|
+
return callAthena2("/storage/permissions/check", "POST", input, options);
|
|
5161
|
+
}
|
|
5162
|
+
};
|
|
5163
|
+
const objectFolder = {
|
|
5164
|
+
create(input, options) {
|
|
5165
|
+
return callAthena2("/storage/objects/folder", "POST", input, options);
|
|
5166
|
+
},
|
|
5167
|
+
delete(input, options) {
|
|
5168
|
+
return callAthena2("/storage/objects/folder/delete", "POST", input, options);
|
|
5169
|
+
},
|
|
5170
|
+
rename(input, options) {
|
|
5171
|
+
return callAthena2("/storage/objects/folder/rename", "POST", input, options);
|
|
4156
5172
|
}
|
|
4157
5173
|
};
|
|
5174
|
+
const object = {
|
|
5175
|
+
list(input, options) {
|
|
5176
|
+
return callAthena2("/storage/objects", "POST", input, options);
|
|
5177
|
+
},
|
|
5178
|
+
head(input, options) {
|
|
5179
|
+
return callAthena2("/storage/objects/head", "POST", input, options);
|
|
5180
|
+
},
|
|
5181
|
+
exists(input, options) {
|
|
5182
|
+
return callAthena2("/storage/objects/exists", "POST", input, options);
|
|
5183
|
+
},
|
|
5184
|
+
validate(input, options) {
|
|
5185
|
+
return callAthena2("/storage/objects/validate", "POST", input, options);
|
|
5186
|
+
},
|
|
5187
|
+
update(input, options) {
|
|
5188
|
+
return callAthena2("/storage/objects/update", "POST", input, options);
|
|
5189
|
+
},
|
|
5190
|
+
copy(input, options) {
|
|
5191
|
+
return callAthena2("/storage/objects/copy", "POST", input, options);
|
|
5192
|
+
},
|
|
5193
|
+
url(input, options) {
|
|
5194
|
+
return callAthena2("/storage/objects/url", "POST", input, options);
|
|
5195
|
+
},
|
|
5196
|
+
publicUrl(input, options) {
|
|
5197
|
+
return callAthena2("/storage/objects/public-url", "POST", input, options);
|
|
5198
|
+
},
|
|
5199
|
+
delete(input, options) {
|
|
5200
|
+
return callAthena2("/storage/objects/delete", "POST", input, options);
|
|
5201
|
+
},
|
|
5202
|
+
uploadUrl(input, options) {
|
|
5203
|
+
return callAthena2("/storage/objects/upload-url", "POST", input, options);
|
|
5204
|
+
},
|
|
5205
|
+
folder: objectFolder
|
|
5206
|
+
};
|
|
5207
|
+
const bucket = {
|
|
5208
|
+
list(input, options) {
|
|
5209
|
+
return callAthena2("/storage/buckets/list", "POST", input, options);
|
|
5210
|
+
},
|
|
5211
|
+
create(input, options) {
|
|
5212
|
+
return callAthena2("/storage/buckets/create", "POST", input, options);
|
|
5213
|
+
},
|
|
5214
|
+
delete(input, options) {
|
|
5215
|
+
return callAthena2("/storage/buckets/delete", "POST", input, options);
|
|
5216
|
+
},
|
|
5217
|
+
cors: {
|
|
5218
|
+
get(input, options) {
|
|
5219
|
+
return callAthena2("/storage/buckets/cors", "POST", input, options);
|
|
5220
|
+
},
|
|
5221
|
+
set(input, options) {
|
|
5222
|
+
return callAthena2("/storage/buckets/cors/set", "POST", input, options);
|
|
5223
|
+
},
|
|
5224
|
+
delete(input, options) {
|
|
5225
|
+
return callAthena2("/storage/buckets/cors/delete", "POST", input, options);
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
};
|
|
5229
|
+
const multipart = {
|
|
5230
|
+
create(input, options) {
|
|
5231
|
+
return callAthena2("/storage/multipart/create", "POST", input, options);
|
|
5232
|
+
},
|
|
5233
|
+
signPart(input, options) {
|
|
5234
|
+
return callAthena2("/storage/multipart/sign-part", "POST", input, options);
|
|
5235
|
+
},
|
|
5236
|
+
complete(input, options) {
|
|
5237
|
+
return callAthena2("/storage/multipart/complete", "POST", input, options);
|
|
5238
|
+
},
|
|
5239
|
+
abort(input, options) {
|
|
5240
|
+
return callAthena2("/storage/multipart/abort", "POST", input, options);
|
|
5241
|
+
},
|
|
5242
|
+
listParts(input, options) {
|
|
5243
|
+
return callAthena2("/storage/multipart/list-parts", "POST", input, options);
|
|
5244
|
+
}
|
|
5245
|
+
};
|
|
5246
|
+
const audit = {
|
|
5247
|
+
list(input, options) {
|
|
5248
|
+
return callAthena2("/storage/audit/list", "POST", input, options);
|
|
5249
|
+
}
|
|
5250
|
+
};
|
|
5251
|
+
return {
|
|
5252
|
+
...base,
|
|
5253
|
+
credentials,
|
|
5254
|
+
catalog,
|
|
5255
|
+
file,
|
|
5256
|
+
folder,
|
|
5257
|
+
permission,
|
|
5258
|
+
object,
|
|
5259
|
+
bucket,
|
|
5260
|
+
multipart,
|
|
5261
|
+
audit,
|
|
5262
|
+
delete: file.delete
|
|
5263
|
+
};
|
|
5264
|
+
}
|
|
5265
|
+
|
|
5266
|
+
// src/client-builder.ts
|
|
5267
|
+
var DEFAULT_BACKEND = { type: "athena" };
|
|
5268
|
+
function toBackendConfig(value) {
|
|
5269
|
+
if (!value) return DEFAULT_BACKEND;
|
|
5270
|
+
return typeof value === "string" ? { type: value } : value;
|
|
4158
5271
|
}
|
|
4159
5272
|
|
|
4160
5273
|
// src/query-ast.ts
|
|
@@ -4184,7 +5297,7 @@ var BOOLEAN_SAFE_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
4184
5297
|
"ilike",
|
|
4185
5298
|
"is"
|
|
4186
5299
|
]);
|
|
4187
|
-
function
|
|
5300
|
+
function isRecord7(value) {
|
|
4188
5301
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4189
5302
|
}
|
|
4190
5303
|
function isUuidString(value) {
|
|
@@ -4197,7 +5310,7 @@ function shouldUseUuidTextComparison(column, value) {
|
|
|
4197
5310
|
return typeof value === "string" && isUuidString(value) && isUuidIdentifierColumn(column);
|
|
4198
5311
|
}
|
|
4199
5312
|
function isRelationSelectNode(value) {
|
|
4200
|
-
return
|
|
5313
|
+
return isRecord7(value) && isRecord7(value.select);
|
|
4201
5314
|
}
|
|
4202
5315
|
function normalizeIdentifier(value, label) {
|
|
4203
5316
|
const normalized = value.trim();
|
|
@@ -4253,7 +5366,7 @@ function compileRelationToken(key, node) {
|
|
|
4253
5366
|
return `${prefix}${relationToken}(${nested})`;
|
|
4254
5367
|
}
|
|
4255
5368
|
function compileSelectShape(select) {
|
|
4256
|
-
if (!
|
|
5369
|
+
if (!isRecord7(select)) {
|
|
4257
5370
|
throw new Error("findMany select must be an object");
|
|
4258
5371
|
}
|
|
4259
5372
|
const tokens = [];
|
|
@@ -4277,7 +5390,7 @@ function compileSelectShape(select) {
|
|
|
4277
5390
|
return tokens.join(",");
|
|
4278
5391
|
}
|
|
4279
5392
|
function selectShapeUsesRelationSchema(select) {
|
|
4280
|
-
if (!
|
|
5393
|
+
if (!isRecord7(select)) {
|
|
4281
5394
|
return false;
|
|
4282
5395
|
}
|
|
4283
5396
|
for (const rawValue of Object.values(select)) {
|
|
@@ -4295,7 +5408,7 @@ function selectShapeUsesRelationSchema(select) {
|
|
|
4295
5408
|
}
|
|
4296
5409
|
function compileColumnWhere(column, input) {
|
|
4297
5410
|
const normalizedColumn = normalizeIdentifier(column, "where column");
|
|
4298
|
-
if (!
|
|
5411
|
+
if (!isRecord7(input)) {
|
|
4299
5412
|
return [buildGatewayCondition("eq", normalizedColumn, input)];
|
|
4300
5413
|
}
|
|
4301
5414
|
const conditions = [];
|
|
@@ -4323,7 +5436,7 @@ function compileColumnWhere(column, input) {
|
|
|
4323
5436
|
return conditions;
|
|
4324
5437
|
}
|
|
4325
5438
|
function compileBooleanExpressionTerms(clause, label) {
|
|
4326
|
-
if (!
|
|
5439
|
+
if (!isRecord7(clause)) {
|
|
4327
5440
|
throw new Error(`findMany where.${label} clauses must be objects`);
|
|
4328
5441
|
}
|
|
4329
5442
|
const entries = Object.entries(clause).filter(([, value]) => value !== void 0);
|
|
@@ -4332,7 +5445,7 @@ function compileBooleanExpressionTerms(clause, label) {
|
|
|
4332
5445
|
}
|
|
4333
5446
|
const [rawColumn, rawValue] = entries[0];
|
|
4334
5447
|
const column = normalizeIdentifier(rawColumn, `where.${label} column`);
|
|
4335
|
-
if (!
|
|
5448
|
+
if (!isRecord7(rawValue)) {
|
|
4336
5449
|
return [`${column}.eq.${stringifyFilterValue(rawValue)}`];
|
|
4337
5450
|
}
|
|
4338
5451
|
const operatorEntries = Object.entries(rawValue).filter(([, value]) => value !== void 0);
|
|
@@ -4356,7 +5469,7 @@ function compileWhere(where) {
|
|
|
4356
5469
|
if (where === void 0) {
|
|
4357
5470
|
return void 0;
|
|
4358
5471
|
}
|
|
4359
|
-
if (!
|
|
5472
|
+
if (!isRecord7(where)) {
|
|
4360
5473
|
throw new Error("findMany where must be an object");
|
|
4361
5474
|
}
|
|
4362
5475
|
const conditions = [];
|
|
@@ -4406,7 +5519,7 @@ function compileOrderBy(orderBy) {
|
|
|
4406
5519
|
if (orderBy === void 0) {
|
|
4407
5520
|
return void 0;
|
|
4408
5521
|
}
|
|
4409
|
-
if (!
|
|
5522
|
+
if (!isRecord7(orderBy)) {
|
|
4410
5523
|
throw new Error("findMany orderBy must be an object");
|
|
4411
5524
|
}
|
|
4412
5525
|
if ("column" in orderBy) {
|
|
@@ -4581,11 +5694,11 @@ function toFindManyAstOrder(order) {
|
|
|
4581
5694
|
ascending: order.direction !== "descending"
|
|
4582
5695
|
};
|
|
4583
5696
|
}
|
|
4584
|
-
function
|
|
5697
|
+
function isRecord8(value) {
|
|
4585
5698
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4586
5699
|
}
|
|
4587
5700
|
function normalizeFindManyAstColumnPredicate(value) {
|
|
4588
|
-
if (!
|
|
5701
|
+
if (!isRecord8(value)) {
|
|
4589
5702
|
return {
|
|
4590
5703
|
eq: value
|
|
4591
5704
|
};
|
|
@@ -4609,7 +5722,7 @@ function normalizeFindManyAstBooleanOperand(clause) {
|
|
|
4609
5722
|
return normalized;
|
|
4610
5723
|
}
|
|
4611
5724
|
function normalizeFindManyAstWhere(where) {
|
|
4612
|
-
if (!where || !
|
|
5725
|
+
if (!where || !isRecord8(where)) {
|
|
4613
5726
|
return where;
|
|
4614
5727
|
}
|
|
4615
5728
|
const normalized = {};
|
|
@@ -4623,7 +5736,7 @@ function normalizeFindManyAstWhere(where) {
|
|
|
4623
5736
|
);
|
|
4624
5737
|
continue;
|
|
4625
5738
|
}
|
|
4626
|
-
if (key === "not" &&
|
|
5739
|
+
if (key === "not" && isRecord8(value)) {
|
|
4627
5740
|
normalized.not = normalizeFindManyAstBooleanOperand(
|
|
4628
5741
|
value
|
|
4629
5742
|
);
|
|
@@ -4634,7 +5747,7 @@ function normalizeFindManyAstWhere(where) {
|
|
|
4634
5747
|
return normalized;
|
|
4635
5748
|
}
|
|
4636
5749
|
function predicateRequiresUuidQueryFallback(column, value) {
|
|
4637
|
-
if (!
|
|
5750
|
+
if (!isRecord8(value)) {
|
|
4638
5751
|
return shouldUseUuidTextComparison(column, value);
|
|
4639
5752
|
}
|
|
4640
5753
|
const eqValue = value.eq;
|
|
@@ -4652,7 +5765,7 @@ function booleanOperandRequiresUuidQueryFallback(clause) {
|
|
|
4652
5765
|
return false;
|
|
4653
5766
|
}
|
|
4654
5767
|
function findManyAstWhereRequiresLegacyTransport(where) {
|
|
4655
|
-
if (!where || !
|
|
5768
|
+
if (!where || !isRecord8(where)) {
|
|
4656
5769
|
return false;
|
|
4657
5770
|
}
|
|
4658
5771
|
for (const [key, value] of Object.entries(where)) {
|
|
@@ -4667,7 +5780,7 @@ function findManyAstWhereRequiresLegacyTransport(where) {
|
|
|
4667
5780
|
}
|
|
4668
5781
|
continue;
|
|
4669
5782
|
}
|
|
4670
|
-
if (key === "not" &&
|
|
5783
|
+
if (key === "not" && isRecord8(value)) {
|
|
4671
5784
|
if (booleanOperandRequiresUuidQueryFallback(value)) {
|
|
4672
5785
|
return true;
|
|
4673
5786
|
}
|
|
@@ -4779,20 +5892,437 @@ function createSelectTransportPlan(input) {
|
|
|
4779
5892
|
};
|
|
4780
5893
|
}
|
|
4781
5894
|
|
|
5895
|
+
// src/query-debug-ast.ts
|
|
5896
|
+
var ATHENA_DEBUG_AST_KEY = "__athenaDebugAst";
|
|
5897
|
+
function cloneConditions(conditions) {
|
|
5898
|
+
return conditions.map((condition) => ({ ...condition }));
|
|
5899
|
+
}
|
|
5900
|
+
function cloneTableBuilderStateAst(state) {
|
|
5901
|
+
return {
|
|
5902
|
+
conditions: cloneConditions(state.conditions),
|
|
5903
|
+
limit: state.limit,
|
|
5904
|
+
offset: state.offset,
|
|
5905
|
+
order: state.order ? { ...state.order } : void 0,
|
|
5906
|
+
currentPage: state.currentPage,
|
|
5907
|
+
pageSize: state.pageSize,
|
|
5908
|
+
totalPages: state.totalPages
|
|
5909
|
+
};
|
|
5910
|
+
}
|
|
5911
|
+
function cloneRpcBuilderStateAst(state) {
|
|
5912
|
+
return {
|
|
5913
|
+
filters: state.filters.map((filter) => ({ ...filter })),
|
|
5914
|
+
limit: state.limit,
|
|
5915
|
+
offset: state.offset,
|
|
5916
|
+
order: state.order ? { ...state.order } : void 0
|
|
5917
|
+
};
|
|
5918
|
+
}
|
|
5919
|
+
function toSelectTransportAst(plan) {
|
|
5920
|
+
if (plan.kind === "query") {
|
|
5921
|
+
return {
|
|
5922
|
+
mode: "typed-query",
|
|
5923
|
+
endpoint: "/gateway/query",
|
|
5924
|
+
payload: plan.payload
|
|
5925
|
+
};
|
|
5926
|
+
}
|
|
5927
|
+
return {
|
|
5928
|
+
mode: plan.payload.select !== void 0 ? "structured-fetch" : "compiled-fetch",
|
|
5929
|
+
endpoint: "/gateway/fetch",
|
|
5930
|
+
payload: plan.payload
|
|
5931
|
+
};
|
|
5932
|
+
}
|
|
5933
|
+
function resolveDebugTableName(tableName) {
|
|
5934
|
+
return tableName ?? "__unknown_table__";
|
|
5935
|
+
}
|
|
5936
|
+
function buildSelectDebugAst(input) {
|
|
5937
|
+
return {
|
|
5938
|
+
version: 1,
|
|
5939
|
+
kind: "select",
|
|
5940
|
+
tableName: input.tableName,
|
|
5941
|
+
input: {
|
|
5942
|
+
columns: input.columns,
|
|
5943
|
+
state: cloneTableBuilderStateAst(input.state)
|
|
5944
|
+
},
|
|
5945
|
+
transport: toSelectTransportAst(input.plan)
|
|
5946
|
+
};
|
|
5947
|
+
}
|
|
5948
|
+
function buildFindManyCompiledDebugAst(input) {
|
|
5949
|
+
return {
|
|
5950
|
+
version: 1,
|
|
5951
|
+
kind: "findMany",
|
|
5952
|
+
tableName: input.tableName,
|
|
5953
|
+
input: {
|
|
5954
|
+
select: input.options.select,
|
|
5955
|
+
where: input.options.where,
|
|
5956
|
+
orderBy: input.options.orderBy,
|
|
5957
|
+
limit: input.options.limit
|
|
5958
|
+
},
|
|
5959
|
+
compiled: {
|
|
5960
|
+
columns: input.compiledColumns,
|
|
5961
|
+
baseState: cloneTableBuilderStateAst(input.baseState),
|
|
5962
|
+
executionState: cloneTableBuilderStateAst(input.executionState)
|
|
5963
|
+
},
|
|
5964
|
+
transport: planToFindManyTransport(input.plan)
|
|
5965
|
+
};
|
|
5966
|
+
}
|
|
5967
|
+
function buildFindManyDirectDebugAst(input) {
|
|
5968
|
+
return {
|
|
5969
|
+
version: 1,
|
|
5970
|
+
kind: "findMany",
|
|
5971
|
+
tableName: input.tableName,
|
|
5972
|
+
input: {
|
|
5973
|
+
select: input.options.select,
|
|
5974
|
+
where: input.options.where,
|
|
5975
|
+
orderBy: input.options.orderBy,
|
|
5976
|
+
limit: input.options.limit
|
|
5977
|
+
},
|
|
5978
|
+
compiled: {
|
|
5979
|
+
columns: input.compiledColumns,
|
|
5980
|
+
baseState: cloneTableBuilderStateAst(input.baseState),
|
|
5981
|
+
executionState: cloneTableBuilderStateAst(input.executionState)
|
|
5982
|
+
},
|
|
5983
|
+
transport: {
|
|
5984
|
+
mode: "direct-ast-fetch",
|
|
5985
|
+
endpoint: "/gateway/fetch",
|
|
5986
|
+
payload: input.payload
|
|
5987
|
+
}
|
|
5988
|
+
};
|
|
5989
|
+
}
|
|
5990
|
+
function planToFindManyTransport(plan) {
|
|
5991
|
+
if (plan.kind === "query") {
|
|
5992
|
+
return {
|
|
5993
|
+
mode: "compiled-query",
|
|
5994
|
+
endpoint: "/gateway/query",
|
|
5995
|
+
payload: plan.payload
|
|
5996
|
+
};
|
|
5997
|
+
}
|
|
5998
|
+
return {
|
|
5999
|
+
mode: plan.payload.select !== void 0 ? "structured-fetch" : "compiled-fetch",
|
|
6000
|
+
endpoint: "/gateway/fetch",
|
|
6001
|
+
payload: plan.payload
|
|
6002
|
+
};
|
|
6003
|
+
}
|
|
6004
|
+
function buildInsertDebugAst(payload) {
|
|
6005
|
+
return {
|
|
6006
|
+
version: 1,
|
|
6007
|
+
kind: "insert",
|
|
6008
|
+
tableName: payload.table_name,
|
|
6009
|
+
input: {
|
|
6010
|
+
values: payload.insert_body,
|
|
6011
|
+
returning: payload.columns,
|
|
6012
|
+
count: payload.count,
|
|
6013
|
+
head: payload.head,
|
|
6014
|
+
defaultToNull: payload.default_to_null
|
|
6015
|
+
},
|
|
6016
|
+
transport: {
|
|
6017
|
+
mode: "insert",
|
|
6018
|
+
endpoint: "/gateway/insert",
|
|
6019
|
+
payload
|
|
6020
|
+
}
|
|
6021
|
+
};
|
|
6022
|
+
}
|
|
6023
|
+
function buildUpsertDebugAst(payload) {
|
|
6024
|
+
return {
|
|
6025
|
+
version: 1,
|
|
6026
|
+
kind: "upsert",
|
|
6027
|
+
tableName: payload.table_name,
|
|
6028
|
+
input: {
|
|
6029
|
+
values: payload.insert_body,
|
|
6030
|
+
updateBody: payload.update_body,
|
|
6031
|
+
onConflict: payload.on_conflict,
|
|
6032
|
+
returning: payload.columns,
|
|
6033
|
+
count: payload.count,
|
|
6034
|
+
head: payload.head,
|
|
6035
|
+
defaultToNull: payload.default_to_null
|
|
6036
|
+
},
|
|
6037
|
+
transport: {
|
|
6038
|
+
mode: "upsert",
|
|
6039
|
+
endpoint: "/gateway/insert",
|
|
6040
|
+
payload
|
|
6041
|
+
}
|
|
6042
|
+
};
|
|
6043
|
+
}
|
|
6044
|
+
function buildUpdateDebugAst(input) {
|
|
6045
|
+
return {
|
|
6046
|
+
version: 1,
|
|
6047
|
+
kind: "update",
|
|
6048
|
+
tableName: resolveDebugTableName(input.payload.table_name),
|
|
6049
|
+
input: {
|
|
6050
|
+
values: input.payload.set,
|
|
6051
|
+
state: cloneTableBuilderStateAst(input.state),
|
|
6052
|
+
returning: input.payload.columns
|
|
6053
|
+
},
|
|
6054
|
+
transport: {
|
|
6055
|
+
mode: "update",
|
|
6056
|
+
endpoint: "/gateway/update",
|
|
6057
|
+
payload: input.payload
|
|
6058
|
+
}
|
|
6059
|
+
};
|
|
6060
|
+
}
|
|
6061
|
+
function buildDeleteDebugAst(input) {
|
|
6062
|
+
return {
|
|
6063
|
+
version: 1,
|
|
6064
|
+
kind: "delete",
|
|
6065
|
+
tableName: input.payload.table_name,
|
|
6066
|
+
input: {
|
|
6067
|
+
resourceId: input.payload.resource_id,
|
|
6068
|
+
state: cloneTableBuilderStateAst(input.state),
|
|
6069
|
+
returning: input.payload.columns
|
|
6070
|
+
},
|
|
6071
|
+
transport: {
|
|
6072
|
+
mode: "delete",
|
|
6073
|
+
endpoint: "/gateway/delete",
|
|
6074
|
+
payload: input.payload
|
|
6075
|
+
}
|
|
6076
|
+
};
|
|
6077
|
+
}
|
|
6078
|
+
function buildRpcDebugAst(input) {
|
|
6079
|
+
return {
|
|
6080
|
+
version: 1,
|
|
6081
|
+
kind: "rpc",
|
|
6082
|
+
functionName: input.functionName,
|
|
6083
|
+
input: {
|
|
6084
|
+
args: input.args,
|
|
6085
|
+
select: input.selectedColumns,
|
|
6086
|
+
state: cloneRpcBuilderStateAst(input.state)
|
|
6087
|
+
},
|
|
6088
|
+
transport: {
|
|
6089
|
+
mode: input.endpoint === "/gateway/rpc" ? "rpc-post" : "rpc-get",
|
|
6090
|
+
endpoint: input.endpoint,
|
|
6091
|
+
payload: input.payload
|
|
6092
|
+
}
|
|
6093
|
+
};
|
|
6094
|
+
}
|
|
6095
|
+
function buildRawQueryDebugAst(query) {
|
|
6096
|
+
return {
|
|
6097
|
+
version: 1,
|
|
6098
|
+
kind: "query",
|
|
6099
|
+
input: {
|
|
6100
|
+
query
|
|
6101
|
+
},
|
|
6102
|
+
transport: {
|
|
6103
|
+
mode: "raw-query",
|
|
6104
|
+
endpoint: "/gateway/query",
|
|
6105
|
+
payload: {
|
|
6106
|
+
query
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6109
|
+
};
|
|
6110
|
+
}
|
|
6111
|
+
function attachAthenaDebugAst(target, ast) {
|
|
6112
|
+
if (!ast) {
|
|
6113
|
+
return;
|
|
6114
|
+
}
|
|
6115
|
+
if (!target || typeof target !== "object" && typeof target !== "function") {
|
|
6116
|
+
return;
|
|
6117
|
+
}
|
|
6118
|
+
Object.defineProperty(target, ATHENA_DEBUG_AST_KEY, {
|
|
6119
|
+
value: ast,
|
|
6120
|
+
enumerable: false,
|
|
6121
|
+
configurable: true,
|
|
6122
|
+
writable: false
|
|
6123
|
+
});
|
|
6124
|
+
}
|
|
6125
|
+
|
|
6126
|
+
// src/query-tracing.ts
|
|
6127
|
+
var QUERY_TRACE_STACK_SKIP_PATTERNS = [
|
|
6128
|
+
"src\\client.ts",
|
|
6129
|
+
"src/client.ts",
|
|
6130
|
+
"src\\query-tracing.ts",
|
|
6131
|
+
"src/query-tracing.ts",
|
|
6132
|
+
"dist\\client.",
|
|
6133
|
+
"dist/client.",
|
|
6134
|
+
"dist\\query-tracing.",
|
|
6135
|
+
"dist/query-tracing.",
|
|
6136
|
+
"node_modules\\@xylex-group\\athena",
|
|
6137
|
+
"node_modules/@xylex-group/athena",
|
|
6138
|
+
"node:internal",
|
|
6139
|
+
"internal/process"
|
|
6140
|
+
];
|
|
6141
|
+
function parseQueryTraceCallsiteFrame(frame) {
|
|
6142
|
+
const trimmed = frame.trim();
|
|
6143
|
+
if (!trimmed) {
|
|
6144
|
+
return null;
|
|
6145
|
+
}
|
|
6146
|
+
let body = trimmed.replace(/^at\s+/, "");
|
|
6147
|
+
if (body.startsWith("async ")) {
|
|
6148
|
+
body = body.slice(6);
|
|
6149
|
+
}
|
|
6150
|
+
let functionName;
|
|
6151
|
+
let location = body;
|
|
6152
|
+
const wrappedMatch = body.match(/^(.*?)\s+\((.*)\)$/);
|
|
6153
|
+
if (wrappedMatch) {
|
|
6154
|
+
functionName = wrappedMatch[1].trim() || void 0;
|
|
6155
|
+
location = wrappedMatch[2].trim();
|
|
6156
|
+
}
|
|
6157
|
+
const locationMatch = location.match(/^(.*):(\d+):(\d+)$/);
|
|
6158
|
+
if (!locationMatch) {
|
|
6159
|
+
return null;
|
|
6160
|
+
}
|
|
6161
|
+
const filePath = locationMatch[1].replace(/^file:\/\//, "");
|
|
6162
|
+
const line = Number(locationMatch[2]);
|
|
6163
|
+
const column = Number(locationMatch[3]);
|
|
6164
|
+
if (!Number.isFinite(line) || !Number.isFinite(column)) {
|
|
6165
|
+
return null;
|
|
6166
|
+
}
|
|
6167
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
6168
|
+
const fileName = normalizedPath.split("/").at(-1) ?? filePath;
|
|
6169
|
+
return {
|
|
6170
|
+
filePath,
|
|
6171
|
+
fileName,
|
|
6172
|
+
line,
|
|
6173
|
+
column,
|
|
6174
|
+
frame: trimmed,
|
|
6175
|
+
functionName
|
|
6176
|
+
};
|
|
6177
|
+
}
|
|
6178
|
+
function captureQueryTraceCallsite() {
|
|
6179
|
+
const stack = new Error().stack;
|
|
6180
|
+
if (!stack) return null;
|
|
6181
|
+
const frames = stack.split("\n").slice(2).map((frame) => frame.trim()).filter(Boolean);
|
|
6182
|
+
for (const frame of frames) {
|
|
6183
|
+
if (QUERY_TRACE_STACK_SKIP_PATTERNS.some((pattern) => frame.includes(pattern))) {
|
|
6184
|
+
continue;
|
|
6185
|
+
}
|
|
6186
|
+
const callsite = parseQueryTraceCallsiteFrame(frame);
|
|
6187
|
+
if (callsite) return callsite;
|
|
6188
|
+
}
|
|
6189
|
+
const fallback = frames.find((frame) => !frame.includes("captureQueryTraceCallsite"));
|
|
6190
|
+
return fallback ? parseQueryTraceCallsiteFrame(fallback) : null;
|
|
6191
|
+
}
|
|
6192
|
+
function defaultQueryTraceLogger(event) {
|
|
6193
|
+
const target = event.table ?? event.functionName ?? "gateway";
|
|
6194
|
+
const outcomeState = event.outcome?.error ? "error" : "ok";
|
|
6195
|
+
const banner = `[athena-js][trace] ${event.operation.toUpperCase()} ${event.endpoint} ${target} ${event.durationMs}ms ${outcomeState}`;
|
|
6196
|
+
console.info(banner, event);
|
|
6197
|
+
}
|
|
6198
|
+
function captureTraceCallsite(tracer) {
|
|
6199
|
+
return tracer?.captureCallsite() ?? null;
|
|
6200
|
+
}
|
|
6201
|
+
function createTraceCallsiteStore(tracer, initialCallsite) {
|
|
6202
|
+
let storedCallsite = initialCallsite ?? void 0;
|
|
6203
|
+
return {
|
|
6204
|
+
resolve(callsite) {
|
|
6205
|
+
if (callsite) {
|
|
6206
|
+
storedCallsite = callsite;
|
|
6207
|
+
return callsite;
|
|
6208
|
+
}
|
|
6209
|
+
if (storedCallsite !== void 0) {
|
|
6210
|
+
return storedCallsite;
|
|
6211
|
+
}
|
|
6212
|
+
const capturedCallsite = captureTraceCallsite(tracer);
|
|
6213
|
+
if (capturedCallsite) {
|
|
6214
|
+
storedCallsite = capturedCallsite;
|
|
6215
|
+
}
|
|
6216
|
+
return capturedCallsite;
|
|
6217
|
+
}
|
|
6218
|
+
};
|
|
6219
|
+
}
|
|
6220
|
+
function createQueryTracer(experimental) {
|
|
6221
|
+
const traceOption = experimental?.traceQueries;
|
|
6222
|
+
if (!traceOption) {
|
|
6223
|
+
return void 0;
|
|
6224
|
+
}
|
|
6225
|
+
const logger = typeof traceOption === "object" && traceOption.logger ? traceOption.logger : defaultQueryTraceLogger;
|
|
6226
|
+
const emit = (event) => {
|
|
6227
|
+
try {
|
|
6228
|
+
logger(event);
|
|
6229
|
+
} catch (error) {
|
|
6230
|
+
console.warn("[athena-js][trace] logger failed", error);
|
|
6231
|
+
}
|
|
6232
|
+
};
|
|
6233
|
+
return {
|
|
6234
|
+
captureCallsite: captureQueryTraceCallsite,
|
|
6235
|
+
publishSuccess(context, result, durationMs, callsite) {
|
|
6236
|
+
emit({
|
|
6237
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6238
|
+
durationMs,
|
|
6239
|
+
operation: context.operation,
|
|
6240
|
+
endpoint: context.endpoint,
|
|
6241
|
+
table: context.table,
|
|
6242
|
+
functionName: context.functionName,
|
|
6243
|
+
sql: context.sql,
|
|
6244
|
+
payload: context.payload,
|
|
6245
|
+
ast: context.ast,
|
|
6246
|
+
options: context.options,
|
|
6247
|
+
callsite,
|
|
6248
|
+
outcome: {
|
|
6249
|
+
status: result.status,
|
|
6250
|
+
error: result.error,
|
|
6251
|
+
errorDetails: result.errorDetails ?? null,
|
|
6252
|
+
count: result.count ?? null,
|
|
6253
|
+
data: result.data,
|
|
6254
|
+
raw: result.raw
|
|
6255
|
+
}
|
|
6256
|
+
});
|
|
6257
|
+
},
|
|
6258
|
+
publishFailure(context, error, durationMs, callsite) {
|
|
6259
|
+
emit({
|
|
6260
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6261
|
+
durationMs,
|
|
6262
|
+
operation: context.operation,
|
|
6263
|
+
endpoint: context.endpoint,
|
|
6264
|
+
table: context.table,
|
|
6265
|
+
functionName: context.functionName,
|
|
6266
|
+
sql: context.sql,
|
|
6267
|
+
payload: context.payload,
|
|
6268
|
+
ast: context.ast,
|
|
6269
|
+
options: context.options,
|
|
6270
|
+
callsite,
|
|
6271
|
+
thrownError: error
|
|
6272
|
+
});
|
|
6273
|
+
}
|
|
6274
|
+
};
|
|
6275
|
+
}
|
|
6276
|
+
async function executeWithQueryTrace(tracer, context, runner, callsiteOverride) {
|
|
6277
|
+
const callsite = tracer ? callsiteOverride ?? tracer.captureCallsite() : null;
|
|
6278
|
+
const startedAt = tracer ? Date.now() : 0;
|
|
6279
|
+
try {
|
|
6280
|
+
const result = await runner();
|
|
6281
|
+
attachAthenaDebugAst(result, context.ast);
|
|
6282
|
+
if (tracer) {
|
|
6283
|
+
tracer.publishSuccess(context, result, Date.now() - startedAt, callsite);
|
|
6284
|
+
}
|
|
6285
|
+
return result;
|
|
6286
|
+
} catch (error) {
|
|
6287
|
+
attachAthenaDebugAst(error, context.ast);
|
|
6288
|
+
if (tracer) {
|
|
6289
|
+
tracer.publishFailure(context, error, Date.now() - startedAt, callsite);
|
|
6290
|
+
}
|
|
6291
|
+
throw error;
|
|
6292
|
+
}
|
|
6293
|
+
}
|
|
6294
|
+
|
|
6295
|
+
// src/schema/model-target.ts
|
|
6296
|
+
function normalizeOptionalName(value) {
|
|
6297
|
+
const normalized = value?.trim();
|
|
6298
|
+
return normalized ? normalized : void 0;
|
|
6299
|
+
}
|
|
6300
|
+
function isAthenaModelTarget(value) {
|
|
6301
|
+
if (!value || typeof value !== "object") {
|
|
6302
|
+
return false;
|
|
6303
|
+
}
|
|
6304
|
+
const candidate = value;
|
|
6305
|
+
return Boolean(candidate.meta && Array.isArray(candidate.meta.primaryKey));
|
|
6306
|
+
}
|
|
6307
|
+
function resolveAthenaModelTargetTableName(target, options = {}) {
|
|
6308
|
+
const explicitTableName = normalizeOptionalName(target.meta.tableName);
|
|
6309
|
+
if (explicitTableName) {
|
|
6310
|
+
return explicitTableName;
|
|
6311
|
+
}
|
|
6312
|
+
const schemaName = normalizeOptionalName(target.meta.schema ?? options.fallbackSchema);
|
|
6313
|
+
const modelName = normalizeOptionalName(target.meta.model ?? options.fallbackModel);
|
|
6314
|
+
if (!modelName) {
|
|
6315
|
+
throw new Error(
|
|
6316
|
+
"Athena model target is missing meta.model or meta.tableName. Provide one of those before calling from(model)."
|
|
6317
|
+
);
|
|
6318
|
+
}
|
|
6319
|
+
return schemaName ? `${schemaName}.${modelName}` : modelName;
|
|
6320
|
+
}
|
|
6321
|
+
|
|
4782
6322
|
// src/client.ts
|
|
4783
6323
|
var DEFAULT_COLUMNS = "*";
|
|
4784
6324
|
var SAFE_CAST_PATTERN = /^[a-z_][a-z0-9_]*(?:\[\])?$/i;
|
|
4785
6325
|
var ATHENA_NORMALIZED_ERROR_KEY = "__athenaNormalizedError";
|
|
4786
|
-
var QUERY_TRACE_STACK_SKIP_PATTERNS = [
|
|
4787
|
-
"src\\client.ts",
|
|
4788
|
-
"src/client.ts",
|
|
4789
|
-
"dist\\client.",
|
|
4790
|
-
"dist/client.",
|
|
4791
|
-
"node_modules\\@xylex-group\\athena",
|
|
4792
|
-
"node_modules/@xylex-group/athena",
|
|
4793
|
-
"node:internal",
|
|
4794
|
-
"internal/process"
|
|
4795
|
-
];
|
|
4796
6326
|
function formatResult(response) {
|
|
4797
6327
|
const result = {
|
|
4798
6328
|
data: response.data ?? null,
|
|
@@ -4869,7 +6399,7 @@ async function executeExperimentalRead(experimental, runner) {
|
|
|
4869
6399
|
throw error;
|
|
4870
6400
|
}
|
|
4871
6401
|
}
|
|
4872
|
-
function
|
|
6402
|
+
function isRecord9(value) {
|
|
4873
6403
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4874
6404
|
}
|
|
4875
6405
|
function firstNonEmptyString2(...values) {
|
|
@@ -4881,8 +6411,8 @@ function firstNonEmptyString2(...values) {
|
|
|
4881
6411
|
return void 0;
|
|
4882
6412
|
}
|
|
4883
6413
|
function resolveStructuredErrorPayload2(raw) {
|
|
4884
|
-
if (!
|
|
4885
|
-
return
|
|
6414
|
+
if (!isRecord9(raw)) return null;
|
|
6415
|
+
return isRecord9(raw.error) ? raw.error : raw;
|
|
4886
6416
|
}
|
|
4887
6417
|
function resolveStructuredErrorDetails(payload, message) {
|
|
4888
6418
|
if (!payload || !("details" in payload)) {
|
|
@@ -4898,7 +6428,7 @@ function resolveStructuredErrorDetails(payload, message) {
|
|
|
4898
6428
|
return details;
|
|
4899
6429
|
}
|
|
4900
6430
|
function createResultError(response, result, normalized) {
|
|
4901
|
-
const rawRecord =
|
|
6431
|
+
const rawRecord = isRecord9(response.raw) ? response.raw : null;
|
|
4902
6432
|
const payload = resolveStructuredErrorPayload2(response.raw);
|
|
4903
6433
|
const message = firstNonEmptyString2(
|
|
4904
6434
|
response.error,
|
|
@@ -4934,154 +6464,6 @@ function createResultError(response, result, normalized) {
|
|
|
4934
6464
|
raw: result.raw
|
|
4935
6465
|
};
|
|
4936
6466
|
}
|
|
4937
|
-
function parseQueryTraceCallsiteFrame(frame) {
|
|
4938
|
-
const trimmed = frame.trim();
|
|
4939
|
-
if (!trimmed) {
|
|
4940
|
-
return null;
|
|
4941
|
-
}
|
|
4942
|
-
let body = trimmed.replace(/^at\s+/, "");
|
|
4943
|
-
if (body.startsWith("async ")) {
|
|
4944
|
-
body = body.slice(6);
|
|
4945
|
-
}
|
|
4946
|
-
let functionName;
|
|
4947
|
-
let location = body;
|
|
4948
|
-
const wrappedMatch = body.match(/^(.*?)\s+\((.*)\)$/);
|
|
4949
|
-
if (wrappedMatch) {
|
|
4950
|
-
functionName = wrappedMatch[1].trim() || void 0;
|
|
4951
|
-
location = wrappedMatch[2].trim();
|
|
4952
|
-
}
|
|
4953
|
-
const locationMatch = location.match(/^(.*):(\d+):(\d+)$/);
|
|
4954
|
-
if (!locationMatch) {
|
|
4955
|
-
return null;
|
|
4956
|
-
}
|
|
4957
|
-
const filePath = locationMatch[1].replace(/^file:\/\//, "");
|
|
4958
|
-
const line = Number(locationMatch[2]);
|
|
4959
|
-
const column = Number(locationMatch[3]);
|
|
4960
|
-
if (!Number.isFinite(line) || !Number.isFinite(column)) {
|
|
4961
|
-
return null;
|
|
4962
|
-
}
|
|
4963
|
-
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
4964
|
-
const fileName = normalizedPath.split("/").at(-1) ?? filePath;
|
|
4965
|
-
return {
|
|
4966
|
-
filePath,
|
|
4967
|
-
fileName,
|
|
4968
|
-
line,
|
|
4969
|
-
column,
|
|
4970
|
-
frame: trimmed,
|
|
4971
|
-
functionName
|
|
4972
|
-
};
|
|
4973
|
-
}
|
|
4974
|
-
function captureQueryTraceCallsite() {
|
|
4975
|
-
const stack = new Error().stack;
|
|
4976
|
-
if (!stack) return null;
|
|
4977
|
-
const frames = stack.split("\n").slice(2).map((frame) => frame.trim()).filter(Boolean);
|
|
4978
|
-
for (const frame of frames) {
|
|
4979
|
-
if (QUERY_TRACE_STACK_SKIP_PATTERNS.some((pattern) => frame.includes(pattern))) {
|
|
4980
|
-
continue;
|
|
4981
|
-
}
|
|
4982
|
-
const callsite = parseQueryTraceCallsiteFrame(frame);
|
|
4983
|
-
if (callsite) return callsite;
|
|
4984
|
-
}
|
|
4985
|
-
const fallback = frames.find((frame) => !frame.includes("captureQueryTraceCallsite"));
|
|
4986
|
-
return fallback ? parseQueryTraceCallsiteFrame(fallback) : null;
|
|
4987
|
-
}
|
|
4988
|
-
function defaultQueryTraceLogger(event) {
|
|
4989
|
-
const target = event.table ?? event.functionName ?? "gateway";
|
|
4990
|
-
const outcomeState = event.outcome?.error ? "error" : "ok";
|
|
4991
|
-
const banner = `[athena-js][trace] ${event.operation.toUpperCase()} ${event.endpoint} ${target} ${event.durationMs}ms ${outcomeState}`;
|
|
4992
|
-
console.info(banner, event);
|
|
4993
|
-
}
|
|
4994
|
-
function captureTraceCallsite(tracer) {
|
|
4995
|
-
return tracer?.captureCallsite() ?? null;
|
|
4996
|
-
}
|
|
4997
|
-
function createTraceCallsiteStore(tracer, initialCallsite) {
|
|
4998
|
-
let storedCallsite = initialCallsite ?? void 0;
|
|
4999
|
-
return {
|
|
5000
|
-
resolve(callsite) {
|
|
5001
|
-
if (callsite) {
|
|
5002
|
-
storedCallsite = callsite;
|
|
5003
|
-
return callsite;
|
|
5004
|
-
}
|
|
5005
|
-
if (storedCallsite !== void 0) {
|
|
5006
|
-
return storedCallsite;
|
|
5007
|
-
}
|
|
5008
|
-
const capturedCallsite = captureTraceCallsite(tracer);
|
|
5009
|
-
if (capturedCallsite) {
|
|
5010
|
-
storedCallsite = capturedCallsite;
|
|
5011
|
-
}
|
|
5012
|
-
return capturedCallsite;
|
|
5013
|
-
}
|
|
5014
|
-
};
|
|
5015
|
-
}
|
|
5016
|
-
function createQueryTracer(experimental) {
|
|
5017
|
-
const traceOption = experimental?.traceQueries;
|
|
5018
|
-
if (!traceOption) {
|
|
5019
|
-
return void 0;
|
|
5020
|
-
}
|
|
5021
|
-
const logger = typeof traceOption === "object" && traceOption.logger ? traceOption.logger : defaultQueryTraceLogger;
|
|
5022
|
-
const emit = (event) => {
|
|
5023
|
-
try {
|
|
5024
|
-
logger(event);
|
|
5025
|
-
} catch (error) {
|
|
5026
|
-
console.warn("[athena-js][trace] logger failed", error);
|
|
5027
|
-
}
|
|
5028
|
-
};
|
|
5029
|
-
return {
|
|
5030
|
-
captureCallsite: captureQueryTraceCallsite,
|
|
5031
|
-
publishSuccess(context, result, durationMs, callsite) {
|
|
5032
|
-
emit({
|
|
5033
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5034
|
-
durationMs,
|
|
5035
|
-
operation: context.operation,
|
|
5036
|
-
endpoint: context.endpoint,
|
|
5037
|
-
table: context.table,
|
|
5038
|
-
functionName: context.functionName,
|
|
5039
|
-
sql: context.sql,
|
|
5040
|
-
payload: context.payload,
|
|
5041
|
-
options: context.options,
|
|
5042
|
-
callsite,
|
|
5043
|
-
outcome: {
|
|
5044
|
-
status: result.status,
|
|
5045
|
-
error: result.error,
|
|
5046
|
-
errorDetails: result.errorDetails ?? null,
|
|
5047
|
-
count: result.count ?? null,
|
|
5048
|
-
data: result.data,
|
|
5049
|
-
raw: result.raw
|
|
5050
|
-
}
|
|
5051
|
-
});
|
|
5052
|
-
},
|
|
5053
|
-
publishFailure(context, error, durationMs, callsite) {
|
|
5054
|
-
emit({
|
|
5055
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5056
|
-
durationMs,
|
|
5057
|
-
operation: context.operation,
|
|
5058
|
-
endpoint: context.endpoint,
|
|
5059
|
-
table: context.table,
|
|
5060
|
-
functionName: context.functionName,
|
|
5061
|
-
sql: context.sql,
|
|
5062
|
-
payload: context.payload,
|
|
5063
|
-
options: context.options,
|
|
5064
|
-
callsite,
|
|
5065
|
-
thrownError: error
|
|
5066
|
-
});
|
|
5067
|
-
}
|
|
5068
|
-
};
|
|
5069
|
-
}
|
|
5070
|
-
async function executeWithQueryTrace(tracer, context, runner, callsiteOverride) {
|
|
5071
|
-
if (!tracer) {
|
|
5072
|
-
return runner();
|
|
5073
|
-
}
|
|
5074
|
-
const callsite = callsiteOverride ?? tracer.captureCallsite();
|
|
5075
|
-
const startedAt = Date.now();
|
|
5076
|
-
try {
|
|
5077
|
-
const result = await runner();
|
|
5078
|
-
tracer.publishSuccess(context, result, Date.now() - startedAt, callsite);
|
|
5079
|
-
return result;
|
|
5080
|
-
} catch (error) {
|
|
5081
|
-
tracer.publishFailure(context, error, Date.now() - startedAt, callsite);
|
|
5082
|
-
throw error;
|
|
5083
|
-
}
|
|
5084
|
-
}
|
|
5085
6467
|
function toSingleResult(response) {
|
|
5086
6468
|
const payload = response.data;
|
|
5087
6469
|
const singleData = Array.isArray(payload) ? payload.length ? payload[0] : null : payload ?? null;
|
|
@@ -5109,6 +6491,15 @@ function asAthenaJsonObject(value) {
|
|
|
5109
6491
|
function asAthenaJsonObjectArray(values) {
|
|
5110
6492
|
return values;
|
|
5111
6493
|
}
|
|
6494
|
+
function normalizeSelectColumnsInput(columns) {
|
|
6495
|
+
if (columns === void 0) {
|
|
6496
|
+
return void 0;
|
|
6497
|
+
}
|
|
6498
|
+
if (typeof columns === "string") {
|
|
6499
|
+
return columns;
|
|
6500
|
+
}
|
|
6501
|
+
return [...columns];
|
|
6502
|
+
}
|
|
5112
6503
|
function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS, tracer, initialCallsite) {
|
|
5113
6504
|
let selectedColumns = defaultColumns === null ? void 0 : defaultColumns;
|
|
5114
6505
|
let selectedOptions;
|
|
@@ -5118,25 +6509,29 @@ function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS, tracer,
|
|
|
5118
6509
|
const payloadColumns = columns ?? selectedColumns;
|
|
5119
6510
|
const payloadOptions = options ?? selectedOptions;
|
|
5120
6511
|
if (!promise) {
|
|
5121
|
-
promise = executor(
|
|
6512
|
+
promise = executor(
|
|
6513
|
+
normalizeSelectColumnsInput(payloadColumns),
|
|
6514
|
+
payloadOptions,
|
|
6515
|
+
callsiteStore.resolve(callsite)
|
|
6516
|
+
);
|
|
5122
6517
|
}
|
|
5123
6518
|
return promise;
|
|
5124
6519
|
};
|
|
5125
6520
|
const mutationQuery = {
|
|
5126
|
-
select(columns
|
|
6521
|
+
select(columns, options) {
|
|
5127
6522
|
selectedColumns = columns;
|
|
5128
6523
|
selectedOptions = options ?? selectedOptions;
|
|
5129
6524
|
return run(columns, options, captureTraceCallsite(tracer));
|
|
5130
6525
|
},
|
|
5131
|
-
returning(columns
|
|
6526
|
+
returning(columns, options) {
|
|
5132
6527
|
return mutationQuery.select(columns, options);
|
|
5133
6528
|
},
|
|
5134
|
-
single(columns
|
|
6529
|
+
single(columns, options) {
|
|
5135
6530
|
selectedColumns = columns;
|
|
5136
6531
|
selectedOptions = options ?? selectedOptions;
|
|
5137
6532
|
return run(columns, options, captureTraceCallsite(tracer)).then(toSingleResult);
|
|
5138
6533
|
},
|
|
5139
|
-
maybeSingle(columns
|
|
6534
|
+
maybeSingle(columns, options) {
|
|
5140
6535
|
return mutationQuery.single(columns, options);
|
|
5141
6536
|
},
|
|
5142
6537
|
then(onfulfilled, onrejected) {
|
|
@@ -5693,7 +7088,10 @@ function createFilterMethods(state, addCondition, self) {
|
|
|
5693
7088
|
}
|
|
5694
7089
|
function toRpcSelect(columns) {
|
|
5695
7090
|
if (!columns) return void 0;
|
|
5696
|
-
|
|
7091
|
+
if (typeof columns === "string") {
|
|
7092
|
+
return columns;
|
|
7093
|
+
}
|
|
7094
|
+
return columns.join(",");
|
|
5697
7095
|
}
|
|
5698
7096
|
function createRpcFilterMethods(filters, self) {
|
|
5699
7097
|
const addFilter = (operator, column, value) => {
|
|
@@ -5742,7 +7140,7 @@ function createRpcFilterMethods(filters, self) {
|
|
|
5742
7140
|
}
|
|
5743
7141
|
};
|
|
5744
7142
|
}
|
|
5745
|
-
function createRpcBuilder(functionName, args, baseOptions, client, formatGatewayResult, tracer, initialCallsite) {
|
|
7143
|
+
function createRpcBuilder(functionName, args, baseOptions, client, formatGatewayResult, tracer, initialCallsite, debugAstEnabled = false) {
|
|
5746
7144
|
const state = {
|
|
5747
7145
|
filters: []
|
|
5748
7146
|
};
|
|
@@ -5752,6 +7150,7 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
|
|
|
5752
7150
|
const callsiteStore = createTraceCallsiteStore(tracer, initialCallsite);
|
|
5753
7151
|
const executeRpc = async (columns, options, callsite) => {
|
|
5754
7152
|
const mergedOptions = mergeOptions(baseOptions, options);
|
|
7153
|
+
const normalizedSelectedColumns = normalizeSelectColumnsInput(columns);
|
|
5755
7154
|
const payload = {
|
|
5756
7155
|
function: functionName,
|
|
5757
7156
|
args,
|
|
@@ -5766,6 +7165,14 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
|
|
|
5766
7165
|
};
|
|
5767
7166
|
const endpoint = mergedOptions?.get ? `/rpc/${functionName}` : "/gateway/rpc";
|
|
5768
7167
|
const sql = buildRpcDebugSql(payload);
|
|
7168
|
+
const debugAst = debugAstEnabled ? buildRpcDebugAst({
|
|
7169
|
+
functionName,
|
|
7170
|
+
args,
|
|
7171
|
+
selectedColumns: normalizedSelectedColumns,
|
|
7172
|
+
state,
|
|
7173
|
+
payload,
|
|
7174
|
+
endpoint
|
|
7175
|
+
}) : void 0;
|
|
5769
7176
|
return executeWithQueryTrace(
|
|
5770
7177
|
tracer,
|
|
5771
7178
|
{
|
|
@@ -5774,6 +7181,7 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
|
|
|
5774
7181
|
functionName,
|
|
5775
7182
|
sql,
|
|
5776
7183
|
payload,
|
|
7184
|
+
ast: debugAst,
|
|
5777
7185
|
options: mergedOptions
|
|
5778
7186
|
},
|
|
5779
7187
|
async () => {
|
|
@@ -5794,7 +7202,7 @@ function createRpcBuilder(functionName, args, baseOptions, client, formatGateway
|
|
|
5794
7202
|
const builder = {};
|
|
5795
7203
|
const filterMethods = createRpcFilterMethods(state.filters, builder);
|
|
5796
7204
|
Object.assign(builder, filterMethods, {
|
|
5797
|
-
select(columns
|
|
7205
|
+
select(columns, options) {
|
|
5798
7206
|
selectedColumns = columns;
|
|
5799
7207
|
selectedOptions = options ?? selectedOptions;
|
|
5800
7208
|
return run(columns, options, captureTraceCallsite(tracer));
|
|
@@ -5839,6 +7247,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
5839
7247
|
const state = {
|
|
5840
7248
|
conditions: []
|
|
5841
7249
|
};
|
|
7250
|
+
const debugAstEnabled = Boolean(experimental?.debugAst);
|
|
5842
7251
|
const addCondition = (operator, column, value, hints) => {
|
|
5843
7252
|
const condition = { operator };
|
|
5844
7253
|
if (column) {
|
|
@@ -5882,15 +7291,27 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
5882
7291
|
addCondition,
|
|
5883
7292
|
builder
|
|
5884
7293
|
);
|
|
5885
|
-
const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite) => {
|
|
7294
|
+
const runSelect = async (columns = DEFAULT_COLUMNS, options, executionState = snapshotState(), callsite, debugAstFactory) => {
|
|
7295
|
+
const runtimeColumns = normalizeSelectColumnsInput(columns) ?? DEFAULT_COLUMNS;
|
|
5886
7296
|
const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
|
|
5887
7297
|
const plan = createSelectTransportPlan({
|
|
5888
7298
|
tableName: resolvedTableName,
|
|
5889
|
-
columns,
|
|
7299
|
+
columns: runtimeColumns,
|
|
5890
7300
|
state: executionState,
|
|
5891
7301
|
options,
|
|
5892
7302
|
buildTypedSelectQuery
|
|
5893
7303
|
});
|
|
7304
|
+
const debugAst = debugAstEnabled ? debugAstFactory?.({
|
|
7305
|
+
tableName: resolvedTableName,
|
|
7306
|
+
columns: runtimeColumns,
|
|
7307
|
+
executionState,
|
|
7308
|
+
plan
|
|
7309
|
+
}) ?? buildSelectDebugAst({
|
|
7310
|
+
tableName: resolvedTableName,
|
|
7311
|
+
columns: runtimeColumns,
|
|
7312
|
+
state: executionState,
|
|
7313
|
+
plan
|
|
7314
|
+
}) : void 0;
|
|
5894
7315
|
if (plan.kind === "query") {
|
|
5895
7316
|
return executeExperimentalRead(
|
|
5896
7317
|
experimental,
|
|
@@ -5902,6 +7323,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
5902
7323
|
table: resolvedTableName,
|
|
5903
7324
|
sql: plan.query,
|
|
5904
7325
|
payload: plan.payload,
|
|
7326
|
+
ast: debugAst,
|
|
5905
7327
|
options
|
|
5906
7328
|
},
|
|
5907
7329
|
async () => {
|
|
@@ -5926,6 +7348,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
5926
7348
|
table: resolvedTableName,
|
|
5927
7349
|
sql,
|
|
5928
7350
|
payload: plan.payload,
|
|
7351
|
+
ast: debugAst,
|
|
5929
7352
|
options
|
|
5930
7353
|
},
|
|
5931
7354
|
async () => {
|
|
@@ -5939,7 +7362,11 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
5939
7362
|
const createSelectChain = (columns, options, initialCallsite) => {
|
|
5940
7363
|
const chain = {};
|
|
5941
7364
|
const callsiteStore = createTraceCallsiteStore(tracer, initialCallsite);
|
|
5942
|
-
const filterMethods2 = createFilterMethods(
|
|
7365
|
+
const filterMethods2 = createFilterMethods(
|
|
7366
|
+
state,
|
|
7367
|
+
addCondition,
|
|
7368
|
+
chain
|
|
7369
|
+
);
|
|
5943
7370
|
Object.assign(chain, filterMethods2, {
|
|
5944
7371
|
async single(cols, opts) {
|
|
5945
7372
|
const r = await runSelect(
|
|
@@ -6026,6 +7453,14 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6026
7453
|
limit: executionState.limit,
|
|
6027
7454
|
order: executionState.order
|
|
6028
7455
|
});
|
|
7456
|
+
const debugAst = debugAstEnabled ? buildFindManyDirectDebugAst({
|
|
7457
|
+
tableName: resolvedTableName,
|
|
7458
|
+
options,
|
|
7459
|
+
compiledColumns: columns,
|
|
7460
|
+
baseState,
|
|
7461
|
+
executionState,
|
|
7462
|
+
payload
|
|
7463
|
+
}) : void 0;
|
|
6029
7464
|
return executeExperimentalRead(
|
|
6030
7465
|
experimental,
|
|
6031
7466
|
() => executeWithQueryTrace(
|
|
@@ -6035,7 +7470,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6035
7470
|
endpoint: "/gateway/fetch",
|
|
6036
7471
|
table: resolvedTableName,
|
|
6037
7472
|
sql,
|
|
6038
|
-
payload
|
|
7473
|
+
payload,
|
|
7474
|
+
ast: debugAst
|
|
6039
7475
|
},
|
|
6040
7476
|
async () => {
|
|
6041
7477
|
const response = await client.fetchGateway(
|
|
@@ -6051,7 +7487,15 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6051
7487
|
columns,
|
|
6052
7488
|
void 0,
|
|
6053
7489
|
executionState,
|
|
6054
|
-
callsite
|
|
7490
|
+
callsite,
|
|
7491
|
+
debugAstEnabled ? ({ tableName: resolvedTableName, executionState: tracedState, plan }) => buildFindManyCompiledDebugAst({
|
|
7492
|
+
tableName: resolvedTableName,
|
|
7493
|
+
options,
|
|
7494
|
+
compiledColumns: columns,
|
|
7495
|
+
baseState,
|
|
7496
|
+
executionState: tracedState,
|
|
7497
|
+
plan
|
|
7498
|
+
}) : void 0
|
|
6055
7499
|
);
|
|
6056
7500
|
},
|
|
6057
7501
|
insert(values, options) {
|
|
@@ -6071,6 +7515,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6071
7515
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
6072
7516
|
}
|
|
6073
7517
|
const sql = buildInsertDebugSql(payload);
|
|
7518
|
+
const debugAst = debugAstEnabled ? buildInsertDebugAst(payload) : void 0;
|
|
6074
7519
|
return executeWithQueryTrace(
|
|
6075
7520
|
tracer,
|
|
6076
7521
|
{
|
|
@@ -6079,6 +7524,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6079
7524
|
table: resolvedTableName,
|
|
6080
7525
|
sql,
|
|
6081
7526
|
payload,
|
|
7527
|
+
ast: debugAst,
|
|
6082
7528
|
options: mergedOptions
|
|
6083
7529
|
},
|
|
6084
7530
|
async () => {
|
|
@@ -6104,6 +7550,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6104
7550
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
6105
7551
|
}
|
|
6106
7552
|
const sql = buildInsertDebugSql(payload);
|
|
7553
|
+
const debugAst = debugAstEnabled ? buildInsertDebugAst(payload) : void 0;
|
|
6107
7554
|
return executeWithQueryTrace(
|
|
6108
7555
|
tracer,
|
|
6109
7556
|
{
|
|
@@ -6112,6 +7559,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6112
7559
|
table: resolvedTableName,
|
|
6113
7560
|
sql,
|
|
6114
7561
|
payload,
|
|
7562
|
+
ast: debugAst,
|
|
6115
7563
|
options: mergedOptions
|
|
6116
7564
|
},
|
|
6117
7565
|
async () => {
|
|
@@ -6142,6 +7590,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6142
7590
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
6143
7591
|
}
|
|
6144
7592
|
const sql = buildInsertDebugSql(payload);
|
|
7593
|
+
const debugAst = debugAstEnabled ? buildUpsertDebugAst(payload) : void 0;
|
|
6145
7594
|
return executeWithQueryTrace(
|
|
6146
7595
|
tracer,
|
|
6147
7596
|
{
|
|
@@ -6150,6 +7599,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6150
7599
|
table: resolvedTableName,
|
|
6151
7600
|
sql,
|
|
6152
7601
|
payload,
|
|
7602
|
+
ast: debugAst,
|
|
6153
7603
|
options: mergedOptions
|
|
6154
7604
|
},
|
|
6155
7605
|
async () => {
|
|
@@ -6177,6 +7627,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6177
7627
|
payload.default_to_null = mergedOptions.defaultToNull;
|
|
6178
7628
|
}
|
|
6179
7629
|
const sql = buildInsertDebugSql(payload);
|
|
7630
|
+
const debugAst = debugAstEnabled ? buildUpsertDebugAst(payload) : void 0;
|
|
6180
7631
|
return executeWithQueryTrace(
|
|
6181
7632
|
tracer,
|
|
6182
7633
|
{
|
|
@@ -6185,6 +7636,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6185
7636
|
table: resolvedTableName,
|
|
6186
7637
|
sql,
|
|
6187
7638
|
payload,
|
|
7639
|
+
ast: debugAst,
|
|
6188
7640
|
options: mergedOptions
|
|
6189
7641
|
},
|
|
6190
7642
|
async () => {
|
|
@@ -6199,7 +7651,8 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6199
7651
|
update(values, options) {
|
|
6200
7652
|
const mutationCallsite = captureTraceCallsite(tracer);
|
|
6201
7653
|
const executeUpdate = async (columns, selectOptions, callsite) => {
|
|
6202
|
-
const
|
|
7654
|
+
const executionState = snapshotState();
|
|
7655
|
+
const filters = executionState.conditions.length ? [...executionState.conditions] : void 0;
|
|
6203
7656
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
6204
7657
|
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
6205
7658
|
const payload = {
|
|
@@ -6208,12 +7661,16 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6208
7661
|
conditions: filters,
|
|
6209
7662
|
strip_nulls: mergedOptions?.stripNulls ?? true
|
|
6210
7663
|
};
|
|
6211
|
-
if (
|
|
6212
|
-
if (
|
|
6213
|
-
if (
|
|
6214
|
-
if (
|
|
7664
|
+
if (executionState.order) payload.sort_by = executionState.order;
|
|
7665
|
+
if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
|
|
7666
|
+
if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
|
|
7667
|
+
if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
|
|
6215
7668
|
if (columns) payload.columns = columns;
|
|
6216
7669
|
const sql = buildUpdateDebugSql(payload);
|
|
7670
|
+
const debugAst = debugAstEnabled ? buildUpdateDebugAst({
|
|
7671
|
+
state: executionState,
|
|
7672
|
+
payload
|
|
7673
|
+
}) : void 0;
|
|
6217
7674
|
return executeWithQueryTrace(
|
|
6218
7675
|
tracer,
|
|
6219
7676
|
{
|
|
@@ -6222,6 +7679,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6222
7679
|
table: resolvedTableName,
|
|
6223
7680
|
sql,
|
|
6224
7681
|
payload,
|
|
7682
|
+
ast: debugAst,
|
|
6225
7683
|
options: mergedOptions
|
|
6226
7684
|
},
|
|
6227
7685
|
async () => {
|
|
@@ -6245,6 +7703,11 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6245
7703
|
}
|
|
6246
7704
|
const mutationCallsite = captureTraceCallsite(tracer);
|
|
6247
7705
|
const executeDelete = async (columns, selectOptions, callsite) => {
|
|
7706
|
+
const executionState = snapshotState();
|
|
7707
|
+
const debugState = {
|
|
7708
|
+
...executionState,
|
|
7709
|
+
conditions: filters ? filters.map((condition) => ({ ...condition })) : []
|
|
7710
|
+
};
|
|
6248
7711
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
6249
7712
|
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
6250
7713
|
const payload = {
|
|
@@ -6252,12 +7715,16 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6252
7715
|
resource_id: resourceId,
|
|
6253
7716
|
conditions: filters
|
|
6254
7717
|
};
|
|
6255
|
-
if (
|
|
6256
|
-
if (
|
|
6257
|
-
if (
|
|
6258
|
-
if (
|
|
7718
|
+
if (executionState.order) payload.sort_by = executionState.order;
|
|
7719
|
+
if (executionState.currentPage !== void 0) payload.current_page = executionState.currentPage;
|
|
7720
|
+
if (executionState.pageSize !== void 0) payload.page_size = executionState.pageSize;
|
|
7721
|
+
if (executionState.totalPages !== void 0) payload.total_pages = executionState.totalPages;
|
|
6259
7722
|
if (columns) payload.columns = columns;
|
|
6260
7723
|
const sql = buildDeleteDebugSql(payload);
|
|
7724
|
+
const debugAst = debugAstEnabled ? buildDeleteDebugAst({
|
|
7725
|
+
state: debugState,
|
|
7726
|
+
payload
|
|
7727
|
+
}) : void 0;
|
|
6261
7728
|
return executeWithQueryTrace(
|
|
6262
7729
|
tracer,
|
|
6263
7730
|
{
|
|
@@ -6266,6 +7733,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6266
7733
|
table: resolvedTableName,
|
|
6267
7734
|
sql,
|
|
6268
7735
|
payload,
|
|
7736
|
+
ast: debugAst,
|
|
6269
7737
|
options: mergedOptions
|
|
6270
7738
|
},
|
|
6271
7739
|
async () => {
|
|
@@ -6293,6 +7761,7 @@ function createTableBuilder(tableName, client, formatGatewayResult, tracer, expe
|
|
|
6293
7761
|
return builder;
|
|
6294
7762
|
}
|
|
6295
7763
|
function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
|
|
7764
|
+
const debugAstEnabled = Boolean(experimental?.debugAst);
|
|
6296
7765
|
return async function query(query, options) {
|
|
6297
7766
|
const normalizedQuery = query.trim();
|
|
6298
7767
|
if (!normalizedQuery) {
|
|
@@ -6309,6 +7778,7 @@ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
|
|
|
6309
7778
|
endpoint: "/gateway/query",
|
|
6310
7779
|
sql: normalizedQuery,
|
|
6311
7780
|
payload,
|
|
7781
|
+
ast: debugAstEnabled ? buildRawQueryDebugAst(normalizedQuery) : void 0,
|
|
6312
7782
|
options
|
|
6313
7783
|
},
|
|
6314
7784
|
async () => {
|
|
@@ -6320,6 +7790,63 @@ function createQueryBuilder(client, formatGatewayResult, experimental, tracer) {
|
|
|
6320
7790
|
);
|
|
6321
7791
|
};
|
|
6322
7792
|
}
|
|
7793
|
+
function resolveClientServiceBaseUrl(value, label) {
|
|
7794
|
+
if (value === void 0 || value === null) {
|
|
7795
|
+
return void 0;
|
|
7796
|
+
}
|
|
7797
|
+
return normalizeAthenaGatewayBaseUrl(value, { label });
|
|
7798
|
+
}
|
|
7799
|
+
function appendServicePath(baseUrl, segment) {
|
|
7800
|
+
const normalizedBaseUrl = normalizeAthenaGatewayBaseUrl(baseUrl, { label: "Athena public base URL" });
|
|
7801
|
+
return `${normalizedBaseUrl}/${segment.replace(/^\/+/, "")}`;
|
|
7802
|
+
}
|
|
7803
|
+
function resolveServiceUrlOverride(value, label) {
|
|
7804
|
+
return resolveClientServiceBaseUrl(value, label);
|
|
7805
|
+
}
|
|
7806
|
+
function resolveServiceUrls(config) {
|
|
7807
|
+
const baseUrl = resolveClientServiceBaseUrl(config.url, "Athena public base URL");
|
|
7808
|
+
return {
|
|
7809
|
+
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),
|
|
7810
|
+
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),
|
|
7811
|
+
storageUrl: resolveServiceUrlOverride(config.storage?.url, "Athena storage base URL") ?? resolveServiceUrlOverride(config.storageUrl, "Athena storage base URL") ?? (baseUrl ? appendServicePath(baseUrl, "storage") : void 0)
|
|
7812
|
+
};
|
|
7813
|
+
}
|
|
7814
|
+
function normalizeAuthClientConfig(auth, defaultBaseUrl) {
|
|
7815
|
+
if (!auth && defaultBaseUrl === void 0) {
|
|
7816
|
+
return void 0;
|
|
7817
|
+
}
|
|
7818
|
+
const { url, ...rest } = auth ?? {};
|
|
7819
|
+
const normalized = {
|
|
7820
|
+
...rest
|
|
7821
|
+
};
|
|
7822
|
+
const resolvedBaseUrl = resolveClientServiceBaseUrl(
|
|
7823
|
+
url ?? rest.baseUrl ?? defaultBaseUrl,
|
|
7824
|
+
"Athena auth base URL"
|
|
7825
|
+
);
|
|
7826
|
+
if (resolvedBaseUrl !== void 0) {
|
|
7827
|
+
normalized.baseUrl = resolvedBaseUrl;
|
|
7828
|
+
}
|
|
7829
|
+
return normalized;
|
|
7830
|
+
}
|
|
7831
|
+
function resolveCreateClientConfig(config) {
|
|
7832
|
+
const resolvedUrls = resolveServiceUrls(config);
|
|
7833
|
+
if (!resolvedUrls.dbUrl) {
|
|
7834
|
+
throw new Error(
|
|
7835
|
+
"Athena DB base URL is required. Pass createClient(url, key) for a unified root, or set db.url / gateway.url / gatewayUrl explicitly."
|
|
7836
|
+
);
|
|
7837
|
+
}
|
|
7838
|
+
return {
|
|
7839
|
+
baseUrl: resolvedUrls.dbUrl,
|
|
7840
|
+
apiKey: config.key,
|
|
7841
|
+
client: config.client,
|
|
7842
|
+
backend: toBackendConfig(config.backend),
|
|
7843
|
+
headers: config.headers,
|
|
7844
|
+
auth: config.auth,
|
|
7845
|
+
authUrl: resolvedUrls.authUrl,
|
|
7846
|
+
storageUrl: resolvedUrls.storageUrl,
|
|
7847
|
+
experimental: config.experimental
|
|
7848
|
+
};
|
|
7849
|
+
}
|
|
6323
7850
|
function createClientFromConfig(config) {
|
|
6324
7851
|
const gatewayHeaders = {
|
|
6325
7852
|
...config.headers ?? {}
|
|
@@ -6334,16 +7861,33 @@ function createClientFromConfig(config) {
|
|
|
6334
7861
|
backend: config.backend,
|
|
6335
7862
|
headers: gatewayHeaders
|
|
6336
7863
|
});
|
|
6337
|
-
const formatGatewayResult = createResultFormatter();
|
|
7864
|
+
const formatGatewayResult = createResultFormatter(config.experimental);
|
|
6338
7865
|
const queryTracer = createQueryTracer(config.experimental);
|
|
6339
|
-
const auth = createAuthClient(config.auth);
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
7866
|
+
const auth = createAuthClient(normalizeAuthClientConfig(config.auth, config.authUrl));
|
|
7867
|
+
function from(tableOrModel, options) {
|
|
7868
|
+
if (isAthenaModelTarget(tableOrModel)) {
|
|
7869
|
+
if (options?.schema !== void 0) {
|
|
7870
|
+
throw new Error(
|
|
7871
|
+
"from(model) does not accept a schema override because the model already defines its target."
|
|
7872
|
+
);
|
|
7873
|
+
}
|
|
7874
|
+
return createTableBuilder(
|
|
7875
|
+
resolveAthenaModelTargetTableName(tableOrModel),
|
|
7876
|
+
gateway,
|
|
7877
|
+
formatGatewayResult,
|
|
7878
|
+
queryTracer,
|
|
7879
|
+
config.experimental
|
|
7880
|
+
);
|
|
7881
|
+
}
|
|
7882
|
+
const resolvedTableName = resolveTableNameForCall(tableOrModel, options?.schema);
|
|
7883
|
+
return createTableBuilder(
|
|
7884
|
+
resolvedTableName,
|
|
7885
|
+
gateway,
|
|
7886
|
+
formatGatewayResult,
|
|
7887
|
+
queryTracer,
|
|
7888
|
+
config.experimental
|
|
7889
|
+
);
|
|
7890
|
+
}
|
|
6347
7891
|
const rpc = (fn, args, options) => {
|
|
6348
7892
|
const normalizedFn = fn.trim();
|
|
6349
7893
|
if (!normalizedFn) {
|
|
@@ -6356,10 +7900,16 @@ function createClientFromConfig(config) {
|
|
|
6356
7900
|
gateway,
|
|
6357
7901
|
formatGatewayResult,
|
|
6358
7902
|
queryTracer,
|
|
6359
|
-
captureTraceCallsite(queryTracer)
|
|
7903
|
+
captureTraceCallsite(queryTracer),
|
|
7904
|
+
Boolean(config.experimental?.debugAst)
|
|
6360
7905
|
);
|
|
6361
7906
|
};
|
|
6362
|
-
const query = createQueryBuilder(
|
|
7907
|
+
const query = createQueryBuilder(
|
|
7908
|
+
gateway,
|
|
7909
|
+
formatGatewayResult,
|
|
7910
|
+
config.experimental,
|
|
7911
|
+
queryTracer
|
|
7912
|
+
);
|
|
6363
7913
|
const db = createDbModule({ from, rpc, query });
|
|
6364
7914
|
const sdkClient = {
|
|
6365
7915
|
from,
|
|
@@ -6372,27 +7922,27 @@ function createClientFromConfig(config) {
|
|
|
6372
7922
|
if (config.experimental?.athenaStorageBackend) {
|
|
6373
7923
|
const storageClient = {
|
|
6374
7924
|
...sdkClient,
|
|
6375
|
-
storage: createStorageModule(gateway,
|
|
7925
|
+
storage: createStorageModule(gateway, {
|
|
7926
|
+
...config.experimental.storage,
|
|
7927
|
+
...config.storageUrl ? {
|
|
7928
|
+
baseUrl: config.storageUrl,
|
|
7929
|
+
stripBasePath: true
|
|
7930
|
+
} : {}
|
|
7931
|
+
})
|
|
6376
7932
|
};
|
|
6377
7933
|
return storageClient;
|
|
6378
7934
|
}
|
|
6379
7935
|
return sdkClient;
|
|
6380
7936
|
}
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
client: options?.client,
|
|
6391
|
-
backend: toBackendConfig(options?.backend),
|
|
6392
|
-
headers: options?.headers,
|
|
6393
|
-
auth: options?.auth,
|
|
6394
|
-
experimental: options?.experimental
|
|
6395
|
-
});
|
|
7937
|
+
function createClient(configOrUrl, apiKey, options) {
|
|
7938
|
+
if (typeof configOrUrl === "string") {
|
|
7939
|
+
return createClientFromConfig(resolveCreateClientConfig({
|
|
7940
|
+
url: configOrUrl,
|
|
7941
|
+
key: apiKey ?? "",
|
|
7942
|
+
...options
|
|
7943
|
+
}));
|
|
7944
|
+
}
|
|
7945
|
+
return createClientFromConfig(resolveCreateClientConfig(configOrUrl));
|
|
6396
7946
|
}
|
|
6397
7947
|
|
|
6398
7948
|
// src/schema/postgres-introspection-core.ts
|
|
@@ -6989,6 +8539,7 @@ function rootUsage() {
|
|
|
6989
8539
|
"",
|
|
6990
8540
|
"Examples:",
|
|
6991
8541
|
" athena-js generate",
|
|
8542
|
+
" DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/app_db athena-js generate --dry-run",
|
|
6992
8543
|
" athena-js generate --config ./athena.config.ts --dry-run",
|
|
6993
8544
|
" athena-js generate --help"
|
|
6994
8545
|
].join("\n");
|
|
@@ -7005,8 +8556,14 @@ function generateUsage() {
|
|
|
7005
8556
|
" --dry-run Build generated files in memory without writing them to disk",
|
|
7006
8557
|
" -h, --help Show help for generate",
|
|
7007
8558
|
"",
|
|
8559
|
+
"Config resolution:",
|
|
8560
|
+
" - uses athena.config.* discovery first",
|
|
8561
|
+
" - falls back to env-only direct mode when DATABASE_URL/PG_URL is present",
|
|
8562
|
+
" - falls back to env-only gateway mode when ATHENA_URL + ATHENA_API_KEY are present",
|
|
8563
|
+
"",
|
|
7008
8564
|
"Examples:",
|
|
7009
8565
|
" athena-js generate",
|
|
8566
|
+
" DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/app_db athena-js generate --dry-run",
|
|
7010
8567
|
" athena-js generate --config ./athena.config.ts --dry-run"
|
|
7011
8568
|
].join("\n");
|
|
7012
8569
|
}
|