@rebasepro/server-postgresql 0.0.1-canary.eae7889 → 0.1.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.es.js +458 -201
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +458 -201
- package/dist/index.umd.js.map +1 -1
- package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +8 -1
- package/dist/server-postgresql/src/schema/introspect-db-inference.d.ts +5 -0
- package/dist/server-postgresql/src/schema/introspect-db-logic.d.ts +117 -0
- package/dist/server-postgresql/src/schema/introspect-db.d.ts +1 -0
- package/dist/server-postgresql/src/services/EntityPersistService.d.ts +9 -0
- package/dist/types/src/controllers/auth.d.ts +8 -2
- package/dist/types/src/controllers/client.d.ts +13 -0
- package/dist/types/src/controllers/collection_registry.d.ts +2 -1
- package/dist/types/src/controllers/data_driver.d.ts +36 -1
- package/dist/types/src/controllers/navigation.d.ts +18 -6
- package/dist/types/src/controllers/registry.d.ts +9 -1
- package/dist/types/src/controllers/side_entity_controller.d.ts +7 -0
- package/dist/types/src/rebase_context.d.ts +17 -0
- package/dist/types/src/types/backend_hooks.d.ts +187 -0
- package/dist/types/src/types/collections.d.ts +31 -11
- package/dist/types/src/types/component_ref.d.ts +47 -0
- package/dist/types/src/types/cron.d.ts +1 -1
- package/dist/types/src/types/entity_views.d.ts +6 -7
- package/dist/types/src/types/formex.d.ts +40 -0
- package/dist/types/src/types/index.d.ts +3 -0
- package/dist/types/src/types/plugins.d.ts +6 -3
- package/dist/types/src/types/properties.d.ts +72 -88
- package/dist/types/src/types/slots.d.ts +20 -10
- package/dist/types/src/types/translations.d.ts +6 -0
- package/examples/sdk-demo/node_modules/esbuild/LICENSE.md +21 -0
- package/examples/sdk-demo/node_modules/esbuild/README.md +3 -0
- package/examples/sdk-demo/node_modules/esbuild/bin/esbuild +223 -0
- package/examples/sdk-demo/node_modules/esbuild/install.js +289 -0
- package/examples/sdk-demo/node_modules/esbuild/lib/main.d.ts +716 -0
- package/examples/sdk-demo/node_modules/esbuild/lib/main.js +2242 -0
- package/examples/sdk-demo/node_modules/esbuild/package.json +49 -0
- package/package.json +6 -5
- package/src/PostgresBackendDriver.ts +32 -6
- package/src/cli.ts +68 -2
- package/src/data-transformer.ts +84 -1
- package/src/schema/doctor.ts +14 -2
- package/src/schema/generate-drizzle-schema-logic.ts +59 -30
- package/src/schema/introspect-db-inference.ts +238 -0
- package/src/schema/introspect-db-logic.ts +896 -0
- package/src/schema/introspect-db.ts +254 -0
- package/src/services/EntityFetchService.ts +16 -0
- package/src/services/EntityPersistService.ts +95 -13
- package/test/generate-drizzle-schema.test.ts +342 -0
- package/test/introspect-db-generation.test.ts +458 -0
- package/test/introspect-db-utils.test.ts +392 -0
- package/test/property-ordering.test.ts +395 -0
- package/test/relations.test.ts +4 -4
- package/test/unmapped-tables-safety.test.ts +345 -0
- package/jest-all.log +0 -3128
- package/jest.log +0 -49
- package/scratch.ts +0 -41
- package/test-drizzle-bug.ts +0 -18
- package/test-drizzle-out/0000_cultured_freak.sql +0 -7
- package/test-drizzle-out/0001_tiresome_professor_monster.sql +0 -1
- package/test-drizzle-out/meta/0000_snapshot.json +0 -55
- package/test-drizzle-out/meta/0001_snapshot.json +0 -63
- package/test-drizzle-out/meta/_journal.json +0 -20
- package/test-drizzle-prompt.sh +0 -2
- package/test-policy-prompt.sh +0 -3
- package/test-programmatic.ts +0 -30
- package/test-programmatic2.ts +0 -59
- package/test-schema-no-policies.ts +0 -12
- package/test_drizzle_mock.js +0 -3
- package/test_find_changed.mjs +0 -32
- package/test_hash.js +0 -14
- package/test_output.txt +0 -3145
package/dist/index.umd.js
CHANGED
|
@@ -132,7 +132,8 @@
|
|
|
132
132
|
}
|
|
133
133
|
const DEFAULT_ONE_OF_TYPE = "type";
|
|
134
134
|
const DEFAULT_ONE_OF_VALUE = "value";
|
|
135
|
-
const
|
|
135
|
+
const tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
|
|
136
|
+
const snakeCaseRegex = tokenizeRegex;
|
|
136
137
|
const toSnakeCase = (str) => {
|
|
137
138
|
const regExpMatchArray = str.match(snakeCaseRegex);
|
|
138
139
|
if (!regExpMatchArray) return "";
|
|
@@ -1029,6 +1030,80 @@
|
|
|
1029
1030
|
const singularName = snakeCaseName.endsWith("s") ? snakeCaseName.slice(0, -1) : snakeCaseName;
|
|
1030
1031
|
return `${singularName}_id`;
|
|
1031
1032
|
}
|
|
1033
|
+
function updateDateAutoValues({
|
|
1034
|
+
inputValues,
|
|
1035
|
+
properties,
|
|
1036
|
+
status,
|
|
1037
|
+
timestampNowValue
|
|
1038
|
+
}) {
|
|
1039
|
+
return traverseValuesProperties(inputValues, properties, (inputValue, property) => {
|
|
1040
|
+
if (property.type === "date") {
|
|
1041
|
+
if (status === "existing" && property.autoValue === "on_update") {
|
|
1042
|
+
return timestampNowValue;
|
|
1043
|
+
} else if ((status === "new" || status === "copy") && (property.autoValue === "on_update" || property.autoValue === "on_create")) {
|
|
1044
|
+
return timestampNowValue;
|
|
1045
|
+
} else {
|
|
1046
|
+
return inputValue;
|
|
1047
|
+
}
|
|
1048
|
+
} else {
|
|
1049
|
+
return inputValue;
|
|
1050
|
+
}
|
|
1051
|
+
}) ?? {};
|
|
1052
|
+
}
|
|
1053
|
+
function traverseValuesProperties(inputValues, properties, operation) {
|
|
1054
|
+
const safeInputValues = inputValues ?? {};
|
|
1055
|
+
const updatedValues = Object.entries(properties).map(([key, property]) => {
|
|
1056
|
+
const inputValue = safeInputValues && safeInputValues[key];
|
|
1057
|
+
const updatedValue = traverseValueProperty(inputValue, property, operation);
|
|
1058
|
+
if (updatedValue === null) return null;
|
|
1059
|
+
if (updatedValue === void 0) return void 0;
|
|
1060
|
+
return {
|
|
1061
|
+
[key]: updatedValue
|
|
1062
|
+
};
|
|
1063
|
+
}).reduce((a, b) => ({
|
|
1064
|
+
...a,
|
|
1065
|
+
...b
|
|
1066
|
+
}), {});
|
|
1067
|
+
const result = mergeDeep(safeInputValues, updatedValues);
|
|
1068
|
+
if (!result || Object.keys(result).length === 0) return void 0;
|
|
1069
|
+
return result;
|
|
1070
|
+
}
|
|
1071
|
+
function traverseValueProperty(inputValue, property, operation) {
|
|
1072
|
+
let value;
|
|
1073
|
+
if (property.type === "map" && property.properties) {
|
|
1074
|
+
value = traverseValuesProperties(inputValue, property.properties, operation);
|
|
1075
|
+
} else if (property.type === "array") {
|
|
1076
|
+
const of = property.of;
|
|
1077
|
+
if (of && Array.isArray(inputValue) && !Array.isArray(of)) {
|
|
1078
|
+
value = inputValue.map((e) => traverseValueProperty(e, of, operation));
|
|
1079
|
+
} else if (of && Array.isArray(inputValue) && Array.isArray(of)) {
|
|
1080
|
+
value = inputValue.map((e, i) => {
|
|
1081
|
+
if (i < of.length) return traverseValueProperty(e, of[i], operation);
|
|
1082
|
+
return null;
|
|
1083
|
+
}).filter(Boolean);
|
|
1084
|
+
} else if (property.oneOf && Array.isArray(inputValue)) {
|
|
1085
|
+
const typeField = property.oneOf?.typeField ?? DEFAULT_ONE_OF_TYPE;
|
|
1086
|
+
const valueField = property.oneOf?.valueField ?? DEFAULT_ONE_OF_VALUE;
|
|
1087
|
+
value = inputValue.map((e) => {
|
|
1088
|
+
if (e === null) return null;
|
|
1089
|
+
if (typeof e !== "object") return e;
|
|
1090
|
+
const rec = e;
|
|
1091
|
+
const type = rec[typeField];
|
|
1092
|
+
const childProperty = property.oneOf?.properties[type];
|
|
1093
|
+
if (!type || !childProperty) return e;
|
|
1094
|
+
return {
|
|
1095
|
+
[typeField]: type,
|
|
1096
|
+
[valueField]: traverseValueProperty(rec[valueField], childProperty, operation)
|
|
1097
|
+
};
|
|
1098
|
+
});
|
|
1099
|
+
} else {
|
|
1100
|
+
value = inputValue;
|
|
1101
|
+
}
|
|
1102
|
+
} else {
|
|
1103
|
+
value = operation(inputValue, property);
|
|
1104
|
+
}
|
|
1105
|
+
return value;
|
|
1106
|
+
}
|
|
1032
1107
|
function createRelationRef(id, path2) {
|
|
1033
1108
|
return {
|
|
1034
1109
|
id,
|
|
@@ -1725,8 +1800,8 @@
|
|
|
1725
1800
|
return jsonLogic;
|
|
1726
1801
|
});
|
|
1727
1802
|
})(logic);
|
|
1728
|
-
|
|
1729
|
-
|
|
1803
|
+
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
|
1804
|
+
const { hasOwnProperty: hasOwnProperty$a } = Object.prototype;
|
|
1730
1805
|
function combineComparators(comparatorA, comparatorB) {
|
|
1731
1806
|
return function isEqual(a, b, state) {
|
|
1732
1807
|
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
|
@@ -1737,38 +1812,45 @@
|
|
|
1737
1812
|
if (!a || !b || typeof a !== "object" || typeof b !== "object") {
|
|
1738
1813
|
return areItemsEqual(a, b, state);
|
|
1739
1814
|
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1815
|
+
const { cache } = state;
|
|
1816
|
+
const cachedA = cache.get(a);
|
|
1817
|
+
const cachedB = cache.get(b);
|
|
1743
1818
|
if (cachedA && cachedB) {
|
|
1744
1819
|
return cachedA === b && cachedB === a;
|
|
1745
1820
|
}
|
|
1746
1821
|
cache.set(a, b);
|
|
1747
1822
|
cache.set(b, a);
|
|
1748
|
-
|
|
1823
|
+
const result = areItemsEqual(a, b, state);
|
|
1749
1824
|
cache.delete(a);
|
|
1750
1825
|
cache.delete(b);
|
|
1751
1826
|
return result;
|
|
1752
1827
|
};
|
|
1753
1828
|
}
|
|
1754
|
-
function getShortTag(value) {
|
|
1755
|
-
return value != null ? value[Symbol.toStringTag] : void 0;
|
|
1756
|
-
}
|
|
1757
1829
|
function getStrictProperties(object) {
|
|
1758
1830
|
return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
|
|
1759
1831
|
}
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1832
|
+
const hasOwn = (
|
|
1833
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1834
|
+
Object.hasOwn || ((object, property) => hasOwnProperty$a.call(object, property))
|
|
1835
|
+
);
|
|
1836
|
+
const PREACT_VNODE = "__v";
|
|
1837
|
+
const PREACT_OWNER = "__o";
|
|
1838
|
+
const REACT_OWNER = "_owner";
|
|
1839
|
+
const { getOwnPropertyDescriptor, keys: keys$4 } = Object;
|
|
1840
|
+
const sameValueEqual = (
|
|
1841
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1842
|
+
Object.is || function sameValueEqual2(a, b) {
|
|
1843
|
+
return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;
|
|
1844
|
+
}
|
|
1845
|
+
);
|
|
1846
|
+
function strictEqual(a, b) {
|
|
1847
|
+
return a === b;
|
|
1848
|
+
}
|
|
1849
|
+
function areArrayBuffersEqual(a, b) {
|
|
1850
|
+
return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a), new Uint8Array(b));
|
|
1765
1851
|
}
|
|
1766
|
-
var PREACT_VNODE = "__v";
|
|
1767
|
-
var PREACT_OWNER = "__o";
|
|
1768
|
-
var REACT_OWNER = "_owner";
|
|
1769
|
-
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys$4 = Object.keys;
|
|
1770
1852
|
function areArraysEqual(a, b, state) {
|
|
1771
|
-
|
|
1853
|
+
let index = a.length;
|
|
1772
1854
|
if (b.length !== index) {
|
|
1773
1855
|
return false;
|
|
1774
1856
|
}
|
|
@@ -1779,35 +1861,35 @@
|
|
|
1779
1861
|
}
|
|
1780
1862
|
return true;
|
|
1781
1863
|
}
|
|
1864
|
+
function areDataViewsEqual(a, b) {
|
|
1865
|
+
return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength));
|
|
1866
|
+
}
|
|
1782
1867
|
function areDatesEqual(a, b) {
|
|
1783
|
-
return
|
|
1868
|
+
return sameValueEqual(a.getTime(), b.getTime());
|
|
1784
1869
|
}
|
|
1785
1870
|
function areErrorsEqual(a, b) {
|
|
1786
1871
|
return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
|
|
1787
1872
|
}
|
|
1788
|
-
function areFunctionsEqual(a, b) {
|
|
1789
|
-
return a === b;
|
|
1790
|
-
}
|
|
1791
1873
|
function areMapsEqual(a, b, state) {
|
|
1792
|
-
|
|
1874
|
+
const size = a.size;
|
|
1793
1875
|
if (size !== b.size) {
|
|
1794
1876
|
return false;
|
|
1795
1877
|
}
|
|
1796
1878
|
if (!size) {
|
|
1797
1879
|
return true;
|
|
1798
1880
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1881
|
+
const matchedIndices = new Array(size);
|
|
1882
|
+
const aIterable = a.entries();
|
|
1883
|
+
let aResult;
|
|
1884
|
+
let bResult;
|
|
1885
|
+
let index = 0;
|
|
1804
1886
|
while (aResult = aIterable.next()) {
|
|
1805
1887
|
if (aResult.done) {
|
|
1806
1888
|
break;
|
|
1807
1889
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1890
|
+
const bIterable = b.entries();
|
|
1891
|
+
let hasMatch = false;
|
|
1892
|
+
let matchIndex = 0;
|
|
1811
1893
|
while (bResult = bIterable.next()) {
|
|
1812
1894
|
if (bResult.done) {
|
|
1813
1895
|
break;
|
|
@@ -1816,8 +1898,8 @@
|
|
|
1816
1898
|
matchIndex++;
|
|
1817
1899
|
continue;
|
|
1818
1900
|
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1901
|
+
const aEntry = aResult.value;
|
|
1902
|
+
const bEntry = bResult.value;
|
|
1821
1903
|
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) && state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
|
1822
1904
|
hasMatch = matchedIndices[matchIndex] = true;
|
|
1823
1905
|
break;
|
|
@@ -1831,10 +1913,9 @@
|
|
|
1831
1913
|
}
|
|
1832
1914
|
return true;
|
|
1833
1915
|
}
|
|
1834
|
-
var areNumbersEqual = sameValueZeroEqual;
|
|
1835
1916
|
function areObjectsEqual(a, b, state) {
|
|
1836
|
-
|
|
1837
|
-
|
|
1917
|
+
const properties = keys$4(a);
|
|
1918
|
+
let index = properties.length;
|
|
1838
1919
|
if (keys$4(b).length !== index) {
|
|
1839
1920
|
return false;
|
|
1840
1921
|
}
|
|
@@ -1846,14 +1927,14 @@
|
|
|
1846
1927
|
return true;
|
|
1847
1928
|
}
|
|
1848
1929
|
function areObjectsEqualStrict(a, b, state) {
|
|
1849
|
-
|
|
1850
|
-
|
|
1930
|
+
const properties = getStrictProperties(a);
|
|
1931
|
+
let index = properties.length;
|
|
1851
1932
|
if (getStrictProperties(b).length !== index) {
|
|
1852
1933
|
return false;
|
|
1853
1934
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1935
|
+
let property;
|
|
1936
|
+
let descriptorA;
|
|
1937
|
+
let descriptorB;
|
|
1857
1938
|
while (index-- > 0) {
|
|
1858
1939
|
property = properties[index];
|
|
1859
1940
|
if (!isPropertyEqual(a, b, state, property)) {
|
|
@@ -1868,30 +1949,30 @@
|
|
|
1868
1949
|
return true;
|
|
1869
1950
|
}
|
|
1870
1951
|
function arePrimitiveWrappersEqual(a, b) {
|
|
1871
|
-
return
|
|
1952
|
+
return sameValueEqual(a.valueOf(), b.valueOf());
|
|
1872
1953
|
}
|
|
1873
1954
|
function areRegExpsEqual(a, b) {
|
|
1874
1955
|
return a.source === b.source && a.flags === b.flags;
|
|
1875
1956
|
}
|
|
1876
1957
|
function areSetsEqual(a, b, state) {
|
|
1877
|
-
|
|
1958
|
+
const size = a.size;
|
|
1878
1959
|
if (size !== b.size) {
|
|
1879
1960
|
return false;
|
|
1880
1961
|
}
|
|
1881
1962
|
if (!size) {
|
|
1882
1963
|
return true;
|
|
1883
1964
|
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1965
|
+
const matchedIndices = new Array(size);
|
|
1966
|
+
const aIterable = a.values();
|
|
1967
|
+
let aResult;
|
|
1968
|
+
let bResult;
|
|
1888
1969
|
while (aResult = aIterable.next()) {
|
|
1889
1970
|
if (aResult.done) {
|
|
1890
1971
|
break;
|
|
1891
1972
|
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1973
|
+
const bIterable = b.values();
|
|
1974
|
+
let hasMatch = false;
|
|
1975
|
+
let matchIndex = 0;
|
|
1895
1976
|
while (bResult = bIterable.next()) {
|
|
1896
1977
|
if (bResult.done) {
|
|
1897
1978
|
break;
|
|
@@ -1909,8 +1990,8 @@
|
|
|
1909
1990
|
return true;
|
|
1910
1991
|
}
|
|
1911
1992
|
function areTypedArraysEqual(a, b) {
|
|
1912
|
-
|
|
1913
|
-
if (b.
|
|
1993
|
+
let index = a.byteLength;
|
|
1994
|
+
if (b.byteLength !== index || a.byteOffset !== b.byteOffset) {
|
|
1914
1995
|
return false;
|
|
1915
1996
|
}
|
|
1916
1997
|
while (index-- > 0) {
|
|
@@ -1929,23 +2010,10 @@
|
|
|
1929
2010
|
}
|
|
1930
2011
|
return hasOwn(b, property) && state.equals(a[property], b[property], property, property, a, b, state);
|
|
1931
2012
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
var MAP_TAG = "[object Map]";
|
|
1937
|
-
var NUMBER_TAG = "[object Number]";
|
|
1938
|
-
var OBJECT_TAG = "[object Object]";
|
|
1939
|
-
var REG_EXP_TAG = "[object RegExp]";
|
|
1940
|
-
var SET_TAG = "[object Set]";
|
|
1941
|
-
var STRING_TAG = "[object String]";
|
|
1942
|
-
var URL_TAG = "[object URL]";
|
|
1943
|
-
var isArray$4 = Array.isArray;
|
|
1944
|
-
var isTypedArray$2 = typeof ArrayBuffer === "function" && ArrayBuffer.isView ? ArrayBuffer.isView : null;
|
|
1945
|
-
var assign = Object.assign;
|
|
1946
|
-
var getTag$4 = Object.prototype.toString.call.bind(Object.prototype.toString);
|
|
1947
|
-
function createEqualityComparator(_a) {
|
|
1948
|
-
var areArraysEqual2 = _a.areArraysEqual, areDatesEqual2 = _a.areDatesEqual, areErrorsEqual2 = _a.areErrorsEqual, areFunctionsEqual2 = _a.areFunctionsEqual, areMapsEqual2 = _a.areMapsEqual, areNumbersEqual2 = _a.areNumbersEqual, areObjectsEqual2 = _a.areObjectsEqual, arePrimitiveWrappersEqual2 = _a.arePrimitiveWrappersEqual, areRegExpsEqual2 = _a.areRegExpsEqual, areSetsEqual2 = _a.areSetsEqual, areTypedArraysEqual2 = _a.areTypedArraysEqual, areUrlsEqual2 = _a.areUrlsEqual, unknownTagComparators = _a.unknownTagComparators;
|
|
2013
|
+
const toString = Object.prototype.toString;
|
|
2014
|
+
function createEqualityComparator(config) {
|
|
2015
|
+
const supportedComparatorMap = createSupportedComparatorMap(config);
|
|
2016
|
+
const { areArraysEqual: areArraysEqual2, areDatesEqual: areDatesEqual2, areFunctionsEqual, areMapsEqual: areMapsEqual2, areNumbersEqual, areObjectsEqual: areObjectsEqual2, areRegExpsEqual: areRegExpsEqual2, areSetsEqual: areSetsEqual2, getUnsupportedCustomComparator } = config;
|
|
1949
2017
|
return function comparator(a, b, state) {
|
|
1950
2018
|
if (a === b) {
|
|
1951
2019
|
return true;
|
|
@@ -1953,32 +2021,29 @@
|
|
|
1953
2021
|
if (a == null || b == null) {
|
|
1954
2022
|
return false;
|
|
1955
2023
|
}
|
|
1956
|
-
|
|
2024
|
+
const type = typeof a;
|
|
1957
2025
|
if (type !== typeof b) {
|
|
1958
2026
|
return false;
|
|
1959
2027
|
}
|
|
1960
2028
|
if (type !== "object") {
|
|
1961
|
-
if (type === "number") {
|
|
1962
|
-
return
|
|
2029
|
+
if (type === "number" || type === "bigint") {
|
|
2030
|
+
return areNumbersEqual(a, b, state);
|
|
1963
2031
|
}
|
|
1964
2032
|
if (type === "function") {
|
|
1965
|
-
return
|
|
2033
|
+
return areFunctionsEqual(a, b, state);
|
|
1966
2034
|
}
|
|
1967
2035
|
return false;
|
|
1968
2036
|
}
|
|
1969
|
-
|
|
2037
|
+
const constructor = a.constructor;
|
|
1970
2038
|
if (constructor !== b.constructor) {
|
|
1971
2039
|
return false;
|
|
1972
2040
|
}
|
|
1973
2041
|
if (constructor === Object) {
|
|
1974
2042
|
return areObjectsEqual2(a, b, state);
|
|
1975
2043
|
}
|
|
1976
|
-
if (
|
|
2044
|
+
if (constructor === Array) {
|
|
1977
2045
|
return areArraysEqual2(a, b, state);
|
|
1978
2046
|
}
|
|
1979
|
-
if (isTypedArray$2 != null && isTypedArray$2(a)) {
|
|
1980
|
-
return areTypedArraysEqual2(a, b, state);
|
|
1981
|
-
}
|
|
1982
2047
|
if (constructor === Date) {
|
|
1983
2048
|
return areDatesEqual2(a, b, state);
|
|
1984
2049
|
}
|
|
@@ -1991,79 +2056,55 @@
|
|
|
1991
2056
|
if (constructor === Set) {
|
|
1992
2057
|
return areSetsEqual2(a, b, state);
|
|
1993
2058
|
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
return areDatesEqual2(a, b, state);
|
|
1997
|
-
}
|
|
1998
|
-
if (tag === REG_EXP_TAG) {
|
|
1999
|
-
return areRegExpsEqual2(a, b, state);
|
|
2000
|
-
}
|
|
2001
|
-
if (tag === MAP_TAG) {
|
|
2002
|
-
return areMapsEqual2(a, b, state);
|
|
2003
|
-
}
|
|
2004
|
-
if (tag === SET_TAG) {
|
|
2005
|
-
return areSetsEqual2(a, b, state);
|
|
2006
|
-
}
|
|
2007
|
-
if (tag === OBJECT_TAG) {
|
|
2008
|
-
return typeof a.then !== "function" && typeof b.then !== "function" && areObjectsEqual2(a, b, state);
|
|
2059
|
+
if (constructor === Promise) {
|
|
2060
|
+
return false;
|
|
2009
2061
|
}
|
|
2010
|
-
if (
|
|
2011
|
-
return
|
|
2062
|
+
if (Array.isArray(a)) {
|
|
2063
|
+
return areArraysEqual2(a, b, state);
|
|
2012
2064
|
}
|
|
2013
|
-
|
|
2014
|
-
|
|
2065
|
+
const tag = toString.call(a);
|
|
2066
|
+
const supportedComparator = supportedComparatorMap[tag];
|
|
2067
|
+
if (supportedComparator) {
|
|
2068
|
+
return supportedComparator(a, b, state);
|
|
2015
2069
|
}
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {
|
|
2020
|
-
return arePrimitiveWrappersEqual2(a, b, state);
|
|
2021
|
-
}
|
|
2022
|
-
if (unknownTagComparators) {
|
|
2023
|
-
var unknownTagComparator = unknownTagComparators[tag];
|
|
2024
|
-
if (!unknownTagComparator) {
|
|
2025
|
-
var shortTag = getShortTag(a);
|
|
2026
|
-
if (shortTag) {
|
|
2027
|
-
unknownTagComparator = unknownTagComparators[shortTag];
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
if (unknownTagComparator) {
|
|
2031
|
-
return unknownTagComparator(a, b, state);
|
|
2032
|
-
}
|
|
2070
|
+
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, state, tag);
|
|
2071
|
+
if (unsupportedCustomComparator) {
|
|
2072
|
+
return unsupportedCustomComparator(a, b, state);
|
|
2033
2073
|
}
|
|
2034
2074
|
return false;
|
|
2035
2075
|
};
|
|
2036
2076
|
}
|
|
2037
|
-
function createEqualityComparatorConfig(
|
|
2038
|
-
|
|
2039
|
-
|
|
2077
|
+
function createEqualityComparatorConfig({ circular, createCustomConfig, strict }) {
|
|
2078
|
+
let config = {
|
|
2079
|
+
areArrayBuffersEqual,
|
|
2040
2080
|
areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,
|
|
2081
|
+
areDataViewsEqual,
|
|
2041
2082
|
areDatesEqual,
|
|
2042
2083
|
areErrorsEqual,
|
|
2043
|
-
areFunctionsEqual,
|
|
2084
|
+
areFunctionsEqual: strictEqual,
|
|
2044
2085
|
areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
|
|
2045
|
-
areNumbersEqual,
|
|
2086
|
+
areNumbersEqual: sameValueEqual,
|
|
2046
2087
|
areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
|
|
2047
2088
|
arePrimitiveWrappersEqual,
|
|
2048
2089
|
areRegExpsEqual,
|
|
2049
2090
|
areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,
|
|
2050
|
-
areTypedArraysEqual: strict ? areObjectsEqualStrict : areTypedArraysEqual,
|
|
2091
|
+
areTypedArraysEqual: strict ? combineComparators(areTypedArraysEqual, areObjectsEqualStrict) : areTypedArraysEqual,
|
|
2051
2092
|
areUrlsEqual,
|
|
2052
|
-
|
|
2093
|
+
getUnsupportedCustomComparator: void 0
|
|
2053
2094
|
};
|
|
2054
2095
|
if (createCustomConfig) {
|
|
2055
|
-
config = assign({}, config, createCustomConfig(config));
|
|
2096
|
+
config = Object.assign({}, config, createCustomConfig(config));
|
|
2056
2097
|
}
|
|
2057
2098
|
if (circular) {
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
config = assign({}, config, {
|
|
2063
|
-
areArraysEqual:
|
|
2064
|
-
areMapsEqual:
|
|
2065
|
-
areObjectsEqual:
|
|
2066
|
-
areSetsEqual:
|
|
2099
|
+
const areArraysEqual2 = createIsCircular(config.areArraysEqual);
|
|
2100
|
+
const areMapsEqual2 = createIsCircular(config.areMapsEqual);
|
|
2101
|
+
const areObjectsEqual2 = createIsCircular(config.areObjectsEqual);
|
|
2102
|
+
const areSetsEqual2 = createIsCircular(config.areSetsEqual);
|
|
2103
|
+
config = Object.assign({}, config, {
|
|
2104
|
+
areArraysEqual: areArraysEqual2,
|
|
2105
|
+
areMapsEqual: areMapsEqual2,
|
|
2106
|
+
areObjectsEqual: areObjectsEqual2,
|
|
2107
|
+
areSetsEqual: areSetsEqual2
|
|
2067
2108
|
});
|
|
2068
2109
|
}
|
|
2069
2110
|
return config;
|
|
@@ -2073,11 +2114,10 @@
|
|
|
2073
2114
|
return compare(a, b, state);
|
|
2074
2115
|
};
|
|
2075
2116
|
}
|
|
2076
|
-
function createIsEqual(
|
|
2077
|
-
var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;
|
|
2117
|
+
function createIsEqual({ circular, comparator, createState, equals, strict }) {
|
|
2078
2118
|
if (createState) {
|
|
2079
2119
|
return function isEqual(a, b) {
|
|
2080
|
-
|
|
2120
|
+
const { cache = circular ? /* @__PURE__ */ new WeakMap() : void 0, meta } = createState();
|
|
2081
2121
|
return comparator(a, b, {
|
|
2082
2122
|
cache,
|
|
2083
2123
|
equals,
|
|
@@ -2096,7 +2136,7 @@
|
|
|
2096
2136
|
});
|
|
2097
2137
|
};
|
|
2098
2138
|
}
|
|
2099
|
-
|
|
2139
|
+
const state = {
|
|
2100
2140
|
cache: void 0,
|
|
2101
2141
|
equals,
|
|
2102
2142
|
meta: void 0,
|
|
@@ -2106,7 +2146,50 @@
|
|
|
2106
2146
|
return comparator(a, b, state);
|
|
2107
2147
|
};
|
|
2108
2148
|
}
|
|
2109
|
-
|
|
2149
|
+
function createSupportedComparatorMap({ areArrayBuffersEqual: areArrayBuffersEqual2, areArraysEqual: areArraysEqual2, areDataViewsEqual: areDataViewsEqual2, areDatesEqual: areDatesEqual2, areErrorsEqual: areErrorsEqual2, areFunctionsEqual, areMapsEqual: areMapsEqual2, areNumbersEqual, areObjectsEqual: areObjectsEqual2, arePrimitiveWrappersEqual: arePrimitiveWrappersEqual2, areRegExpsEqual: areRegExpsEqual2, areSetsEqual: areSetsEqual2, areTypedArraysEqual: areTypedArraysEqual2, areUrlsEqual: areUrlsEqual2 }) {
|
|
2150
|
+
return {
|
|
2151
|
+
"[object Arguments]": areObjectsEqual2,
|
|
2152
|
+
"[object Array]": areArraysEqual2,
|
|
2153
|
+
"[object ArrayBuffer]": areArrayBuffersEqual2,
|
|
2154
|
+
"[object AsyncGeneratorFunction]": areFunctionsEqual,
|
|
2155
|
+
"[object BigInt]": areNumbersEqual,
|
|
2156
|
+
"[object BigInt64Array]": areTypedArraysEqual2,
|
|
2157
|
+
"[object BigUint64Array]": areTypedArraysEqual2,
|
|
2158
|
+
"[object Boolean]": arePrimitiveWrappersEqual2,
|
|
2159
|
+
"[object DataView]": areDataViewsEqual2,
|
|
2160
|
+
"[object Date]": areDatesEqual2,
|
|
2161
|
+
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
|
2162
|
+
// enumerable, and therefore will give false positives if tested like a standard object.
|
|
2163
|
+
"[object Error]": areErrorsEqual2,
|
|
2164
|
+
"[object Float16Array]": areTypedArraysEqual2,
|
|
2165
|
+
"[object Float32Array]": areTypedArraysEqual2,
|
|
2166
|
+
"[object Float64Array]": areTypedArraysEqual2,
|
|
2167
|
+
"[object Function]": areFunctionsEqual,
|
|
2168
|
+
"[object GeneratorFunction]": areFunctionsEqual,
|
|
2169
|
+
"[object Int8Array]": areTypedArraysEqual2,
|
|
2170
|
+
"[object Int16Array]": areTypedArraysEqual2,
|
|
2171
|
+
"[object Int32Array]": areTypedArraysEqual2,
|
|
2172
|
+
"[object Map]": areMapsEqual2,
|
|
2173
|
+
"[object Number]": arePrimitiveWrappersEqual2,
|
|
2174
|
+
"[object Object]": (a, b, state) => (
|
|
2175
|
+
// The exception for value comparison is custom `Promise`-like class instances. These should
|
|
2176
|
+
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
|
2177
|
+
// it reaches this point then that strict equality comparison has already failed.
|
|
2178
|
+
typeof a.then !== "function" && typeof b.then !== "function" && areObjectsEqual2(a, b, state)
|
|
2179
|
+
),
|
|
2180
|
+
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
|
2181
|
+
// tested like a standard object.
|
|
2182
|
+
"[object RegExp]": areRegExpsEqual2,
|
|
2183
|
+
"[object Set]": areSetsEqual2,
|
|
2184
|
+
"[object String]": arePrimitiveWrappersEqual2,
|
|
2185
|
+
"[object URL]": areUrlsEqual2,
|
|
2186
|
+
"[object Uint8Array]": areTypedArraysEqual2,
|
|
2187
|
+
"[object Uint8ClampedArray]": areTypedArraysEqual2,
|
|
2188
|
+
"[object Uint16Array]": areTypedArraysEqual2,
|
|
2189
|
+
"[object Uint32Array]": areTypedArraysEqual2
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
const deepEqual = createCustomEqual();
|
|
2110
2193
|
createCustomEqual({ strict: true });
|
|
2111
2194
|
createCustomEqual({ circular: true });
|
|
2112
2195
|
createCustomEqual({
|
|
@@ -2114,37 +2197,26 @@
|
|
|
2114
2197
|
strict: true
|
|
2115
2198
|
});
|
|
2116
2199
|
createCustomEqual({
|
|
2117
|
-
createInternalComparator:
|
|
2118
|
-
return sameValueZeroEqual;
|
|
2119
|
-
}
|
|
2200
|
+
createInternalComparator: () => sameValueEqual
|
|
2120
2201
|
});
|
|
2121
2202
|
createCustomEqual({
|
|
2122
2203
|
strict: true,
|
|
2123
|
-
createInternalComparator:
|
|
2124
|
-
return sameValueZeroEqual;
|
|
2125
|
-
}
|
|
2204
|
+
createInternalComparator: () => sameValueEqual
|
|
2126
2205
|
});
|
|
2127
2206
|
createCustomEqual({
|
|
2128
2207
|
circular: true,
|
|
2129
|
-
createInternalComparator:
|
|
2130
|
-
return sameValueZeroEqual;
|
|
2131
|
-
}
|
|
2208
|
+
createInternalComparator: () => sameValueEqual
|
|
2132
2209
|
});
|
|
2133
2210
|
createCustomEqual({
|
|
2134
2211
|
circular: true,
|
|
2135
|
-
createInternalComparator:
|
|
2136
|
-
return sameValueZeroEqual;
|
|
2137
|
-
},
|
|
2212
|
+
createInternalComparator: () => sameValueEqual,
|
|
2138
2213
|
strict: true
|
|
2139
2214
|
});
|
|
2140
|
-
function createCustomEqual(options) {
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
var config = createEqualityComparatorConfig(options);
|
|
2146
|
-
var comparator = createEqualityComparator(config);
|
|
2147
|
-
var equals = createCustomInternalComparator ? createCustomInternalComparator(comparator) : createInternalEqualityComparator(comparator);
|
|
2215
|
+
function createCustomEqual(options = {}) {
|
|
2216
|
+
const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false } = options;
|
|
2217
|
+
const config = createEqualityComparatorConfig(options);
|
|
2218
|
+
const comparator = createEqualityComparator(config);
|
|
2219
|
+
const equals = createCustomInternalComparator ? createCustomInternalComparator(comparator) : createInternalEqualityComparator(comparator);
|
|
2148
2220
|
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
2149
2221
|
}
|
|
2150
2222
|
function listCacheClear$1() {
|
|
@@ -2619,8 +2691,8 @@
|
|
|
2619
2691
|
var freeExports = exports$1 && !exports$1.nodeType && exports$1;
|
|
2620
2692
|
var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
|
|
2621
2693
|
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
2622
|
-
var
|
|
2623
|
-
var nativeIsBuffer =
|
|
2694
|
+
var Buffer2 = moduleExports ? root2.Buffer : void 0;
|
|
2695
|
+
var nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0;
|
|
2624
2696
|
var isBuffer2 = nativeIsBuffer || stubFalse2;
|
|
2625
2697
|
module2.exports = isBuffer2;
|
|
2626
2698
|
})(isBuffer$2, isBuffer$2.exports);
|
|
@@ -2785,7 +2857,7 @@
|
|
|
2785
2857
|
var freeExports = exports$1 && !exports$1.nodeType && exports$1;
|
|
2786
2858
|
var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
|
|
2787
2859
|
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
2788
|
-
var
|
|
2860
|
+
var Buffer2 = moduleExports ? root2.Buffer : void 0, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : void 0;
|
|
2789
2861
|
function cloneBuffer2(buffer, isDeep) {
|
|
2790
2862
|
if (isDeep) {
|
|
2791
2863
|
return buffer.slice();
|
|
@@ -3394,7 +3466,10 @@
|
|
|
3394
3466
|
if (!relation) {
|
|
3395
3467
|
throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug}'`);
|
|
3396
3468
|
}
|
|
3397
|
-
|
|
3469
|
+
const target = relation.target();
|
|
3470
|
+
const targetRelationKey = relation.relationName || target.slug;
|
|
3471
|
+
const targetSlug = relation.overrides?.slug ?? targetRelationKey;
|
|
3472
|
+
currentCollection = this.get(targetSlug) || this.normalizeCollection(target);
|
|
3398
3473
|
if (i + 1 < pathSegments.length) ;
|
|
3399
3474
|
}
|
|
3400
3475
|
return currentCollection;
|
|
@@ -3443,7 +3518,7 @@
|
|
|
3443
3518
|
if (!subcollection) {
|
|
3444
3519
|
throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug}`);
|
|
3445
3520
|
}
|
|
3446
|
-
currentCollection = subcollection;
|
|
3521
|
+
currentCollection = this.get(subcollection.slug) || this.normalizeCollection(subcollection);
|
|
3447
3522
|
collections.push(currentCollection);
|
|
3448
3523
|
}
|
|
3449
3524
|
}
|
|
@@ -4485,7 +4560,25 @@
|
|
|
4485
4560
|
return result;
|
|
4486
4561
|
}
|
|
4487
4562
|
return value;
|
|
4563
|
+
case "string":
|
|
4564
|
+
if (typeof value === "string") {
|
|
4565
|
+
if (value.startsWith("data:application/octet-stream;base64,")) {
|
|
4566
|
+
const base64Data = value.split(",")[1];
|
|
4567
|
+
if (base64Data) {
|
|
4568
|
+
return Buffer.from(base64Data, "base64");
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4571
|
+
}
|
|
4572
|
+
return value;
|
|
4488
4573
|
default:
|
|
4574
|
+
if (typeof value === "string") {
|
|
4575
|
+
if (value.startsWith("data:application/octet-stream;base64,")) {
|
|
4576
|
+
const base64Data = value.split(",")[1];
|
|
4577
|
+
if (base64Data) {
|
|
4578
|
+
return Buffer.from(base64Data, "base64");
|
|
4579
|
+
}
|
|
4580
|
+
}
|
|
4581
|
+
}
|
|
4489
4582
|
return value;
|
|
4490
4583
|
}
|
|
4491
4584
|
}
|
|
@@ -4611,6 +4704,37 @@
|
|
|
4611
4704
|
return value;
|
|
4612
4705
|
}
|
|
4613
4706
|
switch (property.type) {
|
|
4707
|
+
case "string": {
|
|
4708
|
+
if (typeof value === "string") return value;
|
|
4709
|
+
let isBuffer2 = false;
|
|
4710
|
+
let buf = null;
|
|
4711
|
+
if (Buffer.isBuffer(value)) {
|
|
4712
|
+
isBuffer2 = true;
|
|
4713
|
+
buf = value;
|
|
4714
|
+
} else if (typeof value === "object" && value !== null && value.type === "Buffer" && Array.isArray(value.data)) {
|
|
4715
|
+
isBuffer2 = true;
|
|
4716
|
+
buf = Buffer.from(value.data);
|
|
4717
|
+
}
|
|
4718
|
+
if (isBuffer2 && buf) {
|
|
4719
|
+
let isPrintable = true;
|
|
4720
|
+
for (let i = 0; i < buf.length; i++) {
|
|
4721
|
+
const b = buf[i];
|
|
4722
|
+
if ((b < 32 || b > 126) && b !== 9 && b !== 10 && b !== 13) {
|
|
4723
|
+
isPrintable = false;
|
|
4724
|
+
break;
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
return isPrintable ? buf.toString("utf8") : `data:application/octet-stream;base64,${buf.toString("base64")}`;
|
|
4728
|
+
}
|
|
4729
|
+
if (typeof value === "object" && value !== null) {
|
|
4730
|
+
try {
|
|
4731
|
+
return JSON.stringify(value);
|
|
4732
|
+
} catch {
|
|
4733
|
+
return String(value);
|
|
4734
|
+
}
|
|
4735
|
+
}
|
|
4736
|
+
return String(value);
|
|
4737
|
+
}
|
|
4614
4738
|
case "relation":
|
|
4615
4739
|
if (typeof value === "string" || typeof value === "number") {
|
|
4616
4740
|
let relationDef = property.relation;
|
|
@@ -4694,8 +4818,29 @@
|
|
|
4694
4818
|
}
|
|
4695
4819
|
return null;
|
|
4696
4820
|
}
|
|
4697
|
-
default:
|
|
4821
|
+
default: {
|
|
4822
|
+
let isBuffer2 = false;
|
|
4823
|
+
let buf = null;
|
|
4824
|
+
if (Buffer.isBuffer(value)) {
|
|
4825
|
+
isBuffer2 = true;
|
|
4826
|
+
buf = value;
|
|
4827
|
+
} else if (typeof value === "object" && value !== null && value.type === "Buffer" && Array.isArray(value.data)) {
|
|
4828
|
+
isBuffer2 = true;
|
|
4829
|
+
buf = Buffer.from(value.data);
|
|
4830
|
+
}
|
|
4831
|
+
if (isBuffer2 && buf) {
|
|
4832
|
+
let isPrintable = true;
|
|
4833
|
+
for (let i = 0; i < buf.length; i++) {
|
|
4834
|
+
const b = buf[i];
|
|
4835
|
+
if ((b < 32 || b > 126) && b !== 9 && b !== 10 && b !== 13) {
|
|
4836
|
+
isPrintable = false;
|
|
4837
|
+
break;
|
|
4838
|
+
}
|
|
4839
|
+
}
|
|
4840
|
+
return isPrintable ? buf.toString("utf8") : `data:application/octet-stream;base64,${buf.toString("base64")}`;
|
|
4841
|
+
}
|
|
4698
4842
|
return value;
|
|
4843
|
+
}
|
|
4699
4844
|
}
|
|
4700
4845
|
}
|
|
4701
4846
|
function normalizeScalarValues(data, properties, collection, resolvedRelations, options) {
|
|
@@ -5963,6 +6108,10 @@
|
|
|
5963
6108
|
await this.resolveJoinPathRelations(entity, collection, collectionPath, parsedId, databaseId);
|
|
5964
6109
|
return entity;
|
|
5965
6110
|
} catch (e) {
|
|
6111
|
+
if (e instanceof Error && e.message.includes("not enough information to infer relation")) {
|
|
6112
|
+
console.error(`[EntityFetchService] Relation inference error for collection '${collectionPath}': ${e.message}`);
|
|
6113
|
+
console.error(`Hint: This usually means a relation in your drizzle schema is missing a reciprocal 'one()' or 'many()' definition. Run 'rebase schema generate' to fix this.`);
|
|
6114
|
+
}
|
|
5966
6115
|
console.warn(`[EntityFetchService] db.query.findFirst failed for ${collectionPath}, falling back to db.select:`, e);
|
|
5967
6116
|
}
|
|
5968
6117
|
}
|
|
@@ -6023,6 +6172,10 @@
|
|
|
6023
6172
|
const entities = results2.map((row) => this.drizzleResultToEntity(row, collection, collectionPath, idInfo, options.databaseId, idInfoArray));
|
|
6024
6173
|
return entities;
|
|
6025
6174
|
} catch (e) {
|
|
6175
|
+
if (e instanceof Error && e.message.includes("not enough information to infer relation")) {
|
|
6176
|
+
console.error(`[EntityFetchService] Relation inference error for collection '${collectionPath}': ${e.message}`);
|
|
6177
|
+
console.error(`Hint: This usually means a relation in your drizzle schema is missing a reciprocal 'one()' or 'many()' definition. Run 'rebase schema generate' to fix this.`);
|
|
6178
|
+
}
|
|
6026
6179
|
console.warn(`[EntityFetchService] db.query.findMany failed for ${collectionPath}, falling back to db.select:`, e);
|
|
6027
6180
|
}
|
|
6028
6181
|
}
|
|
@@ -6292,6 +6445,10 @@
|
|
|
6292
6445
|
await this.resolveJoinPathRelationsBatchRest(restRows, collection, collectionPath, idInfoArray, include);
|
|
6293
6446
|
return restRows;
|
|
6294
6447
|
} catch (e) {
|
|
6448
|
+
if (e instanceof Error && e.message.includes("not enough information to infer relation")) {
|
|
6449
|
+
console.error(`[EntityFetchService] Relation inference error for collection '${collectionPath}': ${e.message}`);
|
|
6450
|
+
console.error(`Hint: This usually means a relation in your drizzle schema is missing a reciprocal 'one()' or 'many()' definition. Run 'rebase schema generate' to fix this.`);
|
|
6451
|
+
}
|
|
6295
6452
|
console.warn(`[fetchCollectionForRest] db.query.findMany failed for ${collectionPath}, falling back:`, e);
|
|
6296
6453
|
}
|
|
6297
6454
|
}
|
|
@@ -6372,6 +6529,10 @@
|
|
|
6372
6529
|
await this.resolveJoinPathRelationsBatchRest([restRow], collection, collectionPath, idInfoArray, include);
|
|
6373
6530
|
return restRow;
|
|
6374
6531
|
} catch (e) {
|
|
6532
|
+
if (e instanceof Error && e.message.includes("not enough information to infer relation")) {
|
|
6533
|
+
console.error(`[EntityFetchService] Relation inference error for collection '${collectionPath}': ${e.message}`);
|
|
6534
|
+
console.error(`Hint: This usually means a relation in your drizzle schema is missing a reciprocal 'one()' or 'many()' definition. Run 'rebase schema generate' to fix this.`);
|
|
6535
|
+
}
|
|
6375
6536
|
console.warn(`[fetchEntityForRest] db.query.findFirst failed for ${collectionPath}, falling back:`, e);
|
|
6376
6537
|
}
|
|
6377
6538
|
}
|
|
@@ -6630,7 +6791,7 @@
|
|
|
6630
6791
|
targetColumnName = relation.localKey;
|
|
6631
6792
|
} else if (relation.foreignKeyOnTarget) {
|
|
6632
6793
|
targetColumnName = relation.foreignKeyOnTarget;
|
|
6633
|
-
} else if (relation.joinPath && relation.joinPath.length
|
|
6794
|
+
} else if (relation.joinPath && relation.joinPath.length === 1) {
|
|
6634
6795
|
const targetTableName = getTableName(targetCollection);
|
|
6635
6796
|
const relevantJoinStep = relation.joinPath.find((joinStep) => joinStep.table === targetTableName);
|
|
6636
6797
|
if (relevantJoinStep) {
|
|
@@ -6641,6 +6802,8 @@
|
|
|
6641
6802
|
const targetColumnNames = DrizzleConditionBuilder.getColumnNamesFromColumns(relation.joinPath[0].on.to);
|
|
6642
6803
|
targetColumnName = targetColumnNames[0];
|
|
6643
6804
|
}
|
|
6805
|
+
} else if (relation.joinPath && relation.joinPath.length > 1) {
|
|
6806
|
+
break;
|
|
6644
6807
|
} else {
|
|
6645
6808
|
throw new Error(`Relation '${relationKey}' lacks configuration for path-based saving.`);
|
|
6646
6809
|
}
|
|
@@ -6763,22 +6926,78 @@
|
|
|
6763
6926
|
const pgError = this.extractPgError(error);
|
|
6764
6927
|
if (pgError) {
|
|
6765
6928
|
const detail = pgError.detail;
|
|
6929
|
+
const hint = pgError.hint;
|
|
6766
6930
|
const constraint = pgError.constraint;
|
|
6767
6931
|
const column = pgError.column;
|
|
6768
6932
|
const table = pgError.table;
|
|
6933
|
+
const dataType = pgError.dataType;
|
|
6934
|
+
const pgMessage = pgError.message || "Unknown database error";
|
|
6935
|
+
const suffix = hint ? ` Hint: ${hint}` : "";
|
|
6936
|
+
const tableRef = table ?? collectionSlug;
|
|
6769
6937
|
switch (pgError.code) {
|
|
6770
6938
|
case "23503":
|
|
6771
|
-
return new Error(detail ? `Foreign key constraint violated: ${detail}` : `Cannot save: a foreign key constraint${constraint ? ` (${constraint})` : ""} was violated in "${collectionSlug}"
|
|
6939
|
+
return new Error(detail ? `Foreign key constraint violated: ${detail}${suffix}` : `Cannot save: a foreign key constraint${constraint ? ` (${constraint})` : ""} was violated in "${collectionSlug}".${suffix}`);
|
|
6772
6940
|
case "23505":
|
|
6773
|
-
return new Error(detail ? `Duplicate value: ${detail}` : `Cannot save: a unique constraint${constraint ? ` (${constraint})` : ""} was violated in "${collectionSlug}"
|
|
6941
|
+
return new Error(detail ? `Duplicate value: ${detail}${suffix}` : `Cannot save: a unique constraint${constraint ? ` (${constraint})` : ""} was violated in "${collectionSlug}".${suffix}`);
|
|
6774
6942
|
case "23502":
|
|
6775
|
-
return new Error(`Missing required field: "${column ?? "unknown"}" in "${
|
|
6943
|
+
return new Error(`Missing required field: "${column ?? "unknown"}" in "${tableRef}" cannot be empty.${suffix}`);
|
|
6776
6944
|
case "23514":
|
|
6777
|
-
return new Error(`Validation failed: a check constraint${constraint ? ` (${constraint})` : ""} was violated in "${collectionSlug}"
|
|
6945
|
+
return new Error(`Validation failed: a check constraint${constraint ? ` (${constraint})` : ""} was violated in "${collectionSlug}".${suffix}`);
|
|
6946
|
+
case "22P02":
|
|
6947
|
+
return new Error(`Invalid data format in "${collectionSlug}": ${pgMessage}${suffix}`);
|
|
6948
|
+
case "22001":
|
|
6949
|
+
return new Error(`Value too long for column "${column ?? "unknown"}" in "${tableRef}": ${pgMessage}${suffix}`);
|
|
6950
|
+
case "22003":
|
|
6951
|
+
return new Error(`Numeric value out of range for column "${column ?? "unknown"}" in "${tableRef}": ${pgMessage}${suffix}`);
|
|
6952
|
+
case "42703":
|
|
6953
|
+
return new Error(`Unknown column in "${tableRef}": ${pgMessage}. Check if your schema is up to date (run migrations).${suffix}`);
|
|
6954
|
+
case "42P01":
|
|
6955
|
+
return new Error(`Table not found for "${collectionSlug}": ${pgMessage}. Check if your schema is up to date (run migrations).${suffix}`);
|
|
6956
|
+
default: {
|
|
6957
|
+
const parts = [`Database error in "${collectionSlug}" [${pgError.code}]: ${pgMessage}`];
|
|
6958
|
+
if (detail) parts.push(`Detail: ${detail}`);
|
|
6959
|
+
if (column) parts.push(`Column: ${column}`);
|
|
6960
|
+
if (dataType) parts.push(`Data type: ${dataType}`);
|
|
6961
|
+
if (constraint) parts.push(`Constraint: ${constraint}`);
|
|
6962
|
+
if (hint) parts.push(`Hint: ${hint}`);
|
|
6963
|
+
return new Error(parts.join(". "));
|
|
6964
|
+
}
|
|
6965
|
+
}
|
|
6966
|
+
}
|
|
6967
|
+
const causeMessage = this.extractCauseMessage(error);
|
|
6968
|
+
if (causeMessage) {
|
|
6969
|
+
return new Error(`Database error in "${collectionSlug}": ${causeMessage}`);
|
|
6970
|
+
}
|
|
6971
|
+
if (error instanceof Error) {
|
|
6972
|
+
const cleaned = this.stripSqlFromMessage(error.message, collectionSlug);
|
|
6973
|
+
return new Error(cleaned);
|
|
6974
|
+
}
|
|
6975
|
+
return new Error(`Database error in "${collectionSlug}": ${String(error)}`);
|
|
6976
|
+
}
|
|
6977
|
+
/**
|
|
6978
|
+
* Walk the error cause chain and return the deepest meaningful message.
|
|
6979
|
+
*/
|
|
6980
|
+
extractCauseMessage(error) {
|
|
6981
|
+
if (!error || typeof error !== "object") return null;
|
|
6982
|
+
const err = error;
|
|
6983
|
+
if (err.cause && typeof err.cause === "object") {
|
|
6984
|
+
const deeper = this.extractCauseMessage(err.cause);
|
|
6985
|
+
if (deeper) return deeper;
|
|
6986
|
+
if (err.cause instanceof Error && err.cause.message) {
|
|
6987
|
+
return err.cause.message;
|
|
6778
6988
|
}
|
|
6779
6989
|
}
|
|
6780
|
-
|
|
6781
|
-
|
|
6990
|
+
return null;
|
|
6991
|
+
}
|
|
6992
|
+
/**
|
|
6993
|
+
* Strip the raw SQL query from a Drizzle "Failed query: ..." message,
|
|
6994
|
+
* keeping only the error description.
|
|
6995
|
+
*/
|
|
6996
|
+
stripSqlFromMessage(message, collectionSlug) {
|
|
6997
|
+
if (message.startsWith("Failed query:")) {
|
|
6998
|
+
return `Failed to save entity in "${collectionSlug}". Check server logs for details.`;
|
|
6999
|
+
}
|
|
7000
|
+
return message;
|
|
6782
7001
|
}
|
|
6783
7002
|
/**
|
|
6784
7003
|
* Extract the underlying PostgreSQL error from a Drizzle wrapper.
|
|
@@ -6787,7 +7006,7 @@
|
|
|
6787
7006
|
extractPgError(error) {
|
|
6788
7007
|
if (!error || typeof error !== "object") return null;
|
|
6789
7008
|
const err = error;
|
|
6790
|
-
if (err.code && /^[0-
|
|
7009
|
+
if (err.code && /^[0-9A-Z]{5}$/.test(err.code)) {
|
|
6791
7010
|
return err;
|
|
6792
7011
|
}
|
|
6793
7012
|
if (err.cause && typeof err.cause === "object") {
|
|
@@ -7075,6 +7294,7 @@
|
|
|
7075
7294
|
branchService;
|
|
7076
7295
|
user;
|
|
7077
7296
|
data;
|
|
7297
|
+
client;
|
|
7078
7298
|
/**
|
|
7079
7299
|
* When true, realtime notifications are deferred until after the
|
|
7080
7300
|
* wrapping transaction commits. Set by `withAuth` → `withTransaction`.
|
|
@@ -7103,6 +7323,14 @@
|
|
|
7103
7323
|
} : {}
|
|
7104
7324
|
};
|
|
7105
7325
|
}
|
|
7326
|
+
/**
|
|
7327
|
+
* REST-optimised fetch service (include-aware eager-loading).
|
|
7328
|
+
* Delegates to the underlying EntityFetchService which already
|
|
7329
|
+
* implements the matching method signatures.
|
|
7330
|
+
*/
|
|
7331
|
+
get restFetchService() {
|
|
7332
|
+
return this.entityService.getFetchService();
|
|
7333
|
+
}
|
|
7106
7334
|
resolveCollectionCallbacks(collection, path2) {
|
|
7107
7335
|
if (!collection && !path2) return {
|
|
7108
7336
|
collection: void 0,
|
|
@@ -7156,7 +7384,8 @@
|
|
|
7156
7384
|
const contextForCallback = {
|
|
7157
7385
|
user: this.user,
|
|
7158
7386
|
driver: this,
|
|
7159
|
-
data: this.data
|
|
7387
|
+
data: this.data,
|
|
7388
|
+
client: this.client
|
|
7160
7389
|
};
|
|
7161
7390
|
return Promise.all(entities.map(async (entity) => {
|
|
7162
7391
|
let fetched = entity;
|
|
@@ -7250,7 +7479,8 @@
|
|
|
7250
7479
|
const contextForCallback = {
|
|
7251
7480
|
user: this.user,
|
|
7252
7481
|
driver: this,
|
|
7253
|
-
data: this.data
|
|
7482
|
+
data: this.data,
|
|
7483
|
+
client: this.client
|
|
7254
7484
|
};
|
|
7255
7485
|
if (callbacks?.afterRead) {
|
|
7256
7486
|
entity = await callbacks.afterRead({
|
|
@@ -7319,7 +7549,8 @@
|
|
|
7319
7549
|
const contextForCallback = {
|
|
7320
7550
|
user: this.user,
|
|
7321
7551
|
driver: this,
|
|
7322
|
-
data: this.data
|
|
7552
|
+
data: this.data,
|
|
7553
|
+
client: this.client
|
|
7323
7554
|
};
|
|
7324
7555
|
let previousValuesForHistory;
|
|
7325
7556
|
if (status === "existing" && entityId) {
|
|
@@ -7354,6 +7585,14 @@
|
|
|
7354
7585
|
if (result) updatedValues = mergeDeep(updatedValues, result);
|
|
7355
7586
|
}
|
|
7356
7587
|
}
|
|
7588
|
+
if (resolvedCollection?.properties) {
|
|
7589
|
+
updatedValues = updateDateAutoValues({
|
|
7590
|
+
inputValues: updatedValues,
|
|
7591
|
+
properties: resolvedCollection.properties,
|
|
7592
|
+
status: status ?? "new",
|
|
7593
|
+
timestampNowValue: /* @__PURE__ */ new Date()
|
|
7594
|
+
});
|
|
7595
|
+
}
|
|
7357
7596
|
try {
|
|
7358
7597
|
let savedEntity = await this.entityService.saveEntity(path2, updatedValues, entityId, resolvedCollection?.databaseId);
|
|
7359
7598
|
if (savedEntity && (callbacks?.afterRead || propertyCallbacks?.afterRead)) {
|
|
@@ -7459,7 +7698,8 @@
|
|
|
7459
7698
|
const contextForCallback = {
|
|
7460
7699
|
user: this.user,
|
|
7461
7700
|
driver: this,
|
|
7462
|
-
data: this.data
|
|
7701
|
+
data: this.data,
|
|
7702
|
+
client: this.client
|
|
7463
7703
|
};
|
|
7464
7704
|
if (callbacks?.beforeDelete || propertyCallbacks?.beforeDelete) {
|
|
7465
7705
|
if (callbacks?.beforeDelete) {
|
|
@@ -7786,6 +8026,7 @@
|
|
|
7786
8026
|
txDelegate.entityService = txEntityService;
|
|
7787
8027
|
txDelegate._deferNotifications = true;
|
|
7788
8028
|
txDelegate._pendingNotifications = pendingNotifications;
|
|
8029
|
+
txDelegate.client = this.delegate.client;
|
|
7789
8030
|
return await operation(txDelegate);
|
|
7790
8031
|
});
|
|
7791
8032
|
for (const notification of pendingNotifications) {
|
|
@@ -8067,6 +8308,12 @@
|
|
|
8067
8308
|
references: [users.id]
|
|
8068
8309
|
})
|
|
8069
8310
|
}));
|
|
8311
|
+
const resolveColumnName = (propName, prop) => {
|
|
8312
|
+
if (prop && "columnName" in prop && typeof prop.columnName === "string") {
|
|
8313
|
+
return prop.columnName;
|
|
8314
|
+
}
|
|
8315
|
+
return toSnakeCase(propName);
|
|
8316
|
+
};
|
|
8070
8317
|
const getPrimaryKeyProp = (collection) => {
|
|
8071
8318
|
if (collection.properties) {
|
|
8072
8319
|
const idPropEntry = Object.entries(collection.properties).find(([_, prop]) => "isId" in prop && Boolean(prop.isId));
|
|
@@ -8107,7 +8354,7 @@
|
|
|
8107
8354
|
return !hasExplicitId && propName === "id";
|
|
8108
8355
|
};
|
|
8109
8356
|
const getDrizzleColumn = (propName, prop, collection, collections) => {
|
|
8110
|
-
const colName =
|
|
8357
|
+
const colName = resolveColumnName(propName, prop);
|
|
8111
8358
|
let columnDefinition;
|
|
8112
8359
|
switch (prop.type) {
|
|
8113
8360
|
case "string": {
|
|
@@ -8179,6 +8426,9 @@
|
|
|
8179
8426
|
} else {
|
|
8180
8427
|
columnDefinition = `timestamp("${colName}", { withTimezone: true, mode: 'string' })`;
|
|
8181
8428
|
}
|
|
8429
|
+
if (dateProp.autoValue === "on_create" || dateProp.autoValue === "on_update") {
|
|
8430
|
+
columnDefinition += `.default(sql\`now()\`)`;
|
|
8431
|
+
}
|
|
8182
8432
|
break;
|
|
8183
8433
|
}
|
|
8184
8434
|
case "map":
|
|
@@ -8211,7 +8461,7 @@
|
|
|
8211
8461
|
} catch {
|
|
8212
8462
|
return null;
|
|
8213
8463
|
}
|
|
8214
|
-
const fkColumnName =
|
|
8464
|
+
const fkColumnName = relation.localKey;
|
|
8215
8465
|
const targetTableVar = getTableVarName(getTableName(targetCollection));
|
|
8216
8466
|
const pkProp = getPrimaryKeyProp(targetCollection);
|
|
8217
8467
|
const targetIdField = pkProp.name;
|
|
@@ -8399,7 +8649,7 @@
|
|
|
8399
8649
|
Object.entries(collection.properties ?? {}).forEach(([propName, prop]) => {
|
|
8400
8650
|
if ("enum" in prop && (prop.type === "string" || prop.type === "number") && prop.enum) {
|
|
8401
8651
|
const enumVarName = getEnumVarName(collectionPath, propName);
|
|
8402
|
-
const enumDbName = `${collectionPath}_${
|
|
8652
|
+
const enumDbName = `${collectionPath}_${resolveColumnName(propName, prop)}`;
|
|
8403
8653
|
const values = Array.isArray(prop.enum) ? prop.enum.map((v) => String(v.id ?? v)) : Object.keys(prop.enum);
|
|
8404
8654
|
if (values.length > 0) {
|
|
8405
8655
|
schemaContent += `export const ${enumVarName} = pgEnum("${enumDbName}", [${values.map((v) => `'${v}'`).join(", ")}]);
|
|
@@ -8456,9 +8706,9 @@
|
|
|
8456
8706
|
const targetId = getPrimaryKeyName(targetCollection);
|
|
8457
8707
|
schemaContent += `export const ${tableVarName} = pgTable("${tableName}", {
|
|
8458
8708
|
`;
|
|
8459
|
-
schemaContent += ` ${sourceColumn}: ${sourceColType}("${
|
|
8709
|
+
schemaContent += ` ${sourceColumn}: ${sourceColType}("${sourceColumn}").notNull().references(() => ${getTableVarName(getTableName(sourceCollection))}.${sourceId}, ${refOptions}),
|
|
8460
8710
|
`;
|
|
8461
|
-
schemaContent += ` ${targetColumn}: ${targetColType}("${
|
|
8711
|
+
schemaContent += ` ${targetColumn}: ${targetColType}("${targetColumn}").notNull().references(() => ${getTableVarName(getTableName(targetCollection))}.${targetId}, ${refOptions}),
|
|
8462
8712
|
`;
|
|
8463
8713
|
schemaContent += "}, (table) => ({\n";
|
|
8464
8714
|
schemaContent += ` pk: primaryKey({ columns: [table.${sourceColumn}, table.${targetColumn}] })
|
|
@@ -8551,29 +8801,10 @@
|
|
|
8551
8801
|
references: [${targetTableVar}.${getPrimaryKeyName(target)}],
|
|
8552
8802
|
relationName: "${drizzleRelationName}"
|
|
8553
8803
|
})`);
|
|
8554
|
-
} else if (rel.direction === "inverse"
|
|
8555
|
-
const sourceIdField = getPrimaryKeyName(collection);
|
|
8804
|
+
} else if (rel.direction === "inverse") {
|
|
8556
8805
|
tableRelations.push(` "${relationKey}": one(${targetTableVar}, {
|
|
8557
|
-
fields: [${tableVarName}.${sourceIdField}],
|
|
8558
|
-
references: [${targetTableVar}.${rel.foreignKeyOnTarget}],
|
|
8559
8806
|
relationName: "${drizzleRelationName}"
|
|
8560
8807
|
})`);
|
|
8561
|
-
} else if (rel.direction === "inverse" && !rel.foreignKeyOnTarget) {
|
|
8562
|
-
try {
|
|
8563
|
-
const targetCollection = rel.target();
|
|
8564
|
-
const targetResolvedRelations = resolveCollectionRelations(targetCollection);
|
|
8565
|
-
const correspondingRelation = Object.values(targetResolvedRelations).find((targetRel) => targetRel.direction === "owning" && targetRel.cardinality === "one" && targetRel.target().slug === collection.slug);
|
|
8566
|
-
if (correspondingRelation && correspondingRelation.localKey) {
|
|
8567
|
-
const sourceIdField = getPrimaryKeyName(collection);
|
|
8568
|
-
tableRelations.push(` "${relationKey}": one(${targetTableVar}, {
|
|
8569
|
-
fields: [${tableVarName}.${sourceIdField}],
|
|
8570
|
-
references: [${targetTableVar}.${correspondingRelation.localKey}],
|
|
8571
|
-
relationName: "${drizzleRelationName}"
|
|
8572
|
-
})`);
|
|
8573
|
-
}
|
|
8574
|
-
} catch (e) {
|
|
8575
|
-
console.warn(`Could not resolve inverse one-to-one relation '${relationKey}':`, e);
|
|
8576
|
-
}
|
|
8577
8808
|
}
|
|
8578
8809
|
} else if (rel.cardinality === "many") {
|
|
8579
8810
|
if (rel.direction === "inverse" && rel.foreignKeyOnTarget) {
|
|
@@ -8601,6 +8832,32 @@
|
|
|
8601
8832
|
console.warn(`Could not generate relation ${relationKey} for ${collection.name}:`, e);
|
|
8602
8833
|
}
|
|
8603
8834
|
}
|
|
8835
|
+
for (const otherCollection of collections) {
|
|
8836
|
+
if (otherCollection.slug === collection.slug) continue;
|
|
8837
|
+
const otherRelations = resolveCollectionRelations(otherCollection);
|
|
8838
|
+
for (const [otherKey, otherRel] of Object.entries(otherRelations)) {
|
|
8839
|
+
if (otherRel.direction === "inverse" && otherRel.foreignKeyOnTarget) {
|
|
8840
|
+
try {
|
|
8841
|
+
const otherTarget = otherRel.target();
|
|
8842
|
+
if (otherTarget.slug === collection.slug) {
|
|
8843
|
+
const drizzleRelationName = computeSharedRelationName(otherRel, otherCollection, collections);
|
|
8844
|
+
const deduplicationKey = `${drizzleRelationName}::owning`;
|
|
8845
|
+
if (!emittedRelationNames.has(deduplicationKey)) {
|
|
8846
|
+
const otherTableVar = getTableVarName(getTableName(otherCollection));
|
|
8847
|
+
const synthKey = `_synth_${otherTableVar}_${otherRel.foreignKeyOnTarget}`;
|
|
8848
|
+
tableRelations.push(` "${synthKey}": one(${otherTableVar}, {
|
|
8849
|
+
fields: [${tableVarName}.${otherRel.foreignKeyOnTarget}],
|
|
8850
|
+
references: [${otherTableVar}.${getPrimaryKeyName(otherCollection)}],
|
|
8851
|
+
relationName: "${drizzleRelationName}"
|
|
8852
|
+
})`);
|
|
8853
|
+
emittedRelationNames.add(deduplicationKey);
|
|
8854
|
+
}
|
|
8855
|
+
}
|
|
8856
|
+
} catch (e) {
|
|
8857
|
+
}
|
|
8858
|
+
}
|
|
8859
|
+
}
|
|
8860
|
+
}
|
|
8604
8861
|
}
|
|
8605
8862
|
if (tableRelations.length > 0) {
|
|
8606
8863
|
const relVarName = `${tableVarName}Relations`;
|