@dbsp/core 1.11.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +80 -843
- package/dist/index.js +120 -1054
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -687,6 +687,13 @@ var SchemaValidationError = class extends Error {
|
|
|
687
687
|
table;
|
|
688
688
|
column;
|
|
689
689
|
};
|
|
690
|
+
function validateSchemaIndexOptions(tableName, idx) {
|
|
691
|
+
if (idx.nullsNotDistinct === true && idx.unique !== true) {
|
|
692
|
+
throw new SchemaValidationError(
|
|
693
|
+
`Index "${idx.name ?? `idx_${tableName}_${idx.columns.join("_")}`}" on "${tableName}" cannot use nullsNotDistinct unless unique is true`
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
690
697
|
function schemaToModelIR(definition, constraints, extras, options) {
|
|
691
698
|
if (typeof options?.defaultPkColumnName === "string" && options.defaultPkColumnName.trim().length === 0) {
|
|
692
699
|
throw new SchemaValidationError(
|
|
@@ -1095,13 +1102,18 @@ function buildTableConstraints(tableName, constraints) {
|
|
|
1095
1102
|
}
|
|
1096
1103
|
if (tableConstraints.indexes) {
|
|
1097
1104
|
for (const idx of tableConstraints.indexes) {
|
|
1105
|
+
validateSchemaIndexOptions(tableName, idx);
|
|
1098
1106
|
const indexIR = {
|
|
1099
1107
|
name: idx.name ?? `idx_${tableName}_${idx.columns.join("_")}`,
|
|
1100
1108
|
columns: idx.columns,
|
|
1101
1109
|
unique: idx.unique ?? false
|
|
1102
1110
|
};
|
|
1111
|
+
if (idx.nullsNotDistinct !== void 0) {
|
|
1112
|
+
indexIR.nullsNotDistinct = idx.nullsNotDistinct;
|
|
1113
|
+
}
|
|
1103
1114
|
if (idx.method) indexIR.method = idx.method;
|
|
1104
1115
|
if (idx.where) indexIR.where = idx.where;
|
|
1116
|
+
if (idx.include !== void 0) indexIR.include = idx.include;
|
|
1105
1117
|
if (idx.opclass) indexIR.opclass = idx.opclass;
|
|
1106
1118
|
if (idx.with) indexIR.with = idx.with;
|
|
1107
1119
|
extraIndexes.push(indexIR);
|
|
@@ -1489,12 +1501,6 @@ async function getSchemaFromDb(adapter, options) {
|
|
|
1489
1501
|
}
|
|
1490
1502
|
|
|
1491
1503
|
// src/conventions.ts
|
|
1492
|
-
var DEFAULT_CONVENTIONS = {
|
|
1493
|
-
fkPattern: "{singular}Id",
|
|
1494
|
-
pluralize: true,
|
|
1495
|
-
timestamps: ["createdAt", "updatedAt"],
|
|
1496
|
-
fkAutoIndex: true
|
|
1497
|
-
};
|
|
1498
1504
|
var IRREGULAR_PLURALS = {
|
|
1499
1505
|
people: "person",
|
|
1500
1506
|
children: "child",
|
|
@@ -1553,257 +1559,6 @@ function capitalize(name) {
|
|
|
1553
1559
|
function decapitalize(name) {
|
|
1554
1560
|
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
1555
1561
|
}
|
|
1556
|
-
function getSelfRefInverseName(belongsToName) {
|
|
1557
|
-
if (belongsToName === "parent") return "children";
|
|
1558
|
-
return pluralize(belongsToName);
|
|
1559
|
-
}
|
|
1560
|
-
function detectForeignKeys(tableName, table, conventions, tableNames) {
|
|
1561
|
-
const fks = [];
|
|
1562
|
-
const pattern = conventions.fkPattern;
|
|
1563
|
-
for (const [colName, colDef] of Object.entries(table)) {
|
|
1564
|
-
if (colDef.references) {
|
|
1565
|
-
const targetTable = colDef.references.table;
|
|
1566
|
-
if (colDef.references.schema === void 0 && tableNames.has(targetTable)) {
|
|
1567
|
-
const inferredName = colName.endsWith("Id") ? colName.slice(0, -2) : singularize(targetTable);
|
|
1568
|
-
const isSelfRef = targetTable === tableName;
|
|
1569
|
-
const detectedFK = {
|
|
1570
|
-
column: colName,
|
|
1571
|
-
targetTable,
|
|
1572
|
-
inferredName,
|
|
1573
|
-
explicit: true,
|
|
1574
|
-
targetColumn: colDef.references.column ?? "id"
|
|
1575
|
-
};
|
|
1576
|
-
if (isSelfRef) {
|
|
1577
|
-
detectedFK.parentRole = colDef.references.parentRole ?? inferredName;
|
|
1578
|
-
detectedFK.childRole = colDef.references.childRole ?? getSelfRefInverseName(inferredName);
|
|
1579
|
-
}
|
|
1580
|
-
fks.push(detectedFK);
|
|
1581
|
-
}
|
|
1582
|
-
continue;
|
|
1583
|
-
}
|
|
1584
|
-
for (const candidateTable of tableNames) {
|
|
1585
|
-
if (candidateTable === tableName) continue;
|
|
1586
|
-
const singular = singularize(candidateTable);
|
|
1587
|
-
const expectedColumn = pattern.replace("{singular}", singular);
|
|
1588
|
-
if (colName === expectedColumn) {
|
|
1589
|
-
fks.push({
|
|
1590
|
-
column: colName,
|
|
1591
|
-
targetTable: candidateTable,
|
|
1592
|
-
inferredName: singular,
|
|
1593
|
-
explicit: false,
|
|
1594
|
-
targetColumn: "id"
|
|
1595
|
-
});
|
|
1596
|
-
break;
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1599
|
-
if (colName.endsWith("Id")) {
|
|
1600
|
-
const prefix = colName.slice(0, -2);
|
|
1601
|
-
const singular = singularize(tableName);
|
|
1602
|
-
if (["parent", "manager", "supervisor", "owner", singular].includes(prefix)) {
|
|
1603
|
-
if (!fks.some((fk) => fk.column === colName)) {
|
|
1604
|
-
fks.push({
|
|
1605
|
-
column: colName,
|
|
1606
|
-
targetTable: tableName,
|
|
1607
|
-
inferredName: prefix,
|
|
1608
|
-
explicit: false,
|
|
1609
|
-
targetColumn: "id",
|
|
1610
|
-
// Auto-infer roles for convention-based self-ref FKs
|
|
1611
|
-
parentRole: prefix,
|
|
1612
|
-
childRole: getSelfRefInverseName(prefix)
|
|
1613
|
-
});
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
return fks;
|
|
1619
|
-
}
|
|
1620
|
-
function isBusinessColumn(colName, colDef, timestamps) {
|
|
1621
|
-
if (colDef.primaryKey) return false;
|
|
1622
|
-
if (timestamps.includes(colName)) return false;
|
|
1623
|
-
if (colDef.references) return false;
|
|
1624
|
-
if (colName.endsWith("Id")) return false;
|
|
1625
|
-
if (["id", "createdBy", "updatedBy", "deletedAt"].includes(colName))
|
|
1626
|
-
return false;
|
|
1627
|
-
return true;
|
|
1628
|
-
}
|
|
1629
|
-
function detectManyToMany(tables, conventions, tableNames) {
|
|
1630
|
-
const results = [];
|
|
1631
|
-
for (const [tableName, table] of Object.entries(tables)) {
|
|
1632
|
-
const fks = detectForeignKeys(tableName, table, conventions, tableNames);
|
|
1633
|
-
if (fks.length !== 2) continue;
|
|
1634
|
-
const hasBusinessColumns = Object.entries(table).some(
|
|
1635
|
-
([colName, colDef]) => isBusinessColumn(colName, colDef, conventions.timestamps)
|
|
1636
|
-
);
|
|
1637
|
-
if (hasBusinessColumns) continue;
|
|
1638
|
-
const fkA = fks[0];
|
|
1639
|
-
const fkB = fks[1];
|
|
1640
|
-
if (fkA && fkB) {
|
|
1641
|
-
results.push({
|
|
1642
|
-
junction: tableName,
|
|
1643
|
-
tableA: fkA.targetTable,
|
|
1644
|
-
tableB: fkB.targetTable,
|
|
1645
|
-
fkA: fkA.column,
|
|
1646
|
-
fkB: fkB.column
|
|
1647
|
-
});
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
return results;
|
|
1651
|
-
}
|
|
1652
|
-
function inferRelationsFromSchema(tables, conventions, explicitRelations = {}) {
|
|
1653
|
-
const result = { ...explicitRelations };
|
|
1654
|
-
const tableNames = new Set(Object.keys(tables));
|
|
1655
|
-
const manyToManys = detectManyToMany(tables, conventions, tableNames);
|
|
1656
|
-
const junctionTables = new Set(manyToManys.map((m) => m.junction));
|
|
1657
|
-
for (const m2m of manyToManys) {
|
|
1658
|
-
const { junction, tableA, tableB, fkA, fkB } = m2m;
|
|
1659
|
-
const relNameAtoB = conventions.pluralize ? pluralize(singularize(tableB)) : tableB;
|
|
1660
|
-
const relNameBtoA = conventions.pluralize ? pluralize(singularize(tableA)) : tableA;
|
|
1661
|
-
const keyAtoB = `${tableA}.${relNameAtoB}`;
|
|
1662
|
-
const keyBtoA = `${tableB}.${relNameBtoA}`;
|
|
1663
|
-
if (!(keyAtoB in result)) {
|
|
1664
|
-
const rel = {
|
|
1665
|
-
kind: "manyToMany",
|
|
1666
|
-
target: tableB,
|
|
1667
|
-
through: junction,
|
|
1668
|
-
sourceFk: fkA,
|
|
1669
|
-
targetFk: fkB
|
|
1670
|
-
};
|
|
1671
|
-
result[keyAtoB] = rel;
|
|
1672
|
-
}
|
|
1673
|
-
if (!(keyBtoA in result)) {
|
|
1674
|
-
const rel = {
|
|
1675
|
-
kind: "manyToMany",
|
|
1676
|
-
target: tableA,
|
|
1677
|
-
through: junction,
|
|
1678
|
-
sourceFk: fkB,
|
|
1679
|
-
targetFk: fkA
|
|
1680
|
-
};
|
|
1681
|
-
result[keyBtoA] = rel;
|
|
1682
|
-
}
|
|
1683
|
-
}
|
|
1684
|
-
for (const [tableName, table] of Object.entries(tables)) {
|
|
1685
|
-
if (junctionTables.has(tableName)) continue;
|
|
1686
|
-
const fks = detectForeignKeys(tableName, table, conventions, tableNames);
|
|
1687
|
-
for (const fk of fks) {
|
|
1688
|
-
if (junctionTables.has(fk.targetTable)) continue;
|
|
1689
|
-
const belongsToKey = `${tableName}.${fk.inferredName}`;
|
|
1690
|
-
if (!(belongsToKey in result)) {
|
|
1691
|
-
const rel = {
|
|
1692
|
-
kind: "belongsTo",
|
|
1693
|
-
target: fk.targetTable,
|
|
1694
|
-
foreignKey: fk.column,
|
|
1695
|
-
targetKey: fk.targetColumn
|
|
1696
|
-
};
|
|
1697
|
-
result[belongsToKey] = rel;
|
|
1698
|
-
}
|
|
1699
|
-
const isSelfRef = fk.targetTable === tableName;
|
|
1700
|
-
const hasManyName = isSelfRef ? getSelfRefInverseName(fk.inferredName) : (() => {
|
|
1701
|
-
const hasCustomAlias = fk.inferredName !== singularize(fk.targetTable);
|
|
1702
|
-
if (hasCustomAlias) {
|
|
1703
|
-
return conventions.pluralize ? pluralize(fk.inferredName) : fk.inferredName;
|
|
1704
|
-
}
|
|
1705
|
-
return conventions.pluralize ? pluralize(singularize(tableName)) : tableName;
|
|
1706
|
-
})();
|
|
1707
|
-
const hasManyKey = `${fk.targetTable}.${hasManyName}`;
|
|
1708
|
-
if (!(hasManyKey in result)) {
|
|
1709
|
-
const rel = {
|
|
1710
|
-
kind: "hasMany",
|
|
1711
|
-
target: tableName,
|
|
1712
|
-
foreignKey: fk.column,
|
|
1713
|
-
sourceKey: "id"
|
|
1714
|
-
};
|
|
1715
|
-
result[hasManyKey] = rel;
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1719
|
-
return result;
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
// src/schema-dsl.ts
|
|
1723
|
-
function defineSchema(tables, config) {
|
|
1724
|
-
const relations = config?.relations ?? {};
|
|
1725
|
-
const hints = config?.hints ?? {};
|
|
1726
|
-
const conventions = config?.conventions ?? {};
|
|
1727
|
-
const indexes = config?.indexes ?? {};
|
|
1728
|
-
const defaultFilters = config?.defaultFilters ?? {};
|
|
1729
|
-
const resolvedConventions = {
|
|
1730
|
-
...DEFAULT_CONVENTIONS,
|
|
1731
|
-
...conventions
|
|
1732
|
-
};
|
|
1733
|
-
const allRelations = inferRelationsFromSchema(
|
|
1734
|
-
tables,
|
|
1735
|
-
resolvedConventions,
|
|
1736
|
-
relations
|
|
1737
|
-
);
|
|
1738
|
-
validateRelations(tables, relations);
|
|
1739
|
-
validateHints(allRelations, hints);
|
|
1740
|
-
validateDefaultFilters(tables, defaultFilters);
|
|
1741
|
-
return {
|
|
1742
|
-
tables,
|
|
1743
|
-
relations: allRelations,
|
|
1744
|
-
hints,
|
|
1745
|
-
conventions: resolvedConventions,
|
|
1746
|
-
indexes,
|
|
1747
|
-
defaultFilters
|
|
1748
|
-
};
|
|
1749
|
-
}
|
|
1750
|
-
function validateRelations(tables, relations) {
|
|
1751
|
-
const tableNames = new Set(Object.keys(tables));
|
|
1752
|
-
for (const [key, rel] of Object.entries(relations)) {
|
|
1753
|
-
const sourceTable = key.split(".")[0] ?? key;
|
|
1754
|
-
if (!tableNames.has(sourceTable)) {
|
|
1755
|
-
throw new SchemaValidationError2(
|
|
1756
|
-
`Relation '${key}' references non-existent source table '${sourceTable}'`
|
|
1757
|
-
);
|
|
1758
|
-
}
|
|
1759
|
-
if (!tableNames.has(rel.target)) {
|
|
1760
|
-
throw new SchemaValidationError2(
|
|
1761
|
-
`Relation '${key}' references non-existent target table '${rel.target}'`
|
|
1762
|
-
);
|
|
1763
|
-
}
|
|
1764
|
-
if (rel.kind === "manyToMany" && !tableNames.has(rel.through)) {
|
|
1765
|
-
throw new SchemaValidationError2(
|
|
1766
|
-
`Relation '${key}' references non-existent junction table '${rel.through}'`
|
|
1767
|
-
);
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
}
|
|
1771
|
-
function validateHints(relations, hints) {
|
|
1772
|
-
for (const path of Object.keys(hints)) {
|
|
1773
|
-
if (!(path in relations)) {
|
|
1774
|
-
throw new SchemaValidationError2(
|
|
1775
|
-
`Hint path '${path}' does not match any relation. Available: ${Object.keys(relations).join(", ")}`
|
|
1776
|
-
);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
function validateDefaultFilters(tables, defaultFilters) {
|
|
1781
|
-
const tableNames = new Set(Object.keys(tables));
|
|
1782
|
-
for (const tableName of Object.keys(defaultFilters)) {
|
|
1783
|
-
if (!tableNames.has(tableName)) {
|
|
1784
|
-
throw new SchemaValidationError2(
|
|
1785
|
-
`Default filter for non-existent table '${tableName}'. Available: ${[...tableNames].join(", ")}`
|
|
1786
|
-
);
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
var SchemaValidationError2 = class extends Error {
|
|
1791
|
-
constructor(message) {
|
|
1792
|
-
super(message);
|
|
1793
|
-
this.name = "SchemaValidationError";
|
|
1794
|
-
}
|
|
1795
|
-
};
|
|
1796
|
-
|
|
1797
|
-
// src/schema-dsl-types.ts
|
|
1798
|
-
function isBelongsTo(rel) {
|
|
1799
|
-
return rel.kind === "belongsTo";
|
|
1800
|
-
}
|
|
1801
|
-
function isHasMany(rel) {
|
|
1802
|
-
return rel.kind === "hasMany";
|
|
1803
|
-
}
|
|
1804
|
-
function isManyToMany(rel) {
|
|
1805
|
-
return rel.kind === "manyToMany";
|
|
1806
|
-
}
|
|
1807
1562
|
|
|
1808
1563
|
// src/planner.ts
|
|
1809
1564
|
import { resolveJsonAggOrderKey, toColumnList } from "@dbsp/types";
|
|
@@ -3191,13 +2946,13 @@ function supportsExecution(adapter) {
|
|
|
3191
2946
|
return "execute" in adapter && "executeOne" in adapter && typeof adapter.execute === "function";
|
|
3192
2947
|
}
|
|
3193
2948
|
function supportsStreaming(adapter) {
|
|
3194
|
-
return "stream" in adapter && typeof adapter.stream === "function";
|
|
2949
|
+
return adapter.capabilities?.supportsStreaming === true && "stream" in adapter && typeof adapter.stream === "function";
|
|
3195
2950
|
}
|
|
3196
2951
|
function supportsIntrospection(adapter) {
|
|
3197
2952
|
return "introspect" in adapter && typeof adapter.introspect === "function";
|
|
3198
2953
|
}
|
|
3199
2954
|
function supportsTransactions(adapter) {
|
|
3200
|
-
return "transaction" in adapter && "withSchema" in adapter && typeof adapter.transaction === "function";
|
|
2955
|
+
return adapter.capabilities?.supportsTransactions === true && "transaction" in adapter && "withSchema" in adapter && typeof adapter.transaction === "function";
|
|
3201
2956
|
}
|
|
3202
2957
|
function supportsRawSql(adapter) {
|
|
3203
2958
|
return "executeRaw" in adapter && typeof adapter.executeRaw === "function";
|
|
@@ -6426,7 +6181,7 @@ function hydrateJsonAggIncludes(results, planReport) {
|
|
|
6426
6181
|
if (typeof row !== "object" || row === null) {
|
|
6427
6182
|
continue;
|
|
6428
6183
|
}
|
|
6429
|
-
const
|
|
6184
|
+
const record = row;
|
|
6430
6185
|
for (const [relationName, info] of relationInfo) {
|
|
6431
6186
|
const candidates = [relationName];
|
|
6432
6187
|
if (info.includeAlias && info.includeAlias !== relationName) {
|
|
@@ -6439,17 +6194,17 @@ function hydrateJsonAggIncludes(results, planReport) {
|
|
|
6439
6194
|
/_([a-z])/g,
|
|
6440
6195
|
(_, c) => c.toUpperCase()
|
|
6441
6196
|
);
|
|
6442
|
-
if (snakeJson in
|
|
6197
|
+
if (snakeJson in record) {
|
|
6443
6198
|
actualColumnName = snakeJson;
|
|
6444
6199
|
break;
|
|
6445
6200
|
}
|
|
6446
|
-
if (camelJson in
|
|
6201
|
+
if (camelJson in record) {
|
|
6447
6202
|
actualColumnName = camelJson;
|
|
6448
6203
|
break;
|
|
6449
6204
|
}
|
|
6450
6205
|
}
|
|
6451
6206
|
if (actualColumnName) {
|
|
6452
|
-
const jsonValue =
|
|
6207
|
+
const jsonValue = record[actualColumnName];
|
|
6453
6208
|
let parsed;
|
|
6454
6209
|
if (typeof jsonValue === "string") {
|
|
6455
6210
|
try {
|
|
@@ -6468,8 +6223,8 @@ function hydrateJsonAggIncludes(results, planReport) {
|
|
|
6468
6223
|
parsed = parsed.length > 0 ? parsed[0] : null;
|
|
6469
6224
|
}
|
|
6470
6225
|
const outputKey = info.includeAlias ?? relationName;
|
|
6471
|
-
|
|
6472
|
-
delete
|
|
6226
|
+
record[outputKey] = parsed;
|
|
6227
|
+
delete record[actualColumnName];
|
|
6473
6228
|
}
|
|
6474
6229
|
}
|
|
6475
6230
|
}
|
|
@@ -8398,12 +8153,12 @@ var ResultHydrator = class {
|
|
|
8398
8153
|
if (typeof row !== "object" || row === null) {
|
|
8399
8154
|
continue;
|
|
8400
8155
|
}
|
|
8401
|
-
const
|
|
8156
|
+
const record = row;
|
|
8402
8157
|
const valuesByPath = /* @__PURE__ */ new Map();
|
|
8403
|
-
for (const key of Object.keys(
|
|
8158
|
+
for (const key of Object.keys(record)) {
|
|
8404
8159
|
const info = findLongestJoinInfo(key, joinInfos);
|
|
8405
8160
|
if (!info) continue;
|
|
8406
|
-
const value =
|
|
8161
|
+
const value = record[key];
|
|
8407
8162
|
let entry = valuesByPath.get(info.relationPath);
|
|
8408
8163
|
if (!entry) {
|
|
8409
8164
|
entry = { values: {}, allNull: true };
|
|
@@ -8415,13 +8170,13 @@ var ResultHydrator = class {
|
|
|
8415
8170
|
value
|
|
8416
8171
|
);
|
|
8417
8172
|
if (value !== null && value !== void 0) entry.allNull = false;
|
|
8418
|
-
delete
|
|
8173
|
+
delete record[key];
|
|
8419
8174
|
}
|
|
8420
8175
|
for (const info of infosByDepth) {
|
|
8421
8176
|
const entry = valuesByPath.get(info.relationPath);
|
|
8422
8177
|
if (!entry) continue;
|
|
8423
8178
|
assignNestedValue(
|
|
8424
|
-
|
|
8179
|
+
record,
|
|
8425
8180
|
info.segments,
|
|
8426
8181
|
entry.allNull ? null : entry.values
|
|
8427
8182
|
);
|
|
@@ -8651,10 +8406,10 @@ var ResultHydrator = class {
|
|
|
8651
8406
|
return obj[columns[0]];
|
|
8652
8407
|
}
|
|
8653
8408
|
const values = columns.map((k) => obj[k]);
|
|
8654
|
-
if (values.some((
|
|
8409
|
+
if (values.some((v) => v === void 0 || v === null)) {
|
|
8655
8410
|
return void 0;
|
|
8656
8411
|
}
|
|
8657
|
-
const parts = values.map((
|
|
8412
|
+
const parts = values.map((v) => String(v));
|
|
8658
8413
|
if (parts.some((p) => p.includes(COMPOSITE_KEY_SEP))) {
|
|
8659
8414
|
return JSON.stringify(parts);
|
|
8660
8415
|
}
|
|
@@ -8669,7 +8424,7 @@ var ResultHydrator = class {
|
|
|
8669
8424
|
return obj[columns[0]];
|
|
8670
8425
|
}
|
|
8671
8426
|
const values = columns.map((k) => obj[k]);
|
|
8672
|
-
return values.some((
|
|
8427
|
+
return values.some((v) => v === void 0 || v === null) ? void 0 : values;
|
|
8673
8428
|
}
|
|
8674
8429
|
};
|
|
8675
8430
|
|
|
@@ -8763,6 +8518,13 @@ function buildSetOperationIntent(op2, all, left, right) {
|
|
|
8763
8518
|
}
|
|
8764
8519
|
|
|
8765
8520
|
// src/dx/stream-impl.ts
|
|
8521
|
+
function createUnsupportedStreamingError() {
|
|
8522
|
+
return new ExecutionError({
|
|
8523
|
+
operation: "stream()",
|
|
8524
|
+
reason: "The adapter declares supportsStreaming: false for this ORM instance.",
|
|
8525
|
+
fix: "Use an adapter configuration that supports streaming."
|
|
8526
|
+
});
|
|
8527
|
+
}
|
|
8766
8528
|
function stream(builder, options) {
|
|
8767
8529
|
const adapter = builder.getConfiguredAdapter();
|
|
8768
8530
|
const adapterOptions = options?.chunkSize !== void 0 ? { chunkSize: options.chunkSize } : void 0;
|
|
@@ -8782,6 +8544,9 @@ function stream(builder, options) {
|
|
|
8782
8544
|
return this;
|
|
8783
8545
|
},
|
|
8784
8546
|
async next() {
|
|
8547
|
+
if (!supportsStreaming(adapter)) {
|
|
8548
|
+
throw createUnsupportedStreamingError();
|
|
8549
|
+
}
|
|
8785
8550
|
if (!hooksFired) {
|
|
8786
8551
|
hooksFired = true;
|
|
8787
8552
|
if (hookStore && hasHooks(hookStore)) {
|
|
@@ -10323,6 +10088,31 @@ function generateVacuumSQL(tableName, schemaName, options) {
|
|
|
10323
10088
|
const mod = modifiers.length > 0 ? `(${modifiers.join(", ")}) ` : "";
|
|
10324
10089
|
return `VACUUM ${mod}${buildQualifiedTable(tableName, schemaName)}`;
|
|
10325
10090
|
}
|
|
10091
|
+
function createUnsupportedTransactionError() {
|
|
10092
|
+
return new ExecutionError({
|
|
10093
|
+
operation: "transaction()",
|
|
10094
|
+
reason: "The adapter does not declare capabilities.supportsTransactions: true for this ORM instance.",
|
|
10095
|
+
fix: "Use an adapter that implements transaction() and withSchema(), and declare adapter.capabilities.supportsTransactions: true."
|
|
10096
|
+
});
|
|
10097
|
+
}
|
|
10098
|
+
function adapterTransactionState(adapter, operation, statement) {
|
|
10099
|
+
const inTransaction = adapter.inTransaction;
|
|
10100
|
+
if (typeof inTransaction !== "boolean") {
|
|
10101
|
+
throw new InvalidOperationError(
|
|
10102
|
+
operation,
|
|
10103
|
+
`${statement} requires an adapter that exposes inTransaction: boolean; dbsp refuses to run it when transaction state is unknown.`
|
|
10104
|
+
);
|
|
10105
|
+
}
|
|
10106
|
+
return inTransaction;
|
|
10107
|
+
}
|
|
10108
|
+
function assertOutsideTransaction(adapter, operation, statement) {
|
|
10109
|
+
if (adapterTransactionState(adapter, operation, statement)) {
|
|
10110
|
+
throw new InvalidOperationError(
|
|
10111
|
+
operation,
|
|
10112
|
+
`${statement} cannot run inside a transaction block`
|
|
10113
|
+
);
|
|
10114
|
+
}
|
|
10115
|
+
}
|
|
10326
10116
|
function generateAlterColumnSQL(tableName, column, schemaName, options) {
|
|
10327
10117
|
const tbl = buildQualifiedTable(tableName, schemaName);
|
|
10328
10118
|
const col2 = quoteIdent(column);
|
|
@@ -10382,7 +10172,7 @@ function generateCreateIndexSQL(tableName, schemaName, opts) {
|
|
|
10382
10172
|
parts.push("NULLS NOT DISTINCT");
|
|
10383
10173
|
}
|
|
10384
10174
|
if (opts.with && Object.keys(opts.with).length > 0) {
|
|
10385
|
-
const withClauses = Object.entries(opts.with).map(([k,
|
|
10175
|
+
const withClauses = Object.entries(opts.with).map(([k, v]) => `${k} = ${v}`).join(", ");
|
|
10386
10176
|
parts.push(`WITH (${withClauses})`);
|
|
10387
10177
|
}
|
|
10388
10178
|
if (opts.where) parts.push(`WHERE ${opts.where}`);
|
|
@@ -10401,24 +10191,19 @@ function buildIndexAPI(tableName, schemaName, adapter, requireAdapter2) {
|
|
|
10401
10191
|
return {
|
|
10402
10192
|
async create(opts) {
|
|
10403
10193
|
const a = requireAdapter2();
|
|
10404
|
-
if (opts.concurrently
|
|
10405
|
-
|
|
10406
|
-
"createIndex",
|
|
10407
|
-
"CREATE INDEX CONCURRENTLY cannot run inside a transaction block"
|
|
10408
|
-
);
|
|
10194
|
+
if (opts.concurrently) {
|
|
10195
|
+
assertOutsideTransaction(a, "createIndex", "CREATE INDEX CONCURRENTLY");
|
|
10409
10196
|
}
|
|
10410
10197
|
const sql2 = a.generateCreateIndex ? a.generateCreateIndex(tableName, opts, schemaName) : generateCreateIndexSQL(tableName, schemaName, opts);
|
|
10411
10198
|
await a.executeDDL?.(sql2);
|
|
10412
10199
|
},
|
|
10413
10200
|
async drop(name, options) {
|
|
10414
10201
|
const a = requireAdapter2();
|
|
10415
|
-
if (options?.concurrently
|
|
10416
|
-
|
|
10417
|
-
"dropIndex",
|
|
10418
|
-
"DROP INDEX CONCURRENTLY cannot run inside a transaction block"
|
|
10419
|
-
);
|
|
10202
|
+
if (options?.concurrently) {
|
|
10203
|
+
assertOutsideTransaction(a, "dropIndex", "DROP INDEX CONCURRENTLY");
|
|
10420
10204
|
}
|
|
10421
|
-
const
|
|
10205
|
+
const scopedOptions = schemaName ? { ...options, schema: options?.schema ?? schemaName } : options;
|
|
10206
|
+
const sql2 = a.generateDropIndex ? a.generateDropIndex(name, scopedOptions) : generateDropIndexSQL(name, schemaName, options);
|
|
10422
10207
|
await a.executeDDL?.(sql2);
|
|
10423
10208
|
},
|
|
10424
10209
|
async list(options) {
|
|
@@ -10471,12 +10256,7 @@ function buildTableDDL(tableName, schemaName, adapter) {
|
|
|
10471
10256
|
},
|
|
10472
10257
|
async vacuum(options) {
|
|
10473
10258
|
const a = requireAdapter2();
|
|
10474
|
-
|
|
10475
|
-
throw new InvalidOperationError(
|
|
10476
|
-
"vacuum",
|
|
10477
|
-
"VACUUM cannot run inside a transaction block"
|
|
10478
|
-
);
|
|
10479
|
-
}
|
|
10259
|
+
assertOutsideTransaction(a, "vacuum", "VACUUM");
|
|
10480
10260
|
const sql2 = a.generateVacuum ? a.generateVacuum(tableName, schemaName, options) : generateVacuumSQL(tableName, schemaName, options);
|
|
10481
10261
|
await a.executeDDL?.(sql2);
|
|
10482
10262
|
},
|
|
@@ -10808,31 +10588,47 @@ function createOrmInstance(model, strictMode, relationHints, adapter, schemaName
|
|
|
10808
10588
|
// =====================================================================
|
|
10809
10589
|
// Transaction Methods (DX-025)
|
|
10810
10590
|
// =====================================================================
|
|
10811
|
-
async
|
|
10591
|
+
// NOT `async`, and that is load-bearing. An async method awaits whatever it
|
|
10592
|
+
// returns and re-wraps it in a fresh Promise — which would mean the language
|
|
10593
|
+
// itself attaches to the adapter's promise, and an adapter that needs to know
|
|
10594
|
+
// whether the CALLER awaited a nested transaction would see every one of them
|
|
10595
|
+
// as awaited, by core, before the caller ever touched it. So the adapter's
|
|
10596
|
+
// promise is passed through untouched. The guards still reject rather than
|
|
10597
|
+
// throwing synchronously, because that is what callers already rely on.
|
|
10598
|
+
transaction(fn2) {
|
|
10812
10599
|
if (!adapter) {
|
|
10813
|
-
|
|
10814
|
-
|
|
10600
|
+
return Promise.reject(
|
|
10601
|
+
new Error(
|
|
10602
|
+
"transaction() requires an adapter. Pass an adapter when creating the ORM."
|
|
10603
|
+
)
|
|
10815
10604
|
);
|
|
10816
10605
|
}
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10606
|
+
if (!supportsTransactions(adapter)) {
|
|
10607
|
+
return Promise.reject(createUnsupportedTransactionError());
|
|
10608
|
+
}
|
|
10609
|
+
try {
|
|
10610
|
+
return adapter.transaction(async (txAdapter) => {
|
|
10611
|
+
const txOrm = createOrmInstance(
|
|
10612
|
+
model,
|
|
10613
|
+
strictMode,
|
|
10614
|
+
relationHints,
|
|
10615
|
+
txAdapter,
|
|
10616
|
+
schemaName,
|
|
10617
|
+
dialectCapabilities,
|
|
10618
|
+
schemaDefinition,
|
|
10619
|
+
globalPlanOptions,
|
|
10620
|
+
defaultFilters,
|
|
10621
|
+
hookStore,
|
|
10622
|
+
onHookError,
|
|
10623
|
+
true,
|
|
10624
|
+
// inTransaction
|
|
10625
|
+
tablesProxy
|
|
10626
|
+
);
|
|
10627
|
+
return fn2(txOrm);
|
|
10628
|
+
});
|
|
10629
|
+
} catch (error) {
|
|
10630
|
+
return Promise.reject(error);
|
|
10631
|
+
}
|
|
10836
10632
|
},
|
|
10837
10633
|
// =====================================================================
|
|
10838
10634
|
// Raw SQL Execution (DX-027)
|
|
@@ -10911,12 +10707,20 @@ function createOrmInstance(model, strictMode, relationHints, adapter, schemaName
|
|
|
10911
10707
|
"executeDDL() requires an adapter that supports DDL execution."
|
|
10912
10708
|
);
|
|
10913
10709
|
}
|
|
10710
|
+
if (options?.concurrently) {
|
|
10711
|
+
assertOutsideTransaction(
|
|
10712
|
+
adapter,
|
|
10713
|
+
"dropIndex",
|
|
10714
|
+
"DROP INDEX CONCURRENTLY"
|
|
10715
|
+
);
|
|
10716
|
+
}
|
|
10914
10717
|
validateIdentifier(name, "index");
|
|
10915
10718
|
const sc = options?.schema ?? schemaName;
|
|
10916
10719
|
if (sc) {
|
|
10917
10720
|
validateIdentifier(sc, "schema");
|
|
10918
10721
|
}
|
|
10919
|
-
const
|
|
10722
|
+
const scopedOptions = sc ? { ...options, schema: sc } : options;
|
|
10723
|
+
const sql2 = adapter.generateDropIndex ? adapter.generateDropIndex(name, scopedOptions) : (() => {
|
|
10920
10724
|
const parts = ["DROP INDEX"];
|
|
10921
10725
|
if (options?.concurrently) parts.push("CONCURRENTLY");
|
|
10922
10726
|
if (options?.ifExists) parts.push("IF EXISTS");
|
|
@@ -11056,729 +10860,6 @@ function rangeContainedBy(fieldOrColumn, valueOrRange, rangeType = "daterange")
|
|
|
11056
10860
|
};
|
|
11057
10861
|
}
|
|
11058
10862
|
|
|
11059
|
-
// src/dx/schema-bridge.ts
|
|
11060
|
-
import { buildRelationKeyFields, toColumnList as toColumnList3 } from "@dbsp/types";
|
|
11061
|
-
import * as v from "valibot";
|
|
11062
|
-
function normalizeReferenceSchema2(schemaName) {
|
|
11063
|
-
if (schemaName == null) return void 0;
|
|
11064
|
-
const t = schemaName.trim();
|
|
11065
|
-
return t.length > 0 ? t : void 0;
|
|
11066
|
-
}
|
|
11067
|
-
function hasExternalSchema3(schemaName) {
|
|
11068
|
-
return normalizeReferenceSchema2(schemaName) !== void 0;
|
|
11069
|
-
}
|
|
11070
|
-
function generatedTypeToColumnType(genType) {
|
|
11071
|
-
switch (genType) {
|
|
11072
|
-
case "string":
|
|
11073
|
-
case "text":
|
|
11074
|
-
return "string";
|
|
11075
|
-
case "number":
|
|
11076
|
-
case "decimal":
|
|
11077
|
-
return "number";
|
|
11078
|
-
case "integer":
|
|
11079
|
-
return "integer";
|
|
11080
|
-
case "bigint":
|
|
11081
|
-
return "bigint";
|
|
11082
|
-
case "boolean":
|
|
11083
|
-
return "boolean";
|
|
11084
|
-
case "date":
|
|
11085
|
-
return "date";
|
|
11086
|
-
case "timestamp":
|
|
11087
|
-
case "datetime":
|
|
11088
|
-
return "datetime";
|
|
11089
|
-
case "json":
|
|
11090
|
-
return "json";
|
|
11091
|
-
case "jsonb":
|
|
11092
|
-
return "jsonb";
|
|
11093
|
-
case "time":
|
|
11094
|
-
return "time";
|
|
11095
|
-
case "uuid":
|
|
11096
|
-
return "uuid";
|
|
11097
|
-
case "daterange":
|
|
11098
|
-
return "daterange";
|
|
11099
|
-
case "tstzrange":
|
|
11100
|
-
return "tstzrange";
|
|
11101
|
-
case "int4range":
|
|
11102
|
-
return "int4range";
|
|
11103
|
-
case "tsrange":
|
|
11104
|
-
return "tsrange";
|
|
11105
|
-
case "int8range":
|
|
11106
|
-
return "int8range";
|
|
11107
|
-
case "numrange":
|
|
11108
|
-
return "numrange";
|
|
11109
|
-
}
|
|
11110
|
-
}
|
|
11111
|
-
function mapRelationType2(kind) {
|
|
11112
|
-
switch (kind) {
|
|
11113
|
-
case "belongsTo":
|
|
11114
|
-
return "belongsTo";
|
|
11115
|
-
case "hasMany":
|
|
11116
|
-
return "hasMany";
|
|
11117
|
-
case "manyToMany":
|
|
11118
|
-
return "belongsToMany";
|
|
11119
|
-
}
|
|
11120
|
-
}
|
|
11121
|
-
function sourceTableFromQualifiedName(qualifiedName) {
|
|
11122
|
-
const dotIndex = qualifiedName.indexOf(".");
|
|
11123
|
-
return dotIndex > 0 ? qualifiedName.slice(0, dotIndex) : qualifiedName;
|
|
11124
|
-
}
|
|
11125
|
-
function relationNameFromQualifiedName(qualifiedName) {
|
|
11126
|
-
const dotIndex = qualifiedName.indexOf(".");
|
|
11127
|
-
return dotIndex > 0 ? qualifiedName.slice(dotIndex + 1) : qualifiedName;
|
|
11128
|
-
}
|
|
11129
|
-
function columnListsEqual(left, right) {
|
|
11130
|
-
const leftColumns = toColumnList3(left);
|
|
11131
|
-
const rightColumns = toColumnList3(right);
|
|
11132
|
-
return leftColumns.length === rightColumns.length && leftColumns.every((column, index) => column === rightColumns[index]);
|
|
11133
|
-
}
|
|
11134
|
-
function generatedReferencedColumns(key) {
|
|
11135
|
-
const columns = toColumnList3(key);
|
|
11136
|
-
return columns.length > 0 ? columns : ["id"];
|
|
11137
|
-
}
|
|
11138
|
-
function findRelationForeignKey(sourceTable, genRelation, tables) {
|
|
11139
|
-
switch (genRelation.kind) {
|
|
11140
|
-
case "belongsTo":
|
|
11141
|
-
return tables.get(sourceTable)?.foreignKeys.find(
|
|
11142
|
-
(fk) => !hasExternalSchema3(fk.references.schema) && fk.references.table === genRelation.target && columnListsEqual(fk.columns, genRelation.foreignKey)
|
|
11143
|
-
);
|
|
11144
|
-
case "hasMany":
|
|
11145
|
-
return tables.get(genRelation.target)?.foreignKeys.find(
|
|
11146
|
-
(fk) => !hasExternalSchema3(fk.references.schema) && fk.references.table === sourceTable && columnListsEqual(fk.columns, genRelation.foreignKey)
|
|
11147
|
-
);
|
|
11148
|
-
case "manyToMany":
|
|
11149
|
-
return void 0;
|
|
11150
|
-
}
|
|
11151
|
-
}
|
|
11152
|
-
function isGeneratedTableWithConfig(table) {
|
|
11153
|
-
const columns = table.columns;
|
|
11154
|
-
return typeof columns === "object" && columns !== null && typeof columns.type !== "string";
|
|
11155
|
-
}
|
|
11156
|
-
function buildTableIRFromDefinition(tableName, genTable, fkAutoIndex) {
|
|
11157
|
-
const columns = [];
|
|
11158
|
-
const foreignKeys = [];
|
|
11159
|
-
const indexes = [];
|
|
11160
|
-
const primaryKeys = [];
|
|
11161
|
-
const tableColumns = isGeneratedTableWithConfig(genTable) ? genTable.columns : genTable;
|
|
11162
|
-
const indexedColumns = /* @__PURE__ */ new Set();
|
|
11163
|
-
for (const [colName, colDef] of Object.entries(tableColumns)) {
|
|
11164
|
-
const col2 = {
|
|
11165
|
-
name: colName,
|
|
11166
|
-
type: generatedTypeToColumnType(colDef.type),
|
|
11167
|
-
nullable: colDef.nullable ?? false,
|
|
11168
|
-
default: colDef.default
|
|
11169
|
-
};
|
|
11170
|
-
if (colDef.unique !== void 0) {
|
|
11171
|
-
col2.unique = colDef.unique;
|
|
11172
|
-
}
|
|
11173
|
-
if (colDef.autoIncrement !== void 0) {
|
|
11174
|
-
col2.autoIncrement = colDef.autoIncrement;
|
|
11175
|
-
}
|
|
11176
|
-
columns.push(col2);
|
|
11177
|
-
if (colDef.primaryKey) {
|
|
11178
|
-
primaryKeys.push(colName);
|
|
11179
|
-
}
|
|
11180
|
-
if (colDef.references) {
|
|
11181
|
-
const externalSchema = normalizeReferenceSchema2(colDef.references.schema);
|
|
11182
|
-
const fk = {
|
|
11183
|
-
columns: [colName],
|
|
11184
|
-
references: {
|
|
11185
|
-
table: colDef.references.table,
|
|
11186
|
-
columns: [colDef.references.column ?? "id"],
|
|
11187
|
-
...externalSchema !== void 0 ? { schema: externalSchema } : {}
|
|
11188
|
-
}
|
|
11189
|
-
};
|
|
11190
|
-
if (colDef.references.onDelete) {
|
|
11191
|
-
fk.onDelete = colDef.references.onDelete;
|
|
11192
|
-
}
|
|
11193
|
-
foreignKeys.push(fk);
|
|
11194
|
-
}
|
|
11195
|
-
if (colDef.index) {
|
|
11196
|
-
const indexName = typeof colDef.index === "string" ? colDef.index : `idx_${tableName}_${colName}`;
|
|
11197
|
-
indexes.push({
|
|
11198
|
-
name: indexName,
|
|
11199
|
-
columns: [colName],
|
|
11200
|
-
unique: false
|
|
11201
|
-
});
|
|
11202
|
-
indexedColumns.add(colName);
|
|
11203
|
-
}
|
|
11204
|
-
if (fkAutoIndex && colDef.references && !colDef.index) {
|
|
11205
|
-
indexes.push({
|
|
11206
|
-
name: `idx_${tableName}_${colName}`,
|
|
11207
|
-
columns: [colName],
|
|
11208
|
-
unique: false
|
|
11209
|
-
});
|
|
11210
|
-
indexedColumns.add(colName);
|
|
11211
|
-
}
|
|
11212
|
-
}
|
|
11213
|
-
const pseudoColumns = [];
|
|
11214
|
-
for (const fk of foreignKeys) {
|
|
11215
|
-
const fkColumn = fk.columns[0];
|
|
11216
|
-
const targetColumn = fk.references.columns[0];
|
|
11217
|
-
if (fk.references.table === tableName && !hasExternalSchema3(fk.references.schema) && fkColumn !== void 0 && targetColumn !== void 0) {
|
|
11218
|
-
const colDef = tableColumns[fkColumn];
|
|
11219
|
-
const inferredName = fkColumn.endsWith("Id") ? fkColumn.slice(0, -2) : "parent";
|
|
11220
|
-
const parentRole = colDef?.references?.parentRole ?? inferredName;
|
|
11221
|
-
const childRole = colDef?.references?.childRole ?? (parentRole === "parent" ? "children" : `${parentRole}s`);
|
|
11222
|
-
pseudoColumns.push(
|
|
11223
|
-
createPseudoColumnMetadata(
|
|
11224
|
-
tableName,
|
|
11225
|
-
fkColumn,
|
|
11226
|
-
targetColumn,
|
|
11227
|
-
parentRole,
|
|
11228
|
-
childRole
|
|
11229
|
-
)
|
|
11230
|
-
);
|
|
11231
|
-
}
|
|
11232
|
-
}
|
|
11233
|
-
let primaryKey;
|
|
11234
|
-
const configuredPrimaryKey = isGeneratedTableWithConfig(genTable) ? genTable.primaryKey : void 0;
|
|
11235
|
-
if (configuredPrimaryKey !== void 0) {
|
|
11236
|
-
primaryKey = configuredPrimaryKey;
|
|
11237
|
-
} else if (primaryKeys.length > 0) {
|
|
11238
|
-
primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : primaryKeys;
|
|
11239
|
-
} else {
|
|
11240
|
-
const fkColumns = foreignKeys.flatMap((fk) => fk.columns);
|
|
11241
|
-
if (fkColumns.length > 0) {
|
|
11242
|
-
primaryKey = fkColumns.length === 1 ? fkColumns[0] : fkColumns;
|
|
11243
|
-
} else {
|
|
11244
|
-
const hasId = columns.some((c) => c.name === "id");
|
|
11245
|
-
primaryKey = hasId ? "id" : void 0;
|
|
11246
|
-
}
|
|
11247
|
-
}
|
|
11248
|
-
if (isGeneratedTableWithConfig(genTable)) {
|
|
11249
|
-
for (const fk of genTable.foreignKeys ?? []) {
|
|
11250
|
-
const externalSchema = normalizeReferenceSchema2(fk.references.schema);
|
|
11251
|
-
const foreignKey = {
|
|
11252
|
-
columns: [...fk.columns],
|
|
11253
|
-
references: {
|
|
11254
|
-
table: fk.references.table,
|
|
11255
|
-
columns: [...fk.references.columns],
|
|
11256
|
-
...externalSchema !== void 0 ? { schema: externalSchema } : {}
|
|
11257
|
-
}
|
|
11258
|
-
};
|
|
11259
|
-
if (fk.onDelete) foreignKey.onDelete = fk.onDelete;
|
|
11260
|
-
if (fk.onUpdate) foreignKey.onUpdate = fk.onUpdate;
|
|
11261
|
-
foreignKeys.push(foreignKey);
|
|
11262
|
-
}
|
|
11263
|
-
for (const index of genTable.indexes ?? []) {
|
|
11264
|
-
indexes.push({
|
|
11265
|
-
columns: [...index.columns],
|
|
11266
|
-
unique: index.unique ?? false,
|
|
11267
|
-
...index.name !== void 0 && { name: index.name }
|
|
11268
|
-
});
|
|
11269
|
-
}
|
|
11270
|
-
}
|
|
11271
|
-
const frozenColumns = Object.freeze(columns);
|
|
11272
|
-
return Object.freeze({
|
|
11273
|
-
name: tableName,
|
|
11274
|
-
columns: frozenColumns,
|
|
11275
|
-
...primaryKey !== void 0 ? { primaryKey } : {},
|
|
11276
|
-
foreignKeys: Object.freeze(foreignKeys),
|
|
11277
|
-
indexes: Object.freeze(indexes),
|
|
11278
|
-
...pseudoColumns.length > 0 && {
|
|
11279
|
-
pseudoColumns: Object.freeze(pseudoColumns)
|
|
11280
|
-
}
|
|
11281
|
-
});
|
|
11282
|
-
}
|
|
11283
|
-
function buildRelationIR(qualifiedName, genRelation, hints, relationFk) {
|
|
11284
|
-
const sourceTable = sourceTableFromQualifiedName(qualifiedName);
|
|
11285
|
-
const relationName = relationNameFromQualifiedName(qualifiedName);
|
|
11286
|
-
const hint = hints[qualifiedName];
|
|
11287
|
-
const relCardinality = genRelation.kind === "hasMany" ? genRelation.cardinality : void 0;
|
|
11288
|
-
const cardinality = hint?.cardinality === "one" ? "one" : relCardinality === "one" ? "one" : genRelation.kind === "belongsTo" ? "one" : "many";
|
|
11289
|
-
const optionality = genRelation.kind === "belongsTo" ? "optional" : "optional";
|
|
11290
|
-
let relationType = mapRelationType2(genRelation.kind);
|
|
11291
|
-
if (genRelation.kind === "hasMany" && cardinality === "one") {
|
|
11292
|
-
relationType = "hasOne";
|
|
11293
|
-
}
|
|
11294
|
-
const baseRelation = {
|
|
11295
|
-
name: relationName,
|
|
11296
|
-
source: sourceTable,
|
|
11297
|
-
target: genRelation.target,
|
|
11298
|
-
type: relationType,
|
|
11299
|
-
cardinality,
|
|
11300
|
-
optionality,
|
|
11301
|
-
includeStrategy: genRelation.includeStrategy ?? "auto",
|
|
11302
|
-
filterStrategy: hint?.defaultStrategy ?? "auto",
|
|
11303
|
-
joinDefault: "auto"
|
|
11304
|
-
};
|
|
11305
|
-
switch (genRelation.kind) {
|
|
11306
|
-
case "belongsTo":
|
|
11307
|
-
return {
|
|
11308
|
-
...baseRelation,
|
|
11309
|
-
...buildRelationKeyFields(
|
|
11310
|
-
relationFk ?? {
|
|
11311
|
-
columns: genRelation.foreignKey,
|
|
11312
|
-
references: {
|
|
11313
|
-
table: genRelation.target,
|
|
11314
|
-
columns: generatedReferencedColumns(genRelation.targetKey)
|
|
11315
|
-
}
|
|
11316
|
-
},
|
|
11317
|
-
"belongsTo",
|
|
11318
|
-
{
|
|
11319
|
-
foreignKeyShape: genRelation.foreignKey,
|
|
11320
|
-
...genRelation.targetKey !== void 0 ? { referencedKeyShape: genRelation.targetKey } : {}
|
|
11321
|
-
}
|
|
11322
|
-
)
|
|
11323
|
-
};
|
|
11324
|
-
case "hasMany":
|
|
11325
|
-
return {
|
|
11326
|
-
...baseRelation,
|
|
11327
|
-
...buildRelationKeyFields(
|
|
11328
|
-
relationFk ?? {
|
|
11329
|
-
columns: genRelation.foreignKey,
|
|
11330
|
-
references: {
|
|
11331
|
-
table: sourceTable,
|
|
11332
|
-
columns: generatedReferencedColumns(genRelation.sourceKey)
|
|
11333
|
-
}
|
|
11334
|
-
},
|
|
11335
|
-
"inverse",
|
|
11336
|
-
{
|
|
11337
|
-
foreignKeyShape: genRelation.foreignKey,
|
|
11338
|
-
...genRelation.sourceKey !== void 0 ? { referencedKeyShape: genRelation.sourceKey } : {}
|
|
11339
|
-
}
|
|
11340
|
-
)
|
|
11341
|
-
};
|
|
11342
|
-
case "manyToMany":
|
|
11343
|
-
return {
|
|
11344
|
-
...baseRelation,
|
|
11345
|
-
through: genRelation.through,
|
|
11346
|
-
foreignKey: genRelation.sourceFk,
|
|
11347
|
-
otherKey: genRelation.targetFk
|
|
11348
|
-
};
|
|
11349
|
-
}
|
|
11350
|
-
}
|
|
11351
|
-
function buildModelFromSchema(schema2) {
|
|
11352
|
-
const tables = /* @__PURE__ */ new Map();
|
|
11353
|
-
const relations = /* @__PURE__ */ new Map();
|
|
11354
|
-
const fkAutoIndex = schema2.conventions.fkAutoIndex;
|
|
11355
|
-
for (const [tableName, genTable] of Object.entries(schema2.tables)) {
|
|
11356
|
-
tables.set(
|
|
11357
|
-
tableName,
|
|
11358
|
-
buildTableIRFromDefinition(tableName, genTable, fkAutoIndex)
|
|
11359
|
-
);
|
|
11360
|
-
}
|
|
11361
|
-
for (const [qualifiedName, genRelation] of Object.entries(schema2.relations)) {
|
|
11362
|
-
const sourceTable = sourceTableFromQualifiedName(qualifiedName);
|
|
11363
|
-
relations.set(
|
|
11364
|
-
qualifiedName,
|
|
11365
|
-
buildRelationIR(
|
|
11366
|
-
qualifiedName,
|
|
11367
|
-
genRelation,
|
|
11368
|
-
schema2.hints,
|
|
11369
|
-
findRelationForeignKey(sourceTable, genRelation, tables)
|
|
11370
|
-
)
|
|
11371
|
-
);
|
|
11372
|
-
}
|
|
11373
|
-
return new ModelIRImpl(tables, relations);
|
|
11374
|
-
}
|
|
11375
|
-
function buildModelFromResolvedSchema(schema2) {
|
|
11376
|
-
const generatedSchema = assertResolvedSchemaToGeneratedSchema(schema2);
|
|
11377
|
-
return buildModelFromSchema(generatedSchema);
|
|
11378
|
-
}
|
|
11379
|
-
function isGeneratedSchema(value) {
|
|
11380
|
-
if (typeof value !== "object" || value === null) {
|
|
11381
|
-
return false;
|
|
11382
|
-
}
|
|
11383
|
-
const obj = value;
|
|
11384
|
-
return typeof obj.tables === "object" && obj.tables !== null && typeof obj.relations === "object" && obj.relations !== null && typeof obj.hints === "object" && obj.hints !== null && typeof obj.conventions === "object" && obj.conventions !== null;
|
|
11385
|
-
}
|
|
11386
|
-
var RESOLVED_SCHEMA_ONLY_TYPES = /* @__PURE__ */ new Set(["time", "jsonb"]);
|
|
11387
|
-
var GENERATED_SCHEMA_ONLY_TYPES = /* @__PURE__ */ new Set(["number", "datetime"]);
|
|
11388
|
-
function hasResolvedSchemaOnlyTypes(tables) {
|
|
11389
|
-
for (const table of Object.values(tables)) {
|
|
11390
|
-
for (const column of Object.values(table)) {
|
|
11391
|
-
if (column?.type && RESOLVED_SCHEMA_ONLY_TYPES.has(column.type)) {
|
|
11392
|
-
return true;
|
|
11393
|
-
}
|
|
11394
|
-
}
|
|
11395
|
-
}
|
|
11396
|
-
return false;
|
|
11397
|
-
}
|
|
11398
|
-
function hasGeneratedSchemaOnlyTypes(tables) {
|
|
11399
|
-
for (const table of Object.values(tables)) {
|
|
11400
|
-
for (const column of Object.values(table)) {
|
|
11401
|
-
if (column?.type && GENERATED_SCHEMA_ONLY_TYPES.has(column.type)) {
|
|
11402
|
-
return true;
|
|
11403
|
-
}
|
|
11404
|
-
}
|
|
11405
|
-
}
|
|
11406
|
-
return false;
|
|
11407
|
-
}
|
|
11408
|
-
function isResolvedSchema(value) {
|
|
11409
|
-
if (!isGeneratedSchema(value)) {
|
|
11410
|
-
return false;
|
|
11411
|
-
}
|
|
11412
|
-
if (hasResolvedSchemaOnlyTypes(
|
|
11413
|
-
value.tables
|
|
11414
|
-
)) {
|
|
11415
|
-
return true;
|
|
11416
|
-
}
|
|
11417
|
-
if (hasGeneratedSchemaOnlyTypes(
|
|
11418
|
-
value.tables
|
|
11419
|
-
)) {
|
|
11420
|
-
return false;
|
|
11421
|
-
}
|
|
11422
|
-
return false;
|
|
11423
|
-
}
|
|
11424
|
-
function normalizeSchema(input) {
|
|
11425
|
-
if (!isGeneratedSchema(input)) {
|
|
11426
|
-
throw new Error(
|
|
11427
|
-
"Invalid schema: must have tables, relations, hints, and conventions properties"
|
|
11428
|
-
);
|
|
11429
|
-
}
|
|
11430
|
-
if (isResolvedSchema(input)) {
|
|
11431
|
-
const result = resolvedSchemaToGeneratedSchema(input);
|
|
11432
|
-
if (!result.success) {
|
|
11433
|
-
const messages = result.errors.map((e) => e.message).join(", ");
|
|
11434
|
-
throw new Error(`Schema conversion failed: ${messages}`);
|
|
11435
|
-
}
|
|
11436
|
-
return result.schema;
|
|
11437
|
-
}
|
|
11438
|
-
return input;
|
|
11439
|
-
}
|
|
11440
|
-
var SchemaColumnTypeSchema = v.picklist([
|
|
11441
|
-
"uuid",
|
|
11442
|
-
"string",
|
|
11443
|
-
"text",
|
|
11444
|
-
"integer",
|
|
11445
|
-
"bigint",
|
|
11446
|
-
"decimal",
|
|
11447
|
-
"boolean",
|
|
11448
|
-
"timestamp",
|
|
11449
|
-
"date",
|
|
11450
|
-
"time",
|
|
11451
|
-
"json",
|
|
11452
|
-
"jsonb",
|
|
11453
|
-
"daterange",
|
|
11454
|
-
"tstzrange",
|
|
11455
|
-
"int4range",
|
|
11456
|
-
"tsrange",
|
|
11457
|
-
"int8range",
|
|
11458
|
-
"numrange"
|
|
11459
|
-
]);
|
|
11460
|
-
var PROTO_POLLUTION_KEYS = ["__proto__", "constructor", "prototype"];
|
|
11461
|
-
function safeRecord(valueSchema) {
|
|
11462
|
-
return v.pipe(
|
|
11463
|
-
v.unknown(),
|
|
11464
|
-
v.check((input) => {
|
|
11465
|
-
if (typeof input !== "object" || input === null) return true;
|
|
11466
|
-
return !Object.keys(input).some(
|
|
11467
|
-
(k) => PROTO_POLLUTION_KEYS.includes(k)
|
|
11468
|
-
);
|
|
11469
|
-
}, "Schema keys must not include prototype-pollution names (__proto__, constructor, prototype)"),
|
|
11470
|
-
v.record(v.string(), valueSchema)
|
|
11471
|
-
);
|
|
11472
|
-
}
|
|
11473
|
-
var OptionalReferenceSchemaNameSchema = v.optional(
|
|
11474
|
-
v.pipe(
|
|
11475
|
-
v.string(),
|
|
11476
|
-
v.transform((schemaName) => normalizeReferenceSchema2(schemaName))
|
|
11477
|
-
)
|
|
11478
|
-
);
|
|
11479
|
-
var ForeignKeyActionValues = [
|
|
11480
|
-
"CASCADE",
|
|
11481
|
-
"SET NULL",
|
|
11482
|
-
"SET DEFAULT",
|
|
11483
|
-
"RESTRICT",
|
|
11484
|
-
"NO ACTION"
|
|
11485
|
-
];
|
|
11486
|
-
var ForeignKeyActionSchema = v.picklist(ForeignKeyActionValues);
|
|
11487
|
-
var ForeignKeyReferenceSchema = v.object({
|
|
11488
|
-
schema: OptionalReferenceSchemaNameSchema,
|
|
11489
|
-
table: v.string(),
|
|
11490
|
-
column: v.optional(v.string()),
|
|
11491
|
-
onDelete: v.optional(ForeignKeyActionSchema),
|
|
11492
|
-
index: v.optional(v.boolean()),
|
|
11493
|
-
parentRole: v.optional(v.string()),
|
|
11494
|
-
childRole: v.optional(v.string())
|
|
11495
|
-
});
|
|
11496
|
-
var StringOrStringArraySchema = v.union([v.string(), v.array(v.string())]);
|
|
11497
|
-
var ColumnDefinitionSchema = v.object({
|
|
11498
|
-
type: SchemaColumnTypeSchema,
|
|
11499
|
-
primaryKey: v.optional(v.boolean()),
|
|
11500
|
-
nullable: v.optional(v.boolean()),
|
|
11501
|
-
unique: v.optional(v.boolean()),
|
|
11502
|
-
autoIncrement: v.optional(v.boolean()),
|
|
11503
|
-
default: v.optional(v.union([v.string(), v.number(), v.boolean()])),
|
|
11504
|
-
references: v.optional(ForeignKeyReferenceSchema),
|
|
11505
|
-
index: v.optional(v.union([v.boolean(), v.string()]))
|
|
11506
|
-
});
|
|
11507
|
-
var FlatTableDefinitionSchema = safeRecord(ColumnDefinitionSchema);
|
|
11508
|
-
var TableDefWithConfigSchema = v.object({
|
|
11509
|
-
columns: FlatTableDefinitionSchema,
|
|
11510
|
-
primaryKey: v.optional(StringOrStringArraySchema),
|
|
11511
|
-
foreignKeys: v.optional(
|
|
11512
|
-
v.array(
|
|
11513
|
-
v.object({
|
|
11514
|
-
columns: v.array(v.string()),
|
|
11515
|
-
references: v.object({
|
|
11516
|
-
schema: OptionalReferenceSchemaNameSchema,
|
|
11517
|
-
table: v.string(),
|
|
11518
|
-
columns: v.array(v.string())
|
|
11519
|
-
}),
|
|
11520
|
-
onDelete: v.optional(ForeignKeyActionSchema),
|
|
11521
|
-
onUpdate: v.optional(ForeignKeyActionSchema)
|
|
11522
|
-
})
|
|
11523
|
-
)
|
|
11524
|
-
),
|
|
11525
|
-
indexes: v.optional(
|
|
11526
|
-
v.array(
|
|
11527
|
-
v.object({
|
|
11528
|
-
columns: v.array(v.string()),
|
|
11529
|
-
unique: v.optional(v.boolean()),
|
|
11530
|
-
name: v.optional(v.string())
|
|
11531
|
-
})
|
|
11532
|
-
)
|
|
11533
|
-
)
|
|
11534
|
-
});
|
|
11535
|
-
var TableDefinitionSchema = v.union([
|
|
11536
|
-
TableDefWithConfigSchema,
|
|
11537
|
-
FlatTableDefinitionSchema
|
|
11538
|
-
]);
|
|
11539
|
-
var TablesDefinitionSchema = safeRecord(TableDefinitionSchema);
|
|
11540
|
-
var IncludeStrategySchema = v.optional(
|
|
11541
|
-
v.picklist(["join", "subquery", "cte", "lateral", "json_agg", "auto"])
|
|
11542
|
-
);
|
|
11543
|
-
var BelongsToRelationSchema = v.object({
|
|
11544
|
-
kind: v.literal("belongsTo"),
|
|
11545
|
-
target: v.string(),
|
|
11546
|
-
foreignKey: StringOrStringArraySchema,
|
|
11547
|
-
targetKey: v.optional(StringOrStringArraySchema),
|
|
11548
|
-
includeStrategy: IncludeStrategySchema
|
|
11549
|
-
});
|
|
11550
|
-
var HasManyRelationSchema = v.object({
|
|
11551
|
-
kind: v.literal("hasMany"),
|
|
11552
|
-
target: v.string(),
|
|
11553
|
-
foreignKey: StringOrStringArraySchema,
|
|
11554
|
-
sourceKey: v.optional(StringOrStringArraySchema),
|
|
11555
|
-
includeStrategy: IncludeStrategySchema
|
|
11556
|
-
});
|
|
11557
|
-
var ManyToManyRelationSchema = v.object({
|
|
11558
|
-
kind: v.literal("manyToMany"),
|
|
11559
|
-
target: v.string(),
|
|
11560
|
-
through: v.string(),
|
|
11561
|
-
sourceFk: v.string(),
|
|
11562
|
-
targetFk: v.string(),
|
|
11563
|
-
includeStrategy: IncludeStrategySchema
|
|
11564
|
-
});
|
|
11565
|
-
var RelationDefinitionSchema = v.variant("kind", [
|
|
11566
|
-
BelongsToRelationSchema,
|
|
11567
|
-
HasManyRelationSchema,
|
|
11568
|
-
ManyToManyRelationSchema
|
|
11569
|
-
]);
|
|
11570
|
-
var RelationsDefinitionSchema = safeRecord(RelationDefinitionSchema);
|
|
11571
|
-
var HintDefinitionSchema = v.object({
|
|
11572
|
-
defaultStrategy: v.optional(v.picklist(["exists", "join"])),
|
|
11573
|
-
cardinality: v.optional(v.picklist(["one", "many"]))
|
|
11574
|
-
});
|
|
11575
|
-
var HintsDefinitionSchema = safeRecord(HintDefinitionSchema);
|
|
11576
|
-
var ConventionsDefinitionSchema = v.object({
|
|
11577
|
-
fkPattern: v.string(),
|
|
11578
|
-
pluralize: v.boolean(),
|
|
11579
|
-
timestamps: v.array(v.string()),
|
|
11580
|
-
fkAutoIndex: v.boolean()
|
|
11581
|
-
});
|
|
11582
|
-
var IndexDefinitionSchema = v.object({
|
|
11583
|
-
columns: v.array(v.string()),
|
|
11584
|
-
unique: v.optional(v.boolean()),
|
|
11585
|
-
name: v.optional(v.string())
|
|
11586
|
-
});
|
|
11587
|
-
var IndexesDefinitionSchema = safeRecord(v.array(IndexDefinitionSchema));
|
|
11588
|
-
var ResolvedSchemaValidation = v.object({
|
|
11589
|
-
tables: TablesDefinitionSchema,
|
|
11590
|
-
relations: RelationsDefinitionSchema,
|
|
11591
|
-
hints: HintsDefinitionSchema,
|
|
11592
|
-
conventions: ConventionsDefinitionSchema,
|
|
11593
|
-
indexes: v.optional(IndexesDefinitionSchema)
|
|
11594
|
-
});
|
|
11595
|
-
function mapSchemaColumnType(schemaType) {
|
|
11596
|
-
switch (schemaType) {
|
|
11597
|
-
case "uuid":
|
|
11598
|
-
return "uuid";
|
|
11599
|
-
case "string":
|
|
11600
|
-
return "string";
|
|
11601
|
-
case "text":
|
|
11602
|
-
return "text";
|
|
11603
|
-
case "integer":
|
|
11604
|
-
return "integer";
|
|
11605
|
-
case "bigint":
|
|
11606
|
-
return "bigint";
|
|
11607
|
-
case "decimal":
|
|
11608
|
-
return "decimal";
|
|
11609
|
-
case "boolean":
|
|
11610
|
-
return "boolean";
|
|
11611
|
-
case "timestamp":
|
|
11612
|
-
return "timestamp";
|
|
11613
|
-
case "date":
|
|
11614
|
-
return "date";
|
|
11615
|
-
case "time":
|
|
11616
|
-
return "time";
|
|
11617
|
-
case "json":
|
|
11618
|
-
return "json";
|
|
11619
|
-
case "jsonb":
|
|
11620
|
-
return "jsonb";
|
|
11621
|
-
case "daterange":
|
|
11622
|
-
return "daterange";
|
|
11623
|
-
case "tstzrange":
|
|
11624
|
-
return "tstzrange";
|
|
11625
|
-
case "int4range":
|
|
11626
|
-
return "int4range";
|
|
11627
|
-
case "tsrange":
|
|
11628
|
-
return "tsrange";
|
|
11629
|
-
case "int8range":
|
|
11630
|
-
return "int8range";
|
|
11631
|
-
case "numrange":
|
|
11632
|
-
return "numrange";
|
|
11633
|
-
}
|
|
11634
|
-
}
|
|
11635
|
-
function convertColumn(col2) {
|
|
11636
|
-
const result = {
|
|
11637
|
-
type: mapSchemaColumnType(col2.type)
|
|
11638
|
-
};
|
|
11639
|
-
if (col2.primaryKey !== void 0) {
|
|
11640
|
-
result.primaryKey = col2.primaryKey;
|
|
11641
|
-
}
|
|
11642
|
-
if (col2.nullable !== void 0) {
|
|
11643
|
-
result.nullable = col2.nullable;
|
|
11644
|
-
}
|
|
11645
|
-
if (col2.unique !== void 0) {
|
|
11646
|
-
result.unique = col2.unique;
|
|
11647
|
-
}
|
|
11648
|
-
if (col2.autoIncrement !== void 0) {
|
|
11649
|
-
result.autoIncrement = col2.autoIncrement;
|
|
11650
|
-
}
|
|
11651
|
-
if (col2.default !== void 0) {
|
|
11652
|
-
result.default = col2.default;
|
|
11653
|
-
}
|
|
11654
|
-
if (col2.references) {
|
|
11655
|
-
const externalSchema = normalizeReferenceSchema2(col2.references.schema);
|
|
11656
|
-
result.references = {
|
|
11657
|
-
table: col2.references.table,
|
|
11658
|
-
...externalSchema !== void 0 ? { schema: externalSchema } : {},
|
|
11659
|
-
...col2.references.column !== void 0 ? { column: col2.references.column } : {},
|
|
11660
|
-
...col2.references.onDelete ? { onDelete: col2.references.onDelete } : {},
|
|
11661
|
-
...col2.references.index !== void 0 ? { index: col2.references.index } : {},
|
|
11662
|
-
...col2.references.parentRole ? { parentRole: col2.references.parentRole } : {},
|
|
11663
|
-
...col2.references.childRole ? { childRole: col2.references.childRole } : {}
|
|
11664
|
-
};
|
|
11665
|
-
}
|
|
11666
|
-
return result;
|
|
11667
|
-
}
|
|
11668
|
-
function convertRelation(rel) {
|
|
11669
|
-
switch (rel.kind) {
|
|
11670
|
-
case "belongsTo": {
|
|
11671
|
-
const result = {
|
|
11672
|
-
kind: "belongsTo",
|
|
11673
|
-
target: rel.target,
|
|
11674
|
-
foreignKey: rel.foreignKey
|
|
11675
|
-
};
|
|
11676
|
-
if (rel.targetKey !== void 0) {
|
|
11677
|
-
result.targetKey = rel.targetKey;
|
|
11678
|
-
}
|
|
11679
|
-
if (rel.includeStrategy !== void 0) {
|
|
11680
|
-
result.includeStrategy = rel.includeStrategy;
|
|
11681
|
-
}
|
|
11682
|
-
return result;
|
|
11683
|
-
}
|
|
11684
|
-
case "hasMany": {
|
|
11685
|
-
const result = {
|
|
11686
|
-
kind: "hasMany",
|
|
11687
|
-
target: rel.target,
|
|
11688
|
-
foreignKey: rel.foreignKey
|
|
11689
|
-
};
|
|
11690
|
-
if (rel.sourceKey !== void 0) {
|
|
11691
|
-
result.sourceKey = rel.sourceKey;
|
|
11692
|
-
}
|
|
11693
|
-
if (rel.includeStrategy !== void 0) {
|
|
11694
|
-
result.includeStrategy = rel.includeStrategy;
|
|
11695
|
-
}
|
|
11696
|
-
return result;
|
|
11697
|
-
}
|
|
11698
|
-
case "manyToMany": {
|
|
11699
|
-
const result = {
|
|
11700
|
-
kind: "manyToMany",
|
|
11701
|
-
target: rel.target,
|
|
11702
|
-
through: rel.through,
|
|
11703
|
-
sourceFk: rel.sourceFk,
|
|
11704
|
-
targetFk: rel.targetFk
|
|
11705
|
-
};
|
|
11706
|
-
if (rel.includeStrategy !== void 0) {
|
|
11707
|
-
result.includeStrategy = rel.includeStrategy;
|
|
11708
|
-
}
|
|
11709
|
-
return result;
|
|
11710
|
-
}
|
|
11711
|
-
}
|
|
11712
|
-
}
|
|
11713
|
-
function convertHint(hint) {
|
|
11714
|
-
const result = {};
|
|
11715
|
-
if (hint.defaultStrategy !== void 0) {
|
|
11716
|
-
result.defaultStrategy = hint.defaultStrategy;
|
|
11717
|
-
}
|
|
11718
|
-
if (hint.cardinality !== void 0) {
|
|
11719
|
-
result.cardinality = hint.cardinality;
|
|
11720
|
-
}
|
|
11721
|
-
return result;
|
|
11722
|
-
}
|
|
11723
|
-
function resolvedSchemaToGeneratedSchema(input) {
|
|
11724
|
-
const parseResult = v.safeParse(ResolvedSchemaValidation, input);
|
|
11725
|
-
if (!parseResult.success) {
|
|
11726
|
-
return {
|
|
11727
|
-
success: false,
|
|
11728
|
-
errors: parseResult.issues
|
|
11729
|
-
};
|
|
11730
|
-
}
|
|
11731
|
-
const validated = parseResult.output;
|
|
11732
|
-
const tables = /* @__PURE__ */ Object.create(null);
|
|
11733
|
-
for (const [tableName, tableDef] of Object.entries(validated.tables)) {
|
|
11734
|
-
const convertedTable = /* @__PURE__ */ Object.create(null);
|
|
11735
|
-
const tableObj = tableDef;
|
|
11736
|
-
const isWithConfig = Array.isArray(tableObj.primaryKey);
|
|
11737
|
-
const columns = isWithConfig ? tableObj.columns : tableObj;
|
|
11738
|
-
for (const [colName, colDef] of Object.entries(columns)) {
|
|
11739
|
-
convertedTable[colName] = convertColumn(
|
|
11740
|
-
colDef
|
|
11741
|
-
);
|
|
11742
|
-
}
|
|
11743
|
-
tables[tableName] = convertedTable;
|
|
11744
|
-
}
|
|
11745
|
-
const relations = /* @__PURE__ */ Object.create(null);
|
|
11746
|
-
for (const [relName, relDef] of Object.entries(validated.relations)) {
|
|
11747
|
-
relations[relName] = convertRelation(relDef);
|
|
11748
|
-
}
|
|
11749
|
-
const hints = /* @__PURE__ */ Object.create(null);
|
|
11750
|
-
for (const [hintName, hintDef] of Object.entries(validated.hints)) {
|
|
11751
|
-
hints[hintName] = convertHint(hintDef);
|
|
11752
|
-
}
|
|
11753
|
-
const conventions = {
|
|
11754
|
-
fkPattern: validated.conventions.fkPattern,
|
|
11755
|
-
pluralize: validated.conventions.pluralize,
|
|
11756
|
-
timestamps: validated.conventions.timestamps,
|
|
11757
|
-
fkAutoIndex: validated.conventions.fkAutoIndex
|
|
11758
|
-
};
|
|
11759
|
-
return {
|
|
11760
|
-
success: true,
|
|
11761
|
-
schema: {
|
|
11762
|
-
tables,
|
|
11763
|
-
relations,
|
|
11764
|
-
hints,
|
|
11765
|
-
conventions
|
|
11766
|
-
}
|
|
11767
|
-
};
|
|
11768
|
-
}
|
|
11769
|
-
function assertResolvedSchemaToGeneratedSchema(input) {
|
|
11770
|
-
const result = resolvedSchemaToGeneratedSchema(input);
|
|
11771
|
-
if (!result.success) {
|
|
11772
|
-
const messages = result.errors.map((e) => {
|
|
11773
|
-
const path = e.path?.map((p) => p.key).join(".") || "root";
|
|
11774
|
-
return `[${path}] ${e.message} (expected: ${e.expected}, received: ${e.received})`;
|
|
11775
|
-
}).join("\n");
|
|
11776
|
-
throw new Error(`Schema validation failed:
|
|
11777
|
-
${messages}`);
|
|
11778
|
-
}
|
|
11779
|
-
return result.schema;
|
|
11780
|
-
}
|
|
11781
|
-
|
|
11782
10863
|
// src/dialects/index.ts
|
|
11783
10864
|
var POSTGRESQL_CAPABILITIES = {
|
|
11784
10865
|
name: "postgresql",
|
|
@@ -13159,7 +12240,6 @@ export {
|
|
|
13159
12240
|
ColumnNotFoundError,
|
|
13160
12241
|
CteBuilder,
|
|
13161
12242
|
CteQueryBuilder,
|
|
13162
|
-
DEFAULT_CONVENTIONS,
|
|
13163
12243
|
DEFAULT_FEATURE_CHECKERS,
|
|
13164
12244
|
DUCKDB_CAPABILITIES,
|
|
13165
12245
|
DeleteBuilder,
|
|
@@ -13182,12 +12262,11 @@ export {
|
|
|
13182
12262
|
RawCteQueryBuilder,
|
|
13183
12263
|
RecursiveShapeMismatchError,
|
|
13184
12264
|
RelationNotFoundError,
|
|
13185
|
-
ResolvedSchemaValidation,
|
|
13186
12265
|
ResultHydrator,
|
|
13187
12266
|
SQLITE_CAPABILITIES,
|
|
13188
12267
|
SQL_RAW_MARKER,
|
|
13189
12268
|
SchemaValidationError as SchemaError,
|
|
13190
|
-
|
|
12269
|
+
SchemaValidationError,
|
|
13191
12270
|
SubqueryBuilder,
|
|
13192
12271
|
SubqueryExpression,
|
|
13193
12272
|
TABLE_META,
|
|
@@ -13226,7 +12305,6 @@ export {
|
|
|
13226
12305
|
assertParamsLength,
|
|
13227
12306
|
assertParamsType,
|
|
13228
12307
|
assertParamsValue,
|
|
13229
|
-
assertResolvedSchemaToGeneratedSchema,
|
|
13230
12308
|
assertSQLColumn,
|
|
13231
12309
|
assertSQLEquals,
|
|
13232
12310
|
assertSQLJoin,
|
|
@@ -13234,8 +12312,6 @@ export {
|
|
|
13234
12312
|
assertSuccess,
|
|
13235
12313
|
assertTypeSupported,
|
|
13236
12314
|
batchValues,
|
|
13237
|
-
buildModelFromResolvedSchema,
|
|
13238
|
-
buildModelFromSchema,
|
|
13239
12315
|
capitalize,
|
|
13240
12316
|
caseWhen,
|
|
13241
12317
|
cast,
|
|
@@ -13257,11 +12333,8 @@ export {
|
|
|
13257
12333
|
decapitalize,
|
|
13258
12334
|
defaultLogger,
|
|
13259
12335
|
defineModel,
|
|
13260
|
-
defineSchema,
|
|
13261
12336
|
denseRank,
|
|
13262
12337
|
deriveRelationPathFromIntentPath,
|
|
13263
|
-
detectForeignKeys,
|
|
13264
|
-
detectManyToMany,
|
|
13265
12338
|
distinct,
|
|
13266
12339
|
emitWarning,
|
|
13267
12340
|
eq,
|
|
@@ -13284,13 +12357,11 @@ export {
|
|
|
13284
12357
|
inArray,
|
|
13285
12358
|
inSubquery,
|
|
13286
12359
|
inferForeignKey,
|
|
13287
|
-
inferRelationsFromSchema,
|
|
13288
12360
|
export_isAdjacencyTraversal as isAdjacencyTraversal,
|
|
13289
12361
|
export_isAggregateWindowFunction as isAggregateWindowFunction,
|
|
13290
12362
|
isAliasedColumn,
|
|
13291
12363
|
isAllColumns,
|
|
13292
12364
|
isBatchValuesRef,
|
|
13293
|
-
isBelongsTo,
|
|
13294
12365
|
isCardinalityShorthand,
|
|
13295
12366
|
export_isCoalesceExpression as isCoalesceExpression,
|
|
13296
12367
|
export_isColumnAliasExpression as isColumnAliasExpression,
|
|
@@ -13301,11 +12372,8 @@ export {
|
|
|
13301
12372
|
isDistinctFrom,
|
|
13302
12373
|
export_isEdgeTableTraversal as isEdgeTableTraversal,
|
|
13303
12374
|
isExpressionSpec,
|
|
13304
|
-
isGeneratedSchema,
|
|
13305
|
-
isHasMany,
|
|
13306
12375
|
export_isInsertIntent as isInsertIntent,
|
|
13307
12376
|
isKnownDialect,
|
|
13308
|
-
isManyToMany,
|
|
13309
12377
|
export_isMutationIntent as isMutationIntent,
|
|
13310
12378
|
isNotNull,
|
|
13311
12379
|
isNull,
|
|
@@ -13320,7 +12388,6 @@ export {
|
|
|
13320
12388
|
isRelationObjectDef,
|
|
13321
12389
|
isRelationRef,
|
|
13322
12390
|
isRelationTupleDef,
|
|
13323
|
-
isResolvedSchema,
|
|
13324
12391
|
export_isSelectAggregate as isSelectAggregate,
|
|
13325
12392
|
export_isSelectAll as isSelectAll,
|
|
13326
12393
|
export_isSelectFields as isSelectFields,
|
|
@@ -13360,7 +12427,6 @@ export {
|
|
|
13360
12427
|
neq,
|
|
13361
12428
|
none,
|
|
13362
12429
|
normalizeSQL,
|
|
13363
|
-
normalizeSchema,
|
|
13364
12430
|
not,
|
|
13365
12431
|
notExists,
|
|
13366
12432
|
nqlRaw,
|
|
@@ -13393,7 +12459,6 @@ export {
|
|
|
13393
12459
|
requiresDatabase,
|
|
13394
12460
|
resetLogger,
|
|
13395
12461
|
resolveQueryIndex,
|
|
13396
|
-
resolvedSchemaToGeneratedSchema,
|
|
13397
12462
|
rowNumber,
|
|
13398
12463
|
runAssertions,
|
|
13399
12464
|
schema,
|
|
@@ -13418,6 +12483,7 @@ export {
|
|
|
13418
12483
|
validateAssertionBlocks,
|
|
13419
12484
|
validateRecursiveInclude,
|
|
13420
12485
|
validateRecursiveShape,
|
|
12486
|
+
validateSchemaIndexOptions,
|
|
13421
12487
|
validateTypeName,
|
|
13422
12488
|
wAvg,
|
|
13423
12489
|
wCount,
|