@rebasepro/server-postgresql 0.1.0 → 0.2.1

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.
Files changed (75) hide show
  1. package/LICENSE +22 -6
  2. package/dist/common/src/util/entities.d.ts +2 -2
  3. package/dist/common/src/util/relations.d.ts +1 -1
  4. package/dist/index.es.js +1250 -1665
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/index.umd.js +1196 -1611
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/server-postgresql/src/PostgresAdapter.d.ts +6 -0
  9. package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +2 -1
  10. package/dist/server-postgresql/src/PostgresBootstrapper.d.ts +0 -5
  11. package/dist/server-postgresql/src/auth/ensure-tables.d.ts +2 -1
  12. package/dist/server-postgresql/src/auth/services.d.ts +37 -15
  13. package/dist/server-postgresql/src/index.d.ts +1 -0
  14. package/dist/server-postgresql/src/schema/auth-schema.d.ts +43 -856
  15. package/dist/server-postgresql/src/schema/default-collections.d.ts +2 -0
  16. package/dist/server-postgresql/src/schema/doctor.d.ts +10 -1
  17. package/dist/server-postgresql/src/schema/introspect-db-logic.d.ts +1 -0
  18. package/dist/server-postgresql/src/services/entity-helpers.d.ts +1 -1
  19. package/dist/server-postgresql/src/services/realtimeService.d.ts +12 -0
  20. package/dist/server-postgresql/src/websocket.d.ts +2 -1
  21. package/dist/types/src/controllers/auth.d.ts +9 -8
  22. package/dist/types/src/controllers/client.d.ts +3 -0
  23. package/dist/types/src/types/auth_adapter.d.ts +356 -0
  24. package/dist/types/src/types/collections.d.ts +67 -2
  25. package/dist/types/src/types/database_adapter.d.ts +94 -0
  26. package/dist/types/src/types/entity_actions.d.ts +7 -1
  27. package/dist/types/src/types/entity_callbacks.d.ts +1 -1
  28. package/dist/types/src/types/entity_views.d.ts +36 -1
  29. package/dist/types/src/types/index.d.ts +2 -0
  30. package/dist/types/src/types/plugins.d.ts +1 -1
  31. package/dist/types/src/types/properties.d.ts +24 -5
  32. package/dist/types/src/types/property_config.d.ts +6 -2
  33. package/dist/types/src/types/relations.d.ts +1 -1
  34. package/dist/types/src/types/translations.d.ts +8 -0
  35. package/dist/types/src/users/user.d.ts +5 -0
  36. package/package.json +21 -15
  37. package/src/PostgresAdapter.ts +59 -0
  38. package/src/PostgresBackendDriver.ts +57 -8
  39. package/src/PostgresBootstrapper.ts +35 -15
  40. package/src/auth/ensure-tables.ts +82 -189
  41. package/src/auth/services.ts +421 -170
  42. package/src/cli.ts +44 -13
  43. package/src/data-transformer.ts +78 -8
  44. package/src/history/HistoryService.ts +25 -2
  45. package/src/index.ts +1 -0
  46. package/src/schema/auth-schema.ts +130 -98
  47. package/src/schema/default-collections.ts +68 -0
  48. package/src/schema/doctor-cli.ts +5 -1
  49. package/src/schema/doctor.ts +85 -8
  50. package/src/schema/generate-drizzle-schema-logic.ts +74 -27
  51. package/src/schema/generate-drizzle-schema.ts +13 -3
  52. package/src/schema/introspect-db-inference.ts +5 -5
  53. package/src/schema/introspect-db-logic.ts +9 -2
  54. package/src/schema/introspect-db.ts +14 -3
  55. package/src/services/EntityFetchService.ts +5 -5
  56. package/src/services/RelationService.ts +2 -2
  57. package/src/services/entity-helpers.ts +1 -1
  58. package/src/services/realtimeService.ts +145 -136
  59. package/src/utils/drizzle-conditions.ts +16 -2
  60. package/src/websocket.ts +113 -37
  61. package/test/auth-services.test.ts +163 -74
  62. package/test/data-transformer-hardening.test.ts +57 -0
  63. package/test/data-transformer.test.ts +43 -0
  64. package/test/generate-drizzle-schema.test.ts +7 -5
  65. package/test/introspect-db-utils.test.ts +4 -1
  66. package/test/postgresDataDriver.test.ts +17 -0
  67. package/test/realtimeService.test.ts +7 -7
  68. package/test/websocket.test.ts +139 -0
  69. package/examples/sdk-demo/node_modules/esbuild/LICENSE.md +0 -21
  70. package/examples/sdk-demo/node_modules/esbuild/README.md +0 -3
  71. package/examples/sdk-demo/node_modules/esbuild/bin/esbuild +0 -223
  72. package/examples/sdk-demo/node_modules/esbuild/install.js +0 -289
  73. package/examples/sdk-demo/node_modules/esbuild/lib/main.d.ts +0 -716
  74. package/examples/sdk-demo/node_modules/esbuild/lib/main.js +0 -2242
  75. package/examples/sdk-demo/node_modules/esbuild/package.json +0 -49
package/dist/index.es.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Pool, Client } from "pg";
2
2
  import { drizzle } from "drizzle-orm/node-postgres";
3
- import { sql, inArray, eq as eq$3, and, or, ilike, asc, desc, gt, lt, getTableName as getTableName$1, count, relations, isTable } from "drizzle-orm";
4
- import { pgSchema, timestamp, varchar, boolean, uuid, jsonb, primaryKey, unique } from "drizzle-orm/pg-core";
3
+ import { sql, inArray, eq, and, or, ilike, asc, desc, gt, lt, getTableName as getTableName$1, count, relations, isTable } from "drizzle-orm";
4
+ import { PgVarchar, PgText, PgChar, pgSchema, pgTable, timestamp, jsonb, varchar, boolean, uuid, primaryKey, unique, getTableConfig } from "drizzle-orm/pg-core";
5
5
  import { createHash, randomUUID } from "crypto";
6
6
  import * as fs from "fs";
7
7
  import { promises } from "fs";
@@ -51,6 +51,12 @@ function createPostgresDatabaseConnection(connectionString, schema, poolConfig)
51
51
  connectionString
52
52
  };
53
53
  }
54
+ class Vector {
55
+ value;
56
+ constructor(value) {
57
+ this.value = value;
58
+ }
59
+ }
54
60
  function isPostgresCollection(collection) {
55
61
  return !collection.driver || collection.driver === "postgres";
56
62
  }
@@ -127,19 +133,25 @@ const DEFAULT_ONE_OF_VALUE = "value";
127
133
  const tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
128
134
  const snakeCaseRegex = tokenizeRegex;
129
135
  const toSnakeCase = (str) => {
136
+ if (!str || typeof str !== "string") return "";
130
137
  const regExpMatchArray = str.match(snakeCaseRegex);
131
138
  if (!regExpMatchArray) return "";
132
139
  return regExpMatchArray.map((x) => x.toLowerCase()).join("_");
133
140
  };
134
- var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
135
- function getDefaultExportFromCjs(x) {
136
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
141
+ function camelCase(str) {
142
+ if (!str) return "";
143
+ if (str.length === 1) return str.toLowerCase();
144
+ const parts = str.split(/[-_ ]+/).filter(Boolean);
145
+ if (parts.length === 0) return "";
146
+ return parts[0].toLowerCase() + // Transform remaining parts to have first letter uppercase
147
+ parts.slice(1).map((part) => part.charAt(0).toUpperCase() + part.substring(1).toLowerCase()).join("");
137
148
  }
149
+ var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
138
150
  function commonjsRequire(path2) {
139
151
  throw new Error('Could not dynamically require "' + path2 + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
140
152
  }
141
153
  var object_hash = { exports: {} };
142
- (function(module, exports$1) {
154
+ (function(module, exports) {
143
155
  !function(e) {
144
156
  module.exports = e();
145
157
  }(function() {
@@ -921,7 +933,23 @@ var object_hash = { exports: {} };
921
933
  }, { buffer: 3, lYpoI2: 11 }] }, {}, [1])(1);
922
934
  });
923
935
  })(object_hash);
924
- function isObject$6(item) {
936
+ function deepClone(value) {
937
+ if (value === null || value === void 0) return value;
938
+ if (typeof value === "function") return value;
939
+ if (typeof value !== "object") return value;
940
+ if (Array.isArray(value)) {
941
+ return value.map((item) => deepClone(item));
942
+ }
943
+ if (Object.getPrototypeOf(value) !== Object.prototype) {
944
+ return value;
945
+ }
946
+ const result = {};
947
+ for (const key of Object.keys(value)) {
948
+ result[key] = deepClone(value[key]);
949
+ }
950
+ return result;
951
+ }
952
+ function isObject(item) {
925
953
  return !!item && typeof item === "object" && !Array.isArray(item);
926
954
  }
927
955
  function isPlainObject(obj) {
@@ -932,13 +960,13 @@ function isPlainObject(obj) {
932
960
  return proto === Object.prototype;
933
961
  }
934
962
  function mergeDeep(target, source, ignoreUndefined = false) {
935
- if (!isObject$6(target)) {
963
+ if (!isObject(target)) {
936
964
  return target;
937
965
  }
938
966
  const output = {
939
967
  ...target
940
968
  };
941
- if (!isObject$6(source)) {
969
+ if (!isObject(source)) {
942
970
  return output;
943
971
  }
944
972
  for (const key in source) {
@@ -979,7 +1007,7 @@ function mergeDeep(target, source, ignoreUndefined = false) {
979
1007
  } else {
980
1008
  output[key] = sourceValue;
981
1009
  }
982
- } else if (isObject$6(sourceValue)) {
1010
+ } else if (isObject(sourceValue)) {
983
1011
  output[key] = sourceValue;
984
1012
  } else {
985
1013
  output[key] = sourceValue;
@@ -1242,14 +1270,56 @@ const buildPropertyCallbacks = (properties) => {
1242
1270
  }
1243
1271
  return Object.keys(propertyCallbacks).length > 0 ? propertyCallbacks : void 0;
1244
1272
  };
1245
- function sanitizeRelation(relation, sourceCollection) {
1273
+ function sanitizeRelation(relation, sourceCollection, resolveCollection) {
1246
1274
  if (!relation.target) {
1247
1275
  throw new Error("Relation is missing a `target` collection.");
1248
1276
  }
1249
- const targetCollection = relation.target();
1277
+ const rawTarget = relation.target;
1278
+ let targetCollection;
1279
+ if (typeof rawTarget === "string") {
1280
+ if (resolveCollection) {
1281
+ targetCollection = resolveCollection(rawTarget);
1282
+ }
1283
+ if (!targetCollection) {
1284
+ targetCollection = {
1285
+ slug: rawTarget,
1286
+ name: rawTarget
1287
+ };
1288
+ }
1289
+ } else if (typeof rawTarget === "function") {
1290
+ const evaluated = rawTarget();
1291
+ if (typeof evaluated === "string") {
1292
+ if (resolveCollection) {
1293
+ targetCollection = resolveCollection(evaluated);
1294
+ }
1295
+ if (!targetCollection) {
1296
+ targetCollection = {
1297
+ slug: evaluated,
1298
+ name: evaluated
1299
+ };
1300
+ }
1301
+ } else {
1302
+ targetCollection = evaluated;
1303
+ }
1304
+ }
1305
+ if (!targetCollection) {
1306
+ throw new Error("Relation is missing a valid `target` collection.");
1307
+ }
1250
1308
  const newRelation = {
1251
1309
  ...relation
1252
1310
  };
1311
+ newRelation.target = () => {
1312
+ if (typeof rawTarget === "string") {
1313
+ return resolveCollection && resolveCollection(rawTarget) || targetCollection;
1314
+ } else if (typeof rawTarget === "function") {
1315
+ const evaluated = rawTarget();
1316
+ if (typeof evaluated === "string") {
1317
+ return resolveCollection && resolveCollection(evaluated) || targetCollection;
1318
+ }
1319
+ return evaluated;
1320
+ }
1321
+ return targetCollection;
1322
+ };
1253
1323
  if (!newRelation.relationName) {
1254
1324
  newRelation.relationName = toSnakeCase(targetCollection.slug);
1255
1325
  }
@@ -1302,6 +1372,17 @@ function sanitizeRelation(relation, sourceCollection) {
1302
1372
  break;
1303
1373
  }
1304
1374
  }
1375
+ if (!isManyToManyInverse && targetCollection.properties) {
1376
+ for (const [propKey, prop] of Object.entries(targetCollection.properties)) {
1377
+ if (prop.type !== "relation") continue;
1378
+ const relProp = prop;
1379
+ const relName = relProp.relationName || propKey;
1380
+ if (relName === newRelation.inverseRelationName && relProp.cardinality === "many" && (relProp.direction === "owning" || !relProp.direction)) {
1381
+ isManyToManyInverse = true;
1382
+ break;
1383
+ }
1384
+ }
1385
+ }
1305
1386
  } catch (e) {
1306
1387
  }
1307
1388
  }
@@ -1424,8 +1505,8 @@ function findRelation(resolvedRelations, key) {
1424
1505
  return void 0;
1425
1506
  }
1426
1507
  var logic = { exports: {} };
1427
- (function(module, exports$1) {
1428
- (function(root2, factory) {
1508
+ (function(module, exports) {
1509
+ (function(root, factory) {
1429
1510
  {
1430
1511
  module.exports = factory();
1431
1512
  }
@@ -1793,7 +1874,7 @@ var logic = { exports: {} };
1793
1874
  });
1794
1875
  })(logic);
1795
1876
  const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
1796
- const { hasOwnProperty: hasOwnProperty$a } = Object.prototype;
1877
+ const { hasOwnProperty } = Object.prototype;
1797
1878
  function combineComparators(comparatorA, comparatorB) {
1798
1879
  return function isEqual(a, b, state) {
1799
1880
  return comparatorA(a, b, state) && comparatorB(a, b, state);
@@ -1823,12 +1904,12 @@ function getStrictProperties(object) {
1823
1904
  }
1824
1905
  const hasOwn = (
1825
1906
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1826
- Object.hasOwn || ((object, property) => hasOwnProperty$a.call(object, property))
1907
+ Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property))
1827
1908
  );
1828
1909
  const PREACT_VNODE = "__v";
1829
1910
  const PREACT_OWNER = "__o";
1830
1911
  const REACT_OWNER = "_owner";
1831
- const { getOwnPropertyDescriptor, keys: keys$4 } = Object;
1912
+ const { getOwnPropertyDescriptor, keys } = Object;
1832
1913
  const sameValueEqual = (
1833
1914
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1834
1915
  Object.is || function sameValueEqual2(a, b) {
@@ -1906,9 +1987,9 @@ function areMapsEqual(a, b, state) {
1906
1987
  return true;
1907
1988
  }
1908
1989
  function areObjectsEqual(a, b, state) {
1909
- const properties = keys$4(a);
1990
+ const properties = keys(a);
1910
1991
  let index = properties.length;
1911
- if (keys$4(b).length !== index) {
1992
+ if (keys(b).length !== index) {
1912
1993
  return false;
1913
1994
  }
1914
1995
  while (index-- > 0) {
@@ -2181,7 +2262,7 @@ function createSupportedComparatorMap({ areArrayBuffersEqual: areArrayBuffersEqu
2181
2262
  "[object Uint32Array]": areTypedArraysEqual2
2182
2263
  };
2183
2264
  }
2184
- const deepEqual = createCustomEqual();
2265
+ const deepEqual$1 = createCustomEqual();
2185
2266
  createCustomEqual({ strict: true });
2186
2267
  createCustomEqual({ circular: true });
2187
2268
  createCustomEqual({
@@ -2211,982 +2292,6 @@ function createCustomEqual(options = {}) {
2211
2292
  const equals = createCustomInternalComparator ? createCustomInternalComparator(comparator) : createInternalEqualityComparator(comparator);
2212
2293
  return createIsEqual({ circular, comparator, createState, equals, strict });
2213
2294
  }
2214
- function listCacheClear$1() {
2215
- this.__data__ = [];
2216
- this.size = 0;
2217
- }
2218
- var _listCacheClear = listCacheClear$1;
2219
- function eq$2(value, other) {
2220
- return value === other || value !== value && other !== other;
2221
- }
2222
- var eq_1 = eq$2;
2223
- var eq$1 = eq_1;
2224
- function assocIndexOf$4(array, key) {
2225
- var length = array.length;
2226
- while (length--) {
2227
- if (eq$1(array[length][0], key)) {
2228
- return length;
2229
- }
2230
- }
2231
- return -1;
2232
- }
2233
- var _assocIndexOf = assocIndexOf$4;
2234
- var assocIndexOf$3 = _assocIndexOf;
2235
- var arrayProto = Array.prototype;
2236
- var splice = arrayProto.splice;
2237
- function listCacheDelete$1(key) {
2238
- var data = this.__data__, index = assocIndexOf$3(data, key);
2239
- if (index < 0) {
2240
- return false;
2241
- }
2242
- var lastIndex = data.length - 1;
2243
- if (index == lastIndex) {
2244
- data.pop();
2245
- } else {
2246
- splice.call(data, index, 1);
2247
- }
2248
- --this.size;
2249
- return true;
2250
- }
2251
- var _listCacheDelete = listCacheDelete$1;
2252
- var assocIndexOf$2 = _assocIndexOf;
2253
- function listCacheGet$1(key) {
2254
- var data = this.__data__, index = assocIndexOf$2(data, key);
2255
- return index < 0 ? void 0 : data[index][1];
2256
- }
2257
- var _listCacheGet = listCacheGet$1;
2258
- var assocIndexOf$1 = _assocIndexOf;
2259
- function listCacheHas$1(key) {
2260
- return assocIndexOf$1(this.__data__, key) > -1;
2261
- }
2262
- var _listCacheHas = listCacheHas$1;
2263
- var assocIndexOf = _assocIndexOf;
2264
- function listCacheSet$1(key, value) {
2265
- var data = this.__data__, index = assocIndexOf(data, key);
2266
- if (index < 0) {
2267
- ++this.size;
2268
- data.push([key, value]);
2269
- } else {
2270
- data[index][1] = value;
2271
- }
2272
- return this;
2273
- }
2274
- var _listCacheSet = listCacheSet$1;
2275
- var listCacheClear = _listCacheClear, listCacheDelete = _listCacheDelete, listCacheGet = _listCacheGet, listCacheHas = _listCacheHas, listCacheSet = _listCacheSet;
2276
- function ListCache$4(entries) {
2277
- var index = -1, length = entries == null ? 0 : entries.length;
2278
- this.clear();
2279
- while (++index < length) {
2280
- var entry = entries[index];
2281
- this.set(entry[0], entry[1]);
2282
- }
2283
- }
2284
- ListCache$4.prototype.clear = listCacheClear;
2285
- ListCache$4.prototype["delete"] = listCacheDelete;
2286
- ListCache$4.prototype.get = listCacheGet;
2287
- ListCache$4.prototype.has = listCacheHas;
2288
- ListCache$4.prototype.set = listCacheSet;
2289
- var _ListCache = ListCache$4;
2290
- var ListCache$3 = _ListCache;
2291
- function stackClear$1() {
2292
- this.__data__ = new ListCache$3();
2293
- this.size = 0;
2294
- }
2295
- var _stackClear = stackClear$1;
2296
- function stackDelete$1(key) {
2297
- var data = this.__data__, result = data["delete"](key);
2298
- this.size = data.size;
2299
- return result;
2300
- }
2301
- var _stackDelete = stackDelete$1;
2302
- function stackGet$1(key) {
2303
- return this.__data__.get(key);
2304
- }
2305
- var _stackGet = stackGet$1;
2306
- function stackHas$1(key) {
2307
- return this.__data__.has(key);
2308
- }
2309
- var _stackHas = stackHas$1;
2310
- var freeGlobal$1 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
2311
- var _freeGlobal = freeGlobal$1;
2312
- var freeGlobal = _freeGlobal;
2313
- var freeSelf = typeof self == "object" && self && self.Object === Object && self;
2314
- var root$8 = freeGlobal || freeSelf || Function("return this")();
2315
- var _root = root$8;
2316
- var root$7 = _root;
2317
- var Symbol$4 = root$7.Symbol;
2318
- var _Symbol = Symbol$4;
2319
- var Symbol$3 = _Symbol;
2320
- var objectProto$c = Object.prototype;
2321
- var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
2322
- var nativeObjectToString$1 = objectProto$c.toString;
2323
- var symToStringTag$1 = Symbol$3 ? Symbol$3.toStringTag : void 0;
2324
- function getRawTag$1(value) {
2325
- var isOwn = hasOwnProperty$9.call(value, symToStringTag$1), tag = value[symToStringTag$1];
2326
- try {
2327
- value[symToStringTag$1] = void 0;
2328
- var unmasked = true;
2329
- } catch (e) {
2330
- }
2331
- var result = nativeObjectToString$1.call(value);
2332
- if (unmasked) {
2333
- if (isOwn) {
2334
- value[symToStringTag$1] = tag;
2335
- } else {
2336
- delete value[symToStringTag$1];
2337
- }
2338
- }
2339
- return result;
2340
- }
2341
- var _getRawTag = getRawTag$1;
2342
- var objectProto$b = Object.prototype;
2343
- var nativeObjectToString = objectProto$b.toString;
2344
- function objectToString$1(value) {
2345
- return nativeObjectToString.call(value);
2346
- }
2347
- var _objectToString = objectToString$1;
2348
- var Symbol$2 = _Symbol, getRawTag = _getRawTag, objectToString = _objectToString;
2349
- var nullTag = "[object Null]", undefinedTag = "[object Undefined]";
2350
- var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : void 0;
2351
- function baseGetTag$4(value) {
2352
- if (value == null) {
2353
- return value === void 0 ? undefinedTag : nullTag;
2354
- }
2355
- return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
2356
- }
2357
- var _baseGetTag = baseGetTag$4;
2358
- function isObject$5(value) {
2359
- var type = typeof value;
2360
- return value != null && (type == "object" || type == "function");
2361
- }
2362
- var isObject_1 = isObject$5;
2363
- var baseGetTag$3 = _baseGetTag, isObject$4 = isObject_1;
2364
- var asyncTag = "[object AsyncFunction]", funcTag$2 = "[object Function]", genTag$1 = "[object GeneratorFunction]", proxyTag = "[object Proxy]";
2365
- function isFunction$2(value) {
2366
- if (!isObject$4(value)) {
2367
- return false;
2368
- }
2369
- var tag = baseGetTag$3(value);
2370
- return tag == funcTag$2 || tag == genTag$1 || tag == asyncTag || tag == proxyTag;
2371
- }
2372
- var isFunction_1 = isFunction$2;
2373
- var root$6 = _root;
2374
- var coreJsData$1 = root$6["__core-js_shared__"];
2375
- var _coreJsData = coreJsData$1;
2376
- var coreJsData = _coreJsData;
2377
- var maskSrcKey = function() {
2378
- var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
2379
- return uid ? "Symbol(src)_1." + uid : "";
2380
- }();
2381
- function isMasked$1(func) {
2382
- return !!maskSrcKey && maskSrcKey in func;
2383
- }
2384
- var _isMasked = isMasked$1;
2385
- var funcProto$1 = Function.prototype;
2386
- var funcToString$1 = funcProto$1.toString;
2387
- function toSource$2(func) {
2388
- if (func != null) {
2389
- try {
2390
- return funcToString$1.call(func);
2391
- } catch (e) {
2392
- }
2393
- try {
2394
- return func + "";
2395
- } catch (e) {
2396
- }
2397
- }
2398
- return "";
2399
- }
2400
- var _toSource = toSource$2;
2401
- var isFunction$1 = isFunction_1, isMasked = _isMasked, isObject$3 = isObject_1, toSource$1 = _toSource;
2402
- var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
2403
- var reIsHostCtor = /^\[object .+?Constructor\]$/;
2404
- var funcProto = Function.prototype, objectProto$a = Object.prototype;
2405
- var funcToString = funcProto.toString;
2406
- var hasOwnProperty$8 = objectProto$a.hasOwnProperty;
2407
- var reIsNative = RegExp(
2408
- "^" + funcToString.call(hasOwnProperty$8).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
2409
- );
2410
- function baseIsNative$1(value) {
2411
- if (!isObject$3(value) || isMasked(value)) {
2412
- return false;
2413
- }
2414
- var pattern = isFunction$1(value) ? reIsNative : reIsHostCtor;
2415
- return pattern.test(toSource$1(value));
2416
- }
2417
- var _baseIsNative = baseIsNative$1;
2418
- function getValue$1(object, key) {
2419
- return object == null ? void 0 : object[key];
2420
- }
2421
- var _getValue = getValue$1;
2422
- var baseIsNative = _baseIsNative, getValue = _getValue;
2423
- function getNative$7(object, key) {
2424
- var value = getValue(object, key);
2425
- return baseIsNative(value) ? value : void 0;
2426
- }
2427
- var _getNative = getNative$7;
2428
- var getNative$6 = _getNative, root$5 = _root;
2429
- var Map$4 = getNative$6(root$5, "Map");
2430
- var _Map = Map$4;
2431
- var getNative$5 = _getNative;
2432
- var nativeCreate$4 = getNative$5(Object, "create");
2433
- var _nativeCreate = nativeCreate$4;
2434
- var nativeCreate$3 = _nativeCreate;
2435
- function hashClear$1() {
2436
- this.__data__ = nativeCreate$3 ? nativeCreate$3(null) : {};
2437
- this.size = 0;
2438
- }
2439
- var _hashClear = hashClear$1;
2440
- function hashDelete$1(key) {
2441
- var result = this.has(key) && delete this.__data__[key];
2442
- this.size -= result ? 1 : 0;
2443
- return result;
2444
- }
2445
- var _hashDelete = hashDelete$1;
2446
- var nativeCreate$2 = _nativeCreate;
2447
- var HASH_UNDEFINED$1 = "__lodash_hash_undefined__";
2448
- var objectProto$9 = Object.prototype;
2449
- var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
2450
- function hashGet$1(key) {
2451
- var data = this.__data__;
2452
- if (nativeCreate$2) {
2453
- var result = data[key];
2454
- return result === HASH_UNDEFINED$1 ? void 0 : result;
2455
- }
2456
- return hasOwnProperty$7.call(data, key) ? data[key] : void 0;
2457
- }
2458
- var _hashGet = hashGet$1;
2459
- var nativeCreate$1 = _nativeCreate;
2460
- var objectProto$8 = Object.prototype;
2461
- var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
2462
- function hashHas$1(key) {
2463
- var data = this.__data__;
2464
- return nativeCreate$1 ? data[key] !== void 0 : hasOwnProperty$6.call(data, key);
2465
- }
2466
- var _hashHas = hashHas$1;
2467
- var nativeCreate = _nativeCreate;
2468
- var HASH_UNDEFINED = "__lodash_hash_undefined__";
2469
- function hashSet$1(key, value) {
2470
- var data = this.__data__;
2471
- this.size += this.has(key) ? 0 : 1;
2472
- data[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value;
2473
- return this;
2474
- }
2475
- var _hashSet = hashSet$1;
2476
- var hashClear = _hashClear, hashDelete = _hashDelete, hashGet = _hashGet, hashHas = _hashHas, hashSet = _hashSet;
2477
- function Hash$1(entries) {
2478
- var index = -1, length = entries == null ? 0 : entries.length;
2479
- this.clear();
2480
- while (++index < length) {
2481
- var entry = entries[index];
2482
- this.set(entry[0], entry[1]);
2483
- }
2484
- }
2485
- Hash$1.prototype.clear = hashClear;
2486
- Hash$1.prototype["delete"] = hashDelete;
2487
- Hash$1.prototype.get = hashGet;
2488
- Hash$1.prototype.has = hashHas;
2489
- Hash$1.prototype.set = hashSet;
2490
- var _Hash = Hash$1;
2491
- var Hash = _Hash, ListCache$2 = _ListCache, Map$3 = _Map;
2492
- function mapCacheClear$1() {
2493
- this.size = 0;
2494
- this.__data__ = {
2495
- "hash": new Hash(),
2496
- "map": new (Map$3 || ListCache$2)(),
2497
- "string": new Hash()
2498
- };
2499
- }
2500
- var _mapCacheClear = mapCacheClear$1;
2501
- function isKeyable$1(value) {
2502
- var type = typeof value;
2503
- return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
2504
- }
2505
- var _isKeyable = isKeyable$1;
2506
- var isKeyable = _isKeyable;
2507
- function getMapData$4(map, key) {
2508
- var data = map.__data__;
2509
- return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
2510
- }
2511
- var _getMapData = getMapData$4;
2512
- var getMapData$3 = _getMapData;
2513
- function mapCacheDelete$1(key) {
2514
- var result = getMapData$3(this, key)["delete"](key);
2515
- this.size -= result ? 1 : 0;
2516
- return result;
2517
- }
2518
- var _mapCacheDelete = mapCacheDelete$1;
2519
- var getMapData$2 = _getMapData;
2520
- function mapCacheGet$1(key) {
2521
- return getMapData$2(this, key).get(key);
2522
- }
2523
- var _mapCacheGet = mapCacheGet$1;
2524
- var getMapData$1 = _getMapData;
2525
- function mapCacheHas$1(key) {
2526
- return getMapData$1(this, key).has(key);
2527
- }
2528
- var _mapCacheHas = mapCacheHas$1;
2529
- var getMapData = _getMapData;
2530
- function mapCacheSet$1(key, value) {
2531
- var data = getMapData(this, key), size = data.size;
2532
- data.set(key, value);
2533
- this.size += data.size == size ? 0 : 1;
2534
- return this;
2535
- }
2536
- var _mapCacheSet = mapCacheSet$1;
2537
- var mapCacheClear = _mapCacheClear, mapCacheDelete = _mapCacheDelete, mapCacheGet = _mapCacheGet, mapCacheHas = _mapCacheHas, mapCacheSet = _mapCacheSet;
2538
- function MapCache$1(entries) {
2539
- var index = -1, length = entries == null ? 0 : entries.length;
2540
- this.clear();
2541
- while (++index < length) {
2542
- var entry = entries[index];
2543
- this.set(entry[0], entry[1]);
2544
- }
2545
- }
2546
- MapCache$1.prototype.clear = mapCacheClear;
2547
- MapCache$1.prototype["delete"] = mapCacheDelete;
2548
- MapCache$1.prototype.get = mapCacheGet;
2549
- MapCache$1.prototype.has = mapCacheHas;
2550
- MapCache$1.prototype.set = mapCacheSet;
2551
- var _MapCache = MapCache$1;
2552
- var ListCache$1 = _ListCache, Map$2 = _Map, MapCache = _MapCache;
2553
- var LARGE_ARRAY_SIZE = 200;
2554
- function stackSet$1(key, value) {
2555
- var data = this.__data__;
2556
- if (data instanceof ListCache$1) {
2557
- var pairs = data.__data__;
2558
- if (!Map$2 || pairs.length < LARGE_ARRAY_SIZE - 1) {
2559
- pairs.push([key, value]);
2560
- this.size = ++data.size;
2561
- return this;
2562
- }
2563
- data = this.__data__ = new MapCache(pairs);
2564
- }
2565
- data.set(key, value);
2566
- this.size = data.size;
2567
- return this;
2568
- }
2569
- var _stackSet = stackSet$1;
2570
- var ListCache = _ListCache, stackClear = _stackClear, stackDelete = _stackDelete, stackGet = _stackGet, stackHas = _stackHas, stackSet = _stackSet;
2571
- function Stack$1(entries) {
2572
- var data = this.__data__ = new ListCache(entries);
2573
- this.size = data.size;
2574
- }
2575
- Stack$1.prototype.clear = stackClear;
2576
- Stack$1.prototype["delete"] = stackDelete;
2577
- Stack$1.prototype.get = stackGet;
2578
- Stack$1.prototype.has = stackHas;
2579
- Stack$1.prototype.set = stackSet;
2580
- var _Stack = Stack$1;
2581
- function arrayEach$1(array, iteratee) {
2582
- var index = -1, length = array == null ? 0 : array.length;
2583
- while (++index < length) {
2584
- if (iteratee(array[index], index, array) === false) {
2585
- break;
2586
- }
2587
- }
2588
- return array;
2589
- }
2590
- var _arrayEach = arrayEach$1;
2591
- var getNative$4 = _getNative;
2592
- var defineProperty$1 = function() {
2593
- try {
2594
- var func = getNative$4(Object, "defineProperty");
2595
- func({}, "", {});
2596
- return func;
2597
- } catch (e) {
2598
- }
2599
- }();
2600
- var _defineProperty = defineProperty$1;
2601
- var defineProperty = _defineProperty;
2602
- function baseAssignValue$2(object, key, value) {
2603
- if (key == "__proto__" && defineProperty) {
2604
- defineProperty(object, key, {
2605
- "configurable": true,
2606
- "enumerable": true,
2607
- "value": value,
2608
- "writable": true
2609
- });
2610
- } else {
2611
- object[key] = value;
2612
- }
2613
- }
2614
- var _baseAssignValue = baseAssignValue$2;
2615
- var baseAssignValue$1 = _baseAssignValue, eq = eq_1;
2616
- var objectProto$7 = Object.prototype;
2617
- var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
2618
- function assignValue$2(object, key, value) {
2619
- var objValue = object[key];
2620
- if (!(hasOwnProperty$5.call(object, key) && eq(objValue, value)) || value === void 0 && !(key in object)) {
2621
- baseAssignValue$1(object, key, value);
2622
- }
2623
- }
2624
- var _assignValue = assignValue$2;
2625
- var assignValue$1 = _assignValue, baseAssignValue = _baseAssignValue;
2626
- function copyObject$4(source, props, object, customizer) {
2627
- var isNew = !object;
2628
- object || (object = {});
2629
- var index = -1, length = props.length;
2630
- while (++index < length) {
2631
- var key = props[index];
2632
- var newValue = customizer ? customizer(object[key], source[key], key, object, source) : void 0;
2633
- if (newValue === void 0) {
2634
- newValue = source[key];
2635
- }
2636
- if (isNew) {
2637
- baseAssignValue(object, key, newValue);
2638
- } else {
2639
- assignValue$1(object, key, newValue);
2640
- }
2641
- }
2642
- return object;
2643
- }
2644
- var _copyObject = copyObject$4;
2645
- function baseTimes$1(n, iteratee) {
2646
- var index = -1, result = Array(n);
2647
- while (++index < n) {
2648
- result[index] = iteratee(index);
2649
- }
2650
- return result;
2651
- }
2652
- var _baseTimes = baseTimes$1;
2653
- function isObjectLike$5(value) {
2654
- return value != null && typeof value == "object";
2655
- }
2656
- var isObjectLike_1 = isObjectLike$5;
2657
- var baseGetTag$2 = _baseGetTag, isObjectLike$4 = isObjectLike_1;
2658
- var argsTag$2 = "[object Arguments]";
2659
- function baseIsArguments$1(value) {
2660
- return isObjectLike$4(value) && baseGetTag$2(value) == argsTag$2;
2661
- }
2662
- var _baseIsArguments = baseIsArguments$1;
2663
- var baseIsArguments = _baseIsArguments, isObjectLike$3 = isObjectLike_1;
2664
- var objectProto$6 = Object.prototype;
2665
- var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
2666
- var propertyIsEnumerable$1 = objectProto$6.propertyIsEnumerable;
2667
- var isArguments$1 = baseIsArguments(/* @__PURE__ */ function() {
2668
- return arguments;
2669
- }()) ? baseIsArguments : function(value) {
2670
- return isObjectLike$3(value) && hasOwnProperty$4.call(value, "callee") && !propertyIsEnumerable$1.call(value, "callee");
2671
- };
2672
- var isArguments_1 = isArguments$1;
2673
- var isArray$3 = Array.isArray;
2674
- var isArray_1 = isArray$3;
2675
- var isBuffer$2 = { exports: {} };
2676
- function stubFalse() {
2677
- return false;
2678
- }
2679
- var stubFalse_1 = stubFalse;
2680
- isBuffer$2.exports;
2681
- (function(module, exports$1) {
2682
- var root2 = _root, stubFalse2 = stubFalse_1;
2683
- var freeExports = exports$1 && !exports$1.nodeType && exports$1;
2684
- var freeModule = freeExports && true && module && !module.nodeType && module;
2685
- var moduleExports = freeModule && freeModule.exports === freeExports;
2686
- var Buffer2 = moduleExports ? root2.Buffer : void 0;
2687
- var nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0;
2688
- var isBuffer2 = nativeIsBuffer || stubFalse2;
2689
- module.exports = isBuffer2;
2690
- })(isBuffer$2, isBuffer$2.exports);
2691
- var isBufferExports = isBuffer$2.exports;
2692
- var MAX_SAFE_INTEGER$1 = 9007199254740991;
2693
- var reIsUint = /^(?:0|[1-9]\d*)$/;
2694
- function isIndex$1(value, length) {
2695
- var type = typeof value;
2696
- length = length == null ? MAX_SAFE_INTEGER$1 : length;
2697
- return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
2698
- }
2699
- var _isIndex = isIndex$1;
2700
- var MAX_SAFE_INTEGER = 9007199254740991;
2701
- function isLength$2(value) {
2702
- return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
2703
- }
2704
- var isLength_1 = isLength$2;
2705
- var baseGetTag$1 = _baseGetTag, isLength$1 = isLength_1, isObjectLike$2 = isObjectLike_1;
2706
- var argsTag$1 = "[object Arguments]", arrayTag$1 = "[object Array]", boolTag$2 = "[object Boolean]", dateTag$2 = "[object Date]", errorTag$1 = "[object Error]", funcTag$1 = "[object Function]", mapTag$4 = "[object Map]", numberTag$2 = "[object Number]", objectTag$2 = "[object Object]", regexpTag$2 = "[object RegExp]", setTag$4 = "[object Set]", stringTag$2 = "[object String]", weakMapTag$2 = "[object WeakMap]";
2707
- var arrayBufferTag$2 = "[object ArrayBuffer]", dataViewTag$3 = "[object DataView]", float32Tag$2 = "[object Float32Array]", float64Tag$2 = "[object Float64Array]", int8Tag$2 = "[object Int8Array]", int16Tag$2 = "[object Int16Array]", int32Tag$2 = "[object Int32Array]", uint8Tag$2 = "[object Uint8Array]", uint8ClampedTag$2 = "[object Uint8ClampedArray]", uint16Tag$2 = "[object Uint16Array]", uint32Tag$2 = "[object Uint32Array]";
2708
- var typedArrayTags = {};
2709
- typedArrayTags[float32Tag$2] = typedArrayTags[float64Tag$2] = typedArrayTags[int8Tag$2] = typedArrayTags[int16Tag$2] = typedArrayTags[int32Tag$2] = typedArrayTags[uint8Tag$2] = typedArrayTags[uint8ClampedTag$2] = typedArrayTags[uint16Tag$2] = typedArrayTags[uint32Tag$2] = true;
2710
- typedArrayTags[argsTag$1] = typedArrayTags[arrayTag$1] = typedArrayTags[arrayBufferTag$2] = typedArrayTags[boolTag$2] = typedArrayTags[dataViewTag$3] = typedArrayTags[dateTag$2] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag$1] = typedArrayTags[mapTag$4] = typedArrayTags[numberTag$2] = typedArrayTags[objectTag$2] = typedArrayTags[regexpTag$2] = typedArrayTags[setTag$4] = typedArrayTags[stringTag$2] = typedArrayTags[weakMapTag$2] = false;
2711
- function baseIsTypedArray$1(value) {
2712
- return isObjectLike$2(value) && isLength$1(value.length) && !!typedArrayTags[baseGetTag$1(value)];
2713
- }
2714
- var _baseIsTypedArray = baseIsTypedArray$1;
2715
- function baseUnary$3(func) {
2716
- return function(value) {
2717
- return func(value);
2718
- };
2719
- }
2720
- var _baseUnary = baseUnary$3;
2721
- var _nodeUtil = { exports: {} };
2722
- _nodeUtil.exports;
2723
- (function(module, exports$1) {
2724
- var freeGlobal2 = _freeGlobal;
2725
- var freeExports = exports$1 && !exports$1.nodeType && exports$1;
2726
- var freeModule = freeExports && true && module && !module.nodeType && module;
2727
- var moduleExports = freeModule && freeModule.exports === freeExports;
2728
- var freeProcess = moduleExports && freeGlobal2.process;
2729
- var nodeUtil2 = function() {
2730
- try {
2731
- var types = freeModule && freeModule.require && freeModule.require("util").types;
2732
- if (types) {
2733
- return types;
2734
- }
2735
- return freeProcess && freeProcess.binding && freeProcess.binding("util");
2736
- } catch (e) {
2737
- }
2738
- }();
2739
- module.exports = nodeUtil2;
2740
- })(_nodeUtil, _nodeUtil.exports);
2741
- var _nodeUtilExports = _nodeUtil.exports;
2742
- var baseIsTypedArray = _baseIsTypedArray, baseUnary$2 = _baseUnary, nodeUtil$2 = _nodeUtilExports;
2743
- var nodeIsTypedArray = nodeUtil$2 && nodeUtil$2.isTypedArray;
2744
- var isTypedArray$1 = nodeIsTypedArray ? baseUnary$2(nodeIsTypedArray) : baseIsTypedArray;
2745
- var isTypedArray_1 = isTypedArray$1;
2746
- var baseTimes = _baseTimes, isArguments = isArguments_1, isArray$2 = isArray_1, isBuffer$1 = isBufferExports, isIndex = _isIndex, isTypedArray = isTypedArray_1;
2747
- var objectProto$5 = Object.prototype;
2748
- var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
2749
- function arrayLikeKeys$2(value, inherited) {
2750
- var isArr = isArray$2(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer$1(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length;
2751
- for (var key in value) {
2752
- if ((inherited || hasOwnProperty$3.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode.
2753
- (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers.
2754
- isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays.
2755
- isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties.
2756
- isIndex(key, length)))) {
2757
- result.push(key);
2758
- }
2759
- }
2760
- return result;
2761
- }
2762
- var _arrayLikeKeys = arrayLikeKeys$2;
2763
- var objectProto$4 = Object.prototype;
2764
- function isPrototype$3(value) {
2765
- var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto$4;
2766
- return value === proto;
2767
- }
2768
- var _isPrototype = isPrototype$3;
2769
- function overArg$2(func, transform) {
2770
- return function(arg) {
2771
- return func(transform(arg));
2772
- };
2773
- }
2774
- var _overArg = overArg$2;
2775
- var overArg$1 = _overArg;
2776
- var nativeKeys$1 = overArg$1(Object.keys, Object);
2777
- var _nativeKeys = nativeKeys$1;
2778
- var isPrototype$2 = _isPrototype, nativeKeys = _nativeKeys;
2779
- var objectProto$3 = Object.prototype;
2780
- var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
2781
- function baseKeys$1(object) {
2782
- if (!isPrototype$2(object)) {
2783
- return nativeKeys(object);
2784
- }
2785
- var result = [];
2786
- for (var key in Object(object)) {
2787
- if (hasOwnProperty$2.call(object, key) && key != "constructor") {
2788
- result.push(key);
2789
- }
2790
- }
2791
- return result;
2792
- }
2793
- var _baseKeys = baseKeys$1;
2794
- var isFunction = isFunction_1, isLength = isLength_1;
2795
- function isArrayLike$2(value) {
2796
- return value != null && isLength(value.length) && !isFunction(value);
2797
- }
2798
- var isArrayLike_1 = isArrayLike$2;
2799
- var arrayLikeKeys$1 = _arrayLikeKeys, baseKeys = _baseKeys, isArrayLike$1 = isArrayLike_1;
2800
- function keys$3(object) {
2801
- return isArrayLike$1(object) ? arrayLikeKeys$1(object) : baseKeys(object);
2802
- }
2803
- var keys_1 = keys$3;
2804
- var copyObject$3 = _copyObject, keys$2 = keys_1;
2805
- function baseAssign$1(object, source) {
2806
- return object && copyObject$3(source, keys$2(source), object);
2807
- }
2808
- var _baseAssign = baseAssign$1;
2809
- function nativeKeysIn$1(object) {
2810
- var result = [];
2811
- if (object != null) {
2812
- for (var key in Object(object)) {
2813
- result.push(key);
2814
- }
2815
- }
2816
- return result;
2817
- }
2818
- var _nativeKeysIn = nativeKeysIn$1;
2819
- var isObject$2 = isObject_1, isPrototype$1 = _isPrototype, nativeKeysIn = _nativeKeysIn;
2820
- var objectProto$2 = Object.prototype;
2821
- var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
2822
- function baseKeysIn$1(object) {
2823
- if (!isObject$2(object)) {
2824
- return nativeKeysIn(object);
2825
- }
2826
- var isProto = isPrototype$1(object), result = [];
2827
- for (var key in object) {
2828
- if (!(key == "constructor" && (isProto || !hasOwnProperty$1.call(object, key)))) {
2829
- result.push(key);
2830
- }
2831
- }
2832
- return result;
2833
- }
2834
- var _baseKeysIn = baseKeysIn$1;
2835
- var arrayLikeKeys = _arrayLikeKeys, baseKeysIn = _baseKeysIn, isArrayLike = isArrayLike_1;
2836
- function keysIn$3(object) {
2837
- return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
2838
- }
2839
- var keysIn_1 = keysIn$3;
2840
- var copyObject$2 = _copyObject, keysIn$2 = keysIn_1;
2841
- function baseAssignIn$1(object, source) {
2842
- return object && copyObject$2(source, keysIn$2(source), object);
2843
- }
2844
- var _baseAssignIn = baseAssignIn$1;
2845
- var _cloneBuffer = { exports: {} };
2846
- _cloneBuffer.exports;
2847
- (function(module, exports$1) {
2848
- var root2 = _root;
2849
- var freeExports = exports$1 && !exports$1.nodeType && exports$1;
2850
- var freeModule = freeExports && true && module && !module.nodeType && module;
2851
- var moduleExports = freeModule && freeModule.exports === freeExports;
2852
- var Buffer2 = moduleExports ? root2.Buffer : void 0, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : void 0;
2853
- function cloneBuffer2(buffer, isDeep) {
2854
- if (isDeep) {
2855
- return buffer.slice();
2856
- }
2857
- var length = buffer.length, result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
2858
- buffer.copy(result);
2859
- return result;
2860
- }
2861
- module.exports = cloneBuffer2;
2862
- })(_cloneBuffer, _cloneBuffer.exports);
2863
- var _cloneBufferExports = _cloneBuffer.exports;
2864
- function copyArray$1(source, array) {
2865
- var index = -1, length = source.length;
2866
- array || (array = Array(length));
2867
- while (++index < length) {
2868
- array[index] = source[index];
2869
- }
2870
- return array;
2871
- }
2872
- var _copyArray = copyArray$1;
2873
- function arrayFilter$1(array, predicate) {
2874
- var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = [];
2875
- while (++index < length) {
2876
- var value = array[index];
2877
- if (predicate(value, index, array)) {
2878
- result[resIndex++] = value;
2879
- }
2880
- }
2881
- return result;
2882
- }
2883
- var _arrayFilter = arrayFilter$1;
2884
- function stubArray$2() {
2885
- return [];
2886
- }
2887
- var stubArray_1 = stubArray$2;
2888
- var arrayFilter = _arrayFilter, stubArray$1 = stubArray_1;
2889
- var objectProto$1 = Object.prototype;
2890
- var propertyIsEnumerable = objectProto$1.propertyIsEnumerable;
2891
- var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
2892
- var getSymbols$3 = !nativeGetSymbols$1 ? stubArray$1 : function(object) {
2893
- if (object == null) {
2894
- return [];
2895
- }
2896
- object = Object(object);
2897
- return arrayFilter(nativeGetSymbols$1(object), function(symbol) {
2898
- return propertyIsEnumerable.call(object, symbol);
2899
- });
2900
- };
2901
- var _getSymbols = getSymbols$3;
2902
- var copyObject$1 = _copyObject, getSymbols$2 = _getSymbols;
2903
- function copySymbols$1(source, object) {
2904
- return copyObject$1(source, getSymbols$2(source), object);
2905
- }
2906
- var _copySymbols = copySymbols$1;
2907
- function arrayPush$2(array, values) {
2908
- var index = -1, length = values.length, offset = array.length;
2909
- while (++index < length) {
2910
- array[offset + index] = values[index];
2911
- }
2912
- return array;
2913
- }
2914
- var _arrayPush = arrayPush$2;
2915
- var overArg = _overArg;
2916
- var getPrototype$2 = overArg(Object.getPrototypeOf, Object);
2917
- var _getPrototype = getPrototype$2;
2918
- var arrayPush$1 = _arrayPush, getPrototype$1 = _getPrototype, getSymbols$1 = _getSymbols, stubArray = stubArray_1;
2919
- var nativeGetSymbols = Object.getOwnPropertySymbols;
2920
- var getSymbolsIn$2 = !nativeGetSymbols ? stubArray : function(object) {
2921
- var result = [];
2922
- while (object) {
2923
- arrayPush$1(result, getSymbols$1(object));
2924
- object = getPrototype$1(object);
2925
- }
2926
- return result;
2927
- };
2928
- var _getSymbolsIn = getSymbolsIn$2;
2929
- var copyObject = _copyObject, getSymbolsIn$1 = _getSymbolsIn;
2930
- function copySymbolsIn$1(source, object) {
2931
- return copyObject(source, getSymbolsIn$1(source), object);
2932
- }
2933
- var _copySymbolsIn = copySymbolsIn$1;
2934
- var arrayPush = _arrayPush, isArray$1 = isArray_1;
2935
- function baseGetAllKeys$2(object, keysFunc, symbolsFunc) {
2936
- var result = keysFunc(object);
2937
- return isArray$1(object) ? result : arrayPush(result, symbolsFunc(object));
2938
- }
2939
- var _baseGetAllKeys = baseGetAllKeys$2;
2940
- var baseGetAllKeys$1 = _baseGetAllKeys, getSymbols = _getSymbols, keys$1 = keys_1;
2941
- function getAllKeys$1(object) {
2942
- return baseGetAllKeys$1(object, keys$1, getSymbols);
2943
- }
2944
- var _getAllKeys = getAllKeys$1;
2945
- var baseGetAllKeys = _baseGetAllKeys, getSymbolsIn = _getSymbolsIn, keysIn$1 = keysIn_1;
2946
- function getAllKeysIn$1(object) {
2947
- return baseGetAllKeys(object, keysIn$1, getSymbolsIn);
2948
- }
2949
- var _getAllKeysIn = getAllKeysIn$1;
2950
- var getNative$3 = _getNative, root$4 = _root;
2951
- var DataView$1 = getNative$3(root$4, "DataView");
2952
- var _DataView = DataView$1;
2953
- var getNative$2 = _getNative, root$3 = _root;
2954
- var Promise$2 = getNative$2(root$3, "Promise");
2955
- var _Promise = Promise$2;
2956
- var getNative$1 = _getNative, root$2 = _root;
2957
- var Set$2 = getNative$1(root$2, "Set");
2958
- var _Set = Set$2;
2959
- var getNative = _getNative, root$1 = _root;
2960
- var WeakMap$2 = getNative(root$1, "WeakMap");
2961
- var _WeakMap = WeakMap$2;
2962
- var DataView = _DataView, Map$1 = _Map, Promise$1 = _Promise, Set$1 = _Set, WeakMap$1 = _WeakMap, baseGetTag = _baseGetTag, toSource = _toSource;
2963
- var mapTag$3 = "[object Map]", objectTag$1 = "[object Object]", promiseTag = "[object Promise]", setTag$3 = "[object Set]", weakMapTag$1 = "[object WeakMap]";
2964
- var dataViewTag$2 = "[object DataView]";
2965
- var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map$1), promiseCtorString = toSource(Promise$1), setCtorString = toSource(Set$1), weakMapCtorString = toSource(WeakMap$1);
2966
- var getTag$3 = baseGetTag;
2967
- if (DataView && getTag$3(new DataView(new ArrayBuffer(1))) != dataViewTag$2 || Map$1 && getTag$3(new Map$1()) != mapTag$3 || Promise$1 && getTag$3(Promise$1.resolve()) != promiseTag || Set$1 && getTag$3(new Set$1()) != setTag$3 || WeakMap$1 && getTag$3(new WeakMap$1()) != weakMapTag$1) {
2968
- getTag$3 = function(value) {
2969
- var result = baseGetTag(value), Ctor = result == objectTag$1 ? value.constructor : void 0, ctorString = Ctor ? toSource(Ctor) : "";
2970
- if (ctorString) {
2971
- switch (ctorString) {
2972
- case dataViewCtorString:
2973
- return dataViewTag$2;
2974
- case mapCtorString:
2975
- return mapTag$3;
2976
- case promiseCtorString:
2977
- return promiseTag;
2978
- case setCtorString:
2979
- return setTag$3;
2980
- case weakMapCtorString:
2981
- return weakMapTag$1;
2982
- }
2983
- }
2984
- return result;
2985
- };
2986
- }
2987
- var _getTag = getTag$3;
2988
- var objectProto = Object.prototype;
2989
- var hasOwnProperty = objectProto.hasOwnProperty;
2990
- function initCloneArray$1(array) {
2991
- var length = array.length, result = new array.constructor(length);
2992
- if (length && typeof array[0] == "string" && hasOwnProperty.call(array, "index")) {
2993
- result.index = array.index;
2994
- result.input = array.input;
2995
- }
2996
- return result;
2997
- }
2998
- var _initCloneArray = initCloneArray$1;
2999
- var root = _root;
3000
- var Uint8Array$2 = root.Uint8Array;
3001
- var _Uint8Array = Uint8Array$2;
3002
- var Uint8Array$1 = _Uint8Array;
3003
- function cloneArrayBuffer$3(arrayBuffer) {
3004
- var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
3005
- new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer));
3006
- return result;
3007
- }
3008
- var _cloneArrayBuffer = cloneArrayBuffer$3;
3009
- var cloneArrayBuffer$2 = _cloneArrayBuffer;
3010
- function cloneDataView$1(dataView, isDeep) {
3011
- var buffer = isDeep ? cloneArrayBuffer$2(dataView.buffer) : dataView.buffer;
3012
- return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
3013
- }
3014
- var _cloneDataView = cloneDataView$1;
3015
- var reFlags = /\w*$/;
3016
- function cloneRegExp$1(regexp) {
3017
- var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
3018
- result.lastIndex = regexp.lastIndex;
3019
- return result;
3020
- }
3021
- var _cloneRegExp = cloneRegExp$1;
3022
- var Symbol$1 = _Symbol;
3023
- var symbolProto = Symbol$1 ? Symbol$1.prototype : void 0, symbolValueOf = symbolProto ? symbolProto.valueOf : void 0;
3024
- function cloneSymbol$1(symbol) {
3025
- return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
3026
- }
3027
- var _cloneSymbol = cloneSymbol$1;
3028
- var cloneArrayBuffer$1 = _cloneArrayBuffer;
3029
- function cloneTypedArray$1(typedArray, isDeep) {
3030
- var buffer = isDeep ? cloneArrayBuffer$1(typedArray.buffer) : typedArray.buffer;
3031
- return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
3032
- }
3033
- var _cloneTypedArray = cloneTypedArray$1;
3034
- var cloneArrayBuffer = _cloneArrayBuffer, cloneDataView = _cloneDataView, cloneRegExp = _cloneRegExp, cloneSymbol = _cloneSymbol, cloneTypedArray = _cloneTypedArray;
3035
- var boolTag$1 = "[object Boolean]", dateTag$1 = "[object Date]", mapTag$2 = "[object Map]", numberTag$1 = "[object Number]", regexpTag$1 = "[object RegExp]", setTag$2 = "[object Set]", stringTag$1 = "[object String]", symbolTag$1 = "[object Symbol]";
3036
- var arrayBufferTag$1 = "[object ArrayBuffer]", dataViewTag$1 = "[object DataView]", float32Tag$1 = "[object Float32Array]", float64Tag$1 = "[object Float64Array]", int8Tag$1 = "[object Int8Array]", int16Tag$1 = "[object Int16Array]", int32Tag$1 = "[object Int32Array]", uint8Tag$1 = "[object Uint8Array]", uint8ClampedTag$1 = "[object Uint8ClampedArray]", uint16Tag$1 = "[object Uint16Array]", uint32Tag$1 = "[object Uint32Array]";
3037
- function initCloneByTag$1(object, tag, isDeep) {
3038
- var Ctor = object.constructor;
3039
- switch (tag) {
3040
- case arrayBufferTag$1:
3041
- return cloneArrayBuffer(object);
3042
- case boolTag$1:
3043
- case dateTag$1:
3044
- return new Ctor(+object);
3045
- case dataViewTag$1:
3046
- return cloneDataView(object, isDeep);
3047
- case float32Tag$1:
3048
- case float64Tag$1:
3049
- case int8Tag$1:
3050
- case int16Tag$1:
3051
- case int32Tag$1:
3052
- case uint8Tag$1:
3053
- case uint8ClampedTag$1:
3054
- case uint16Tag$1:
3055
- case uint32Tag$1:
3056
- return cloneTypedArray(object, isDeep);
3057
- case mapTag$2:
3058
- return new Ctor();
3059
- case numberTag$1:
3060
- case stringTag$1:
3061
- return new Ctor(object);
3062
- case regexpTag$1:
3063
- return cloneRegExp(object);
3064
- case setTag$2:
3065
- return new Ctor();
3066
- case symbolTag$1:
3067
- return cloneSymbol(object);
3068
- }
3069
- }
3070
- var _initCloneByTag = initCloneByTag$1;
3071
- var isObject$1 = isObject_1;
3072
- var objectCreate = Object.create;
3073
- var baseCreate$1 = /* @__PURE__ */ function() {
3074
- function object() {
3075
- }
3076
- return function(proto) {
3077
- if (!isObject$1(proto)) {
3078
- return {};
3079
- }
3080
- if (objectCreate) {
3081
- return objectCreate(proto);
3082
- }
3083
- object.prototype = proto;
3084
- var result = new object();
3085
- object.prototype = void 0;
3086
- return result;
3087
- };
3088
- }();
3089
- var _baseCreate = baseCreate$1;
3090
- var baseCreate = _baseCreate, getPrototype = _getPrototype, isPrototype = _isPrototype;
3091
- function initCloneObject$1(object) {
3092
- return typeof object.constructor == "function" && !isPrototype(object) ? baseCreate(getPrototype(object)) : {};
3093
- }
3094
- var _initCloneObject = initCloneObject$1;
3095
- var getTag$2 = _getTag, isObjectLike$1 = isObjectLike_1;
3096
- var mapTag$1 = "[object Map]";
3097
- function baseIsMap$1(value) {
3098
- return isObjectLike$1(value) && getTag$2(value) == mapTag$1;
3099
- }
3100
- var _baseIsMap = baseIsMap$1;
3101
- var baseIsMap = _baseIsMap, baseUnary$1 = _baseUnary, nodeUtil$1 = _nodeUtilExports;
3102
- var nodeIsMap = nodeUtil$1 && nodeUtil$1.isMap;
3103
- var isMap$1 = nodeIsMap ? baseUnary$1(nodeIsMap) : baseIsMap;
3104
- var isMap_1 = isMap$1;
3105
- var getTag$1 = _getTag, isObjectLike = isObjectLike_1;
3106
- var setTag$1 = "[object Set]";
3107
- function baseIsSet$1(value) {
3108
- return isObjectLike(value) && getTag$1(value) == setTag$1;
3109
- }
3110
- var _baseIsSet = baseIsSet$1;
3111
- var baseIsSet = _baseIsSet, baseUnary = _baseUnary, nodeUtil = _nodeUtilExports;
3112
- var nodeIsSet = nodeUtil && nodeUtil.isSet;
3113
- var isSet$1 = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
3114
- var isSet_1 = isSet$1;
3115
- var Stack = _Stack, arrayEach = _arrayEach, assignValue = _assignValue, baseAssign = _baseAssign, baseAssignIn = _baseAssignIn, cloneBuffer = _cloneBufferExports, copyArray = _copyArray, copySymbols = _copySymbols, copySymbolsIn = _copySymbolsIn, getAllKeys = _getAllKeys, getAllKeysIn = _getAllKeysIn, getTag = _getTag, initCloneArray = _initCloneArray, initCloneByTag = _initCloneByTag, initCloneObject = _initCloneObject, isArray = isArray_1, isBuffer = isBufferExports, isMap = isMap_1, isObject = isObject_1, isSet = isSet_1, keys = keys_1, keysIn = keysIn_1;
3116
- var CLONE_DEEP_FLAG$1 = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG$1 = 4;
3117
- var argsTag = "[object Arguments]", arrayTag = "[object Array]", boolTag = "[object Boolean]", dateTag = "[object Date]", errorTag = "[object Error]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", objectTag = "[object Object]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag = "[object Symbol]", weakMapTag = "[object WeakMap]";
3118
- var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]";
3119
- var cloneableTags = {};
3120
- cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
3121
- cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;
3122
- function baseClone$1(value, bitmask, customizer, key, object, stack) {
3123
- var result, isDeep = bitmask & CLONE_DEEP_FLAG$1, isFlat = bitmask & CLONE_FLAT_FLAG, isFull = bitmask & CLONE_SYMBOLS_FLAG$1;
3124
- if (customizer) {
3125
- result = object ? customizer(value, key, object, stack) : customizer(value);
3126
- }
3127
- if (result !== void 0) {
3128
- return result;
3129
- }
3130
- if (!isObject(value)) {
3131
- return value;
3132
- }
3133
- var isArr = isArray(value);
3134
- if (isArr) {
3135
- result = initCloneArray(value);
3136
- if (!isDeep) {
3137
- return copyArray(value, result);
3138
- }
3139
- } else {
3140
- var tag = getTag(value), isFunc = tag == funcTag || tag == genTag;
3141
- if (isBuffer(value)) {
3142
- return cloneBuffer(value, isDeep);
3143
- }
3144
- if (tag == objectTag || tag == argsTag || isFunc && !object) {
3145
- result = isFlat || isFunc ? {} : initCloneObject(value);
3146
- if (!isDeep) {
3147
- return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value));
3148
- }
3149
- } else {
3150
- if (!cloneableTags[tag]) {
3151
- return object ? value : {};
3152
- }
3153
- result = initCloneByTag(value, tag, isDeep);
3154
- }
3155
- }
3156
- stack || (stack = new Stack());
3157
- var stacked = stack.get(value);
3158
- if (stacked) {
3159
- return stacked;
3160
- }
3161
- stack.set(value, result);
3162
- if (isSet(value)) {
3163
- value.forEach(function(subValue) {
3164
- result.add(baseClone$1(subValue, bitmask, customizer, subValue, value, stack));
3165
- });
3166
- } else if (isMap(value)) {
3167
- value.forEach(function(subValue, key2) {
3168
- result.set(key2, baseClone$1(subValue, bitmask, customizer, key2, value, stack));
3169
- });
3170
- }
3171
- var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys;
3172
- var props = isArr ? void 0 : keysFunc(value);
3173
- arrayEach(props || value, function(subValue, key2) {
3174
- if (props) {
3175
- key2 = subValue;
3176
- subValue = value[key2];
3177
- }
3178
- assignValue(result, key2, baseClone$1(subValue, bitmask, customizer, key2, value, stack));
3179
- });
3180
- return result;
3181
- }
3182
- var _baseClone = baseClone$1;
3183
- var baseClone = _baseClone;
3184
- var CLONE_DEEP_FLAG = 1, CLONE_SYMBOLS_FLAG = 4;
3185
- function cloneDeep(value) {
3186
- return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
3187
- }
3188
- var cloneDeep_1 = cloneDeep;
3189
- const cloneDeep$1 = /* @__PURE__ */ getDefaultExportFromCjs(cloneDeep_1);
3190
2295
  class CollectionRegistry {
3191
2296
  // Normalized runtime layer (used by Data Grid / UI)
3192
2297
  collectionsByTableName = /* @__PURE__ */ new Map();
@@ -3226,15 +2331,21 @@ class CollectionRegistry {
3226
2331
  */
3227
2332
  registerMultiple(collections) {
3228
2333
  const rawSnapshot = collections.map((c) => removeFunctions(c));
3229
- if (this.lastRawInputSnapshot && deepEqual(this.lastRawInputSnapshot, rawSnapshot)) {
2334
+ if (this.lastRawInputSnapshot && deepEqual$1(this.lastRawInputSnapshot, rawSnapshot)) {
3230
2335
  return false;
3231
2336
  }
3232
2337
  this.reset();
2338
+ collections.forEach((c) => {
2339
+ if (c.slug) {
2340
+ this.collectionsBySlug.set(c.slug, c);
2341
+ }
2342
+ this.collectionsByTableName.set(getTableName(c), c);
2343
+ });
3233
2344
  const normalizedCollections = collections.map((c) => this.normalizeCollection({
3234
2345
  ...c
3235
2346
  }));
3236
2347
  normalizedCollections.forEach((c, index) => {
3237
- const raw = cloneDeep$1(collections[index]);
2348
+ const raw = deepClone(collections[index]);
3238
2349
  this.rootCollections.push(c);
3239
2350
  this.rawRootCollections.push(raw);
3240
2351
  const normalized = this.normalizeCollection(c);
@@ -3254,7 +2365,7 @@ class CollectionRegistry {
3254
2365
  if (!subCollection) return;
3255
2366
  this._registerRecursively(this.normalizeCollection({
3256
2367
  ...subCollection
3257
- }), cloneDeep$1(subCollection));
2368
+ }), deepClone(subCollection));
3258
2369
  });
3259
2370
  }
3260
2371
  });
@@ -3262,7 +2373,7 @@ class CollectionRegistry {
3262
2373
  return true;
3263
2374
  }
3264
2375
  register(collection, rawCollection) {
3265
- const raw = rawCollection ? cloneDeep$1(rawCollection) : cloneDeep$1(collection);
2376
+ const raw = rawCollection ? deepClone(rawCollection) : deepClone(collection);
3266
2377
  this.rootCollections.push(collection);
3267
2378
  this.rawRootCollections.push(raw);
3268
2379
  this._registerRecursively(collection, raw);
@@ -3286,7 +2397,7 @@ class CollectionRegistry {
3286
2397
  if (!subCollection) return;
3287
2398
  this._registerRecursively(this.normalizeCollection({
3288
2399
  ...subCollection
3289
- }), cloneDeep$1(subCollection));
2400
+ }), deepClone(subCollection));
3290
2401
  });
3291
2402
  }
3292
2403
  }
@@ -3308,7 +2419,7 @@ class CollectionRegistry {
3308
2419
  if (getDataSourceCapabilities(result.driver).supportsRelations) {
3309
2420
  mergedRelations = mergedRelationsRaw.map((r) => {
3310
2421
  try {
3311
- return sanitizeRelation(r, result);
2422
+ return sanitizeRelation(r, result, (slug) => this.get(slug));
3312
2423
  } catch {
3313
2424
  return r;
3314
2425
  }
@@ -3747,8 +2858,14 @@ class DrizzleConditionBuilder {
3747
2858
  static buildSingleFilterCondition(column, op, value) {
3748
2859
  switch (op) {
3749
2860
  case "==":
3750
- return eq$3(column, value);
2861
+ if (value === null || value === void 0) {
2862
+ return sql`${column} IS NULL`;
2863
+ }
2864
+ return eq(column, value);
3751
2865
  case "!=":
2866
+ if (value === null || value === void 0) {
2867
+ return sql`${column} IS NOT NULL`;
2868
+ }
3752
2869
  return sql`${column} != ${value}`;
3753
2870
  case ">":
3754
2871
  return sql`${column} > ${value}`;
@@ -3877,7 +2994,7 @@ class DrizzleConditionBuilder {
3877
2994
  throw new Error(`Join path did not result in connecting to parent table. Current: ${currentTableName}, Parent: ${parentTableName}`);
3878
2995
  }
3879
2996
  }
3880
- const finalCondition = Array.isArray(parentEntityId) ? inArray(parentIdColumn, parentEntityId) : eq$3(parentIdColumn, parentEntityId);
2997
+ const finalCondition = Array.isArray(parentEntityId) ? inArray(parentIdColumn, parentEntityId) : eq(parentIdColumn, parentEntityId);
3881
2998
  return {
3882
2999
  joins,
3883
3000
  finalCondition
@@ -3903,7 +3020,7 @@ class DrizzleConditionBuilder {
3903
3020
  throw new Error(`Join columns not found: ${fromTableName}.${fromColName} = ${toTableName}.${toColName}`);
3904
3021
  }
3905
3022
  joinTable = fromTable;
3906
- condition = eq$3(left, right);
3023
+ condition = eq(left, right);
3907
3024
  } else if (currentTable === fromTable) {
3908
3025
  const left = toTable[toColName];
3909
3026
  const right = currentTable[fromColName];
@@ -3917,7 +3034,7 @@ class DrizzleConditionBuilder {
3917
3034
  throw new Error(`Join columns not found: ${toTableName}.${toColName} = ${fromTableName}.${fromColName}`);
3918
3035
  }
3919
3036
  joinTable = toTable;
3920
- condition = eq$3(left, right);
3037
+ condition = eq(left, right);
3921
3038
  } else {
3922
3039
  throw new Error(`Join step does not match current table. Current table does not match from: ${fromTableName} or to: ${toTableName}`);
3923
3040
  }
@@ -3948,19 +3065,19 @@ class DrizzleConditionBuilder {
3948
3065
  if (currentTable === targetTable) {
3949
3066
  return {
3950
3067
  joinTable: targetTable,
3951
- condition: eq$3(targetTableIdCol, junctionTargetCol),
3068
+ condition: eq(targetTableIdCol, junctionTargetCol),
3952
3069
  additionalJoins: [{
3953
3070
  table: junctionTable,
3954
- condition: eq$3(currentTableIdCol, junctionSourceCol)
3071
+ condition: eq(currentTableIdCol, junctionSourceCol)
3955
3072
  }]
3956
3073
  };
3957
3074
  } else {
3958
3075
  return {
3959
3076
  joinTable: junctionTable,
3960
- condition: eq$3(currentTableIdCol, junctionSourceCol),
3077
+ condition: eq(currentTableIdCol, junctionSourceCol),
3961
3078
  additionalJoins: [{
3962
3079
  table: targetTable,
3963
- condition: eq$3(targetTableIdCol, junctionTargetCol)
3080
+ condition: eq(targetTableIdCol, junctionTargetCol)
3964
3081
  }]
3965
3082
  };
3966
3083
  }
@@ -3985,11 +3102,11 @@ class DrizzleConditionBuilder {
3985
3102
  if (!junctionTargetCol) {
3986
3103
  throw new Error(`Target column '${through.targetColumn}' not found in junction table '${through.table}'`);
3987
3104
  }
3988
- const condition = Array.isArray(parentEntityId) ? inArray(junctionSourceCol, parentEntityId) : eq$3(junctionSourceCol, parentEntityId);
3105
+ const condition = Array.isArray(parentEntityId) ? inArray(junctionSourceCol, parentEntityId) : eq(junctionSourceCol, parentEntityId);
3989
3106
  return {
3990
3107
  join: {
3991
3108
  table: junctionTable,
3992
- condition: eq$3(targetIdColumn, junctionTargetCol)
3109
+ condition: eq(targetIdColumn, junctionTargetCol)
3993
3110
  },
3994
3111
  condition
3995
3112
  };
@@ -4010,11 +3127,11 @@ class DrizzleConditionBuilder {
4010
3127
  if (!junctionTargetCol) {
4011
3128
  throw new Error(`Target column '${through.targetColumn}' not found in junction table '${through.table}'`);
4012
3129
  }
4013
- const condition = Array.isArray(parentEntityId) ? inArray(junctionSourceCol, parentEntityId) : eq$3(junctionSourceCol, parentEntityId);
3130
+ const condition = Array.isArray(parentEntityId) ? inArray(junctionSourceCol, parentEntityId) : eq(junctionSourceCol, parentEntityId);
4014
3131
  return {
4015
3132
  join: {
4016
3133
  table: junctionTable,
4017
- condition: eq$3(targetIdColumn, junctionTargetCol)
3134
+ condition: eq(targetIdColumn, junctionTargetCol)
4018
3135
  },
4019
3136
  condition
4020
3137
  };
@@ -4030,15 +3147,15 @@ class DrizzleConditionBuilder {
4030
3147
  if (!idCol) {
4031
3148
  throw new Error('No primary key or "id" column found in target table');
4032
3149
  }
4033
- return Array.isArray(parentEntityId) ? inArray(idCol, parentEntityId) : eq$3(idCol, parentEntityId);
3150
+ return Array.isArray(parentEntityId) ? inArray(idCol, parentEntityId) : eq(idCol, parentEntityId);
4034
3151
  }
4035
- return Array.isArray(parentEntityId) ? inArray(targetIdCol, parentEntityId) : eq$3(targetIdCol, parentEntityId);
3152
+ return Array.isArray(parentEntityId) ? inArray(targetIdCol, parentEntityId) : eq(targetIdCol, parentEntityId);
4036
3153
  } else if (relation.direction === "inverse" && relation.foreignKeyOnTarget) {
4037
3154
  const foreignKeyCol = targetTable[relation.foreignKeyOnTarget];
4038
3155
  if (!foreignKeyCol) {
4039
3156
  throw new Error(`Foreign key column '${relation.foreignKeyOnTarget}' not found in target table. This might be a many-to-many relationship that requires a junction table. Consider using 'through' property or ensure the corresponding owning relation exists with junction table configuration.`);
4040
3157
  }
4041
- return Array.isArray(parentEntityId) ? inArray(foreignKeyCol, parentEntityId) : eq$3(foreignKeyCol, parentEntityId);
3158
+ return Array.isArray(parentEntityId) ? inArray(foreignKeyCol, parentEntityId) : eq(foreignKeyCol, parentEntityId);
4042
3159
  } else if (relation.direction === "inverse" && relation.cardinality === "many" && relation.inverseRelationName) {
4043
3160
  throw new Error(`Inverse many-to-many relation '${relation.relationName}' requires a junction table. Either specify 'through' property or ensure the corresponding owning relation exists with junction table configuration.`);
4044
3161
  } else if (relation.direction === "inverse" && relation.cardinality === "one" && relation.inverseRelationName) {
@@ -4048,7 +3165,7 @@ class DrizzleConditionBuilder {
4048
3165
  throw new Error(`Auto-inferred foreign key column '${inferredForeignKeyName}' not found in target table for inverse relation '${relation.relationName}'. Please specify 'foreignKeyOnTarget' explicitly.`);
4049
3166
  }
4050
3167
  console.debug(`🔍 [DrizzleConditionBuilder] Auto-inferred foreign key '${inferredForeignKeyName}' for inverse relation '${relation.relationName}'`);
4051
- return Array.isArray(parentEntityId) ? inArray(foreignKeyCol, parentEntityId) : eq$3(foreignKeyCol, parentEntityId);
3168
+ return Array.isArray(parentEntityId) ? inArray(foreignKeyCol, parentEntityId) : eq(foreignKeyCol, parentEntityId);
4052
3169
  } else {
4053
3170
  throw new Error(`Relation '${relation.relationName}' lacks proper configuration. For many-to-many relations, use 'through' property. For simple relations, use 'localKey' or 'foreignKeyOnTarget'.`);
4054
3171
  }
@@ -4079,7 +3196,10 @@ class DrizzleConditionBuilder {
4079
3196
  if (p.type === "string" && !p.enum && p.isId !== "uuid") {
4080
3197
  const fieldColumn = table[key];
4081
3198
  if (fieldColumn) {
4082
- searchConditions.push(ilike(fieldColumn, `%${searchString}%`));
3199
+ const supportsILike = fieldColumn instanceof PgVarchar || fieldColumn instanceof PgText || fieldColumn instanceof PgChar || fieldColumn && typeof fieldColumn === "object" && !("columnType" in fieldColumn);
3200
+ if (supportsILike) {
3201
+ searchConditions.push(ilike(fieldColumn, `%${searchString}%`));
3202
+ }
4083
3203
  }
4084
3204
  }
4085
3205
  }
@@ -4089,7 +3209,7 @@ class DrizzleConditionBuilder {
4089
3209
  * Build a unique field check condition
4090
3210
  */
4091
3211
  static buildUniqueFieldCondition(fieldColumn, value, idColumn, excludeId) {
4092
- const conditions = [eq$3(fieldColumn, value)];
3212
+ const conditions = [eq(fieldColumn, value)];
4093
3213
  if (excludeId && idColumn) {
4094
3214
  conditions.push(sql`${idColumn} != ${excludeId}`);
4095
3215
  }
@@ -4164,7 +3284,7 @@ class DrizzleConditionBuilder {
4164
3284
  if (currentTable !== parentTable) {
4165
3285
  throw new Error("Join path did not result in connecting to parent table");
4166
3286
  }
4167
- const allConditions = [eq$3(parentIdColumn, parentEntityId)];
3287
+ const allConditions = [eq(parentIdColumn, parentEntityId)];
4168
3288
  if (additionalFilters) {
4169
3289
  allConditions.push(...additionalFilters);
4170
3290
  }
@@ -4186,11 +3306,11 @@ class DrizzleConditionBuilder {
4186
3306
  if (!junctionTargetCol) {
4187
3307
  throw new Error(`Target column '${through.targetColumn}' not found in junction table '${through.table}'`);
4188
3308
  }
4189
- const baseConditions = [eq$3(junctionSourceCol, parentEntityId)];
3309
+ const baseConditions = [eq(junctionSourceCol, parentEntityId)];
4190
3310
  if (additionalFilters && additionalFilters.length > 0) {
4191
3311
  baseConditions.push(...additionalFilters);
4192
3312
  }
4193
- return baseCountQuery.innerJoin(junctionTable, eq$3(targetIdColumn, junctionTargetCol)).where(and(...baseConditions));
3313
+ return baseCountQuery.innerJoin(junctionTable, eq(targetIdColumn, junctionTargetCol)).where(and(...baseConditions));
4194
3314
  }
4195
3315
  /**
4196
3316
  * Build inverse junction table conditions for count queries
@@ -4208,11 +3328,11 @@ class DrizzleConditionBuilder {
4208
3328
  if (!junctionTargetCol) {
4209
3329
  throw new Error(`Target column '${through.targetColumn}' not found in junction table '${through.table}'`);
4210
3330
  }
4211
- const baseConditions = [eq$3(junctionSourceCol, parentEntityId)];
3331
+ const baseConditions = [eq(junctionSourceCol, parentEntityId)];
4212
3332
  if (additionalFilters && additionalFilters.length > 0) {
4213
3333
  baseConditions.push(...additionalFilters);
4214
3334
  }
4215
- return baseCountQuery.innerJoin(junctionTable, eq$3(targetIdColumn, junctionTargetCol)).where(and(...baseConditions));
3335
+ return baseCountQuery.innerJoin(junctionTable, eq(targetIdColumn, junctionTargetCol)).where(and(...baseConditions));
4216
3336
  }
4217
3337
  /**
4218
3338
  * Helper method to extract table names from columns
@@ -4552,6 +3672,31 @@ function serializePropertyToServer(value, property) {
4552
3672
  return result;
4553
3673
  }
4554
3674
  return value;
3675
+ case "vector": {
3676
+ if (value instanceof Vector) {
3677
+ return value.value;
3678
+ }
3679
+ if (value && typeof value === "object" && "value" in value && Array.isArray(value.value)) {
3680
+ return value.value.map(Number);
3681
+ }
3682
+ if (Array.isArray(value)) {
3683
+ return value.map(Number);
3684
+ }
3685
+ return value;
3686
+ }
3687
+ case "binary":
3688
+ if (typeof value === "string") {
3689
+ if (value.startsWith("data:application/octet-stream;base64,")) {
3690
+ const base64Data = value.split(",")[1];
3691
+ if (base64Data) {
3692
+ return Buffer.from(base64Data, "base64");
3693
+ }
3694
+ }
3695
+ }
3696
+ if (Buffer.isBuffer(value)) {
3697
+ return value;
3698
+ }
3699
+ return value;
4555
3700
  case "string":
4556
3701
  if (typeof value === "string") {
4557
3702
  if (value.startsWith("data:application/octet-stream;base64,")) {
@@ -4604,7 +3749,7 @@ async function parseDataFromServer(data, collection, db, registry) {
4604
3749
  if (targetTable && currentEntityId) {
4605
3750
  const foreignKeyColumn = targetTable[relation.foreignKeyOnTarget];
4606
3751
  if (foreignKeyColumn) {
4607
- const relatedEntities = await db.select().from(targetTable).where(eq$3(foreignKeyColumn, currentEntityId)).limit(relation.cardinality === "one" ? 1 : 100);
3752
+ const relatedEntities = await db.select().from(targetTable).where(eq(foreignKeyColumn, currentEntityId)).limit(relation.cardinality === "one" ? 1 : 100);
4608
3753
  if (relatedEntities.length > 0) {
4609
3754
  if (relation.cardinality === "one") {
4610
3755
  const targetPks = getPrimaryKeys(targetCollection, registry);
@@ -4651,12 +3796,12 @@ async function parseDataFromServer(data, collection, db, registry) {
4651
3796
  console.warn(`Join columns not found: ${fromColumn} -> ${toColumn}`);
4652
3797
  break;
4653
3798
  }
4654
- query = query.innerJoin(joinTable, eq$3(fromCol, toCol));
3799
+ query = query.innerJoin(joinTable, eq(fromCol, toCol));
4655
3800
  currentTable = joinTable;
4656
3801
  }
4657
3802
  if (pks.length === 1) {
4658
3803
  const sourceIdField = sourceTable[pks[0].fieldName];
4659
- query = query.where(eq$3(sourceIdField, currentEntityId));
3804
+ query = query.where(eq(sourceIdField, currentEntityId));
4660
3805
  } else {
4661
3806
  console.warn(`Join path resolution for composite primary keys is not yet fully supported: ${collection.slug}`);
4662
3807
  }
@@ -4664,7 +3809,7 @@ async function parseDataFromServer(data, collection, db, registry) {
4664
3809
  let combinedWhere;
4665
3810
  if (pks.length === 1) {
4666
3811
  const sourceIdField = sourceTable[pks[0].fieldName];
4667
- combinedWhere = DrizzleConditionBuilder.combineConditionsWithAnd([eq$3(sourceIdField, currentEntityId), ...additionalFilters].filter(Boolean));
3812
+ combinedWhere = DrizzleConditionBuilder.combineConditionsWithAnd([eq(sourceIdField, currentEntityId), ...additionalFilters].filter(Boolean));
4668
3813
  }
4669
3814
  const joinResults = await query.where(combinedWhere).limit(relation.cardinality === "one" ? 1 : 100);
4670
3815
  if (joinResults.length > 0) {
@@ -4696,18 +3841,36 @@ function parsePropertyFromServer(value, property, collection, propertyKey) {
4696
3841
  return value;
4697
3842
  }
4698
3843
  switch (property.type) {
3844
+ case "binary": {
3845
+ let buf = null;
3846
+ if (Buffer.isBuffer(value)) {
3847
+ buf = value;
3848
+ } else if (typeof value === "object" && value !== null) {
3849
+ const rawVal = value;
3850
+ if (rawVal.type === "Buffer" && Array.isArray(rawVal.data)) {
3851
+ buf = Buffer.from(rawVal.data);
3852
+ }
3853
+ }
3854
+ if (buf) {
3855
+ return `data:application/octet-stream;base64,${buf.toString("base64")}`;
3856
+ }
3857
+ return value;
3858
+ }
4699
3859
  case "string": {
4700
3860
  if (typeof value === "string") return value;
4701
- let isBuffer2 = false;
3861
+ let isBuffer = false;
4702
3862
  let buf = null;
4703
3863
  if (Buffer.isBuffer(value)) {
4704
- isBuffer2 = true;
3864
+ isBuffer = true;
4705
3865
  buf = value;
4706
- } else if (typeof value === "object" && value !== null && value.type === "Buffer" && Array.isArray(value.data)) {
4707
- isBuffer2 = true;
4708
- buf = Buffer.from(value.data);
3866
+ } else if (typeof value === "object" && value !== null) {
3867
+ const rawVal = value;
3868
+ if (rawVal.type === "Buffer" && Array.isArray(rawVal.data)) {
3869
+ isBuffer = true;
3870
+ buf = Buffer.from(rawVal.data);
3871
+ }
4709
3872
  }
4710
- if (isBuffer2 && buf) {
3873
+ if (isBuffer && buf) {
4711
3874
  let isPrintable = true;
4712
3875
  for (let i = 0; i < buf.length; i++) {
4713
3876
  const b = buf[i];
@@ -4792,8 +3955,27 @@ function parsePropertyFromServer(value, property, collection, propertyKey) {
4792
3955
  return isNaN(parsed) ? null : parsed;
4793
3956
  }
4794
3957
  return value;
4795
- case "date": {
4796
- let date;
3958
+ case "vector": {
3959
+ let nums = [];
3960
+ if (typeof value === "string") {
3961
+ nums = value.slice(1, -1).split(",").map(Number);
3962
+ } else if (Array.isArray(value)) {
3963
+ nums = value.map(Number);
3964
+ } else if (value instanceof Vector) {
3965
+ nums = value.value;
3966
+ } else if (typeof value === "object" && value !== null && "value" in value) {
3967
+ const valObj = value;
3968
+ if (Array.isArray(valObj.value)) {
3969
+ nums = valObj.value.map(Number);
3970
+ }
3971
+ }
3972
+ return {
3973
+ __type: "Vector",
3974
+ value: nums
3975
+ };
3976
+ }
3977
+ case "date": {
3978
+ let date;
4797
3979
  if (value instanceof Date) {
4798
3980
  date = value;
4799
3981
  } else if (typeof value === "string" || typeof value === "number") {
@@ -4811,16 +3993,19 @@ function parsePropertyFromServer(value, property, collection, propertyKey) {
4811
3993
  return null;
4812
3994
  }
4813
3995
  default: {
4814
- let isBuffer2 = false;
3996
+ let isBuffer = false;
4815
3997
  let buf = null;
4816
3998
  if (Buffer.isBuffer(value)) {
4817
- isBuffer2 = true;
3999
+ isBuffer = true;
4818
4000
  buf = value;
4819
- } else if (typeof value === "object" && value !== null && value.type === "Buffer" && Array.isArray(value.data)) {
4820
- isBuffer2 = true;
4821
- buf = Buffer.from(value.data);
4001
+ } else if (typeof value === "object" && value !== null) {
4002
+ const rawVal = value;
4003
+ if (rawVal.type === "Buffer" && Array.isArray(rawVal.data)) {
4004
+ isBuffer = true;
4005
+ buf = Buffer.from(rawVal.data);
4006
+ }
4822
4007
  }
4823
- if (isBuffer2 && buf) {
4008
+ if (isBuffer && buf) {
4824
4009
  let isPrintable = true;
4825
4010
  for (let i = 0; i < buf.length; i++) {
4826
4011
  const b = buf[i];
@@ -4915,11 +4100,11 @@ class RelationService {
4915
4100
  if (!fromCol || !toCol) {
4916
4101
  throw new Error(`Join columns not found: ${fromColumn} -> ${toColumn}`);
4917
4102
  }
4918
- query2 = query2.innerJoin(joinTable, eq$3(fromCol, toCol));
4103
+ query2 = query2.innerJoin(joinTable, eq(fromCol, toCol));
4919
4104
  currentTable = joinTable;
4920
4105
  }
4921
4106
  const parentIdField = parentTable[getPrimaryKeys(parentCollection, this.registry)[0].fieldName];
4922
- query2 = query2.where(eq$3(parentIdField, parsedParentId));
4107
+ query2 = query2.where(eq(parentIdField, parsedParentId));
4923
4108
  if (options.limit) {
4924
4109
  query2 = query2.limit(options.limit);
4925
4110
  }
@@ -5038,7 +4223,7 @@ class RelationService {
5038
4223
  if (!fromCol || !toCol) {
5039
4224
  throw new Error(`Join columns not found: ${fromColumn} -> ${toColumn}`);
5040
4225
  }
5041
- query2 = query2.innerJoin(joinTable, eq$3(fromCol, toCol));
4226
+ query2 = query2.innerJoin(joinTable, eq(fromCol, toCol));
5042
4227
  currentTable = joinTable;
5043
4228
  }
5044
4229
  const parentIdField = parentTable[getPrimaryKeys(parentCollection, this.registry)[0].fieldName];
@@ -5169,7 +4354,7 @@ class RelationService {
5169
4354
  const fromCol = currentTable[fromColName];
5170
4355
  const toCol = joinTable[toColName];
5171
4356
  if (!fromCol || !toCol) throw new Error(`Join columns not found: ${fromColumn} -> ${toColumn}`);
5172
- query2 = query2.innerJoin(joinTable, eq$3(fromCol, toCol));
4357
+ query2 = query2.innerJoin(joinTable, eq(fromCol, toCol));
5173
4358
  currentTable = joinTable;
5174
4359
  }
5175
4360
  const parentIdField = parentTable[getPrimaryKeys(parentCollection, this.registry)[0].fieldName];
@@ -5204,7 +4389,7 @@ class RelationService {
5204
4389
  console.warn(`[batchFetchRelatedEntitiesMany] Junction columns not found in '${relation.through.table}'`);
5205
4390
  return /* @__PURE__ */ new Map();
5206
4391
  }
5207
- const query2 = this.db.select().from(junctionTable).innerJoin(targetTable, eq$3(targetJunctionCol, targetIdField)).where(inArray(sourceJunctionCol, parsedParentIds));
4392
+ const query2 = this.db.select().from(junctionTable).innerJoin(targetTable, eq(targetJunctionCol, targetIdField)).where(inArray(sourceJunctionCol, parsedParentIds));
5208
4393
  const results2 = await query2;
5209
4394
  const resultMap2 = /* @__PURE__ */ new Map();
5210
4395
  const targetTableName = getTableName(targetCollection);
@@ -5302,7 +4487,7 @@ class RelationService {
5302
4487
  const parentIdInfo = parentPks[0];
5303
4488
  const parsedParentIdObj = parseIdValues(entityId, parentPks);
5304
4489
  const parsedParentId = parsedParentIdObj[parentIdInfo.fieldName];
5305
- await tx.delete(junctionTable).where(eq$3(sourceJunctionColumn, parsedParentId));
4490
+ await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedParentId));
5306
4491
  if (targetEntityIds.length > 0) {
5307
4492
  const targetPks = getPrimaryKeys(targetCollection, this.registry);
5308
4493
  const targetIdInfo = targetPks[0];
@@ -5331,7 +4516,7 @@ class RelationService {
5331
4516
  const parentIdInfo = parentPks[0];
5332
4517
  const parsedParentIdObj = parseIdValues(entityId, parentPks);
5333
4518
  const parsedParentId = parsedParentIdObj[parentIdInfo.fieldName];
5334
- await tx.delete(junctionTable).where(eq$3(sourceJunctionColumn, parsedParentId));
4519
+ await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedParentId));
5335
4520
  if (targetEntityIds.length > 0) {
5336
4521
  const targetPks = getPrimaryKeys(targetCollection, this.registry);
5337
4522
  const targetIdInfo = targetPks[0];
@@ -5364,14 +4549,14 @@ class RelationService {
5364
4549
  const parsedTargetIds = targetEntityIds.map((id) => parseIdValues(id, targetPks)[targetIdInfo.fieldName]);
5365
4550
  await tx.update(targetTable).set({
5366
4551
  [relation.foreignKeyOnTarget]: null
5367
- }).where(and(eq$3(fkCol, parsedParentId), sql`${targetIdCol} NOT IN (${sql.join(parsedTargetIds)})`));
4552
+ }).where(and(eq(fkCol, parsedParentId), sql`${targetIdCol} NOT IN (${sql.join(parsedTargetIds)})`));
5368
4553
  await tx.update(targetTable).set({
5369
4554
  [relation.foreignKeyOnTarget]: parsedParentId
5370
4555
  }).where(inArray(targetIdCol, parsedTargetIds));
5371
4556
  } else {
5372
4557
  await tx.update(targetTable).set({
5373
4558
  [relation.foreignKeyOnTarget]: null
5374
- }).where(eq$3(fkCol, parsedParentId));
4559
+ }).where(eq(fkCol, parsedParentId));
5375
4560
  }
5376
4561
  } else {
5377
4562
  console.warn(`Many relation '${key}' in collection '${collection.slug}' lacks write configuration and will be skipped during save.`);
@@ -5430,17 +4615,17 @@ class RelationService {
5430
4615
  if (newValue === null || newValue === void 0) {
5431
4616
  await tx.update(targetTable).set({
5432
4617
  [relation.foreignKeyOnTarget]: null
5433
- }).where(eq$3(foreignKeyColumn, parsedSourceId));
4618
+ }).where(eq(foreignKeyColumn, parsedSourceId));
5434
4619
  } else {
5435
4620
  const parsedNewTargetIdObj = parseIdValues(newValue, targetPks);
5436
4621
  const parsedNewTargetId = parsedNewTargetIdObj[targetIdInfo.fieldName];
5437
4622
  const targetIdField = targetTable[targetIdInfo.fieldName];
5438
4623
  await tx.update(targetTable).set({
5439
4624
  [relation.foreignKeyOnTarget]: null
5440
- }).where(eq$3(foreignKeyColumn, parsedSourceId));
4625
+ }).where(eq(foreignKeyColumn, parsedSourceId));
5441
4626
  await tx.update(targetTable).set({
5442
4627
  [relation.foreignKeyOnTarget]: parsedSourceId
5443
- }).where(eq$3(targetIdField, parsedNewTargetId));
4628
+ }).where(eq(targetIdField, parsedNewTargetId));
5444
4629
  }
5445
4630
  } catch (e) {
5446
4631
  console.warn(`Failed to update inverse relation '${relation.relationName}':`, e);
@@ -5495,7 +4680,7 @@ class RelationService {
5495
4680
  const sourceIdInfo = sourcePks[0];
5496
4681
  const parsedSourceIdObj = parseIdValues(sourceEntityId, sourcePks);
5497
4682
  const parsedSourceId = parsedSourceIdObj[sourceIdInfo.fieldName];
5498
- await tx.delete(junctionTable).where(eq$3(sourceJunctionColumn, parsedSourceId));
4683
+ await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedSourceId));
5499
4684
  if (newValue && Array.isArray(newValue) && newValue.length > 0) {
5500
4685
  const targetPks = getPrimaryKeys(targetCollection, this.registry);
5501
4686
  const targetIdInfo = targetPks[0];
@@ -5546,7 +4731,7 @@ class RelationService {
5546
4731
  const sourceIdInfo = sourcePks[0];
5547
4732
  const parsedSourceIdObj = parseIdValues(sourceEntityId, sourcePks);
5548
4733
  const parsedSourceId = parsedSourceIdObj[sourceIdInfo.fieldName];
5549
- await tx.delete(junctionTable).where(eq$3(sourceJunctionColumn, parsedSourceId));
4734
+ await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedSourceId));
5550
4735
  if (newValue && Array.isArray(newValue) && newValue.length > 0) {
5551
4736
  const targetPks = getPrimaryKeys(targetCollection, this.registry);
5552
4737
  const targetIdInfo = targetPks[0];
@@ -5601,14 +4786,14 @@ class RelationService {
5601
4786
  }
5602
4787
  const parentRows = await tx.select({
5603
4788
  val: parentSourceCol
5604
- }).from(parentTable).where(eq$3(parentIdCol, parsedParentId)).limit(1);
4789
+ }).from(parentTable).where(eq(parentIdCol, parsedParentId)).limit(1);
5605
4790
  if (parentRows.length === 0) continue;
5606
4791
  const parentFKValue = parentRows[0].val;
5607
4792
  if (newTargetId === null || newTargetId === void 0) {
5608
4793
  if (parentFKValue !== null && parentFKValue !== void 0) {
5609
4794
  await tx.update(targetTable).set({
5610
4795
  [targetFKColName]: null
5611
- }).where(eq$3(targetFKCol, parentFKValue));
4796
+ }).where(eq(targetFKCol, String(parentFKValue)));
5612
4797
  }
5613
4798
  continue;
5614
4799
  }
@@ -5617,14 +4802,14 @@ class RelationService {
5617
4802
  if (parentFKValue !== null && parentFKValue !== void 0) {
5618
4803
  await tx.update(targetTable).set({
5619
4804
  [targetFKColName]: null
5620
- }).where(eq$3(targetFKCol, parentFKValue));
4805
+ }).where(eq(targetFKCol, String(parentFKValue)));
5621
4806
  } else {
5622
4807
  console.warn(`Cannot set joinPath relation '${relation.relationName}' because parent FK value is null/undefined`);
5623
4808
  continue;
5624
4809
  }
5625
4810
  await tx.update(targetTable).set({
5626
4811
  [targetFKColName]: parentFKValue
5627
- }).where(eq$3(targetIdCol, parsedTargetId));
4812
+ }).where(eq(targetIdCol, parsedTargetId));
5628
4813
  }
5629
4814
  }
5630
4815
  /**
@@ -6009,7 +5194,7 @@ class EntityFetchService {
6009
5194
  const collection = getCollectionByPath(collectionPath, this.registry);
6010
5195
  const searchConditions = DrizzleConditionBuilder.buildSearchConditions(options.searchString, collection.properties, table);
6011
5196
  if (searchConditions.length === 0) {
6012
- queryOpts.where = and(eq$3(idField, -99999999));
5197
+ queryOpts.where = and(eq(idField, -99999999));
6013
5198
  return queryOpts;
6014
5199
  }
6015
5200
  allConditions.push(DrizzleConditionBuilder.combineConditionsWithOr(searchConditions));
@@ -6056,9 +5241,9 @@ class EntityFetchService {
6056
5241
  const startAfterId = cursor.id ?? cursor[idInfo.fieldName];
6057
5242
  if (startAfterOrderValue !== void 0 && startAfterId !== void 0) {
6058
5243
  if (options.order === "asc") {
6059
- return [or(gt(orderByField, startAfterOrderValue), and(eq$3(orderByField, startAfterOrderValue), gt(idField, startAfterId)))];
5244
+ return [or(gt(orderByField, startAfterOrderValue), and(eq(orderByField, startAfterOrderValue), gt(idField, startAfterId)))];
6060
5245
  } else {
6061
- return [or(lt(orderByField, startAfterOrderValue), and(eq$3(orderByField, startAfterOrderValue), lt(idField, startAfterId)))];
5246
+ return [or(lt(orderByField, startAfterOrderValue), and(eq(orderByField, startAfterOrderValue), lt(idField, startAfterId)))];
6062
5247
  }
6063
5248
  }
6064
5249
  }
@@ -6092,7 +5277,7 @@ class EntityFetchService {
6092
5277
  try {
6093
5278
  const withConfig = this.buildWithConfig(collection);
6094
5279
  const row = await qb.findFirst({
6095
- where: eq$3(idField, parsedId),
5280
+ where: eq(idField, parsedId),
6096
5281
  with: withConfig
6097
5282
  });
6098
5283
  if (!row) return void 0;
@@ -6107,7 +5292,7 @@ class EntityFetchService {
6107
5292
  console.warn(`[EntityFetchService] db.query.findFirst failed for ${collectionPath}, falling back to db.select:`, e);
6108
5293
  }
6109
5294
  }
6110
- const result = await this.db.select().from(table).where(eq$3(idField, parsedId)).limit(1);
5295
+ const result = await this.db.select().from(table).where(eq(idField, parsedId)).limit(1);
6111
5296
  if (result.length === 0) return void 0;
6112
5297
  const raw = result[0];
6113
5298
  const values = await parseDataFromServer(raw, collection, this.db, this.registry);
@@ -6511,7 +5696,7 @@ class EntityFetchService {
6511
5696
  try {
6512
5697
  const withConfig = include && include.length > 0 ? this.buildWithConfig(collection, include) : void 0;
6513
5698
  const row = await qb.findFirst({
6514
- where: eq$3(idField, parsedId),
5699
+ where: eq(idField, parsedId),
6515
5700
  ...withConfig ? {
6516
5701
  with: withConfig
6517
5702
  } : {}
@@ -6528,7 +5713,7 @@ class EntityFetchService {
6528
5713
  console.warn(`[fetchEntityForRest] db.query.findFirst failed for ${collectionPath}, falling back:`, e);
6529
5714
  }
6530
5715
  }
6531
- const result = await this.db.select().from(table).where(eq$3(idField, parsedId)).limit(1);
5716
+ const result = await this.db.select().from(table).where(eq(idField, parsedId)).limit(1);
6532
5717
  if (result.length === 0) return null;
6533
5718
  const raw = result[0];
6534
5719
  const flatEntity = {
@@ -6737,7 +5922,7 @@ class EntityPersistService {
6737
5922
  }
6738
5923
  const parsedIdObj = parseIdValues(entityId, idInfoArray);
6739
5924
  const parsedId = parsedIdObj[idInfo.fieldName];
6740
- await this.db.delete(table).where(eq$3(idField, parsedId));
5925
+ await this.db.delete(table).where(eq(idField, parsedId));
6741
5926
  }
6742
5927
  /**
6743
5928
  * Save an entity (create or update)
@@ -6861,7 +6046,7 @@ class EntityPersistService {
6861
6046
  const conditions = [];
6862
6047
  for (const info of idInfoArray) {
6863
6048
  const field = table[info.fieldName];
6864
- conditions.push(eq$3(field, idValues[info.fieldName]));
6049
+ conditions.push(eq(field, idValues[info.fieldName]));
6865
6050
  }
6866
6051
  await updateQuery.where(and(...conditions));
6867
6052
  }
@@ -7694,23 +6879,33 @@ class PostgresBackendDriver {
7694
6879
  client: this.client
7695
6880
  };
7696
6881
  if (callbacks?.beforeDelete || propertyCallbacks?.beforeDelete) {
6882
+ let preventDefault = false;
7697
6883
  if (callbacks?.beforeDelete) {
7698
- await callbacks.beforeDelete({
6884
+ const result = await callbacks.beforeDelete({
7699
6885
  collection: resolvedCollection,
7700
6886
  path: entity.path,
7701
6887
  entityId: entity.id,
7702
6888
  entity,
7703
6889
  context: contextForCallback
7704
6890
  });
6891
+ if (result === false) {
6892
+ preventDefault = true;
6893
+ }
7705
6894
  }
7706
6895
  if (propertyCallbacks?.beforeDelete) {
7707
- await propertyCallbacks.beforeDelete({
6896
+ const result = await propertyCallbacks.beforeDelete({
7708
6897
  collection: resolvedCollection,
7709
6898
  path: entity.path,
7710
6899
  entityId: entity.id,
7711
6900
  entity,
7712
6901
  context: contextForCallback
7713
6902
  });
6903
+ if (result === false) {
6904
+ preventDefault = true;
6905
+ }
6906
+ }
6907
+ if (preventDefault) {
6908
+ return;
7714
6909
  }
7715
6910
  }
7716
6911
  await this.entityService.deleteEntity(entity.path, entity.id, entity.databaseId || resolvedCollection?.databaseId);
@@ -7783,7 +6978,17 @@ class PostgresBackendDriver {
7783
6978
  }
7784
6979
  const targetDb = this.getTargetDb(options?.database);
7785
6980
  try {
7786
- if (options?.role) {
6981
+ let needsRoleSwitch = false;
6982
+ if (options?.role && process.env.DISABLE_DB_ROLE_SWITCHING !== "true") {
6983
+ try {
6984
+ const currentRoleResult = await targetDb.execute(sql.raw("SELECT current_user AS role"));
6985
+ const currentRole = currentRoleResult.rows?.[0]?.role;
6986
+ needsRoleSwitch = !!currentRole && currentRole !== options.role;
6987
+ } catch {
6988
+ needsRoleSwitch = true;
6989
+ }
6990
+ }
6991
+ if (needsRoleSwitch && options?.role) {
7787
6992
  const safeRole = options.role.replace(/"/g, '""');
7788
6993
  return await targetDb.transaction(async (tx) => {
7789
6994
  await tx.execute(sql.raw(`SET LOCAL ROLE "${safeRole}"`));
@@ -7821,7 +7026,7 @@ class PostgresBackendDriver {
7821
7026
  return databases;
7822
7027
  }
7823
7028
  async fetchAvailableRoles() {
7824
- const result = await this.executeSql("SELECT rolname FROM pg_roles;");
7029
+ const result = await this.executeSql("SELECT rolname FROM pg_roles WHERE pg_has_role(current_user, rolname, 'member') ORDER BY rolname;");
7825
7030
  return result.map((r) => r.rolname);
7826
7031
  }
7827
7032
  async fetchCurrentDatabase() {
@@ -7990,6 +7195,21 @@ class AuthenticatedPostgresBackendDriver {
7990
7195
  * Typed admin capabilities — delegates to the base driver.
7991
7196
  */
7992
7197
  admin;
7198
+ get restFetchService() {
7199
+ if (!this.delegate.restFetchService) return void 0;
7200
+ return {
7201
+ fetchCollectionForRest: async (collectionPath, options, include) => {
7202
+ return this.withTransaction(async (delegate) => {
7203
+ return delegate.restFetchService.fetchCollectionForRest(collectionPath, options, include);
7204
+ });
7205
+ },
7206
+ fetchEntityForRest: async (collectionPath, entityId, include, databaseId) => {
7207
+ return this.withTransaction(async (delegate) => {
7208
+ return delegate.restFetchService.fetchEntityForRest(collectionPath, entityId, include, databaseId);
7209
+ });
7210
+ }
7211
+ };
7212
+ }
7993
7213
  async withTransaction(operation) {
7994
7214
  const pendingNotifications = [];
7995
7215
  const result = await this.delegate.db.transaction(async (tx) => {
@@ -8144,113 +7364,140 @@ class DatabasePoolManager {
8144
7364
  this.pools.clear();
8145
7365
  }
8146
7366
  }
8147
- const rebaseSchema = pgSchema("rebase");
8148
- const users = rebaseSchema.table("users", {
8149
- id: uuid("id").defaultRandom().primaryKey(),
8150
- email: varchar("email", {
8151
- length: 255
8152
- }).notNull().unique(),
8153
- passwordHash: varchar("password_hash", {
8154
- length: 255
8155
- }),
8156
- // NULL for OAuth-only users
8157
- displayName: varchar("display_name", {
8158
- length: 255
8159
- }),
8160
- photoUrl: varchar("photo_url", {
8161
- length: 500
8162
- }),
8163
- emailVerified: boolean("email_verified").default(false).notNull(),
8164
- emailVerificationToken: varchar("email_verification_token", {
8165
- length: 255
8166
- }),
8167
- emailVerificationSentAt: timestamp("email_verification_sent_at"),
8168
- createdAt: timestamp("created_at").defaultNow().notNull(),
8169
- updatedAt: timestamp("updated_at").defaultNow().notNull()
8170
- });
8171
- const roles = rebaseSchema.table("roles", {
8172
- id: varchar("id", {
8173
- length: 50
8174
- }).primaryKey(),
8175
- // 'admin', 'editor', 'viewer'
8176
- name: varchar("name", {
8177
- length: 100
8178
- }).notNull(),
8179
- isAdmin: boolean("is_admin").default(false).notNull(),
8180
- defaultPermissions: jsonb("default_permissions").$type(),
8181
- collectionPermissions: jsonb("collection_permissions").$type(),
8182
- config: jsonb("config").$type()
8183
- });
8184
- const userRoles = rebaseSchema.table("user_roles", {
8185
- userId: uuid("user_id").notNull().references(() => users.id, {
8186
- onDelete: "cascade"
8187
- }),
8188
- roleId: varchar("role_id", {
8189
- length: 50
8190
- }).notNull().references(() => roles.id, {
8191
- onDelete: "cascade"
8192
- })
8193
- }, (table) => ({
8194
- pk: primaryKey({
8195
- columns: [table.userId, table.roleId]
8196
- })
8197
- }));
8198
- const refreshTokens = rebaseSchema.table("refresh_tokens", {
8199
- id: uuid("id").defaultRandom().primaryKey(),
8200
- userId: uuid("user_id").notNull().references(() => users.id, {
8201
- onDelete: "cascade"
8202
- }),
8203
- tokenHash: varchar("token_hash", {
8204
- length: 255
8205
- }).notNull().unique(),
8206
- expiresAt: timestamp("expires_at").notNull(),
8207
- userAgent: varchar("user_agent", {
8208
- length: 500
8209
- }),
8210
- ipAddress: varchar("ip_address", {
8211
- length: 45
8212
- }),
8213
- createdAt: timestamp("created_at").defaultNow().notNull()
8214
- }, (table) => ({
8215
- uniqueDeviceSession: unique("unique_device_session").on(table.userId, table.userAgent, table.ipAddress)
8216
- }));
8217
- const passwordResetTokens = rebaseSchema.table("password_reset_tokens", {
8218
- id: uuid("id").defaultRandom().primaryKey(),
8219
- userId: uuid("user_id").notNull().references(() => users.id, {
8220
- onDelete: "cascade"
8221
- }),
8222
- tokenHash: varchar("token_hash", {
8223
- length: 255
8224
- }).notNull().unique(),
8225
- expiresAt: timestamp("expires_at").notNull(),
8226
- usedAt: timestamp("used_at"),
8227
- createdAt: timestamp("created_at").defaultNow().notNull()
8228
- });
8229
- const appConfig = rebaseSchema.table("app_config", {
8230
- key: varchar("key", {
8231
- length: 100
8232
- }).primaryKey(),
8233
- value: jsonb("value").notNull(),
8234
- updatedAt: timestamp("updated_at").defaultNow().notNull()
8235
- });
8236
- const userIdentities = rebaseSchema.table("user_identities", {
8237
- id: uuid("id").defaultRandom().primaryKey(),
8238
- userId: uuid("user_id").notNull().references(() => users.id, {
8239
- onDelete: "cascade"
8240
- }),
8241
- provider: varchar("provider", {
8242
- length: 50
8243
- }).notNull(),
8244
- // e.g. 'google', 'linkedin'
8245
- providerId: varchar("provider_id", {
8246
- length: 255
8247
- }).notNull(),
8248
- profileData: jsonb("profile_data"),
8249
- createdAt: timestamp("created_at").defaultNow().notNull(),
8250
- updatedAt: timestamp("updated_at").defaultNow().notNull()
8251
- }, (table) => ({
8252
- uniqueProviderId: unique("unique_provider_id").on(table.provider, table.providerId)
8253
- }));
7367
+ function createAuthSchema(rolesSchemaName = "rebase", usersSchemaName = "rebase") {
7368
+ const rolesSchema = rolesSchemaName === "public" ? null : pgSchema(rolesSchemaName);
7369
+ const usersSchema2 = usersSchemaName === "public" ? null : pgSchema(usersSchemaName);
7370
+ const rolesTableCreator = rolesSchema ? rolesSchema.table.bind(rolesSchema) : pgTable;
7371
+ const usersTableCreator = usersSchema2 ? usersSchema2.table.bind(usersSchema2) : pgTable;
7372
+ const users2 = usersTableCreator("users", {
7373
+ id: uuid("id").defaultRandom().primaryKey(),
7374
+ email: varchar("email", {
7375
+ length: 255
7376
+ }).notNull().unique(),
7377
+ passwordHash: varchar("password_hash", {
7378
+ length: 255
7379
+ }),
7380
+ // NULL for OAuth-only users
7381
+ displayName: varchar("display_name", {
7382
+ length: 255
7383
+ }),
7384
+ photoUrl: varchar("photo_url", {
7385
+ length: 500
7386
+ }),
7387
+ emailVerified: boolean("email_verified").default(false).notNull(),
7388
+ emailVerificationToken: varchar("email_verification_token", {
7389
+ length: 255
7390
+ }),
7391
+ emailVerificationSentAt: timestamp("email_verification_sent_at"),
7392
+ metadata: jsonb("metadata").$type().default({}).notNull(),
7393
+ createdAt: timestamp("created_at").defaultNow().notNull(),
7394
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
7395
+ });
7396
+ const roles2 = rolesTableCreator("roles", {
7397
+ id: varchar("id", {
7398
+ length: 50
7399
+ }).primaryKey(),
7400
+ // 'admin', 'editor', 'viewer'
7401
+ name: varchar("name", {
7402
+ length: 100
7403
+ }).notNull(),
7404
+ isAdmin: boolean("is_admin").default(false).notNull(),
7405
+ defaultPermissions: jsonb("default_permissions").$type(),
7406
+ collectionPermissions: jsonb("collection_permissions").$type(),
7407
+ config: jsonb("config").$type()
7408
+ });
7409
+ const userRoles2 = rolesTableCreator("user_roles", {
7410
+ userId: uuid("user_id").notNull().references(() => users2.id, {
7411
+ onDelete: "cascade"
7412
+ }),
7413
+ roleId: varchar("role_id", {
7414
+ length: 50
7415
+ }).notNull().references(() => roles2.id, {
7416
+ onDelete: "cascade"
7417
+ })
7418
+ }, (table) => ({
7419
+ pk: primaryKey({
7420
+ columns: [table.userId, table.roleId]
7421
+ })
7422
+ }));
7423
+ const refreshTokens2 = rolesTableCreator("refresh_tokens", {
7424
+ id: uuid("id").defaultRandom().primaryKey(),
7425
+ userId: uuid("user_id").notNull().references(() => users2.id, {
7426
+ onDelete: "cascade"
7427
+ }),
7428
+ tokenHash: varchar("token_hash", {
7429
+ length: 255
7430
+ }).notNull().unique(),
7431
+ expiresAt: timestamp("expires_at").notNull(),
7432
+ userAgent: varchar("user_agent", {
7433
+ length: 500
7434
+ }),
7435
+ ipAddress: varchar("ip_address", {
7436
+ length: 45
7437
+ }),
7438
+ createdAt: timestamp("created_at").defaultNow().notNull()
7439
+ }, (table) => ({
7440
+ uniqueDeviceSession: unique("unique_device_session").on(table.userId, table.userAgent, table.ipAddress)
7441
+ }));
7442
+ const passwordResetTokens2 = rolesTableCreator("password_reset_tokens", {
7443
+ id: uuid("id").defaultRandom().primaryKey(),
7444
+ userId: uuid("user_id").notNull().references(() => users2.id, {
7445
+ onDelete: "cascade"
7446
+ }),
7447
+ tokenHash: varchar("token_hash", {
7448
+ length: 255
7449
+ }).notNull().unique(),
7450
+ expiresAt: timestamp("expires_at").notNull(),
7451
+ usedAt: timestamp("used_at"),
7452
+ createdAt: timestamp("created_at").defaultNow().notNull()
7453
+ });
7454
+ const appConfig2 = rolesTableCreator("app_config", {
7455
+ key: varchar("key", {
7456
+ length: 100
7457
+ }).primaryKey(),
7458
+ value: jsonb("value").notNull(),
7459
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
7460
+ });
7461
+ const userIdentities2 = rolesTableCreator("user_identities", {
7462
+ id: uuid("id").defaultRandom().primaryKey(),
7463
+ userId: uuid("user_id").notNull().references(() => users2.id, {
7464
+ onDelete: "cascade"
7465
+ }),
7466
+ provider: varchar("provider", {
7467
+ length: 50
7468
+ }).notNull(),
7469
+ // e.g. 'google', 'linkedin'
7470
+ providerId: varchar("provider_id", {
7471
+ length: 255
7472
+ }).notNull(),
7473
+ profileData: jsonb("profile_data"),
7474
+ createdAt: timestamp("created_at").defaultNow().notNull(),
7475
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
7476
+ }, (table) => ({
7477
+ uniqueProviderId: unique("unique_provider_id").on(table.provider, table.providerId)
7478
+ }));
7479
+ return {
7480
+ rolesSchema,
7481
+ usersSchema: usersSchema2,
7482
+ users: users2,
7483
+ roles: roles2,
7484
+ userRoles: userRoles2,
7485
+ refreshTokens: refreshTokens2,
7486
+ passwordResetTokens: passwordResetTokens2,
7487
+ appConfig: appConfig2,
7488
+ userIdentities: userIdentities2
7489
+ };
7490
+ }
7491
+ const defaultAuthSchema = createAuthSchema("rebase", "rebase");
7492
+ const rebaseSchema = defaultAuthSchema.rolesSchema;
7493
+ const usersSchema = defaultAuthSchema.usersSchema;
7494
+ const users = defaultAuthSchema.users;
7495
+ const roles = defaultAuthSchema.roles;
7496
+ const userRoles = defaultAuthSchema.userRoles;
7497
+ const refreshTokens = defaultAuthSchema.refreshTokens;
7498
+ const passwordResetTokens = defaultAuthSchema.passwordResetTokens;
7499
+ const appConfig = defaultAuthSchema.appConfig;
7500
+ const userIdentities = defaultAuthSchema.userIdentities;
8254
7501
  const usersRelations = relations(users, ({
8255
7502
  many
8256
7503
  }) => ({
@@ -8433,6 +7680,15 @@ const getDrizzleColumn = (propName, prop, collection, collections) => {
8433
7680
  }
8434
7681
  break;
8435
7682
  }
7683
+ case "vector": {
7684
+ const vp = prop;
7685
+ columnDefinition = `vector("${colName}", { dimensions: ${vp.dimensions} })`;
7686
+ break;
7687
+ }
7688
+ case "binary": {
7689
+ columnDefinition = `customType({ dataType() { return 'bytea'; } })("${colName}")`;
7690
+ break;
7691
+ }
8436
7692
  case "relation": {
8437
7693
  const refProp = prop;
8438
7694
  const resolvedRelations = resolveCollectionRelations(collection);
@@ -8499,7 +7755,7 @@ const getDrizzleColumn = (propName, prop, collection, collections) => {
8499
7755
  return ` ${propName}: ${columnDefinition}`;
8500
7756
  };
8501
7757
  const resolveRawSql = (expression) => {
8502
- const resolved = expression.replace(/\{(\w+)\}/g, (_, col) => `\${table.${col}}`);
7758
+ const resolved = expression.replace(/\{(\w+)\}/g, (_, col) => col);
8503
7759
  return `sql\`${resolved}\``;
8504
7760
  };
8505
7761
  const wrapWithRoleCheck = (clause, roles2) => {
@@ -8511,7 +7767,7 @@ const unwrapSql = (sqlExpr) => {
8511
7767
  const match = sqlExpr.match(/^sql`(.*)`$/s);
8512
7768
  return match ? match[1] : sqlExpr;
8513
7769
  };
8514
- const buildUsingClause = (rule) => {
7770
+ const buildUsingClause = (rule, collection) => {
8515
7771
  if (rule.using) {
8516
7772
  return resolveRawSql(rule.using);
8517
7773
  }
@@ -8519,15 +7775,17 @@ const buildUsingClause = (rule) => {
8519
7775
  return "sql`true`";
8520
7776
  }
8521
7777
  if (rule.ownerField) {
8522
- return `sql\`\${table.${rule.ownerField}} = auth.uid()\``;
7778
+ const prop = collection.properties?.[rule.ownerField];
7779
+ const colName = resolveColumnName(rule.ownerField, prop);
7780
+ return `sql\`${colName} = auth.uid()\``;
8523
7781
  }
8524
7782
  return null;
8525
7783
  };
8526
- const buildWithCheckClause = (rule) => {
7784
+ const buildWithCheckClause = (rule, collection) => {
8527
7785
  if (rule.withCheck) {
8528
7786
  return resolveRawSql(rule.withCheck);
8529
7787
  }
8530
- return buildUsingClause(rule);
7788
+ return buildUsingClause(rule, collection);
8531
7789
  };
8532
7790
  const getPolicyNameHash = (rule) => {
8533
7791
  const data = JSON.stringify({
@@ -8543,21 +7801,22 @@ const getPolicyNameHash = (rule) => {
8543
7801
  });
8544
7802
  return createHash("sha1").update(data).digest("hex").substring(0, 7);
8545
7803
  };
8546
- const generatePolicyCode = (tableName, rule, index) => {
7804
+ const generatePolicyCode = (collection, rule, index) => {
7805
+ const tableName = getTableName(collection);
8547
7806
  const ops = rule.operations && rule.operations.length > 0 ? rule.operations : [rule.operation ?? "all"];
8548
7807
  const ruleHash = getPolicyNameHash(rule);
8549
7808
  return ops.map((op, opIdx) => {
8550
7809
  const policyName = rule.name ? ops.length > 1 ? `${rule.name}_${op}` : rule.name : `${tableName}_${op}_${ruleHash}${ops.length > 1 ? `_${opIdx}` : ""}`;
8551
- return generateSinglePolicyCode(tableName, rule, op, policyName);
7810
+ return generateSinglePolicyCode(collection, rule, op, policyName);
8552
7811
  }).join("");
8553
7812
  };
8554
- const generateSinglePolicyCode = (tableName, rule, operation, policyName) => {
7813
+ const generateSinglePolicyCode = (collection, rule, operation, policyName) => {
8555
7814
  const mode = rule.mode ?? "permissive";
8556
7815
  const roles2 = rule.roles ? [...rule.roles].sort() : void 0;
8557
7816
  const needsUsing = operation !== "insert";
8558
7817
  const needsWithCheck = operation !== "select" && operation !== "delete";
8559
- let usingClause = needsUsing ? buildUsingClause(rule) : null;
8560
- let withCheckClause = needsWithCheck ? buildWithCheckClause(rule) : null;
7818
+ let usingClause = needsUsing ? buildUsingClause(rule, collection) : null;
7819
+ let withCheckClause = needsWithCheck ? buildWithCheckClause(rule, collection) : null;
8561
7820
  if (roles2 && roles2.length > 0) {
8562
7821
  if (usingClause) {
8563
7822
  usingClause = wrapWithRoleCheck(usingClause, roles2);
@@ -8626,12 +7885,26 @@ const computeSharedRelationName = (rel, sourceCollection, _collections) => {
8626
7885
  const generateSchema = async (collections, stripPolicies = false) => {
8627
7886
  let schemaContent = "// This file is auto-generated by the Rebase Drizzle generator. Do not edit manually.\n\n";
8628
7887
  const hasUuid = collections.some((c) => c.properties && Object.values(c.properties).some((p) => p.type === "string" && (p.autoValue === "uuid" || p.isId === "uuid")));
8629
- collections.some((c) => c.properties && Object.values(c.properties).some((p) => (p.type === "map" || p.type === "array") && p.columnType === "json"));
7888
+ const hasVector = collections.some((c) => c.properties && Object.values(c.properties).some((p) => p.type === "vector"));
7889
+ const hasBinary = collections.some((c) => c.properties && Object.values(c.properties).some((p) => p.type === "binary"));
8630
7890
  const pgCoreImports = ["primaryKey", "pgTable", "integer", "varchar", "text", "char", "boolean", "timestamp", "date", "time", "jsonb", "json", "pgEnum", "numeric", "real", "doublePrecision", "bigint", "serial", "bigserial", "pgPolicy"];
8631
7891
  if (hasUuid) pgCoreImports.push("uuid");
7892
+ if (hasVector) pgCoreImports.push("vector");
7893
+ if (hasBinary) pgCoreImports.push("customType");
7894
+ const uniqueSchemas = Array.from(new Set(collections.map((c) => isPostgresCollection(c) ? c.schema : void 0).filter(Boolean)));
7895
+ if (uniqueSchemas.length > 0) {
7896
+ pgCoreImports.push("pgSchema");
7897
+ }
8632
7898
  schemaContent += `import { ${pgCoreImports.join(", ")} } from 'drizzle-orm/pg-core';
8633
7899
  `;
8634
7900
  schemaContent += "import { relations as drizzleRelations, sql } from 'drizzle-orm';\n\n";
7901
+ uniqueSchemas.forEach((schema) => {
7902
+ schemaContent += `export const ${schema}Schema = pgSchema("${schema}");
7903
+ `;
7904
+ });
7905
+ if (uniqueSchemas.length > 0) {
7906
+ schemaContent += "\n";
7907
+ }
8635
7908
  const exportedTableVars = [];
8636
7909
  const exportedEnumVars = [];
8637
7910
  const exportedRelationVars = [];
@@ -8686,6 +7959,9 @@ const generateSchema = async (collections, stripPolicies = false) => {
8686
7959
  const tableVarName = getTableVarName(tableName);
8687
7960
  if (isJunction && relation && sourceCollection && relation.through) {
8688
7961
  const targetCollection = relation.target();
7962
+ const schema = (isPostgresCollection(targetCollection) ? targetCollection.schema : void 0) || (isPostgresCollection(sourceCollection) ? sourceCollection.schema : void 0);
7963
+ const tableCreator = schema ? `${schema}Schema.table` : "pgTable";
7964
+ const baseTableName = tableName.includes(".") ? tableName.split(".").pop() : tableName;
8689
7965
  const {
8690
7966
  sourceColumn,
8691
7967
  targetColumn
@@ -8696,7 +7972,7 @@ const generateSchema = async (collections, stripPolicies = false) => {
8696
7972
  const targetColType = isNumericId(targetCollection) ? "integer" : getPrimaryKeyProp(targetCollection).isUuid ? "uuid" : "varchar";
8697
7973
  const sourceId = getPrimaryKeyName(sourceCollection);
8698
7974
  const targetId = getPrimaryKeyName(targetCollection);
8699
- schemaContent += `export const ${tableVarName} = pgTable("${tableName}", {
7975
+ schemaContent += `export const ${tableVarName} = ${tableCreator}("${baseTableName}", {
8700
7976
  `;
8701
7977
  schemaContent += ` ${sourceColumn}: ${sourceColType}("${sourceColumn}").notNull().references(() => ${getTableVarName(getTableName(sourceCollection))}.${sourceId}, ${refOptions}),
8702
7978
  `;
@@ -8707,7 +7983,10 @@ const generateSchema = async (collections, stripPolicies = false) => {
8707
7983
  `;
8708
7984
  schemaContent += "}));\n\n";
8709
7985
  } else if (!isJunction) {
8710
- schemaContent += `export const ${tableVarName} = pgTable("${tableName}", {
7986
+ const schema = isPostgresCollection(collection) ? collection.schema : void 0;
7987
+ const tableCreator = schema ? `${schema}Schema.table` : "pgTable";
7988
+ const baseTableName = tableName.includes(".") ? tableName.split(".").pop() : tableName;
7989
+ schemaContent += `export const ${tableVarName} = ${tableCreator}("${baseTableName}", {
8711
7990
  `;
8712
7991
  const columns = /* @__PURE__ */ new Set();
8713
7992
  Object.entries(collection.properties ?? {}).forEach(([propName, prop]) => {
@@ -8723,7 +8002,7 @@ const generateSchema = async (collections, stripPolicies = false) => {
8723
8002
  if (!stripPolicies && securityRules && securityRules.length > 0) {
8724
8003
  schemaContent += "\n}, (table) => ([\n";
8725
8004
  securityRules.forEach((rule, idx) => {
8726
- schemaContent += generatePolicyCode(tableName, rule);
8005
+ schemaContent += generatePolicyCode(collection, rule);
8727
8006
  });
8728
8007
  schemaContent += "])).enableRLS();\n\n";
8729
8008
  } else {
@@ -8768,11 +8047,11 @@ const generateSchema = async (collections, stripPolicies = false) => {
8768
8047
  references: [${sourceTableVar}.${sourceId}],
8769
8048
  relationName: "${owningRelationName}"
8770
8049
  })`);
8771
- const targetRelName = inverseRelationName ?? owningRelationName;
8050
+ const targetRelationName = inverseRelationName ? inverseRelationName : `${tableName}_${relation.through.targetColumn}`;
8772
8051
  tableRelations.push(` "${relation.through.targetColumn}": one(${targetTableVar}, {
8773
8052
  fields: [${tableVarName}.${relation.through.targetColumn}],
8774
8053
  references: [${targetTableVar}.${targetId}],
8775
- relationName: "${targetRelName}"
8054
+ relationName: "${targetRelationName}"
8776
8055
  })`);
8777
8056
  }
8778
8057
  } else {
@@ -8871,6 +8150,89 @@ ${tableRelations.join(",\n")}
8871
8150
  schemaContent += tablesExport + enumsExport + relationsExport;
8872
8151
  return schemaContent;
8873
8152
  };
8153
+ const defaultUsersCollection = {
8154
+ name: "Users",
8155
+ singularName: "User",
8156
+ slug: "users",
8157
+ table: "users",
8158
+ icon: "Users",
8159
+ group: "Settings",
8160
+ properties: {
8161
+ id: {
8162
+ name: "ID",
8163
+ type: "string",
8164
+ isId: "uuid"
8165
+ },
8166
+ email: {
8167
+ name: "Email",
8168
+ type: "string",
8169
+ validation: {
8170
+ required: true,
8171
+ unique: true
8172
+ }
8173
+ },
8174
+ password_hash: {
8175
+ name: "Password Hash",
8176
+ type: "string",
8177
+ ui: {
8178
+ hideFromCollection: true
8179
+ }
8180
+ },
8181
+ display_name: {
8182
+ name: "Display Name",
8183
+ type: "string"
8184
+ },
8185
+ photo_url: {
8186
+ name: "Photo URL",
8187
+ type: "string"
8188
+ },
8189
+ email_verified: {
8190
+ name: "Email Verified",
8191
+ type: "boolean",
8192
+ defaultValue: false
8193
+ },
8194
+ email_verification_token: {
8195
+ name: "Email Verification Token",
8196
+ type: "string",
8197
+ ui: {
8198
+ hideFromCollection: true
8199
+ }
8200
+ },
8201
+ email_verification_sent_at: {
8202
+ name: "Email Verification Sent At",
8203
+ type: "date",
8204
+ ui: {
8205
+ hideFromCollection: true
8206
+ }
8207
+ },
8208
+ metadata: {
8209
+ name: "Metadata",
8210
+ type: "map",
8211
+ defaultValue: {},
8212
+ ui: {
8213
+ hideFromCollection: true
8214
+ }
8215
+ },
8216
+ created_at: {
8217
+ name: "Created At",
8218
+ type: "date",
8219
+ autoValue: "on_create",
8220
+ ui: {
8221
+ readOnly: true,
8222
+ hideFromCollection: true
8223
+ }
8224
+ },
8225
+ updated_at: {
8226
+ name: "Updated At",
8227
+ type: "date",
8228
+ autoValue: "on_update",
8229
+ ui: {
8230
+ readOnly: true,
8231
+ hideFromCollection: true
8232
+ }
8233
+ }
8234
+ }
8235
+ };
8874
8236
  const formatTerminalText = (text, options = {}) => {
8875
8237
  let codes = "";
8876
8238
  if (options.bold) codes += "\x1B[1m";
@@ -8933,10 +8295,14 @@ const runGeneration = async (collectionsFilePath, outputPath) => {
8933
8295
  const imported = await dynamicImport(fileUrl);
8934
8296
  collections = imported.backendCollections || imported.collections;
8935
8297
  }
8936
- if (!collections || !Array.isArray(collections) || collections.length === 0) {
8937
- console.error("Error: Could not find collections array or failed to load directory.");
8938
- return;
8298
+ if (!collections || !Array.isArray(collections)) {
8299
+ collections = [];
8939
8300
  }
8301
+ const hasUsersCollection = collections.some((c) => c.slug === "users");
8302
+ if (!hasUsersCollection) {
8303
+ collections.push(defaultUsersCollection);
8304
+ }
8305
+ collections.sort((a, b) => a.slug.localeCompare(b.slug));
8940
8306
  const schemaContent = await generateSchema(collections);
8941
8307
  if (outputPath) {
8942
8308
  const outputDir = path.dirname(outputPath);
@@ -9164,29 +8530,14 @@ class RealtimeService extends EventEmitter {
9164
8530
  },
9165
8531
  authContext
9166
8532
  });
9167
- let entities;
9168
- if (this.driver) {
9169
- entities = await this.driver.fetchCollection({
9170
- path: request.path,
9171
- collection,
9172
- filter: request.filter,
9173
- orderBy: request.orderBy,
9174
- order: request.order,
9175
- limit: request.limit,
9176
- startAfter: request.startAfter,
9177
- searchString: request.searchString
9178
- });
9179
- } else {
9180
- entities = await this.entityService.fetchCollection(request.path, {
9181
- filter: request.filter,
9182
- orderBy: request.orderBy,
9183
- order: request.order,
9184
- limit: request.limit,
9185
- startAfter: request.startAfter,
9186
- databaseId: request.collection?.databaseId,
9187
- searchString: request.searchString
9188
- });
9189
- }
8533
+ const entities = await this.fetchCollectionWithAuth(request.path, {
8534
+ filter: request.filter,
8535
+ orderBy: request.orderBy,
8536
+ order: request.order,
8537
+ limit: request.limit,
8538
+ startAfter: request.startAfter,
8539
+ searchString: request.searchString
8540
+ }, authContext);
9190
8541
  this.sendCollectionUpdate(clientId, subscriptionId, entities);
9191
8542
  } catch (error) {
9192
8543
  this.sendError(clientId, `Failed to subscribe to collection: ${error}`, subscriptionId);
@@ -9210,16 +8561,7 @@ class RealtimeService extends EventEmitter {
9210
8561
  entityId: request.entityId,
9211
8562
  authContext
9212
8563
  });
9213
- let entity;
9214
- if (this.driver) {
9215
- entity = await this.driver.fetchEntity({
9216
- path: request.path,
9217
- entityId: request.entityId,
9218
- collection
9219
- });
9220
- } else {
9221
- entity = await this.entityService.fetchEntity(request.path, request.entityId, request.collection?.databaseId);
9222
- }
8564
+ const entity = await this.fetchEntityWithAuth(request.path, String(request.entityId), authContext);
9223
8565
  this.sendEntityUpdate(clientId, subscriptionId, entity || null);
9224
8566
  } catch (error) {
9225
8567
  this.sendError(clientId, `Failed to subscribe to entity: ${request.path} ${request.entityId} ${error}`, subscriptionId);
@@ -9364,87 +8706,77 @@ class RealtimeService extends EventEmitter {
9364
8706
  async fetchCollectionWithAuth(notifyPath, collectionRequest, authContext) {
9365
8707
  if (this.driver) {
9366
8708
  const collection = this.registry.getCollectionByPath(notifyPath);
9367
- const fetchFn = async () => this.driver.fetchCollection({
9368
- path: notifyPath,
9369
- collection,
9370
- filter: collectionRequest.filter,
9371
- orderBy: collectionRequest.orderBy,
9372
- order: collectionRequest.order,
9373
- limit: collectionRequest.limit,
9374
- offset: collectionRequest.offset,
9375
- startAfter: collectionRequest.startAfter,
9376
- searchString: collectionRequest.searchString
8709
+ const activeAuth = authContext || {
8710
+ userId: "anon",
8711
+ roles: ["anon"]
8712
+ };
8713
+ return await this.db.transaction(async (tx) => {
8714
+ await tx.execute(sql`SELECT set_config('app.user_id', ${activeAuth.userId}, true)`);
8715
+ await tx.execute(sql`SELECT set_config('app.user_roles', ${activeAuth.roles.join(",")}, true)`);
8716
+ await tx.execute(sql`SELECT set_config('app.jwt', ${JSON.stringify({
8717
+ sub: activeAuth.userId,
8718
+ roles: activeAuth.roles
8719
+ })}, true)`);
8720
+ const txEntityService = new EntityService(tx, this.registry);
8721
+ let fetchedEntities;
8722
+ if (collectionRequest.searchString) {
8723
+ fetchedEntities = await txEntityService.searchEntities(notifyPath, collectionRequest.searchString, {
8724
+ filter: collectionRequest.filter,
8725
+ orderBy: collectionRequest.orderBy,
8726
+ order: collectionRequest.order,
8727
+ limit: collectionRequest.limit,
8728
+ databaseId: collectionRequest.databaseId
8729
+ });
8730
+ } else {
8731
+ fetchedEntities = await txEntityService.fetchCollection(notifyPath, {
8732
+ filter: collectionRequest.filter,
8733
+ orderBy: collectionRequest.orderBy,
8734
+ order: collectionRequest.order,
8735
+ limit: collectionRequest.limit,
8736
+ offset: collectionRequest.offset,
8737
+ startAfter: collectionRequest.startAfter,
8738
+ databaseId: collectionRequest.databaseId
8739
+ });
8740
+ }
8741
+ const registryCollection = this.registry.getCollectionByPath(notifyPath);
8742
+ const resolvedCollection = collection ? {
8743
+ ...collection,
8744
+ ...registryCollection
8745
+ } : registryCollection;
8746
+ const callbacks = resolvedCollection?.callbacks;
8747
+ const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
8748
+ if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
8749
+ const contextForCallback = {
8750
+ user: {
8751
+ uid: activeAuth.userId,
8752
+ roles: activeAuth.roles
8753
+ },
8754
+ driver: this.driver,
8755
+ data: this.driver && "data" in this.driver ? this.driver.data : void 0
8756
+ };
8757
+ return await Promise.all(fetchedEntities.map(async (entity) => {
8758
+ let processedEntity = entity;
8759
+ if (callbacks?.afterRead) {
8760
+ processedEntity = await callbacks.afterRead({
8761
+ collection: resolvedCollection,
8762
+ path: notifyPath,
8763
+ entity: processedEntity,
8764
+ context: contextForCallback
8765
+ }) ?? processedEntity;
8766
+ }
8767
+ if (propertyCallbacks?.afterRead) {
8768
+ processedEntity = await propertyCallbacks.afterRead({
8769
+ collection: resolvedCollection,
8770
+ path: notifyPath,
8771
+ entity: processedEntity,
8772
+ context: contextForCallback
8773
+ }) ?? processedEntity;
8774
+ }
8775
+ return processedEntity;
8776
+ }));
8777
+ }
8778
+ return fetchedEntities;
9377
8779
  });
9378
- if (authContext) {
9379
- return await this.db.transaction(async (tx) => {
9380
- await tx.execute(sql`SELECT set_config('app.user_id', ${authContext.userId}, true)`);
9381
- await tx.execute(sql`SELECT set_config('app.user_roles', ${authContext.roles.join(",")}, true)`);
9382
- await tx.execute(sql`SELECT set_config('app.jwt', ${JSON.stringify({
9383
- sub: authContext.userId,
9384
- roles: authContext.roles
9385
- })}, true)`);
9386
- const txEntityService = new EntityService(tx, this.registry);
9387
- let fetchedEntities;
9388
- if (collectionRequest.searchString) {
9389
- fetchedEntities = await txEntityService.searchEntities(notifyPath, collectionRequest.searchString, {
9390
- filter: collectionRequest.filter,
9391
- orderBy: collectionRequest.orderBy,
9392
- order: collectionRequest.order,
9393
- limit: collectionRequest.limit,
9394
- databaseId: collectionRequest.databaseId
9395
- });
9396
- } else {
9397
- fetchedEntities = await txEntityService.fetchCollection(notifyPath, {
9398
- filter: collectionRequest.filter,
9399
- orderBy: collectionRequest.orderBy,
9400
- order: collectionRequest.order,
9401
- limit: collectionRequest.limit,
9402
- offset: collectionRequest.offset,
9403
- startAfter: collectionRequest.startAfter,
9404
- databaseId: collectionRequest.databaseId
9405
- });
9406
- }
9407
- const registryCollection = this.registry.getCollectionByPath(notifyPath);
9408
- const resolvedCollection = collection ? {
9409
- ...collection,
9410
- ...registryCollection
9411
- } : registryCollection;
9412
- const callbacks = resolvedCollection?.callbacks;
9413
- const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
9414
- if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
9415
- const contextForCallback = {
9416
- user: {
9417
- uid: authContext.userId,
9418
- roles: authContext.roles
9419
- },
9420
- driver: this.driver,
9421
- data: this.driver ? this.driver.data : void 0
9422
- };
9423
- return await Promise.all(fetchedEntities.map(async (entity) => {
9424
- let processedEntity = entity;
9425
- if (callbacks?.afterRead) {
9426
- processedEntity = await callbacks.afterRead({
9427
- collection: resolvedCollection,
9428
- path: notifyPath,
9429
- entity: processedEntity,
9430
- context: contextForCallback
9431
- }) ?? processedEntity;
9432
- }
9433
- if (propertyCallbacks?.afterRead) {
9434
- processedEntity = await propertyCallbacks.afterRead({
9435
- collection: resolvedCollection,
9436
- path: notifyPath,
9437
- entity: processedEntity,
9438
- context: contextForCallback
9439
- }) ?? processedEntity;
9440
- }
9441
- return processedEntity;
9442
- }));
9443
- }
9444
- return fetchedEntities;
9445
- });
9446
- }
9447
- return fetchFn();
9448
8780
  }
9449
8781
  if (collectionRequest.searchString) {
9450
8782
  return await this.entityService.searchEntities(notifyPath, collectionRequest.searchString, {
@@ -9508,60 +8840,56 @@ class RealtimeService extends EventEmitter {
9508
8840
  async fetchEntityWithAuth(notifyPath, entityId, authContext) {
9509
8841
  if (this.driver) {
9510
8842
  const collection = this.registry.getCollectionByPath(notifyPath);
9511
- const fetchFn = async () => this.driver.fetchEntity({
9512
- path: notifyPath,
9513
- entityId,
9514
- collection
9515
- });
9516
- if (authContext) {
9517
- return await this.db.transaction(async (tx) => {
9518
- await tx.execute(sql`SELECT set_config('app.user_id', ${authContext.userId}, true)`);
9519
- await tx.execute(sql`SELECT set_config('app.user_roles', ${authContext.roles.join(",")}, true)`);
9520
- await tx.execute(sql`SELECT set_config('app.jwt', ${JSON.stringify({
9521
- sub: authContext.userId,
9522
- roles: authContext.roles
9523
- })}, true)`);
9524
- const txEntityService = new EntityService(tx, this.registry);
9525
- let processedEntity = await txEntityService.fetchEntity(notifyPath, entityId, collection?.databaseId);
9526
- if (processedEntity) {
9527
- const registryCollection = this.registry.getCollectionByPath(notifyPath);
9528
- const resolvedCollection = collection ? {
9529
- ...collection,
9530
- ...registryCollection
9531
- } : registryCollection;
9532
- const callbacks = resolvedCollection?.callbacks;
9533
- const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
9534
- if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
9535
- const contextForCallback = {
9536
- user: {
9537
- uid: authContext.userId,
9538
- roles: authContext.roles
9539
- },
9540
- driver: this.driver,
9541
- data: this.driver ? this.driver.data : void 0
9542
- };
9543
- if (callbacks?.afterRead) {
9544
- processedEntity = await callbacks.afterRead({
9545
- collection: resolvedCollection,
9546
- path: notifyPath,
9547
- entity: processedEntity,
9548
- context: contextForCallback
9549
- }) ?? processedEntity;
9550
- }
9551
- if (propertyCallbacks?.afterRead) {
9552
- processedEntity = await propertyCallbacks.afterRead({
9553
- collection: resolvedCollection,
9554
- path: notifyPath,
9555
- entity: processedEntity,
9556
- context: contextForCallback
9557
- }) ?? processedEntity;
9558
- }
8843
+ const activeAuth = authContext || {
8844
+ userId: "anon",
8845
+ roles: ["anon"]
8846
+ };
8847
+ return await this.db.transaction(async (tx) => {
8848
+ await tx.execute(sql`SELECT set_config('app.user_id', ${activeAuth.userId}, true)`);
8849
+ await tx.execute(sql`SELECT set_config('app.user_roles', ${activeAuth.roles.join(",")}, true)`);
8850
+ await tx.execute(sql`SELECT set_config('app.jwt', ${JSON.stringify({
8851
+ sub: activeAuth.userId,
8852
+ roles: activeAuth.roles
8853
+ })}, true)`);
8854
+ const txEntityService = new EntityService(tx, this.registry);
8855
+ let processedEntity = await txEntityService.fetchEntity(notifyPath, entityId, collection?.databaseId);
8856
+ if (processedEntity) {
8857
+ const registryCollection = this.registry.getCollectionByPath(notifyPath);
8858
+ const resolvedCollection = collection ? {
8859
+ ...collection,
8860
+ ...registryCollection
8861
+ } : registryCollection;
8862
+ const callbacks = resolvedCollection?.callbacks;
8863
+ const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
8864
+ if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
8865
+ const contextForCallback = {
8866
+ user: {
8867
+ uid: activeAuth.userId,
8868
+ roles: activeAuth.roles
8869
+ },
8870
+ driver: this.driver,
8871
+ data: this.driver && "data" in this.driver ? this.driver.data : void 0
8872
+ };
8873
+ if (callbacks?.afterRead) {
8874
+ processedEntity = await callbacks.afterRead({
8875
+ collection: resolvedCollection,
8876
+ path: notifyPath,
8877
+ entity: processedEntity,
8878
+ context: contextForCallback
8879
+ }) ?? processedEntity;
8880
+ }
8881
+ if (propertyCallbacks?.afterRead) {
8882
+ processedEntity = await propertyCallbacks.afterRead({
8883
+ collection: resolvedCollection,
8884
+ path: notifyPath,
8885
+ entity: processedEntity,
8886
+ context: contextForCallback
8887
+ }) ?? processedEntity;
9559
8888
  }
9560
8889
  }
9561
- return processedEntity;
9562
- });
9563
- }
9564
- return fetchFn();
8890
+ }
8891
+ return processedEntity;
8892
+ });
9565
8893
  }
9566
8894
  return await this.entityService.fetchEntity(notifyPath, entityId);
9567
8895
  }
@@ -9629,6 +8957,31 @@ class RealtimeService extends EventEmitter {
9629
8957
  return parentPaths;
9630
8958
  }
9631
8959
  // =============================================================================
8960
+ // Lifecycle / Cleanup
8961
+ // =============================================================================
8962
+ /**
8963
+ * Gracefully tear down all realtime resources.
8964
+ *
8965
+ * This MUST be called during process shutdown, **before** `pool.end()`.
8966
+ * It ensures:
8967
+ * 1. All debounced refetch timers are cancelled (prevents queries after pool closes).
8968
+ * 2. All subscription state and callbacks are cleared.
8969
+ * 3. The dedicated LISTEN client (outside the pool) is disconnected.
8970
+ * 4. All WebSocket clients are removed (but not forcefully closed — the
8971
+ * HTTP server close will handle that).
8972
+ */
8973
+ async destroy() {
8974
+ for (const [key, timer] of this.refetchTimers) {
8975
+ clearTimeout(timer);
8976
+ this.refetchTimers.delete(key);
8977
+ }
8978
+ this._subscriptions.clear();
8979
+ this.subscriptionCallbacks.clear();
8980
+ await this.stopListening();
8981
+ this.clients.clear();
8982
+ this.debugLog("🧹 [RealtimeService] destroy() complete — all resources released.");
8983
+ }
8984
+ // =============================================================================
9632
8985
  // Cross-Instance LISTEN/NOTIFY
9633
8986
  // =============================================================================
9634
8987
  /**
@@ -9769,8 +9122,23 @@ const clientSessions = /* @__PURE__ */ new Map();
9769
9122
  const WS_RATE_LIMIT = 2e3;
9770
9123
  const WS_RATE_WINDOW_MS = 6e4;
9771
9124
  const ADMIN_ONLY_TYPES = /* @__PURE__ */ new Set(["EXECUTE_SQL", "FETCH_DATABASES", "FETCH_ROLES", "FETCH_UNMAPPED_TABLES", "FETCH_TABLE_METADATA", "FETCH_CURRENT_DATABASE", "CREATE_BRANCH", "DELETE_BRANCH", "LIST_BRANCHES"]);
9125
+ function extractErrorMessage(error) {
9126
+ if (!error) return "Unknown error";
9127
+ if (typeof error === "object") {
9128
+ const err = error;
9129
+ if (err.cause) {
9130
+ return extractErrorMessage(err.cause);
9131
+ }
9132
+ if (typeof err.message === "string") {
9133
+ return err.message;
9134
+ }
9135
+ }
9136
+ return String(error);
9137
+ }
9772
9138
  function isAdminSession(session) {
9773
- if (!session?.user?.roles) return false;
9139
+ if (!session?.user) return false;
9140
+ if (session.user.isAdmin) return true;
9141
+ if (!session.user.roles) return false;
9774
9142
  return session.user.roles.some((r) => {
9775
9143
  if (typeof r === "string") return r === "admin";
9776
9144
  if (r && typeof r === "object" && "isAdmin" in r) return r.isAdmin;
@@ -9778,7 +9146,7 @@ function isAdminSession(session) {
9778
9146
  return false;
9779
9147
  });
9780
9148
  }
9781
- function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
9149
+ function createPostgresWebSocket(server, realtimeService, driver, authConfig, authAdapter) {
9782
9150
  const isProduction = process.env.NODE_ENV === "production";
9783
9151
  const wsDebug = (...args) => {
9784
9152
  if (!isProduction) console.debug(...args);
@@ -9792,7 +9160,7 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
9792
9160
  }
9793
9161
  console.error("❌ [WebSocket Server] Error:", err);
9794
9162
  });
9795
- const requireAuth = authConfig?.requireAuth !== false && authConfig?.jwtSecret;
9163
+ const requireAuth = authAdapter ? true : authConfig?.requireAuth !== false && !!authConfig?.jwtSecret;
9796
9164
  wss.on("connection", (ws) => {
9797
9165
  const clientId = `client_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
9798
9166
  wsDebug(`WebSocket client connected: ${clientId}`);
@@ -9837,11 +9205,37 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
9837
9205
  sendError("AUTH_ERROR", "INVALID_INPUT", "Token is required");
9838
9206
  return;
9839
9207
  }
9840
- const user = extractUserFromToken(token);
9841
- if (user) {
9208
+ let verifiedUser = null;
9209
+ if (authAdapter) {
9210
+ try {
9211
+ const adapterUser = authAdapter.verifyToken ? await authAdapter.verifyToken(token) : await authAdapter.verifyRequest(new Request("http://localhost/_ws_auth", {
9212
+ headers: {
9213
+ Authorization: `Bearer ${token}`
9214
+ }
9215
+ }));
9216
+ if (adapterUser) {
9217
+ verifiedUser = {
9218
+ userId: adapterUser.uid,
9219
+ roles: adapterUser.roles,
9220
+ isAdmin: adapterUser.isAdmin
9221
+ };
9222
+ }
9223
+ } catch {
9224
+ }
9225
+ } else {
9226
+ const jwtPayload = extractUserFromToken(token);
9227
+ if (jwtPayload) {
9228
+ verifiedUser = {
9229
+ userId: jwtPayload.userId,
9230
+ roles: jwtPayload.roles ?? [],
9231
+ isAdmin: (jwtPayload.roles ?? []).some((r) => r === "admin")
9232
+ };
9233
+ }
9234
+ }
9235
+ if (verifiedUser) {
9842
9236
  const session = clientSessions.get(clientId);
9843
9237
  if (session) {
9844
- session.user = user;
9238
+ session.user = verifiedUser;
9845
9239
  session.authenticated = true;
9846
9240
  }
9847
9241
  wsDebug(`[WS] replying AUTH_SUCCESS for requestId ${requestId}`);
@@ -9849,11 +9243,11 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
9849
9243
  type: "AUTH_SUCCESS",
9850
9244
  requestId,
9851
9245
  payload: {
9852
- userId: user.userId,
9853
- roles: user.roles
9246
+ userId: verifiedUser.userId,
9247
+ roles: verifiedUser.roles
9854
9248
  }
9855
9249
  }));
9856
- wsDebug(`🔐 [WebSocket Server] Client ${clientId} authenticated as ${user.userId}`);
9250
+ wsDebug(`🔐 [WebSocket Server] Client ${clientId} authenticated as ${verifiedUser.userId}`);
9857
9251
  } else {
9858
9252
  wsDebug(`[WS] replying AUTH_ERROR for requestId ${requestId} (invalid token)`);
9859
9253
  sendError("AUTH_ERROR", "INVALID_TOKEN", "Invalid or expired token");
@@ -9891,16 +9285,19 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
9891
9285
  }
9892
9286
  const getScopedDelegate = async () => {
9893
9287
  const session = clientSessions.get(clientId);
9894
- if (session?.user && "withAuth" in driver && typeof driver.withAuth === "function") {
9288
+ if ("withAuth" in driver && typeof driver.withAuth === "function") {
9895
9289
  try {
9896
- const userForAuth = {
9290
+ const userForAuth = session?.user ? {
9897
9291
  uid: session.user.userId,
9898
9292
  roles: session.user.roles ?? []
9293
+ } : {
9294
+ uid: "anon",
9295
+ roles: ["anon"]
9899
9296
  };
9900
9297
  return await driver.withAuth(userForAuth);
9901
9298
  } catch (e) {
9902
- console.error("Failed to create authenticated delegate for WS request", e);
9903
- return driver;
9299
+ console.error("Failed to create RLS scoped delegate for WS request", e);
9300
+ throw new Error("Internal authentication error");
9904
9301
  }
9905
9302
  }
9906
9303
  return driver;
@@ -10031,24 +9428,29 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
10031
9428
  sql: sql2,
10032
9429
  options
10033
9430
  } = payload;
10034
- const delegate = await getScopedDelegate();
10035
- const admin = delegate.admin;
10036
- if (!isSQLAdmin(admin)) {
10037
- sendError("ERROR", "NOT_SUPPORTED", "SQL execution is not available for this driver.");
10038
- break;
10039
- }
10040
- const result = await admin.executeSql(sql2, options);
10041
- if (process.env.NODE_ENV !== "production") {
10042
- wsDebug(`⚡ [WebSocket Server] SQL executed. Returned ${Array.isArray(result) ? result.length : "non-array"} rows.`);
9431
+ try {
9432
+ const delegate = await getScopedDelegate();
9433
+ const admin = delegate.admin;
9434
+ if (!isSQLAdmin(admin)) {
9435
+ sendError("ERROR", "NOT_SUPPORTED", "SQL execution is not available for this driver.");
9436
+ break;
9437
+ }
9438
+ const result = await admin.executeSql(sql2, options);
9439
+ if (process.env.NODE_ENV !== "production") {
9440
+ wsDebug(`⚡ [WebSocket Server] SQL executed. Returned ${Array.isArray(result) ? result.length : "non-array"} rows.`);
9441
+ }
9442
+ const response = {
9443
+ type: "EXECUTE_SQL_SUCCESS",
9444
+ payload: {
9445
+ result
9446
+ },
9447
+ requestId
9448
+ };
9449
+ ws.send(JSON.stringify(response));
9450
+ } catch (sqlError) {
9451
+ const errMsg = extractErrorMessage(sqlError);
9452
+ sendError("ERROR", "SQL_ERROR", errMsg);
10043
9453
  }
10044
- const response = {
10045
- type: "EXECUTE_SQL_SUCCESS",
10046
- payload: {
10047
- result
10048
- },
10049
- requestId
10050
- };
10051
- ws.send(JSON.stringify(response));
10052
9454
  }
10053
9455
  break;
10054
9456
  case "FETCH_DATABASES":
@@ -10227,7 +9629,10 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
10227
9629
  const authContext = session?.user ? {
10228
9630
  userId: session.user.userId,
10229
9631
  roles: session.user.roles ?? []
10230
- } : void 0;
9632
+ } : {
9633
+ userId: "anon",
9634
+ roles: ["anon"]
9635
+ };
10231
9636
  await realtimeService.handleClientMessage(clientId, {
10232
9637
  type,
10233
9638
  payload,
@@ -10371,29 +9776,58 @@ const DEFAULT_ROLES = [{
10371
9776
  },
10372
9777
  config: null
10373
9778
  }];
10374
- async function ensureAuthTablesExist(db) {
9779
+ async function ensureAuthTablesExist(db, registry) {
10375
9780
  console.log("🔍 Checking auth tables...");
10376
9781
  try {
9782
+ let usersTableName = '"users"';
9783
+ let userIdType = "TEXT";
9784
+ let usersSchema2 = "public";
9785
+ if (registry) {
9786
+ const usersTable = registry.getTable("users");
9787
+ if (usersTable) {
9788
+ const {
9789
+ getTableName: getTableName2
9790
+ } = await import("drizzle-orm");
9791
+ usersSchema2 = getTableConfig(usersTable).schema || "public";
9792
+ usersTableName = usersSchema2 === "public" ? `"${getTableName2(usersTable)}"` : `"${usersSchema2}"."${getTableName2(usersTable)}"`;
9793
+ if (usersTable.id) {
9794
+ const col = usersTable.id;
9795
+ const meta = getColumnMeta(col);
9796
+ const columnType = meta.columnType;
9797
+ if (columnType === "PgUUID") {
9798
+ userIdType = "UUID";
9799
+ } else if (columnType === "PgSerial" || columnType === "PgInteger") {
9800
+ userIdType = "INTEGER";
9801
+ } else if (columnType === "PgBigInt" || columnType === "PgBigSerial") {
9802
+ userIdType = "BIGINT";
9803
+ }
9804
+ }
9805
+ }
9806
+ }
9807
+ let rolesSchema = "rebase";
9808
+ if (registry) {
9809
+ const rolesTable = registry.getTable("roles");
9810
+ if (rolesTable) {
9811
+ rolesSchema = getTableConfig(rolesTable).schema || "public";
9812
+ }
9813
+ }
9814
+ if (usersSchema2 !== "public") {
9815
+ await db.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.raw(usersSchema2)}`);
9816
+ }
9817
+ if (rolesSchema !== "public" && rolesSchema !== usersSchema2) {
9818
+ await db.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.raw(rolesSchema)}`);
9819
+ }
10377
9820
  await db.execute(sql`CREATE SCHEMA IF NOT EXISTS rebase`);
9821
+ const userIdentitiesTable = `"${rolesSchema}"."user_identities"`;
9822
+ const rolesTableName = `"${rolesSchema}"."roles"`;
9823
+ const userRolesTableName = `"${rolesSchema}"."user_roles"`;
9824
+ const refreshTokensTableName = `"${rolesSchema}"."refresh_tokens"`;
9825
+ const passwordResetTokensTableName = `"${rolesSchema}"."password_reset_tokens"`;
9826
+ const appConfigTableName = `"${rolesSchema}"."app_config"`;
10378
9827
  await db.execute(sql`
10379
- CREATE TABLE IF NOT EXISTS rebase.users (
9828
+ CREATE TABLE IF NOT EXISTS ${sql.raw(userIdentitiesTable)} (
10380
9829
  id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
10381
- email TEXT NOT NULL UNIQUE,
10382
- password_hash TEXT,
10383
- display_name TEXT,
10384
- photo_url TEXT,
10385
- created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
10386
- updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
10387
- )
10388
- `);
10389
- await db.execute(sql`
10390
- CREATE INDEX IF NOT EXISTS idx_users_email
10391
- ON rebase.users(email)
10392
- `);
10393
- await db.execute(sql`
10394
- CREATE TABLE IF NOT EXISTS rebase.user_identities (
10395
- id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
10396
- user_id TEXT NOT NULL REFERENCES rebase.users(id) ON DELETE CASCADE,
9830
+ user_id ${sql.raw(userIdType)} NOT NULL REFERENCES ${sql.raw(usersTableName)}(id) ON DELETE CASCADE,
10397
9831
  provider TEXT NOT NULL,
10398
9832
  provider_id TEXT NOT NULL,
10399
9833
  profile_data JSONB,
@@ -10404,10 +9838,10 @@ async function ensureAuthTablesExist(db) {
10404
9838
  `);
10405
9839
  await db.execute(sql`
10406
9840
  CREATE INDEX IF NOT EXISTS idx_user_identities_user
10407
- ON rebase.user_identities(user_id)
9841
+ ON ${sql.raw(userIdentitiesTable)}(user_id)
10408
9842
  `);
10409
9843
  await db.execute(sql`
10410
- CREATE TABLE IF NOT EXISTS rebase.roles (
9844
+ CREATE TABLE IF NOT EXISTS ${sql.raw(rolesTableName)} (
10411
9845
  id TEXT PRIMARY KEY,
10412
9846
  name TEXT NOT NULL,
10413
9847
  is_admin BOOLEAN DEFAULT FALSE,
@@ -10418,20 +9852,20 @@ async function ensureAuthTablesExist(db) {
10418
9852
  )
10419
9853
  `);
10420
9854
  await db.execute(sql`
10421
- CREATE TABLE IF NOT EXISTS rebase.user_roles (
10422
- user_id TEXT NOT NULL REFERENCES rebase.users(id) ON DELETE CASCADE,
10423
- role_id TEXT NOT NULL REFERENCES rebase.roles(id) ON DELETE CASCADE,
9855
+ CREATE TABLE IF NOT EXISTS ${sql.raw(userRolesTableName)} (
9856
+ user_id ${sql.raw(userIdType)} NOT NULL REFERENCES ${sql.raw(usersTableName)}(id) ON DELETE CASCADE,
9857
+ role_id TEXT NOT NULL REFERENCES ${sql.raw(rolesTableName)}(id) ON DELETE CASCADE,
10424
9858
  PRIMARY KEY (user_id, role_id)
10425
9859
  )
10426
9860
  `);
10427
9861
  await db.execute(sql`
10428
9862
  CREATE INDEX IF NOT EXISTS idx_user_roles_user
10429
- ON rebase.user_roles(user_id)
9863
+ ON ${sql.raw(userRolesTableName)}(user_id)
10430
9864
  `);
10431
9865
  await db.execute(sql`
10432
- CREATE TABLE IF NOT EXISTS rebase.refresh_tokens (
9866
+ CREATE TABLE IF NOT EXISTS ${sql.raw(refreshTokensTableName)} (
10433
9867
  id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
10434
- user_id TEXT NOT NULL REFERENCES rebase.users(id) ON DELETE CASCADE,
9868
+ user_id ${sql.raw(userIdType)} NOT NULL REFERENCES ${sql.raw(usersTableName)}(id) ON DELETE CASCADE,
10435
9869
  token_hash TEXT NOT NULL UNIQUE,
10436
9870
  expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
10437
9871
  user_agent TEXT,
@@ -10442,16 +9876,16 @@ async function ensureAuthTablesExist(db) {
10442
9876
  `);
10443
9877
  await db.execute(sql`
10444
9878
  CREATE INDEX IF NOT EXISTS idx_refresh_tokens_hash
10445
- ON rebase.refresh_tokens(token_hash)
9879
+ ON ${sql.raw(refreshTokensTableName)}(token_hash)
10446
9880
  `);
10447
9881
  await db.execute(sql`
10448
9882
  CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user
10449
- ON rebase.refresh_tokens(user_id)
9883
+ ON ${sql.raw(refreshTokensTableName)}(user_id)
10450
9884
  `);
10451
9885
  await db.execute(sql`
10452
- CREATE TABLE IF NOT EXISTS rebase.password_reset_tokens (
9886
+ CREATE TABLE IF NOT EXISTS ${sql.raw(passwordResetTokensTableName)} (
10453
9887
  id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
10454
- user_id TEXT NOT NULL REFERENCES rebase.users(id) ON DELETE CASCADE,
9888
+ user_id ${sql.raw(userIdType)} NOT NULL REFERENCES ${sql.raw(usersTableName)}(id) ON DELETE CASCADE,
10455
9889
  token_hash TEXT NOT NULL UNIQUE,
10456
9890
  expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
10457
9891
  used_at TIMESTAMP WITH TIME ZONE,
@@ -10460,20 +9894,19 @@ async function ensureAuthTablesExist(db) {
10460
9894
  `);
10461
9895
  await db.execute(sql`
10462
9896
  CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_hash
10463
- ON rebase.password_reset_tokens(token_hash)
9897
+ ON ${sql.raw(passwordResetTokensTableName)}(token_hash)
10464
9898
  `);
10465
9899
  await db.execute(sql`
10466
9900
  CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_user
10467
- ON rebase.password_reset_tokens(user_id)
9901
+ ON ${sql.raw(passwordResetTokensTableName)}(user_id)
10468
9902
  `);
10469
9903
  await db.execute(sql`
10470
- CREATE TABLE IF NOT EXISTS rebase.app_config (
9904
+ CREATE TABLE IF NOT EXISTS ${sql.raw(appConfigTableName)} (
10471
9905
  key TEXT PRIMARY KEY,
10472
9906
  value JSONB NOT NULL,
10473
9907
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
10474
9908
  )
10475
9909
  `);
10476
- await applyInternalMigrations(db);
10477
9910
  await db.execute(sql`CREATE SCHEMA IF NOT EXISTS auth`);
10478
9911
  await db.transaction(async (tx) => {
10479
9912
  await tx.execute(sql`SELECT pg_advisory_xact_lock(hashtext('rebase_auth_functions_init'))`);
@@ -10496,15 +9929,15 @@ async function ensureAuthTablesExist(db) {
10496
9929
  $$ LANGUAGE sql STABLE
10497
9930
  `);
10498
9931
  });
10499
- await seedDefaultRoles(db);
9932
+ await seedDefaultRoles(db, rolesTableName);
10500
9933
  console.log("✅ Auth tables ready");
10501
9934
  } catch (error) {
10502
9935
  console.error("❌ Failed to create auth tables:", error);
10503
9936
  console.warn("⚠️ Continuing without creating auth tables.");
10504
9937
  }
10505
9938
  }
10506
- async function seedDefaultRoles(db) {
10507
- const result = await db.execute(sql`SELECT COUNT(*) as count FROM rebase.roles`);
9939
+ async function seedDefaultRoles(db, rolesTableName) {
9940
+ const result = await db.execute(sql`SELECT COUNT(*) as count FROM ${sql.raw(rolesTableName)}`);
10508
9941
  const count2 = parseInt(result.rows[0]?.count || "0", 10);
10509
9942
  if (count2 > 0) {
10510
9943
  console.log(`📋 Found ${count2} existing roles`);
@@ -10513,7 +9946,7 @@ async function seedDefaultRoles(db) {
10513
9946
  console.log("🌱 Seeding default roles...");
10514
9947
  for (const role of DEFAULT_ROLES) {
10515
9948
  await db.execute(sql`
10516
- INSERT INTO rebase.roles (id, name, is_admin, default_permissions, config)
9949
+ INSERT INTO ${sql.raw(rolesTableName)} (id, name, is_admin, default_permissions, config)
10517
9950
  VALUES (
10518
9951
  ${role.id},
10519
9952
  ${role.name},
@@ -10526,142 +9959,156 @@ async function seedDefaultRoles(db) {
10526
9959
  }
10527
9960
  console.log("✅ Default roles created: admin, editor, viewer");
10528
9961
  }
10529
- async function applyInternalMigrations(db) {
10530
- try {
10531
- await db.execute(sql`
10532
- ALTER TABLE rebase.users
10533
- ADD COLUMN IF NOT EXISTS email_verified BOOLEAN DEFAULT FALSE,
10534
- ADD COLUMN IF NOT EXISTS email_verification_token TEXT,
10535
- ADD COLUMN IF NOT EXISTS email_verification_sent_at TIMESTAMP WITH TIME ZONE
10536
- `);
10537
- const columnsCheck = await db.execute(sql`
10538
- SELECT column_name
10539
- FROM information_schema.columns
10540
- WHERE table_schema='rebase' AND table_name='users' AND column_name IN ('google_id', 'linkedin_id', 'provider')
10541
- `);
10542
- const existingColumns = columnsCheck.rows.map((r) => r.column_name);
10543
- if (existingColumns.includes("google_id")) {
10544
- await db.execute(sql`
10545
- INSERT INTO rebase.user_identities (user_id, provider, provider_id)
10546
- SELECT id, 'google', google_id
10547
- FROM rebase.users
10548
- WHERE google_id IS NOT NULL
10549
- ON CONFLICT (provider, provider_id) DO NOTHING
10550
- `);
10551
- }
10552
- if (existingColumns.includes("linkedin_id")) {
10553
- await db.execute(sql`
10554
- INSERT INTO rebase.user_identities (user_id, provider, provider_id)
10555
- SELECT id, 'linkedin', linkedin_id
10556
- FROM rebase.users
10557
- WHERE linkedin_id IS NOT NULL
10558
- ON CONFLICT (provider, provider_id) DO NOTHING
10559
- `);
10560
- }
10561
- if (existingColumns.length > 0) {
10562
- await db.execute(sql`
10563
- ALTER TABLE rebase.users
10564
- DROP COLUMN IF EXISTS provider,
10565
- DROP COLUMN IF EXISTS google_id,
10566
- DROP COLUMN IF EXISTS linkedin_id
10567
- `);
10568
- await db.execute(sql`DROP INDEX IF EXISTS rebase.idx_users_google_id`);
10569
- await db.execute(sql`DROP INDEX IF EXISTS rebase.idx_users_linkedin_id`);
10570
- console.log("✅ Migrated to user_identities and dropped legacy columns.");
10571
- }
10572
- await db.execute(sql`
10573
- ALTER TABLE rebase.roles
10574
- ADD COLUMN IF NOT EXISTS collection_permissions JSONB
10575
- `);
10576
- await db.execute(sql`
10577
- ALTER TABLE rebase.refresh_tokens
10578
- ADD COLUMN IF NOT EXISTS user_agent TEXT,
10579
- ADD COLUMN IF NOT EXISTS ip_address TEXT
10580
- `);
10581
- const constraintCheck = await db.execute(sql`
10582
- SELECT 1 FROM information_schema.table_constraints
10583
- WHERE constraint_name = 'unique_device_session'
10584
- AND table_schema = 'rebase'
10585
- AND table_name = 'refresh_tokens'
10586
- `);
10587
- if (constraintCheck.rows.length === 0) {
10588
- try {
10589
- await db.execute(sql`
10590
- ALTER TABLE rebase.refresh_tokens
10591
- ADD CONSTRAINT unique_device_session UNIQUE (user_id, user_agent, ip_address)
10592
- `);
10593
- console.log("✅ Added unique_device_session constraint");
10594
- } catch (e) {
10595
- const errorMessage = e instanceof Error ? e.message : String(e);
10596
- if (errorMessage.includes("could not create unique index")) {
10597
- console.warn("⚠️ Duplicate sessions found, cleaning up before adding constraint...");
10598
- await db.execute(sql`
10599
- DELETE FROM rebase.refresh_tokens a
10600
- USING rebase.refresh_tokens b
10601
- WHERE a.user_id = b.user_id
10602
- AND COALESCE(a.user_agent, '') = COALESCE(b.user_agent, '')
10603
- AND COALESCE(a.ip_address, '') = COALESCE(b.ip_address, '')
10604
- AND a.created_at < b.created_at
10605
- `);
10606
- await db.execute(sql`
10607
- ALTER TABLE rebase.refresh_tokens
10608
- ADD CONSTRAINT unique_device_session UNIQUE (user_id, user_agent, ip_address)
10609
- `).catch((retryErr) => {
10610
- const retryMessage = retryErr instanceof Error ? retryErr.message : String(retryErr);
10611
- console.error("Failed to add unique_device_session constraint after cleanup:", retryMessage);
10612
- });
10613
- } else {
10614
- console.error("Constraint migration issue:", errorMessage);
10615
- }
10616
- }
10617
- }
10618
- } catch (error) {
10619
- console.error("❌ Failed to run internal migrations:", error);
9962
+ function getColumnKey(table, ...keys2) {
9963
+ if (!table) return void 0;
9964
+ for (const key of keys2) {
9965
+ if (key in table) return key;
9966
+ const snake = toSnakeCase(key);
9967
+ if (snake in table) return snake;
9968
+ const camel = camelCase(key);
9969
+ if (camel in table) return camel;
10620
9970
  }
9971
+ return void 0;
9972
+ }
9973
+ function getColumn(table, ...keys2) {
9974
+ if (!table) return void 0;
9975
+ const key = getColumnKey(table, ...keys2);
9976
+ return key ? table[key] : void 0;
10621
9977
  }
10622
9978
  class UserService {
10623
- constructor(db) {
9979
+ constructor(db, tableOrTables) {
10624
9980
  this.db = db;
9981
+ if (tableOrTables && (tableOrTables.users || tableOrTables.roles)) {
9982
+ const tables = tableOrTables;
9983
+ this.usersTable = tables.users || users;
9984
+ this.userIdentitiesTable = tables.userIdentities || userIdentities;
9985
+ this.userRolesTable = tables.userRoles || userRoles;
9986
+ this.rolesTable = tables.roles || roles;
9987
+ } else {
9988
+ const table = tableOrTables;
9989
+ this.usersTable = table || users;
9990
+ this.userIdentitiesTable = userIdentities;
9991
+ this.userRolesTable = userRoles;
9992
+ this.rolesTable = roles;
9993
+ }
9994
+ }
9995
+ usersTable;
9996
+ userIdentitiesTable;
9997
+ userRolesTable;
9998
+ rolesTable;
9999
+ getQualifiedUsersTableName() {
10000
+ const name = getTableName$1(this.usersTable);
10001
+ const schema = getTableConfig(this.usersTable).schema || "public";
10002
+ return `"${schema}"."${name}"`;
10003
+ }
10004
+ mapRowToUser(row) {
10005
+ if (!row) return row;
10006
+ const id = row.id ?? row.uid;
10007
+ const email = row.email;
10008
+ const passwordHash = row.password_hash ?? row.passwordHash ?? null;
10009
+ const displayName = row.display_name ?? row.displayName ?? null;
10010
+ const photoUrl = row.photo_url ?? row.photoUrl ?? row.photoURL ?? null;
10011
+ const emailVerified = row.email_verified ?? row.emailVerified ?? false;
10012
+ const emailVerificationToken = row.email_verification_token ?? row.emailVerificationToken ?? null;
10013
+ const emailVerificationSentAt = row.email_verification_sent_at ?? row.emailVerificationSentAt ?? null;
10014
+ const createdAt = row.created_at ?? row.createdAt;
10015
+ const updatedAt = row.updated_at ?? row.updatedAt;
10016
+ const metadata = {
10017
+ ...row.metadata || {}
10018
+ };
10019
+ const knownKeys = /* @__PURE__ */ new Set(["id", "uid", "email", "password_hash", "passwordHash", "display_name", "displayName", "photo_url", "photoUrl", "photoURL", "email_verified", "emailVerified", "email_verification_token", "emailVerificationToken", "email_verification_sent_at", "emailVerificationSentAt", "created_at", "createdAt", "updated_at", "updatedAt", "metadata"]);
10020
+ for (const [key, val] of Object.entries(row)) {
10021
+ if (!knownKeys.has(key)) {
10022
+ const camelKey = camelCase(key);
10023
+ metadata[camelKey] = val;
10024
+ }
10025
+ }
10026
+ return {
10027
+ id,
10028
+ email,
10029
+ passwordHash,
10030
+ displayName,
10031
+ photoUrl,
10032
+ emailVerified,
10033
+ emailVerificationToken,
10034
+ emailVerificationSentAt: emailVerificationSentAt ? new Date(emailVerificationSentAt) : null,
10035
+ createdAt: createdAt ? new Date(createdAt) : /* @__PURE__ */ new Date(),
10036
+ updatedAt: updatedAt ? new Date(updatedAt) : /* @__PURE__ */ new Date(),
10037
+ metadata
10038
+ };
10039
+ }
10040
+ mapPayload(data) {
10041
+ if (!data) return {};
10042
+ const payload = {};
10043
+ const idKey = getColumnKey(this.usersTable, "id") || "id";
10044
+ const emailKey = getColumnKey(this.usersTable, "email") || "email";
10045
+ const passwordHashKey = getColumnKey(this.usersTable, "passwordHash", "password_hash") || "passwordHash";
10046
+ const displayNameKey = getColumnKey(this.usersTable, "displayName", "display_name") || "displayName";
10047
+ const photoUrlKey = getColumnKey(this.usersTable, "photoUrl", "photo_url") || "photoUrl";
10048
+ const emailVerifiedKey = getColumnKey(this.usersTable, "emailVerified", "email_verified") || "emailVerified";
10049
+ const emailVerificationTokenKey = getColumnKey(this.usersTable, "emailVerificationToken", "email_verification_token") || "emailVerificationToken";
10050
+ const emailVerificationSentAtKey = getColumnKey(this.usersTable, "emailVerificationSentAt", "email_verification_sent_at") || "emailVerificationSentAt";
10051
+ const createdAtKey = getColumnKey(this.usersTable, "createdAt", "created_at") || "createdAt";
10052
+ const updatedAtKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
10053
+ const metadataKey = getColumnKey(this.usersTable, "metadata") || "metadata";
10054
+ if ("id" in data) payload[idKey] = data.id;
10055
+ if ("email" in data) payload[emailKey] = data.email;
10056
+ if ("passwordHash" in data) payload[passwordHashKey] = data.passwordHash;
10057
+ if ("displayName" in data) payload[displayNameKey] = data.displayName;
10058
+ if ("photoUrl" in data) payload[photoUrlKey] = data.photoUrl;
10059
+ if ("emailVerified" in data) payload[emailVerifiedKey] = data.emailVerified;
10060
+ if ("emailVerificationToken" in data) payload[emailVerificationTokenKey] = data.emailVerificationToken;
10061
+ if ("emailVerificationSentAt" in data) payload[emailVerificationSentAtKey] = data.emailVerificationSentAt;
10062
+ if ("createdAt" in data) payload[createdAtKey] = data.createdAt;
10063
+ if ("updatedAt" in data) payload[updatedAtKey] = data.updatedAt;
10064
+ const metadata = {
10065
+ ...data.metadata || {}
10066
+ };
10067
+ const remainingMetadata = {};
10068
+ for (const [key, val] of Object.entries(metadata)) {
10069
+ const tableColKey = getColumnKey(this.usersTable, key);
10070
+ if (tableColKey && tableColKey !== idKey && tableColKey !== emailKey && tableColKey !== passwordHashKey && tableColKey !== displayNameKey && tableColKey !== photoUrlKey && tableColKey !== emailVerifiedKey && tableColKey !== emailVerificationTokenKey && tableColKey !== emailVerificationSentAtKey && tableColKey !== createdAtKey && tableColKey !== updatedAtKey && tableColKey !== metadataKey) {
10071
+ payload[tableColKey] = val;
10072
+ } else {
10073
+ remainingMetadata[key] = val;
10074
+ }
10075
+ }
10076
+ if (metadataKey in this.usersTable) {
10077
+ payload[metadataKey] = remainingMetadata;
10078
+ }
10079
+ return payload;
10625
10080
  }
10626
10081
  async createUser(data) {
10627
- const [user] = await this.db.insert(users).values(data).returning();
10628
- return user;
10082
+ const payload = this.mapPayload(data);
10083
+ const [row] = await this.db.insert(this.usersTable).values(payload).returning();
10084
+ return this.mapRowToUser(row);
10629
10085
  }
10630
10086
  async getUserById(id) {
10631
- const [user] = await this.db.select().from(users).where(eq$3(users.id, id));
10632
- return user || null;
10087
+ const idCol = getColumn(this.usersTable, "id");
10088
+ if (!idCol) return null;
10089
+ const [row] = await this.db.select().from(this.usersTable).where(eq(idCol, id));
10090
+ return row ? this.mapRowToUser(row) : null;
10633
10091
  }
10634
10092
  async getUserByEmail(email) {
10635
- const [user] = await this.db.select().from(users).where(eq$3(users.email, email.toLowerCase()));
10636
- return user || null;
10093
+ const emailCol = getColumn(this.usersTable, "email");
10094
+ if (!emailCol) return null;
10095
+ const [row] = await this.db.select().from(this.usersTable).where(eq(emailCol, email.toLowerCase()));
10096
+ return row ? this.mapRowToUser(row) : null;
10637
10097
  }
10638
10098
  async getUserByIdentity(provider, providerId) {
10639
- const result = await this.db.execute(sql`
10640
- SELECT u.*
10641
- FROM rebase.users u
10642
- INNER JOIN rebase.user_identities ui ON u.id = ui.user_id
10643
- WHERE ui.provider = ${provider} AND ui.provider_id = ${providerId}
10644
- LIMIT 1
10645
- `);
10646
- if (result.rows.length === 0) return null;
10647
- const row = result.rows[0];
10648
- return {
10649
- id: row.id,
10650
- email: row.email,
10651
- passwordHash: row.password_hash ?? null,
10652
- displayName: row.display_name ?? null,
10653
- photoUrl: row.photo_url ?? null,
10654
- emailVerified: row.email_verified ?? false,
10655
- emailVerificationToken: row.email_verification_token ?? null,
10656
- emailVerificationSentAt: row.email_verification_sent_at ?? null,
10657
- createdAt: row.created_at,
10658
- updatedAt: row.updated_at
10659
- };
10099
+ const userIdCol = getColumn(this.usersTable, "id");
10100
+ if (!userIdCol) return null;
10101
+ const result = await this.db.select({
10102
+ user: this.usersTable
10103
+ }).from(this.usersTable).innerJoin(this.userIdentitiesTable, eq(userIdCol, this.userIdentitiesTable.userId)).where(sql`${this.userIdentitiesTable.provider} = ${provider} AND ${this.userIdentitiesTable.providerId} = ${providerId}`).limit(1);
10104
+ if (result.length === 0) return null;
10105
+ return this.mapRowToUser(result[0].user);
10660
10106
  }
10661
10107
  async getUserIdentities(userId) {
10108
+ const schema = getTableConfig(this.userIdentitiesTable).schema || "public";
10662
10109
  const result = await this.db.execute(sql`
10663
10110
  SELECT id, user_id, provider, provider_id, profile_data, created_at, updated_at
10664
- FROM rebase.user_identities
10111
+ FROM ${sql.raw(`"${schema}"."user_identities"`)}
10665
10112
  WHERE user_id = ${userId}
10666
10113
  `);
10667
10114
  return result.rows.map((row) => ({
@@ -10675,27 +10122,32 @@ class UserService {
10675
10122
  }));
10676
10123
  }
10677
10124
  async linkUserIdentity(userId, provider, providerId, profileData) {
10678
- await this.db.insert(userIdentities).values({
10125
+ await this.db.insert(this.userIdentitiesTable).values({
10679
10126
  userId,
10680
10127
  provider,
10681
10128
  providerId,
10682
10129
  profileData: profileData || null
10683
10130
  }).onConflictDoNothing({
10684
- target: [userIdentities.provider, userIdentities.providerId]
10131
+ target: [this.userIdentitiesTable.provider, this.userIdentitiesTable.providerId]
10685
10132
  });
10686
10133
  }
10687
10134
  async updateUser(id, data) {
10688
- const [user] = await this.db.update(users).set({
10689
- ...data,
10690
- updatedAt: /* @__PURE__ */ new Date()
10691
- }).where(eq$3(users.id, id)).returning();
10692
- return user || null;
10135
+ const idCol = getColumn(this.usersTable, "id");
10136
+ if (!idCol) return null;
10137
+ const payload = this.mapPayload(data);
10138
+ const updatedAtKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
10139
+ payload[updatedAtKey] = /* @__PURE__ */ new Date();
10140
+ const [row] = await this.db.update(this.usersTable).set(payload).where(eq(idCol, id)).returning();
10141
+ return row ? this.mapRowToUser(row) : null;
10693
10142
  }
10694
10143
  async deleteUser(id) {
10695
- await this.db.delete(users).where(eq$3(users.id, id));
10144
+ const idCol = getColumn(this.usersTable, "id");
10145
+ if (!idCol) return;
10146
+ await this.db.delete(this.usersTable).where(eq(idCol, id));
10696
10147
  }
10697
10148
  async listUsers() {
10698
- return this.db.select().from(users);
10149
+ const rows = await this.db.select().from(this.usersTable);
10150
+ return rows.map((row) => this.mapRowToUser(row));
10699
10151
  }
10700
10152
  async listUsersPaginated(options) {
10701
10153
  const limit = options?.limit ?? 25;
@@ -10704,49 +10156,40 @@ class UserService {
10704
10156
  const orderBy = options?.orderBy || "createdAt";
10705
10157
  const orderDir = options?.orderDir || "desc";
10706
10158
  const roleId = options?.roleId;
10707
- const columnMap = {
10708
- email: "email",
10709
- displayName: "display_name",
10710
- createdAt: "created_at",
10711
- updatedAt: "updated_at",
10712
- provider: "provider"
10713
- };
10714
- const orderColumn = columnMap[orderBy] || "created_at";
10159
+ const orderCol = getColumn(this.usersTable, orderBy);
10160
+ const orderColumn = orderCol ? orderCol.name : "created_at";
10715
10161
  const direction = orderDir === "asc" ? sql`ASC` : sql`DESC`;
10162
+ const emailCol = getColumn(this.usersTable, "email");
10163
+ const emailColumn = emailCol ? emailCol.name : "email";
10164
+ const displayNameCol = getColumn(this.usersTable, "displayName", "display_name");
10165
+ const displayNameColumn = displayNameCol ? displayNameCol.name : "display_name";
10166
+ const idCol = getColumn(this.usersTable, "id");
10167
+ const idColumn = idCol ? idCol.name : "id";
10168
+ const usersTableName = this.getQualifiedUsersTableName();
10169
+ const rolesSchema = getTableConfig(this.userRolesTable).schema || "public";
10716
10170
  const conditions = [];
10717
10171
  if (roleId) {
10718
- conditions.push(sql`EXISTS (SELECT 1 FROM rebase.user_roles ur WHERE ur.user_id = users.id AND ur.role_id = ${roleId})`);
10172
+ conditions.push(sql`EXISTS (SELECT 1 FROM ${sql.raw(`"${rolesSchema}"."user_roles"`)} ur WHERE ur.user_id = ${sql.raw(usersTableName)}.${sql.raw(idColumn)} AND ur.role_id = ${roleId})`);
10719
10173
  }
10720
10174
  if (search) {
10721
10175
  const pattern = `%${search}%`;
10722
- conditions.push(sql`(email ILIKE ${pattern} OR display_name ILIKE ${pattern})`);
10176
+ conditions.push(sql`(${sql.raw(usersTableName)}.${sql.raw(emailColumn)} ILIKE ${pattern} OR ${sql.raw(usersTableName)}.${sql.raw(displayNameColumn)} ILIKE ${pattern})`);
10723
10177
  }
10724
10178
  const whereClause = conditions.length > 0 ? sql`WHERE ${sql.join(conditions, sql` AND `)}` : sql``;
10725
- const orderByClause = roleId ? sql`ORDER BY ${sql.raw(orderColumn)} ${direction}` : sql`ORDER BY (SELECT count(*) FROM rebase.user_roles ur WHERE ur.user_id = users.id) DESC, ${sql.raw(orderColumn)} ${direction}`;
10179
+ const orderByClause = roleId ? sql`ORDER BY ${sql.raw(usersTableName)}.${sql.raw(orderColumn)} ${direction}` : sql`ORDER BY (SELECT count(*) FROM ${sql.raw(`"${rolesSchema}"."user_roles"`)} ur WHERE ur.user_id = ${sql.raw(usersTableName)}.${sql.raw(idColumn)}) DESC, ${sql.raw(usersTableName)}.${sql.raw(orderColumn)} ${direction}`;
10726
10180
  const countResult = await this.db.execute(sql`
10727
- SELECT count(*)::int as total FROM rebase.users
10181
+ SELECT count(*)::int as total FROM ${sql.raw(usersTableName)}
10728
10182
  ${whereClause}
10729
10183
  `);
10730
10184
  const total = countResult.rows[0].total;
10731
10185
  const dataResult = await this.db.execute(sql`
10732
- SELECT * FROM rebase.users
10186
+ SELECT * FROM ${sql.raw(usersTableName)}
10733
10187
  ${whereClause}
10734
10188
  ${orderByClause}
10735
10189
  LIMIT ${limit} OFFSET ${offset}
10736
10190
  `);
10737
10191
  const rows = dataResult.rows;
10738
- const mappedUsers = rows.map((row) => ({
10739
- id: row.id,
10740
- email: row.email,
10741
- passwordHash: row.password_hash ?? row.passwordHash ?? null,
10742
- displayName: row.display_name ?? row.displayName ?? null,
10743
- photoUrl: row.photo_url ?? row.photoUrl ?? null,
10744
- emailVerified: row.email_verified ?? row.emailVerified ?? false,
10745
- emailVerificationToken: row.email_verification_token ?? row.emailVerificationToken ?? null,
10746
- emailVerificationSentAt: row.email_verification_sent_at ?? row.emailVerificationSentAt ?? null,
10747
- createdAt: row.created_at ?? row.createdAt,
10748
- updatedAt: row.updated_at ?? row.updatedAt
10749
- }));
10192
+ const mappedUsers = rows.map((row) => this.mapRowToUser(row));
10750
10193
  return {
10751
10194
  users: mappedUsers,
10752
10195
  total,
@@ -10758,46 +10201,63 @@ class UserService {
10758
10201
  * Update user's password hash
10759
10202
  */
10760
10203
  async updatePassword(id, passwordHash) {
10761
- await this.db.update(users).set({
10762
- passwordHash,
10763
- updatedAt: /* @__PURE__ */ new Date()
10764
- }).where(eq$3(users.id, id));
10204
+ const idCol = getColumn(this.usersTable, "id");
10205
+ if (!idCol) return;
10206
+ const passwordHashColKey = getColumnKey(this.usersTable, "passwordHash", "password_hash") || "passwordHash";
10207
+ const updatedAtColKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
10208
+ await this.db.update(this.usersTable).set({
10209
+ [passwordHashColKey]: passwordHash,
10210
+ [updatedAtColKey]: /* @__PURE__ */ new Date()
10211
+ }).where(eq(idCol, id));
10765
10212
  }
10766
10213
  /**
10767
10214
  * Set email verification status
10768
10215
  */
10769
10216
  async setEmailVerified(id, verified) {
10770
- await this.db.update(users).set({
10771
- emailVerified: verified,
10772
- emailVerificationToken: null,
10773
- updatedAt: /* @__PURE__ */ new Date()
10774
- }).where(eq$3(users.id, id));
10217
+ const idCol = getColumn(this.usersTable, "id");
10218
+ if (!idCol) return;
10219
+ const emailVerifiedColKey = getColumnKey(this.usersTable, "emailVerified", "email_verified") || "emailVerified";
10220
+ const emailVerificationTokenColKey = getColumnKey(this.usersTable, "emailVerificationToken", "email_verification_token") || "emailVerificationToken";
10221
+ const updatedAtColKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
10222
+ await this.db.update(this.usersTable).set({
10223
+ [emailVerifiedColKey]: verified,
10224
+ [emailVerificationTokenColKey]: null,
10225
+ [updatedAtColKey]: /* @__PURE__ */ new Date()
10226
+ }).where(eq(idCol, id));
10775
10227
  }
10776
10228
  /**
10777
10229
  * Set email verification token
10778
10230
  */
10779
10231
  async setVerificationToken(id, token) {
10780
- await this.db.update(users).set({
10781
- emailVerificationToken: token,
10782
- emailVerificationSentAt: token ? /* @__PURE__ */ new Date() : null,
10783
- updatedAt: /* @__PURE__ */ new Date()
10784
- }).where(eq$3(users.id, id));
10232
+ const idCol = getColumn(this.usersTable, "id");
10233
+ if (!idCol) return;
10234
+ const emailVerificationTokenColKey = getColumnKey(this.usersTable, "emailVerificationToken", "email_verification_token") || "emailVerificationToken";
10235
+ const emailVerificationSentAtColKey = getColumnKey(this.usersTable, "emailVerificationSentAt", "email_verification_sent_at") || "emailVerificationSentAt";
10236
+ const updatedAtColKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
10237
+ await this.db.update(this.usersTable).set({
10238
+ [emailVerificationTokenColKey]: token,
10239
+ [emailVerificationSentAtColKey]: token ? /* @__PURE__ */ new Date() : null,
10240
+ [updatedAtColKey]: /* @__PURE__ */ new Date()
10241
+ }).where(eq(idCol, id));
10785
10242
  }
10786
10243
  /**
10787
10244
  * Find user by email verification token
10788
10245
  */
10789
10246
  async getUserByVerificationToken(token) {
10790
- const [user] = await this.db.select().from(users).where(eq$3(users.emailVerificationToken, token));
10791
- return user || null;
10247
+ const tokenCol = getColumn(this.usersTable, "emailVerificationToken", "email_verification_token");
10248
+ if (!tokenCol) return null;
10249
+ const [row] = await this.db.select().from(this.usersTable).where(eq(tokenCol, token));
10250
+ return row ? this.mapRowToUser(row) : null;
10792
10251
  }
10793
10252
  /**
10794
10253
  * Get roles for a user from database
10795
10254
  */
10796
10255
  async getUserRoles(userId) {
10256
+ const rolesSchema = getTableConfig(this.rolesTable).schema || "public";
10797
10257
  const result = await this.db.execute(sql`
10798
10258
  SELECT r.id, r.name, r.is_admin, r.default_permissions, r.collection_permissions, r.config
10799
- FROM rebase.roles r
10800
- INNER JOIN rebase.user_roles ur ON r.id = ur.role_id
10259
+ FROM ${sql.raw(`"${rolesSchema}"."roles"`)} r
10260
+ INNER JOIN ${sql.raw(`"${rolesSchema}"."user_roles"`)} ur ON r.id = ur.role_id
10801
10261
  WHERE ur.user_id = ${userId}
10802
10262
  `);
10803
10263
  return result.rows.map((row) => ({
@@ -10820,10 +10280,11 @@ class UserService {
10820
10280
  * Set roles for a user
10821
10281
  */
10822
10282
  async setUserRoles(userId, roleIds) {
10823
- await this.db.execute(sql`DELETE FROM rebase.user_roles WHERE user_id = ${userId}`);
10283
+ const rolesSchema = getTableConfig(this.userRolesTable).schema || "public";
10284
+ await this.db.execute(sql`DELETE FROM ${sql.raw(`"${rolesSchema}"."user_roles"`)} WHERE user_id = ${userId}`);
10824
10285
  for (const roleId of roleIds) {
10825
10286
  await this.db.execute(sql`
10826
- INSERT INTO rebase.user_roles (user_id, role_id)
10287
+ INSERT INTO ${sql.raw(`"${rolesSchema}"."user_roles"`)} (user_id, role_id)
10827
10288
  VALUES (${userId}, ${roleId})
10828
10289
  ON CONFLICT DO NOTHING
10829
10290
  `);
@@ -10833,8 +10294,9 @@ class UserService {
10833
10294
  * Assign a specific role to new user
10834
10295
  */
10835
10296
  async assignDefaultRole(userId, roleId) {
10297
+ const rolesSchema = getTableConfig(this.userRolesTable).schema || "public";
10836
10298
  await this.db.execute(sql`
10837
- INSERT INTO rebase.user_roles (user_id, role_id)
10299
+ INSERT INTO ${sql.raw(`"${rolesSchema}"."user_roles"`)} (user_id, role_id)
10838
10300
  VALUES (${userId}, ${roleId})
10839
10301
  ON CONFLICT DO NOTHING
10840
10302
  `);
@@ -10853,13 +10315,25 @@ class UserService {
10853
10315
  }
10854
10316
  }
10855
10317
  class RoleService {
10856
- constructor(db) {
10318
+ constructor(db, tableOrTables) {
10857
10319
  this.db = db;
10320
+ if (tableOrTables && (tableOrTables.roles || tableOrTables.users)) {
10321
+ this.rolesTable = tableOrTables.roles || roles;
10322
+ } else {
10323
+ this.rolesTable = tableOrTables || roles;
10324
+ }
10325
+ }
10326
+ rolesTable;
10327
+ getQualifiedRolesTableName() {
10328
+ const name = getTableName$1(this.rolesTable);
10329
+ const schema = getTableConfig(this.rolesTable).schema || "public";
10330
+ return `"${schema}"."${name}"`;
10858
10331
  }
10859
10332
  async getRoleById(id) {
10333
+ const tableName = this.getQualifiedRolesTableName();
10860
10334
  const result = await this.db.execute(sql`
10861
10335
  SELECT id, name, is_admin, default_permissions, collection_permissions, config
10862
- FROM rebase.roles
10336
+ FROM ${sql.raw(tableName)}
10863
10337
  WHERE id = ${id}
10864
10338
  `);
10865
10339
  if (result.rows.length === 0) return null;
@@ -10874,9 +10348,10 @@ class RoleService {
10874
10348
  };
10875
10349
  }
10876
10350
  async listRoles() {
10351
+ const tableName = this.getQualifiedRolesTableName();
10877
10352
  const result = await this.db.execute(sql`
10878
10353
  SELECT id, name, is_admin, default_permissions, collection_permissions, config
10879
- FROM rebase.roles
10354
+ FROM ${sql.raw(tableName)}
10880
10355
  ORDER BY name
10881
10356
  `);
10882
10357
  return result.rows.map((row) => ({
@@ -10889,8 +10364,9 @@ class RoleService {
10889
10364
  }));
10890
10365
  }
10891
10366
  async createRole(data) {
10367
+ const tableName = this.getQualifiedRolesTableName();
10892
10368
  const result = await this.db.execute(sql`
10893
- INSERT INTO rebase.roles (id, name, is_admin, default_permissions, collection_permissions, config)
10369
+ INSERT INTO ${sql.raw(tableName)} (id, name, is_admin, default_permissions, collection_permissions, config)
10894
10370
  VALUES (
10895
10371
  ${data.id},
10896
10372
  ${data.name},
@@ -10914,8 +10390,9 @@ class RoleService {
10914
10390
  async updateRole(id, data) {
10915
10391
  const existing = await this.getRoleById(id);
10916
10392
  if (!existing) return null;
10393
+ const tableName = this.getQualifiedRolesTableName();
10917
10394
  await this.db.execute(sql`
10918
- UPDATE rebase.roles
10395
+ UPDATE ${sql.raw(tableName)}
10919
10396
  SET
10920
10397
  name = ${data.name ?? existing.name},
10921
10398
  is_admin = ${data.isAdmin ?? existing.isAdmin},
@@ -10927,23 +10404,36 @@ class RoleService {
10927
10404
  return this.getRoleById(id);
10928
10405
  }
10929
10406
  async deleteRole(id) {
10930
- await this.db.execute(sql`DELETE FROM rebase.roles WHERE id = ${id}`);
10407
+ const tableName = this.getQualifiedRolesTableName();
10408
+ await this.db.execute(sql`DELETE FROM ${sql.raw(tableName)} WHERE id = ${id}`);
10931
10409
  }
10932
10410
  }
10933
10411
  class RefreshTokenService {
10934
- constructor(db) {
10412
+ constructor(db, tableOrTables) {
10935
10413
  this.db = db;
10414
+ if (tableOrTables && (tableOrTables.refreshTokens || tableOrTables.users)) {
10415
+ this.refreshTokensTable = tableOrTables.refreshTokens || refreshTokens;
10416
+ } else {
10417
+ this.refreshTokensTable = tableOrTables || refreshTokens;
10418
+ }
10419
+ }
10420
+ refreshTokensTable;
10421
+ getQualifiedRefreshTokensTableName() {
10422
+ const name = getTableName$1(this.refreshTokensTable);
10423
+ const schema = getTableConfig(this.refreshTokensTable).schema || "public";
10424
+ return `"${schema}"."${name}"`;
10936
10425
  }
10937
10426
  async createToken(userId, tokenHash, expiresAt, userAgent, ipAddress) {
10938
10427
  const safeUserAgent = userAgent || "";
10939
10428
  const safeIpAddress = ipAddress || "";
10429
+ const tableName = this.getQualifiedRefreshTokensTableName();
10940
10430
  await this.db.execute(sql`
10941
- DELETE FROM rebase.refresh_tokens
10431
+ DELETE FROM ${sql.raw(tableName)}
10942
10432
  WHERE user_id = ${userId}
10943
10433
  AND user_agent = ${safeUserAgent}
10944
10434
  AND ip_address = ${safeIpAddress}
10945
10435
  `);
10946
- await this.db.insert(refreshTokens).values({
10436
+ await this.db.insert(this.refreshTokensTable).values({
10947
10437
  userId,
10948
10438
  tokenHash,
10949
10439
  expiresAt,
@@ -10953,51 +10443,63 @@ class RefreshTokenService {
10953
10443
  }
10954
10444
  async findByHash(tokenHash) {
10955
10445
  const [token] = await this.db.select({
10956
- id: refreshTokens.id,
10957
- userId: refreshTokens.userId,
10958
- tokenHash: refreshTokens.tokenHash,
10959
- expiresAt: refreshTokens.expiresAt,
10960
- createdAt: refreshTokens.createdAt,
10961
- userAgent: refreshTokens.userAgent,
10962
- ipAddress: refreshTokens.ipAddress
10963
- }).from(refreshTokens).where(eq$3(refreshTokens.tokenHash, tokenHash));
10446
+ id: this.refreshTokensTable.id,
10447
+ userId: this.refreshTokensTable.userId,
10448
+ tokenHash: this.refreshTokensTable.tokenHash,
10449
+ expiresAt: this.refreshTokensTable.expiresAt,
10450
+ createdAt: this.refreshTokensTable.createdAt,
10451
+ userAgent: this.refreshTokensTable.userAgent,
10452
+ ipAddress: this.refreshTokensTable.ipAddress
10453
+ }).from(this.refreshTokensTable).where(eq(this.refreshTokensTable.tokenHash, tokenHash));
10964
10454
  return token || null;
10965
10455
  }
10966
10456
  async deleteByHash(tokenHash) {
10967
- await this.db.delete(refreshTokens).where(eq$3(refreshTokens.tokenHash, tokenHash));
10457
+ await this.db.delete(this.refreshTokensTable).where(eq(this.refreshTokensTable.tokenHash, tokenHash));
10968
10458
  }
10969
10459
  async deleteAllForUser(userId) {
10970
- await this.db.delete(refreshTokens).where(eq$3(refreshTokens.userId, userId));
10460
+ await this.db.delete(this.refreshTokensTable).where(eq(this.refreshTokensTable.userId, userId));
10971
10461
  }
10972
10462
  async listForUser(userId) {
10973
10463
  const tokens = await this.db.select({
10974
- id: refreshTokens.id,
10975
- userId: refreshTokens.userId,
10976
- tokenHash: refreshTokens.tokenHash,
10977
- expiresAt: refreshTokens.expiresAt,
10978
- createdAt: refreshTokens.createdAt,
10979
- userAgent: refreshTokens.userAgent,
10980
- ipAddress: refreshTokens.ipAddress
10981
- }).from(refreshTokens).where(eq$3(refreshTokens.userId, userId)).orderBy(refreshTokens.createdAt);
10464
+ id: this.refreshTokensTable.id,
10465
+ userId: this.refreshTokensTable.userId,
10466
+ tokenHash: this.refreshTokensTable.tokenHash,
10467
+ expiresAt: this.refreshTokensTable.expiresAt,
10468
+ createdAt: this.refreshTokensTable.createdAt,
10469
+ userAgent: this.refreshTokensTable.userAgent,
10470
+ ipAddress: this.refreshTokensTable.ipAddress
10471
+ }).from(this.refreshTokensTable).where(eq(this.refreshTokensTable.userId, userId)).orderBy(this.refreshTokensTable.createdAt);
10982
10472
  return tokens;
10983
10473
  }
10984
10474
  async deleteById(id, userId) {
10985
- await this.db.delete(refreshTokens).where(sql`${refreshTokens.id} = ${id} AND ${refreshTokens.userId} = ${userId}`);
10475
+ await this.db.delete(this.refreshTokensTable).where(sql`${this.refreshTokensTable.id} = ${id} AND ${this.refreshTokensTable.userId} = ${userId}`);
10986
10476
  }
10987
10477
  }
10988
10478
  class PasswordResetTokenService {
10989
- constructor(db) {
10479
+ constructor(db, tableOrTables) {
10990
10480
  this.db = db;
10481
+ if (tableOrTables && (tableOrTables.passwordResetTokens || tableOrTables.users)) {
10482
+ this.passwordResetTokensTable = tableOrTables.passwordResetTokens || passwordResetTokens;
10483
+ } else {
10484
+ this.passwordResetTokensTable = tableOrTables || passwordResetTokens;
10485
+ }
10486
+ }
10487
+ passwordResetTokensTable;
10488
+ getQualifiedPasswordResetTokensTableName() {
10489
+ const name = getTableName$1(this.passwordResetTokensTable);
10490
+ const schema = getTableConfig(this.passwordResetTokensTable).schema || "public";
10491
+ return `"${schema}"."${name}"`;
10991
10492
  }
10992
10493
  /**
10993
10494
  * Create a password reset token
10994
10495
  */
10995
10496
  async createToken(userId, tokenHash, expiresAt) {
10497
+ const tableName = this.getQualifiedPasswordResetTokensTableName();
10996
10498
  await this.db.execute(sql`
10997
- DELETE FROM rebase.password_reset_tokens
10499
+ DELETE FROM ${sql.raw(tableName)}
10998
10500
  WHERE user_id = ${userId} AND used_at IS NULL
10999
10501
  `);
11000
- await this.db.insert(passwordResetTokens).values({
10502
+ await this.db.insert(this.passwordResetTokensTable).values({
11001
10503
  userId,
11002
10504
  tokenHash,
11003
10505
  expiresAt
@@ -11008,13 +10510,14 @@ class PasswordResetTokenService {
11008
10510
  */
11009
10511
  async findValidByHash(tokenHash) {
11010
10512
  const [token] = await this.db.select({
11011
- userId: passwordResetTokens.userId,
11012
- expiresAt: passwordResetTokens.expiresAt
11013
- }).from(passwordResetTokens).where(eq$3(passwordResetTokens.tokenHash, tokenHash));
10513
+ userId: this.passwordResetTokensTable.userId,
10514
+ expiresAt: this.passwordResetTokensTable.expiresAt
10515
+ }).from(this.passwordResetTokensTable).where(eq(this.passwordResetTokensTable.tokenHash, tokenHash));
11014
10516
  if (!token) return null;
10517
+ const tableName = this.getQualifiedPasswordResetTokensTableName();
11015
10518
  const result = await this.db.execute(sql`
11016
10519
  SELECT user_id, expires_at
11017
- FROM rebase.password_reset_tokens
10520
+ FROM ${sql.raw(tableName)}
11018
10521
  WHERE token_hash = ${tokenHash}
11019
10522
  AND used_at IS NULL
11020
10523
  AND expires_at > NOW()
@@ -11030,31 +10533,32 @@ class PasswordResetTokenService {
11030
10533
  * Mark token as used
11031
10534
  */
11032
10535
  async markAsUsed(tokenHash) {
11033
- await this.db.update(passwordResetTokens).set({
10536
+ await this.db.update(this.passwordResetTokensTable).set({
11034
10537
  usedAt: /* @__PURE__ */ new Date()
11035
- }).where(eq$3(passwordResetTokens.tokenHash, tokenHash));
10538
+ }).where(eq(this.passwordResetTokensTable.tokenHash, tokenHash));
11036
10539
  }
11037
10540
  /**
11038
10541
  * Delete all tokens for a user
11039
10542
  */
11040
10543
  async deleteAllForUser(userId) {
11041
- await this.db.delete(passwordResetTokens).where(eq$3(passwordResetTokens.userId, userId));
10544
+ await this.db.delete(this.passwordResetTokensTable).where(eq(this.passwordResetTokensTable.userId, userId));
11042
10545
  }
11043
10546
  /**
11044
10547
  * Clean up expired tokens
11045
10548
  */
11046
10549
  async deleteExpired() {
10550
+ const tableName = this.getQualifiedPasswordResetTokensTableName();
11047
10551
  await this.db.execute(sql`
11048
- DELETE FROM rebase.password_reset_tokens
10552
+ DELETE FROM ${sql.raw(tableName)}
11049
10553
  WHERE expires_at < NOW()
11050
10554
  `);
11051
10555
  }
11052
10556
  }
11053
10557
  class PostgresTokenRepository {
11054
- constructor(db) {
10558
+ constructor(db, tableOrTables) {
11055
10559
  this.db = db;
11056
- this.refreshTokenService = new RefreshTokenService(db);
11057
- this.passwordResetTokenService = new PasswordResetTokenService(db);
10560
+ this.refreshTokenService = new RefreshTokenService(db, tableOrTables);
10561
+ this.passwordResetTokenService = new PasswordResetTokenService(db, tableOrTables);
11058
10562
  }
11059
10563
  refreshTokenService;
11060
10564
  passwordResetTokenService;
@@ -11095,11 +10599,11 @@ class PostgresTokenRepository {
11095
10599
  }
11096
10600
  }
11097
10601
  class PostgresAuthRepository {
11098
- constructor(db) {
10602
+ constructor(db, tableOrTables) {
11099
10603
  this.db = db;
11100
- this.userService = new UserService(db);
11101
- this.roleService = new RoleService(db);
11102
- this.tokenRepository = new PostgresTokenRepository(db);
10604
+ this.userService = new UserService(db, tableOrTables);
10605
+ this.roleService = new RoleService(db, tableOrTables);
10606
+ this.tokenRepository = new PostgresTokenRepository(db, tableOrTables);
11103
10607
  }
11104
10608
  userService;
11105
10609
  roleService;
@@ -11160,8 +10664,7 @@ class PostgresAuthRepository {
11160
10664
  await this.userService.assignDefaultRole(userId, roleId);
11161
10665
  }
11162
10666
  async getUserWithRoles(userId) {
11163
- const result = await this.userService.getUserWithRoles(userId);
11164
- return result;
10667
+ return this.userService.getUserWithRoles(userId);
11165
10668
  }
11166
10669
  // Role operations (delegate to RoleService)
11167
10670
  async getRoleById(id) {
@@ -11349,6 +10852,24 @@ class HistoryService {
11349
10852
  return result.rowCount ?? 0;
11350
10853
  }
11351
10854
  }
10855
+ function deepEqual(a, b) {
10856
+ if (a === b) return true;
10857
+ if (a == null || b == null) return false;
10858
+ if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
10859
+ if (Array.isArray(a) && Array.isArray(b)) {
10860
+ if (a.length !== b.length) return false;
10861
+ return a.every((v, i) => deepEqual(v, b[i]));
10862
+ }
10863
+ if (typeof a === "object" && typeof b === "object") {
10864
+ const aObj = a;
10865
+ const bObj = b;
10866
+ const aKeys = Object.keys(aObj);
10867
+ const bKeys = Object.keys(bObj);
10868
+ if (aKeys.length !== bKeys.length) return false;
10869
+ return aKeys.every((k) => deepEqual(aObj[k], bObj[k]));
10870
+ }
10871
+ return false;
10872
+ }
11352
10873
  function findChangedFields(oldValues, newValues) {
11353
10874
  const changed = [];
11354
10875
  const allKeys = /* @__PURE__ */ new Set([...Object.keys(oldValues), ...Object.keys(newValues)]);
@@ -11358,7 +10879,7 @@ function findChangedFields(oldValues, newValues) {
11358
10879
  if (key.startsWith("__")) continue;
11359
10880
  if (oldVal !== newVal) {
11360
10881
  if (typeof oldVal === "object" && oldVal !== null && typeof newVal === "object" && newVal !== null) {
11361
- if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {
10882
+ if (!deepEqual(oldVal, newVal)) {
11362
10883
  changed.push(key);
11363
10884
  }
11364
10885
  } else {
@@ -11476,14 +10997,32 @@ function createPostgresBootstrapper(pgConfig) {
11476
10997
  if (!authConfig) return void 0;
11477
10998
  const internals = driverResult.internals;
11478
10999
  const db = internals.db;
11479
- await ensureAuthTablesExist(db);
11000
+ const registry = internals.registry;
11001
+ await ensureAuthTablesExist(db, registry);
11480
11002
  let emailService;
11481
11003
  if (authConfig.email) {
11482
11004
  emailService = createEmailService(authConfig.email);
11483
11005
  }
11484
- const userService = new UserService(db);
11485
- const roleService = new RoleService(db);
11486
- const authRepository = new PostgresAuthRepository(db);
11006
+ const customUsersTable = registry?.getTable("users");
11007
+ const customRolesTable = registry?.getTable("roles");
11008
+ let usersSchemaName = "rebase";
11009
+ let rolesSchemaName = "rebase";
11010
+ if (customUsersTable) {
11011
+ usersSchemaName = getTableConfig(customUsersTable).schema || "public";
11012
+ }
11013
+ if (customRolesTable) {
11014
+ rolesSchemaName = getTableConfig(customRolesTable).schema || "public";
11015
+ }
11016
+ const authTables = createAuthSchema(rolesSchemaName, usersSchemaName);
11017
+ if (customUsersTable) {
11018
+ authTables.users = customUsersTable;
11019
+ }
11020
+ if (customRolesTable) {
11021
+ authTables.roles = customRolesTable;
11022
+ }
11023
+ const userService = new UserService(db, authTables);
11024
+ const roleService = new RoleService(db, authTables);
11025
+ const authRepository = new PostgresAuthRepository(db, authTables);
11487
11026
  return {
11488
11027
  userService,
11489
11028
  roleService,
@@ -11515,11 +11054,54 @@ function createPostgresBootstrapper(pgConfig) {
11515
11054
  },
11516
11055
  mountRoutes(app, basePath, driverResult) {
11517
11056
  },
11518
- async initializeWebsockets(server, realtimeService, driver, config) {
11057
+ async initializeWebsockets(server, realtimeService, driver, config, adapter) {
11519
11058
  const {
11520
11059
  createPostgresWebSocket: createPostgresWebSocket2
11521
11060
  } = await Promise.resolve().then(() => websocket);
11522
- createPostgresWebSocket2(server, realtimeService, driver, config);
11061
+ createPostgresWebSocket2(server, realtimeService, driver, config, adapter);
11062
+ }
11063
+ };
11064
+ }
11065
+ function createPostgresAdapter(pgConfig) {
11066
+ const bootstrapper = createPostgresBootstrapper(pgConfig);
11067
+ return {
11068
+ type: bootstrapper.type,
11069
+ async initializeDriver(config) {
11070
+ return bootstrapper.initializeDriver(config);
11071
+ },
11072
+ async initializeRealtime(driverResult) {
11073
+ if (bootstrapper.initializeRealtime) {
11074
+ return bootstrapper.initializeRealtime({}, driverResult);
11075
+ }
11076
+ return void 0;
11077
+ },
11078
+ async initializeAuth(config, driverResult) {
11079
+ if (bootstrapper.initializeAuth) {
11080
+ return bootstrapper.initializeAuth(config, driverResult);
11081
+ }
11082
+ return void 0;
11083
+ },
11084
+ async initializeHistory(config, driverResult) {
11085
+ if (bootstrapper.initializeHistory) {
11086
+ return bootstrapper.initializeHistory(config, driverResult);
11087
+ }
11088
+ return void 0;
11089
+ },
11090
+ initializeWebsockets(server, realtimeService, driver, config) {
11091
+ if (bootstrapper.initializeWebsockets) {
11092
+ return bootstrapper.initializeWebsockets(server, realtimeService, driver, config);
11093
+ }
11094
+ },
11095
+ getAdmin(driverResult) {
11096
+ if (bootstrapper.getAdmin) {
11097
+ return bootstrapper.getAdmin(driverResult);
11098
+ }
11099
+ return void 0;
11100
+ },
11101
+ mountRoutes(app, basePath, driverResult) {
11102
+ if (bootstrapper.mountRoutes) {
11103
+ bootstrapper.mountRoutes(app, basePath, driverResult);
11104
+ }
11523
11105
  }
11524
11106
  };
11525
11107
  }
@@ -11534,6 +11116,8 @@ export {
11534
11116
  PostgresRealtimeProvider,
11535
11117
  RealtimeService,
11536
11118
  appConfig,
11119
+ createAuthSchema,
11120
+ createPostgresAdapter,
11537
11121
  createPostgresBootstrapper,
11538
11122
  createPostgresDatabaseConnection,
11539
11123
  createPostgresWebSocket,
@@ -11550,6 +11134,7 @@ export {
11550
11134
  userRoles,
11551
11135
  userRolesRelations,
11552
11136
  users,
11553
- usersRelations
11137
+ usersRelations,
11138
+ usersSchema
11554
11139
  };
11555
11140
  //# sourceMappingURL=index.es.js.map