@xylex-group/athena 1.6.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -11
- package/bin/athena-js.js +0 -0
- package/dist/cli/index.cjs +150 -53
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +150 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +709 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +307 -41
- package/dist/index.d.ts +307 -41
- package/dist/index.js +703 -54
- package/dist/index.js.map +1 -1
- package/dist/model-form-Bm_kqCn2.d.ts +92 -0
- package/dist/model-form-DkS48fsh.d.cts +92 -0
- package/dist/pipeline-C-cN0ACi.d.cts +164 -0
- package/dist/pipeline-CQgV-Yfo.d.ts +164 -0
- package/dist/react.cjs +64 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.js +62 -1
- package/dist/react.js.map +1 -1
- package/dist/types-BnzoaNRC.d.cts +380 -0
- package/dist/types-BnzoaNRC.d.ts +380 -0
- package/package.json +15 -14
- package/dist/errors-1b-LSTum.d.ts +0 -31
- package/dist/errors-BYRK5phv.d.cts +0 -31
- package/dist/pipeline-BQzpSLD3.d.ts +0 -338
- package/dist/pipeline-CA2aexDl.d.cts +0 -338
- package/dist/types-v6UyGg-x.d.cts +0 -195
- package/dist/types-v6UyGg-x.d.ts +0 -195
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# athena-js
|
|
2
2
|
|
|
3
|
-
current version: `1.
|
|
3
|
+
current version: `1.9.0`
|
|
4
4
|
`@xylex-group/athena` is a database driver and API gateway SDK that lets you interact with SQL backends over HTTP through a fluent builder API. It ships a typed query builder for Node.js / server environments plus Athena-native React hooks for client-side use.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
@@ -43,6 +43,51 @@ if (error) {
|
|
|
43
43
|
}
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
### Auth client (Athena Auth server)
|
|
47
|
+
|
|
48
|
+
If your auth backend is now Athena Auth, you can keep core login/session flows in this SDK:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { createAuthClient } from "@xylex-group/athena";
|
|
52
|
+
|
|
53
|
+
const auth = createAuthClient({
|
|
54
|
+
baseUrl: "http://localhost:3001/api/auth",
|
|
55
|
+
// optional: bearer token if you are not using cookie-based sessions
|
|
56
|
+
bearerToken: process.env.AUTH_BEARER_TOKEN,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const login = await auth.signIn.email({
|
|
60
|
+
email: "demo@example.com",
|
|
61
|
+
password: "super-secret",
|
|
62
|
+
rememberMe: true,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const session = await auth.getSession();
|
|
66
|
+
const sessions = await auth.listSessions();
|
|
67
|
+
|
|
68
|
+
// clear one session
|
|
69
|
+
await auth.revokeSession({ token: "session_token_here" });
|
|
70
|
+
// or clear all sessions
|
|
71
|
+
await auth.revokeSessions();
|
|
72
|
+
|
|
73
|
+
await auth.signOut();
|
|
74
|
+
|
|
75
|
+
// additional core flows
|
|
76
|
+
await auth.forgetPassword({ email: "demo@example.com", redirectTo: "https://app/reset-password" });
|
|
77
|
+
await auth.resetPassword({ newPassword: "new-secret", token: "reset_token" });
|
|
78
|
+
await auth.verifyEmail({ token: "verify_token", callbackURL: "https://app/verified" });
|
|
79
|
+
await auth.changePassword({ currentPassword: "old-secret", newPassword: "new-secret" });
|
|
80
|
+
await auth.updateUser({ name: "Demo User" });
|
|
81
|
+
|
|
82
|
+
// escape hatch for any endpoint on your Athena Auth instance
|
|
83
|
+
await auth.request({
|
|
84
|
+
endpoint: "/ok",
|
|
85
|
+
query: { ping: "pong" },
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Auth responses follow the same envelope style: `{ ok, status, data, error, errorDetails, raw }`.
|
|
90
|
+
|
|
46
91
|
### Typed schema registry (model-first)
|
|
47
92
|
|
|
48
93
|
You can keep `createClient(...).from<T>(...)` as-is, or opt into a typed registry:
|
|
@@ -101,6 +146,7 @@ Generator supports:
|
|
|
101
146
|
|
|
102
147
|
- PostgreSQL direct introspection (`provider.mode = "direct"`, `provider.connectionString` from your `PG_URL`/`DATABASE_URL`)
|
|
103
148
|
- PostgreSQL gateway-only introspection (`provider.mode = "gateway"` via Athena `POST /gateway/query`)
|
|
149
|
+
- Multiple schema syncs such as `public` plus `athena`, with schema-safe default output paths
|
|
104
150
|
- Placeholder-driven output paths
|
|
105
151
|
- Feature flags (`features.emitRegistry`, `features.emitRelations`)
|
|
106
152
|
|
|
@@ -344,11 +390,23 @@ const { data: user } = await athena
|
|
|
344
390
|
.single();
|
|
345
391
|
```
|
|
346
392
|
|
|
347
|
-
`maybeSingle` behaves identically — both return the first element of the result set.
|
|
348
|
-
|
|
349
|
-
###
|
|
350
|
-
|
|
351
|
-
Use `
|
|
393
|
+
`maybeSingle` behaves identically — both return the first element of the result set.
|
|
394
|
+
|
|
395
|
+
### Table schema targeting
|
|
396
|
+
|
|
397
|
+
Use `schema` in table call options to qualify unqualified table names:
|
|
398
|
+
|
|
399
|
+
```ts
|
|
400
|
+
const { data } = await athena
|
|
401
|
+
.from("users")
|
|
402
|
+
.select("id,email", { schema: "public" });
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
This resolves the table target to `public.users`.
|
|
406
|
+
|
|
407
|
+
### RPC
|
|
408
|
+
|
|
409
|
+
Use `athena.rpc(...)` for Postgres function calls. By default it calls `POST /gateway/rpc`, and with `{ get: true }` it uses the compatibility route `GET /rpc/{function_name}`.
|
|
352
410
|
|
|
353
411
|
```ts
|
|
354
412
|
const { data, count } = await athena
|
|
@@ -382,11 +440,12 @@ RPC options: `schema`, `count` (`"exact" | "planned" | "estimated"`), `head`, `g
|
|
|
382
440
|
|
|
383
441
|
Pass options as the second argument to `.select()`:
|
|
384
442
|
|
|
385
|
-
| Option | Type | Description |
|
|
386
|
-
| ------------ | ------------------------------------- | -------------------------------------------- |
|
|
387
|
-
| `
|
|
388
|
-
| `
|
|
389
|
-
| `
|
|
443
|
+
| Option | Type | Description |
|
|
444
|
+
| ------------ | ------------------------------------- | -------------------------------------------- |
|
|
445
|
+
| `schema` | `string` | qualify unqualified table names for table calls |
|
|
446
|
+
| `count` | `"exact" \| "planned" \| "estimated"` | request a row count alongside the data |
|
|
447
|
+
| `head` | `boolean` | return response headers only (no rows) |
|
|
448
|
+
| `stripNulls` | `boolean` | strip null values from rows (default `true`) |
|
|
390
449
|
|
|
391
450
|
```ts
|
|
392
451
|
const { data } = await athena
|
package/bin/athena-js.js
CHANGED
|
File without changes
|
package/dist/cli/index.cjs
CHANGED
|
@@ -291,6 +291,37 @@ function resolvePostgresColumnType(column) {
|
|
|
291
291
|
}
|
|
292
292
|
return wrapArrayType(baseType, column.arrayDimensions);
|
|
293
293
|
}
|
|
294
|
+
|
|
295
|
+
// src/generator/schema-selection.ts
|
|
296
|
+
var DEFAULT_POSTGRES_SCHEMAS = ["public"];
|
|
297
|
+
function collectSchemaNames(input) {
|
|
298
|
+
if (!input) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
const values = typeof input === "string" ? [input] : input;
|
|
302
|
+
return values.flatMap((value) => String(value).split(","));
|
|
303
|
+
}
|
|
304
|
+
function normalizeSchemaSelection(input) {
|
|
305
|
+
const schemas = [];
|
|
306
|
+
const seen = /* @__PURE__ */ new Set();
|
|
307
|
+
for (const value of collectSchemaNames(input)) {
|
|
308
|
+
const schema = value.trim();
|
|
309
|
+
if (!schema || seen.has(schema)) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
seen.add(schema);
|
|
313
|
+
schemas.push(schema);
|
|
314
|
+
}
|
|
315
|
+
return schemas.length > 0 ? schemas : [...DEFAULT_POSTGRES_SCHEMAS];
|
|
316
|
+
}
|
|
317
|
+
function resolveProviderSchemas(providerConfig) {
|
|
318
|
+
if (providerConfig.kind === "postgres") {
|
|
319
|
+
return normalizeSchemaSelection(providerConfig.schemas);
|
|
320
|
+
}
|
|
321
|
+
return [...DEFAULT_POSTGRES_SCHEMAS];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// src/generator/config.ts
|
|
294
325
|
var DEFAULT_CONFIG_CANDIDATES = [
|
|
295
326
|
"athena.config.ts",
|
|
296
327
|
"athena.config.js",
|
|
@@ -300,8 +331,8 @@ var DEFAULT_CONFIG_CANDIDATES = [
|
|
|
300
331
|
".athena.config.js"
|
|
301
332
|
];
|
|
302
333
|
var DEFAULT_TARGETS = {
|
|
303
|
-
model: "athena/models/{model_kebab}.ts",
|
|
304
|
-
schema: "athena/
|
|
334
|
+
model: "athena/models/{schema_kebab}/{model_kebab}.ts",
|
|
335
|
+
schema: "athena/schemas/{schema_kebab}.ts",
|
|
305
336
|
database: "athena/relations.ts",
|
|
306
337
|
registry: "athena/config.ts"
|
|
307
338
|
};
|
|
@@ -331,6 +362,15 @@ function normalizeOutputConfig(output) {
|
|
|
331
362
|
}
|
|
332
363
|
};
|
|
333
364
|
}
|
|
365
|
+
function normalizeProviderConfig(provider) {
|
|
366
|
+
if (provider.kind === "postgres") {
|
|
367
|
+
return {
|
|
368
|
+
...provider,
|
|
369
|
+
schemas: normalizeSchemaSelection(provider.schemas)
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
return provider;
|
|
373
|
+
}
|
|
334
374
|
function isAthenaGeneratorConfig(value) {
|
|
335
375
|
if (!value || typeof value !== "object") {
|
|
336
376
|
return false;
|
|
@@ -340,7 +380,7 @@ function isAthenaGeneratorConfig(value) {
|
|
|
340
380
|
}
|
|
341
381
|
function normalizeGeneratorConfig(input) {
|
|
342
382
|
return {
|
|
343
|
-
provider: input.provider,
|
|
383
|
+
provider: normalizeProviderConfig(input.provider),
|
|
344
384
|
output: normalizeOutputConfig(input.output),
|
|
345
385
|
naming: {
|
|
346
386
|
...DEFAULT_NAMING,
|
|
@@ -550,12 +590,19 @@ export const ${registryConstName} = defineRegistry({
|
|
|
550
590
|
};
|
|
551
591
|
}
|
|
552
592
|
function assertNoDuplicatePaths(files) {
|
|
553
|
-
const seen = /* @__PURE__ */ new
|
|
593
|
+
const seen = /* @__PURE__ */ new Map();
|
|
554
594
|
for (const file of files) {
|
|
555
|
-
|
|
556
|
-
|
|
595
|
+
const existing = seen.get(file.path);
|
|
596
|
+
if (existing) {
|
|
597
|
+
throw new Error(
|
|
598
|
+
[
|
|
599
|
+
`Generator output collision detected for path: ${file.path}`,
|
|
600
|
+
`Collision: ${existing.kind} and ${file.kind}.`,
|
|
601
|
+
"When syncing multiple schemas, include a schema placeholder such as {schema} or {schema_kebab} in model/schema output targets."
|
|
602
|
+
].join(" ")
|
|
603
|
+
);
|
|
557
604
|
}
|
|
558
|
-
seen.
|
|
605
|
+
seen.set(file.path, file);
|
|
559
606
|
}
|
|
560
607
|
}
|
|
561
608
|
var ArtifactComposer = class {
|
|
@@ -1184,6 +1231,12 @@ function mergeOptions(...options) {
|
|
|
1184
1231
|
return { ...acc, ...next };
|
|
1185
1232
|
}, void 0);
|
|
1186
1233
|
}
|
|
1234
|
+
function asAthenaJsonObject(value) {
|
|
1235
|
+
return value;
|
|
1236
|
+
}
|
|
1237
|
+
function asAthenaJsonObjectArray(values) {
|
|
1238
|
+
return values;
|
|
1239
|
+
}
|
|
1187
1240
|
function createMutationQuery(executor, defaultColumns = DEFAULT_COLUMNS) {
|
|
1188
1241
|
let selectedColumns = defaultColumns === null ? void 0 : defaultColumns;
|
|
1189
1242
|
let selectedOptions;
|
|
@@ -1272,6 +1325,22 @@ function buildSelectColumnsClause(columns) {
|
|
|
1272
1325
|
}
|
|
1273
1326
|
return quoteSelectColumnsExpression(columns);
|
|
1274
1327
|
}
|
|
1328
|
+
function resolveTableNameForCall(tableName, schema) {
|
|
1329
|
+
if (!schema) return tableName;
|
|
1330
|
+
const normalizedSchema = schema.trim();
|
|
1331
|
+
if (!normalizedSchema) {
|
|
1332
|
+
throw new Error("schema option must be a non-empty string");
|
|
1333
|
+
}
|
|
1334
|
+
if (tableName.includes(".")) {
|
|
1335
|
+
if (tableName.startsWith(`${normalizedSchema}.`)) {
|
|
1336
|
+
return tableName;
|
|
1337
|
+
}
|
|
1338
|
+
throw new Error(
|
|
1339
|
+
`schema option "${normalizedSchema}" conflicts with schema-qualified table "${tableName}"`
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
return `${normalizedSchema}.${tableName}`;
|
|
1343
|
+
}
|
|
1275
1344
|
function conditionToSqlClause(condition) {
|
|
1276
1345
|
if (!condition.column) return null;
|
|
1277
1346
|
const column = withCast(quoteQualifiedIdentifier(condition.column), condition.column_cast);
|
|
@@ -1351,23 +1420,27 @@ function buildTypedSelectQuery(input) {
|
|
|
1351
1420
|
function createFilterMethods(state, addCondition, self) {
|
|
1352
1421
|
return {
|
|
1353
1422
|
eq(column, value) {
|
|
1354
|
-
|
|
1355
|
-
|
|
1423
|
+
const columnName = String(column);
|
|
1424
|
+
if (shouldUseUuidTextComparison(columnName, value)) {
|
|
1425
|
+
addCondition("eq", columnName, value, { columnCast: "text" });
|
|
1356
1426
|
} else {
|
|
1357
|
-
addCondition("eq",
|
|
1427
|
+
addCondition("eq", columnName, value);
|
|
1358
1428
|
}
|
|
1359
1429
|
return self;
|
|
1360
1430
|
},
|
|
1361
1431
|
eqCast(column, value, cast) {
|
|
1362
|
-
addCondition("eq", column, value, { valueCast: cast });
|
|
1432
|
+
addCondition("eq", String(column), value, { valueCast: cast });
|
|
1363
1433
|
return self;
|
|
1364
1434
|
},
|
|
1365
1435
|
eqUuid(column, value) {
|
|
1366
|
-
addCondition("eq", column, value, { valueCast: "uuid" });
|
|
1436
|
+
addCondition("eq", String(column), value, { valueCast: "uuid" });
|
|
1367
1437
|
return self;
|
|
1368
1438
|
},
|
|
1369
1439
|
match(filters) {
|
|
1370
1440
|
Object.entries(filters).forEach(([column, value]) => {
|
|
1441
|
+
if (value === void 0) {
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1371
1444
|
if (shouldUseUuidTextComparison(column, value)) {
|
|
1372
1445
|
addCondition("eq", column, value, { columnCast: "text" });
|
|
1373
1446
|
} else {
|
|
@@ -1403,60 +1476,61 @@ function createFilterMethods(state, addCondition, self) {
|
|
|
1403
1476
|
},
|
|
1404
1477
|
order(column, options) {
|
|
1405
1478
|
state.order = {
|
|
1406
|
-
field: column,
|
|
1479
|
+
field: String(column),
|
|
1407
1480
|
direction: options?.ascending === false ? "descending" : "ascending"
|
|
1408
1481
|
};
|
|
1409
1482
|
return self;
|
|
1410
1483
|
},
|
|
1411
1484
|
gt(column, value) {
|
|
1412
|
-
addCondition("gt", column, value);
|
|
1485
|
+
addCondition("gt", String(column), value);
|
|
1413
1486
|
return self;
|
|
1414
1487
|
},
|
|
1415
1488
|
gte(column, value) {
|
|
1416
|
-
addCondition("gte", column, value);
|
|
1489
|
+
addCondition("gte", String(column), value);
|
|
1417
1490
|
return self;
|
|
1418
1491
|
},
|
|
1419
1492
|
lt(column, value) {
|
|
1420
|
-
addCondition("lt", column, value);
|
|
1493
|
+
addCondition("lt", String(column), value);
|
|
1421
1494
|
return self;
|
|
1422
1495
|
},
|
|
1423
1496
|
lte(column, value) {
|
|
1424
|
-
addCondition("lte", column, value);
|
|
1497
|
+
addCondition("lte", String(column), value);
|
|
1425
1498
|
return self;
|
|
1426
1499
|
},
|
|
1427
1500
|
neq(column, value) {
|
|
1428
|
-
addCondition("neq", column, value);
|
|
1501
|
+
addCondition("neq", String(column), value);
|
|
1429
1502
|
return self;
|
|
1430
1503
|
},
|
|
1431
1504
|
like(column, value) {
|
|
1432
|
-
addCondition("like", column, value);
|
|
1505
|
+
addCondition("like", String(column), value);
|
|
1433
1506
|
return self;
|
|
1434
1507
|
},
|
|
1435
1508
|
ilike(column, value) {
|
|
1436
|
-
addCondition("ilike", column, value);
|
|
1509
|
+
addCondition("ilike", String(column), value);
|
|
1437
1510
|
return self;
|
|
1438
1511
|
},
|
|
1439
1512
|
is(column, value) {
|
|
1440
|
-
addCondition("is", column, value);
|
|
1513
|
+
addCondition("is", String(column), value);
|
|
1441
1514
|
return self;
|
|
1442
1515
|
},
|
|
1443
1516
|
in(column, values) {
|
|
1444
|
-
addCondition("in", column, values);
|
|
1517
|
+
addCondition("in", String(column), values);
|
|
1445
1518
|
return self;
|
|
1446
1519
|
},
|
|
1447
1520
|
contains(column, values) {
|
|
1448
|
-
addCondition("contains", column, values);
|
|
1521
|
+
addCondition("contains", String(column), values);
|
|
1449
1522
|
return self;
|
|
1450
1523
|
},
|
|
1451
1524
|
containedBy(column, values) {
|
|
1452
|
-
addCondition("containedBy", column, values);
|
|
1525
|
+
addCondition("containedBy", String(column), values);
|
|
1453
1526
|
return self;
|
|
1454
1527
|
},
|
|
1455
1528
|
not(columnOrExpression, operator, value) {
|
|
1529
|
+
const expression = String(columnOrExpression);
|
|
1456
1530
|
if (operator != null && value !== void 0) {
|
|
1457
|
-
addCondition("not", void 0, `${
|
|
1531
|
+
addCondition("not", void 0, `${expression}.${operator}.${stringifyFilterValue(value)}`);
|
|
1458
1532
|
} else {
|
|
1459
|
-
addCondition("not", void 0,
|
|
1533
|
+
addCondition("not", void 0, expression);
|
|
1460
1534
|
}
|
|
1461
1535
|
return self;
|
|
1462
1536
|
},
|
|
@@ -1626,15 +1700,20 @@ function createTableBuilder(tableName, client) {
|
|
|
1626
1700
|
state.conditions.push(condition);
|
|
1627
1701
|
};
|
|
1628
1702
|
const builder = {};
|
|
1629
|
-
const filterMethods = createFilterMethods(
|
|
1703
|
+
const filterMethods = createFilterMethods(
|
|
1704
|
+
state,
|
|
1705
|
+
addCondition,
|
|
1706
|
+
builder
|
|
1707
|
+
);
|
|
1630
1708
|
const runSelect = async (columns = DEFAULT_COLUMNS, options) => {
|
|
1709
|
+
const resolvedTableName = resolveTableNameForCall(tableName, options?.schema);
|
|
1631
1710
|
const conditions = state.conditions.length ? state.conditions.map((condition) => ({ ...condition })) : void 0;
|
|
1632
1711
|
const hasTypedEqualityComparison = conditions?.some(
|
|
1633
1712
|
(condition) => condition.operator === "eq" && (condition.value_cast !== void 0 || condition.column_cast !== void 0)
|
|
1634
1713
|
) ?? false;
|
|
1635
1714
|
if (hasTypedEqualityComparison && !options?.head && !options?.count && conditions) {
|
|
1636
1715
|
const query = buildTypedSelectQuery({
|
|
1637
|
-
tableName,
|
|
1716
|
+
tableName: resolvedTableName,
|
|
1638
1717
|
columns,
|
|
1639
1718
|
conditions,
|
|
1640
1719
|
limit: state.limit,
|
|
@@ -1649,7 +1728,7 @@ function createTableBuilder(tableName, client) {
|
|
|
1649
1728
|
}
|
|
1650
1729
|
}
|
|
1651
1730
|
const payload = {
|
|
1652
|
-
table_name:
|
|
1731
|
+
table_name: resolvedTableName,
|
|
1653
1732
|
columns,
|
|
1654
1733
|
conditions,
|
|
1655
1734
|
limit: state.limit,
|
|
@@ -1706,9 +1785,10 @@ function createTableBuilder(tableName, client) {
|
|
|
1706
1785
|
if (Array.isArray(values)) {
|
|
1707
1786
|
const executeInsertMany = async (columns, selectOptions) => {
|
|
1708
1787
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1788
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1709
1789
|
const payload = {
|
|
1710
|
-
table_name:
|
|
1711
|
-
insert_body: values
|
|
1790
|
+
table_name: resolvedTableName,
|
|
1791
|
+
insert_body: asAthenaJsonObjectArray(values)
|
|
1712
1792
|
};
|
|
1713
1793
|
if (columns) payload.columns = columns;
|
|
1714
1794
|
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
@@ -1723,9 +1803,10 @@ function createTableBuilder(tableName, client) {
|
|
|
1723
1803
|
}
|
|
1724
1804
|
const executeInsertOne = async (columns, selectOptions) => {
|
|
1725
1805
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1806
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1726
1807
|
const payload = {
|
|
1727
|
-
table_name:
|
|
1728
|
-
insert_body: values
|
|
1808
|
+
table_name: resolvedTableName,
|
|
1809
|
+
insert_body: asAthenaJsonObject(values)
|
|
1729
1810
|
};
|
|
1730
1811
|
if (columns) payload.columns = columns;
|
|
1731
1812
|
if (mergedOptions?.count) payload.count = mergedOptions.count;
|
|
@@ -1742,10 +1823,11 @@ function createTableBuilder(tableName, client) {
|
|
|
1742
1823
|
if (Array.isArray(values)) {
|
|
1743
1824
|
const executeUpsertMany = async (columns, selectOptions) => {
|
|
1744
1825
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1826
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1745
1827
|
const payload = {
|
|
1746
|
-
table_name:
|
|
1747
|
-
insert_body: values,
|
|
1748
|
-
update_body: options?.updateBody ? options.updateBody : void 0
|
|
1828
|
+
table_name: resolvedTableName,
|
|
1829
|
+
insert_body: asAthenaJsonObjectArray(values),
|
|
1830
|
+
update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
|
|
1749
1831
|
};
|
|
1750
1832
|
if (columns) payload.columns = columns;
|
|
1751
1833
|
if (options?.onConflict) payload.on_conflict = options.onConflict;
|
|
@@ -1761,10 +1843,11 @@ function createTableBuilder(tableName, client) {
|
|
|
1761
1843
|
}
|
|
1762
1844
|
const executeUpsertOne = async (columns, selectOptions) => {
|
|
1763
1845
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1846
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1764
1847
|
const payload = {
|
|
1765
|
-
table_name:
|
|
1766
|
-
insert_body: values,
|
|
1767
|
-
update_body: options?.updateBody ? options.updateBody : void 0
|
|
1848
|
+
table_name: resolvedTableName,
|
|
1849
|
+
insert_body: asAthenaJsonObject(values),
|
|
1850
|
+
update_body: options?.updateBody ? asAthenaJsonObject(options.updateBody) : void 0
|
|
1768
1851
|
};
|
|
1769
1852
|
if (columns) payload.columns = columns;
|
|
1770
1853
|
if (options?.onConflict) payload.on_conflict = options.onConflict;
|
|
@@ -1782,9 +1865,10 @@ function createTableBuilder(tableName, client) {
|
|
|
1782
1865
|
const executeUpdate = async (columns, selectOptions) => {
|
|
1783
1866
|
const filters = state.conditions.length ? [...state.conditions] : void 0;
|
|
1784
1867
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1868
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1785
1869
|
const payload = {
|
|
1786
|
-
table_name:
|
|
1787
|
-
set: values,
|
|
1870
|
+
table_name: resolvedTableName,
|
|
1871
|
+
set: asAthenaJsonObject(values),
|
|
1788
1872
|
conditions: filters,
|
|
1789
1873
|
strip_nulls: mergedOptions?.stripNulls ?? true
|
|
1790
1874
|
};
|
|
@@ -1810,8 +1894,9 @@ function createTableBuilder(tableName, client) {
|
|
|
1810
1894
|
}
|
|
1811
1895
|
const executeDelete = async (columns, selectOptions) => {
|
|
1812
1896
|
const mergedOptions = mergeOptions(options, selectOptions);
|
|
1897
|
+
const resolvedTableName = resolveTableNameForCall(tableName, mergedOptions?.schema);
|
|
1813
1898
|
const payload = {
|
|
1814
|
-
table_name:
|
|
1899
|
+
table_name: resolvedTableName,
|
|
1815
1900
|
resource_id: resourceId,
|
|
1816
1901
|
conditions: filters
|
|
1817
1902
|
};
|
|
@@ -2111,8 +2196,21 @@ function coerceStringArray(value) {
|
|
|
2111
2196
|
}
|
|
2112
2197
|
return [];
|
|
2113
2198
|
}
|
|
2199
|
+
function normalizePostgresCatalogSchemas(schemas) {
|
|
2200
|
+
const normalized = [];
|
|
2201
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2202
|
+
for (const value of schemas ?? []) {
|
|
2203
|
+
const schema = value.trim();
|
|
2204
|
+
if (!schema || seen.has(schema)) {
|
|
2205
|
+
continue;
|
|
2206
|
+
}
|
|
2207
|
+
seen.add(schema);
|
|
2208
|
+
normalized.push(schema);
|
|
2209
|
+
}
|
|
2210
|
+
return normalized.length > 0 ? normalized : ["public"];
|
|
2211
|
+
}
|
|
2114
2212
|
function buildSchemaArrayLiteral(schemas) {
|
|
2115
|
-
const normalized = schemas
|
|
2213
|
+
const normalized = normalizePostgresCatalogSchemas(schemas);
|
|
2116
2214
|
const literals = normalized.map((schema) => `'${escapeSqlLiteral(schema)}'`).join(", ");
|
|
2117
2215
|
return `ARRAY[${literals}]`;
|
|
2118
2216
|
}
|
|
@@ -2311,12 +2409,14 @@ var PostgresIntrospectionProvider = class {
|
|
|
2311
2409
|
backend = "postgresql";
|
|
2312
2410
|
connectionString;
|
|
2313
2411
|
database;
|
|
2412
|
+
schemas;
|
|
2314
2413
|
constructor(options) {
|
|
2315
2414
|
this.connectionString = options.connectionString;
|
|
2316
2415
|
this.database = options.database ?? "postgres";
|
|
2416
|
+
this.schemas = normalizePostgresCatalogSchemas(options.schemas);
|
|
2317
2417
|
}
|
|
2318
2418
|
async inspect(options) {
|
|
2319
|
-
const schemas = options?.schemas && options.schemas.length > 0 ? options.schemas :
|
|
2419
|
+
const schemas = options?.schemas && options.schemas.length > 0 ? normalizePostgresCatalogSchemas(options.schemas) : this.schemas;
|
|
2320
2420
|
const pool = new pg.Pool({
|
|
2321
2421
|
connectionString: this.connectionString
|
|
2322
2422
|
});
|
|
@@ -2388,11 +2488,13 @@ var AthenaGatewayPostgresIntrospectionProvider = class {
|
|
|
2388
2488
|
type: this.config.backend ?? "postgresql"
|
|
2389
2489
|
}
|
|
2390
2490
|
});
|
|
2491
|
+
this.schemas = normalizeSchemaSelection(this.config.schemas);
|
|
2391
2492
|
}
|
|
2392
2493
|
backend = "postgresql";
|
|
2393
2494
|
client;
|
|
2495
|
+
schemas;
|
|
2394
2496
|
async inspect(options) {
|
|
2395
|
-
const schemas = options?.schemas && options.schemas.length > 0 ? options.schemas : this.
|
|
2497
|
+
const schemas = options?.schemas && options.schemas.length > 0 ? normalizeSchemaSelection(options.schemas) : this.schemas;
|
|
2396
2498
|
const catalogClient = new AthenaGatewayCatalogClient(this.client);
|
|
2397
2499
|
const queries = buildGatewayCatalogQueries(schemas);
|
|
2398
2500
|
const [columnRows, enumMap, primaryKeyRows, foreignKeyRows] = await Promise.all([
|
|
@@ -2428,7 +2530,8 @@ var ScyllaIntrospectionProvider = class {
|
|
|
2428
2530
|
function createPostgresProvider(config) {
|
|
2429
2531
|
return createPostgresIntrospectionProvider({
|
|
2430
2532
|
connectionString: config.connectionString,
|
|
2431
|
-
database: config.database
|
|
2533
|
+
database: config.database,
|
|
2534
|
+
schemas: normalizeSchemaSelection(config.schemas)
|
|
2432
2535
|
});
|
|
2433
2536
|
}
|
|
2434
2537
|
function resolveGeneratorProvider(providerConfig, experimentalFlags) {
|
|
@@ -2450,12 +2553,6 @@ function resolveGeneratorProvider(providerConfig, experimentalFlags) {
|
|
|
2450
2553
|
}
|
|
2451
2554
|
|
|
2452
2555
|
// src/generator/pipeline.ts
|
|
2453
|
-
function extractProviderSchemas(providerConfig) {
|
|
2454
|
-
if (!("schemas" in providerConfig) || !providerConfig.schemas || providerConfig.schemas.length === 0) {
|
|
2455
|
-
return void 0;
|
|
2456
|
-
}
|
|
2457
|
-
return providerConfig.schemas;
|
|
2458
|
-
}
|
|
2459
2556
|
async function writeArtifacts(files, cwd) {
|
|
2460
2557
|
const writtenFiles = [];
|
|
2461
2558
|
for (const file of files) {
|
|
@@ -2475,7 +2572,7 @@ async function runSchemaGenerator(options = {}) {
|
|
|
2475
2572
|
const { configPath, config } = await loadGeneratorConfig(configOptions);
|
|
2476
2573
|
const provider = options.provider ?? resolveGeneratorProvider(config.provider, config.experimental);
|
|
2477
2574
|
const snapshot = await provider.inspect({
|
|
2478
|
-
schemas:
|
|
2575
|
+
schemas: resolveProviderSchemas(config.provider)
|
|
2479
2576
|
});
|
|
2480
2577
|
const generated = generateArtifactsFromSnapshot(snapshot, config);
|
|
2481
2578
|
const writtenFiles = options.dryRun ? [] : await writeArtifacts(generated.files, cwd);
|