@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.
- package/LICENSE +22 -6
- package/dist/common/src/util/entities.d.ts +2 -2
- package/dist/common/src/util/relations.d.ts +1 -1
- package/dist/index.es.js +1250 -1665
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1196 -1611
- package/dist/index.umd.js.map +1 -1
- package/dist/server-postgresql/src/PostgresAdapter.d.ts +6 -0
- package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +2 -1
- package/dist/server-postgresql/src/PostgresBootstrapper.d.ts +0 -5
- package/dist/server-postgresql/src/auth/ensure-tables.d.ts +2 -1
- package/dist/server-postgresql/src/auth/services.d.ts +37 -15
- package/dist/server-postgresql/src/index.d.ts +1 -0
- package/dist/server-postgresql/src/schema/auth-schema.d.ts +43 -856
- package/dist/server-postgresql/src/schema/default-collections.d.ts +2 -0
- package/dist/server-postgresql/src/schema/doctor.d.ts +10 -1
- package/dist/server-postgresql/src/schema/introspect-db-logic.d.ts +1 -0
- package/dist/server-postgresql/src/services/entity-helpers.d.ts +1 -1
- package/dist/server-postgresql/src/services/realtimeService.d.ts +12 -0
- package/dist/server-postgresql/src/websocket.d.ts +2 -1
- package/dist/types/src/controllers/auth.d.ts +9 -8
- package/dist/types/src/controllers/client.d.ts +3 -0
- package/dist/types/src/types/auth_adapter.d.ts +356 -0
- package/dist/types/src/types/collections.d.ts +67 -2
- package/dist/types/src/types/database_adapter.d.ts +94 -0
- package/dist/types/src/types/entity_actions.d.ts +7 -1
- package/dist/types/src/types/entity_callbacks.d.ts +1 -1
- package/dist/types/src/types/entity_views.d.ts +36 -1
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/plugins.d.ts +1 -1
- package/dist/types/src/types/properties.d.ts +24 -5
- package/dist/types/src/types/property_config.d.ts +6 -2
- package/dist/types/src/types/relations.d.ts +1 -1
- package/dist/types/src/types/translations.d.ts +8 -0
- package/dist/types/src/users/user.d.ts +5 -0
- package/package.json +21 -15
- package/src/PostgresAdapter.ts +59 -0
- package/src/PostgresBackendDriver.ts +57 -8
- package/src/PostgresBootstrapper.ts +35 -15
- package/src/auth/ensure-tables.ts +82 -189
- package/src/auth/services.ts +421 -170
- package/src/cli.ts +44 -13
- package/src/data-transformer.ts +78 -8
- package/src/history/HistoryService.ts +25 -2
- package/src/index.ts +1 -0
- package/src/schema/auth-schema.ts +130 -98
- package/src/schema/default-collections.ts +68 -0
- package/src/schema/doctor-cli.ts +5 -1
- package/src/schema/doctor.ts +85 -8
- package/src/schema/generate-drizzle-schema-logic.ts +74 -27
- package/src/schema/generate-drizzle-schema.ts +13 -3
- package/src/schema/introspect-db-inference.ts +5 -5
- package/src/schema/introspect-db-logic.ts +9 -2
- package/src/schema/introspect-db.ts +14 -3
- package/src/services/EntityFetchService.ts +5 -5
- package/src/services/RelationService.ts +2 -2
- package/src/services/entity-helpers.ts +1 -1
- package/src/services/realtimeService.ts +145 -136
- package/src/utils/drizzle-conditions.ts +16 -2
- package/src/websocket.ts +113 -37
- package/test/auth-services.test.ts +163 -74
- package/test/data-transformer-hardening.test.ts +57 -0
- package/test/data-transformer.test.ts +43 -0
- package/test/generate-drizzle-schema.test.ts +7 -5
- package/test/introspect-db-utils.test.ts +4 -1
- package/test/postgresDataDriver.test.ts +17 -0
- package/test/realtimeService.test.ts +7 -7
- package/test/websocket.test.ts +139 -0
- package/examples/sdk-demo/node_modules/esbuild/LICENSE.md +0 -21
- package/examples/sdk-demo/node_modules/esbuild/README.md +0 -3
- package/examples/sdk-demo/node_modules/esbuild/bin/esbuild +0 -223
- package/examples/sdk-demo/node_modules/esbuild/install.js +0 -289
- package/examples/sdk-demo/node_modules/esbuild/lib/main.d.ts +0 -716
- package/examples/sdk-demo/node_modules/esbuild/lib/main.js +0 -2242
- package/examples/sdk-demo/node_modules/esbuild/package.json +0 -49
package/dist/index.umd.js
CHANGED
|
@@ -59,6 +59,12 @@
|
|
|
59
59
|
connectionString
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
+
class Vector {
|
|
63
|
+
value;
|
|
64
|
+
constructor(value) {
|
|
65
|
+
this.value = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
62
68
|
function isPostgresCollection(collection) {
|
|
63
69
|
return !collection.driver || collection.driver === "postgres";
|
|
64
70
|
}
|
|
@@ -135,19 +141,25 @@
|
|
|
135
141
|
const tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
|
|
136
142
|
const snakeCaseRegex = tokenizeRegex;
|
|
137
143
|
const toSnakeCase = (str) => {
|
|
144
|
+
if (!str || typeof str !== "string") return "";
|
|
138
145
|
const regExpMatchArray = str.match(snakeCaseRegex);
|
|
139
146
|
if (!regExpMatchArray) return "";
|
|
140
147
|
return regExpMatchArray.map((x) => x.toLowerCase()).join("_");
|
|
141
148
|
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
function camelCase(str) {
|
|
150
|
+
if (!str) return "";
|
|
151
|
+
if (str.length === 1) return str.toLowerCase();
|
|
152
|
+
const parts = str.split(/[-_ ]+/).filter(Boolean);
|
|
153
|
+
if (parts.length === 0) return "";
|
|
154
|
+
return parts[0].toLowerCase() + // Transform remaining parts to have first letter uppercase
|
|
155
|
+
parts.slice(1).map((part) => part.charAt(0).toUpperCase() + part.substring(1).toLowerCase()).join("");
|
|
145
156
|
}
|
|
157
|
+
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
146
158
|
function commonjsRequire(path2) {
|
|
147
159
|
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.');
|
|
148
160
|
}
|
|
149
161
|
var object_hash = { exports: {} };
|
|
150
|
-
(function(module2,
|
|
162
|
+
(function(module2, exports3) {
|
|
151
163
|
!function(e) {
|
|
152
164
|
module2.exports = e();
|
|
153
165
|
}(function() {
|
|
@@ -929,7 +941,23 @@
|
|
|
929
941
|
}, { buffer: 3, lYpoI2: 11 }] }, {}, [1])(1);
|
|
930
942
|
});
|
|
931
943
|
})(object_hash);
|
|
932
|
-
function
|
|
944
|
+
function deepClone(value) {
|
|
945
|
+
if (value === null || value === void 0) return value;
|
|
946
|
+
if (typeof value === "function") return value;
|
|
947
|
+
if (typeof value !== "object") return value;
|
|
948
|
+
if (Array.isArray(value)) {
|
|
949
|
+
return value.map((item) => deepClone(item));
|
|
950
|
+
}
|
|
951
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
952
|
+
return value;
|
|
953
|
+
}
|
|
954
|
+
const result = {};
|
|
955
|
+
for (const key of Object.keys(value)) {
|
|
956
|
+
result[key] = deepClone(value[key]);
|
|
957
|
+
}
|
|
958
|
+
return result;
|
|
959
|
+
}
|
|
960
|
+
function isObject(item) {
|
|
933
961
|
return !!item && typeof item === "object" && !Array.isArray(item);
|
|
934
962
|
}
|
|
935
963
|
function isPlainObject(obj) {
|
|
@@ -940,13 +968,13 @@
|
|
|
940
968
|
return proto === Object.prototype;
|
|
941
969
|
}
|
|
942
970
|
function mergeDeep(target, source, ignoreUndefined = false) {
|
|
943
|
-
if (!isObject
|
|
971
|
+
if (!isObject(target)) {
|
|
944
972
|
return target;
|
|
945
973
|
}
|
|
946
974
|
const output = {
|
|
947
975
|
...target
|
|
948
976
|
};
|
|
949
|
-
if (!isObject
|
|
977
|
+
if (!isObject(source)) {
|
|
950
978
|
return output;
|
|
951
979
|
}
|
|
952
980
|
for (const key in source) {
|
|
@@ -987,7 +1015,7 @@
|
|
|
987
1015
|
} else {
|
|
988
1016
|
output[key] = sourceValue;
|
|
989
1017
|
}
|
|
990
|
-
} else if (isObject
|
|
1018
|
+
} else if (isObject(sourceValue)) {
|
|
991
1019
|
output[key] = sourceValue;
|
|
992
1020
|
} else {
|
|
993
1021
|
output[key] = sourceValue;
|
|
@@ -1250,14 +1278,56 @@
|
|
|
1250
1278
|
}
|
|
1251
1279
|
return Object.keys(propertyCallbacks).length > 0 ? propertyCallbacks : void 0;
|
|
1252
1280
|
};
|
|
1253
|
-
function sanitizeRelation(relation, sourceCollection) {
|
|
1281
|
+
function sanitizeRelation(relation, sourceCollection, resolveCollection) {
|
|
1254
1282
|
if (!relation.target) {
|
|
1255
1283
|
throw new Error("Relation is missing a `target` collection.");
|
|
1256
1284
|
}
|
|
1257
|
-
const
|
|
1285
|
+
const rawTarget = relation.target;
|
|
1286
|
+
let targetCollection;
|
|
1287
|
+
if (typeof rawTarget === "string") {
|
|
1288
|
+
if (resolveCollection) {
|
|
1289
|
+
targetCollection = resolveCollection(rawTarget);
|
|
1290
|
+
}
|
|
1291
|
+
if (!targetCollection) {
|
|
1292
|
+
targetCollection = {
|
|
1293
|
+
slug: rawTarget,
|
|
1294
|
+
name: rawTarget
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
} else if (typeof rawTarget === "function") {
|
|
1298
|
+
const evaluated = rawTarget();
|
|
1299
|
+
if (typeof evaluated === "string") {
|
|
1300
|
+
if (resolveCollection) {
|
|
1301
|
+
targetCollection = resolveCollection(evaluated);
|
|
1302
|
+
}
|
|
1303
|
+
if (!targetCollection) {
|
|
1304
|
+
targetCollection = {
|
|
1305
|
+
slug: evaluated,
|
|
1306
|
+
name: evaluated
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
} else {
|
|
1310
|
+
targetCollection = evaluated;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
if (!targetCollection) {
|
|
1314
|
+
throw new Error("Relation is missing a valid `target` collection.");
|
|
1315
|
+
}
|
|
1258
1316
|
const newRelation = {
|
|
1259
1317
|
...relation
|
|
1260
1318
|
};
|
|
1319
|
+
newRelation.target = () => {
|
|
1320
|
+
if (typeof rawTarget === "string") {
|
|
1321
|
+
return resolveCollection && resolveCollection(rawTarget) || targetCollection;
|
|
1322
|
+
} else if (typeof rawTarget === "function") {
|
|
1323
|
+
const evaluated = rawTarget();
|
|
1324
|
+
if (typeof evaluated === "string") {
|
|
1325
|
+
return resolveCollection && resolveCollection(evaluated) || targetCollection;
|
|
1326
|
+
}
|
|
1327
|
+
return evaluated;
|
|
1328
|
+
}
|
|
1329
|
+
return targetCollection;
|
|
1330
|
+
};
|
|
1261
1331
|
if (!newRelation.relationName) {
|
|
1262
1332
|
newRelation.relationName = toSnakeCase(targetCollection.slug);
|
|
1263
1333
|
}
|
|
@@ -1310,6 +1380,17 @@
|
|
|
1310
1380
|
break;
|
|
1311
1381
|
}
|
|
1312
1382
|
}
|
|
1383
|
+
if (!isManyToManyInverse && targetCollection.properties) {
|
|
1384
|
+
for (const [propKey, prop] of Object.entries(targetCollection.properties)) {
|
|
1385
|
+
if (prop.type !== "relation") continue;
|
|
1386
|
+
const relProp = prop;
|
|
1387
|
+
const relName = relProp.relationName || propKey;
|
|
1388
|
+
if (relName === newRelation.inverseRelationName && relProp.cardinality === "many" && (relProp.direction === "owning" || !relProp.direction)) {
|
|
1389
|
+
isManyToManyInverse = true;
|
|
1390
|
+
break;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1313
1394
|
} catch (e) {
|
|
1314
1395
|
}
|
|
1315
1396
|
}
|
|
@@ -1432,8 +1513,8 @@
|
|
|
1432
1513
|
return void 0;
|
|
1433
1514
|
}
|
|
1434
1515
|
var logic = { exports: {} };
|
|
1435
|
-
(function(module2,
|
|
1436
|
-
(function(
|
|
1516
|
+
(function(module2, exports3) {
|
|
1517
|
+
(function(root, factory) {
|
|
1437
1518
|
{
|
|
1438
1519
|
module2.exports = factory();
|
|
1439
1520
|
}
|
|
@@ -1801,7 +1882,7 @@
|
|
|
1801
1882
|
});
|
|
1802
1883
|
})(logic);
|
|
1803
1884
|
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
|
1804
|
-
const { hasOwnProperty
|
|
1885
|
+
const { hasOwnProperty } = Object.prototype;
|
|
1805
1886
|
function combineComparators(comparatorA, comparatorB) {
|
|
1806
1887
|
return function isEqual(a, b, state) {
|
|
1807
1888
|
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
|
@@ -1831,12 +1912,12 @@
|
|
|
1831
1912
|
}
|
|
1832
1913
|
const hasOwn = (
|
|
1833
1914
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1834
|
-
Object.hasOwn || ((object, property) => hasOwnProperty
|
|
1915
|
+
Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property))
|
|
1835
1916
|
);
|
|
1836
1917
|
const PREACT_VNODE = "__v";
|
|
1837
1918
|
const PREACT_OWNER = "__o";
|
|
1838
1919
|
const REACT_OWNER = "_owner";
|
|
1839
|
-
const { getOwnPropertyDescriptor, keys
|
|
1920
|
+
const { getOwnPropertyDescriptor, keys } = Object;
|
|
1840
1921
|
const sameValueEqual = (
|
|
1841
1922
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1842
1923
|
Object.is || function sameValueEqual2(a, b) {
|
|
@@ -1914,9 +1995,9 @@
|
|
|
1914
1995
|
return true;
|
|
1915
1996
|
}
|
|
1916
1997
|
function areObjectsEqual(a, b, state) {
|
|
1917
|
-
const properties = keys
|
|
1998
|
+
const properties = keys(a);
|
|
1918
1999
|
let index = properties.length;
|
|
1919
|
-
if (keys
|
|
2000
|
+
if (keys(b).length !== index) {
|
|
1920
2001
|
return false;
|
|
1921
2002
|
}
|
|
1922
2003
|
while (index-- > 0) {
|
|
@@ -2189,7 +2270,7 @@
|
|
|
2189
2270
|
"[object Uint32Array]": areTypedArraysEqual2
|
|
2190
2271
|
};
|
|
2191
2272
|
}
|
|
2192
|
-
const deepEqual = createCustomEqual();
|
|
2273
|
+
const deepEqual$1 = createCustomEqual();
|
|
2193
2274
|
createCustomEqual({ strict: true });
|
|
2194
2275
|
createCustomEqual({ circular: true });
|
|
2195
2276
|
createCustomEqual({
|
|
@@ -2219,982 +2300,6 @@
|
|
|
2219
2300
|
const equals = createCustomInternalComparator ? createCustomInternalComparator(comparator) : createInternalEqualityComparator(comparator);
|
|
2220
2301
|
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
2221
2302
|
}
|
|
2222
|
-
function listCacheClear$1() {
|
|
2223
|
-
this.__data__ = [];
|
|
2224
|
-
this.size = 0;
|
|
2225
|
-
}
|
|
2226
|
-
var _listCacheClear = listCacheClear$1;
|
|
2227
|
-
function eq$2(value, other) {
|
|
2228
|
-
return value === other || value !== value && other !== other;
|
|
2229
|
-
}
|
|
2230
|
-
var eq_1 = eq$2;
|
|
2231
|
-
var eq$1 = eq_1;
|
|
2232
|
-
function assocIndexOf$4(array, key) {
|
|
2233
|
-
var length = array.length;
|
|
2234
|
-
while (length--) {
|
|
2235
|
-
if (eq$1(array[length][0], key)) {
|
|
2236
|
-
return length;
|
|
2237
|
-
}
|
|
2238
|
-
}
|
|
2239
|
-
return -1;
|
|
2240
|
-
}
|
|
2241
|
-
var _assocIndexOf = assocIndexOf$4;
|
|
2242
|
-
var assocIndexOf$3 = _assocIndexOf;
|
|
2243
|
-
var arrayProto = Array.prototype;
|
|
2244
|
-
var splice = arrayProto.splice;
|
|
2245
|
-
function listCacheDelete$1(key) {
|
|
2246
|
-
var data = this.__data__, index = assocIndexOf$3(data, key);
|
|
2247
|
-
if (index < 0) {
|
|
2248
|
-
return false;
|
|
2249
|
-
}
|
|
2250
|
-
var lastIndex = data.length - 1;
|
|
2251
|
-
if (index == lastIndex) {
|
|
2252
|
-
data.pop();
|
|
2253
|
-
} else {
|
|
2254
|
-
splice.call(data, index, 1);
|
|
2255
|
-
}
|
|
2256
|
-
--this.size;
|
|
2257
|
-
return true;
|
|
2258
|
-
}
|
|
2259
|
-
var _listCacheDelete = listCacheDelete$1;
|
|
2260
|
-
var assocIndexOf$2 = _assocIndexOf;
|
|
2261
|
-
function listCacheGet$1(key) {
|
|
2262
|
-
var data = this.__data__, index = assocIndexOf$2(data, key);
|
|
2263
|
-
return index < 0 ? void 0 : data[index][1];
|
|
2264
|
-
}
|
|
2265
|
-
var _listCacheGet = listCacheGet$1;
|
|
2266
|
-
var assocIndexOf$1 = _assocIndexOf;
|
|
2267
|
-
function listCacheHas$1(key) {
|
|
2268
|
-
return assocIndexOf$1(this.__data__, key) > -1;
|
|
2269
|
-
}
|
|
2270
|
-
var _listCacheHas = listCacheHas$1;
|
|
2271
|
-
var assocIndexOf = _assocIndexOf;
|
|
2272
|
-
function listCacheSet$1(key, value) {
|
|
2273
|
-
var data = this.__data__, index = assocIndexOf(data, key);
|
|
2274
|
-
if (index < 0) {
|
|
2275
|
-
++this.size;
|
|
2276
|
-
data.push([key, value]);
|
|
2277
|
-
} else {
|
|
2278
|
-
data[index][1] = value;
|
|
2279
|
-
}
|
|
2280
|
-
return this;
|
|
2281
|
-
}
|
|
2282
|
-
var _listCacheSet = listCacheSet$1;
|
|
2283
|
-
var listCacheClear = _listCacheClear, listCacheDelete = _listCacheDelete, listCacheGet = _listCacheGet, listCacheHas = _listCacheHas, listCacheSet = _listCacheSet;
|
|
2284
|
-
function ListCache$4(entries) {
|
|
2285
|
-
var index = -1, length = entries == null ? 0 : entries.length;
|
|
2286
|
-
this.clear();
|
|
2287
|
-
while (++index < length) {
|
|
2288
|
-
var entry = entries[index];
|
|
2289
|
-
this.set(entry[0], entry[1]);
|
|
2290
|
-
}
|
|
2291
|
-
}
|
|
2292
|
-
ListCache$4.prototype.clear = listCacheClear;
|
|
2293
|
-
ListCache$4.prototype["delete"] = listCacheDelete;
|
|
2294
|
-
ListCache$4.prototype.get = listCacheGet;
|
|
2295
|
-
ListCache$4.prototype.has = listCacheHas;
|
|
2296
|
-
ListCache$4.prototype.set = listCacheSet;
|
|
2297
|
-
var _ListCache = ListCache$4;
|
|
2298
|
-
var ListCache$3 = _ListCache;
|
|
2299
|
-
function stackClear$1() {
|
|
2300
|
-
this.__data__ = new ListCache$3();
|
|
2301
|
-
this.size = 0;
|
|
2302
|
-
}
|
|
2303
|
-
var _stackClear = stackClear$1;
|
|
2304
|
-
function stackDelete$1(key) {
|
|
2305
|
-
var data = this.__data__, result = data["delete"](key);
|
|
2306
|
-
this.size = data.size;
|
|
2307
|
-
return result;
|
|
2308
|
-
}
|
|
2309
|
-
var _stackDelete = stackDelete$1;
|
|
2310
|
-
function stackGet$1(key) {
|
|
2311
|
-
return this.__data__.get(key);
|
|
2312
|
-
}
|
|
2313
|
-
var _stackGet = stackGet$1;
|
|
2314
|
-
function stackHas$1(key) {
|
|
2315
|
-
return this.__data__.has(key);
|
|
2316
|
-
}
|
|
2317
|
-
var _stackHas = stackHas$1;
|
|
2318
|
-
var freeGlobal$1 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|
2319
|
-
var _freeGlobal = freeGlobal$1;
|
|
2320
|
-
var freeGlobal = _freeGlobal;
|
|
2321
|
-
var freeSelf = typeof self == "object" && self && self.Object === Object && self;
|
|
2322
|
-
var root$8 = freeGlobal || freeSelf || Function("return this")();
|
|
2323
|
-
var _root = root$8;
|
|
2324
|
-
var root$7 = _root;
|
|
2325
|
-
var Symbol$4 = root$7.Symbol;
|
|
2326
|
-
var _Symbol = Symbol$4;
|
|
2327
|
-
var Symbol$3 = _Symbol;
|
|
2328
|
-
var objectProto$c = Object.prototype;
|
|
2329
|
-
var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
|
|
2330
|
-
var nativeObjectToString$1 = objectProto$c.toString;
|
|
2331
|
-
var symToStringTag$1 = Symbol$3 ? Symbol$3.toStringTag : void 0;
|
|
2332
|
-
function getRawTag$1(value) {
|
|
2333
|
-
var isOwn = hasOwnProperty$9.call(value, symToStringTag$1), tag = value[symToStringTag$1];
|
|
2334
|
-
try {
|
|
2335
|
-
value[symToStringTag$1] = void 0;
|
|
2336
|
-
var unmasked = true;
|
|
2337
|
-
} catch (e) {
|
|
2338
|
-
}
|
|
2339
|
-
var result = nativeObjectToString$1.call(value);
|
|
2340
|
-
if (unmasked) {
|
|
2341
|
-
if (isOwn) {
|
|
2342
|
-
value[symToStringTag$1] = tag;
|
|
2343
|
-
} else {
|
|
2344
|
-
delete value[symToStringTag$1];
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
return result;
|
|
2348
|
-
}
|
|
2349
|
-
var _getRawTag = getRawTag$1;
|
|
2350
|
-
var objectProto$b = Object.prototype;
|
|
2351
|
-
var nativeObjectToString = objectProto$b.toString;
|
|
2352
|
-
function objectToString$1(value) {
|
|
2353
|
-
return nativeObjectToString.call(value);
|
|
2354
|
-
}
|
|
2355
|
-
var _objectToString = objectToString$1;
|
|
2356
|
-
var Symbol$2 = _Symbol, getRawTag = _getRawTag, objectToString = _objectToString;
|
|
2357
|
-
var nullTag = "[object Null]", undefinedTag = "[object Undefined]";
|
|
2358
|
-
var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : void 0;
|
|
2359
|
-
function baseGetTag$4(value) {
|
|
2360
|
-
if (value == null) {
|
|
2361
|
-
return value === void 0 ? undefinedTag : nullTag;
|
|
2362
|
-
}
|
|
2363
|
-
return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
|
|
2364
|
-
}
|
|
2365
|
-
var _baseGetTag = baseGetTag$4;
|
|
2366
|
-
function isObject$5(value) {
|
|
2367
|
-
var type = typeof value;
|
|
2368
|
-
return value != null && (type == "object" || type == "function");
|
|
2369
|
-
}
|
|
2370
|
-
var isObject_1 = isObject$5;
|
|
2371
|
-
var baseGetTag$3 = _baseGetTag, isObject$4 = isObject_1;
|
|
2372
|
-
var asyncTag = "[object AsyncFunction]", funcTag$2 = "[object Function]", genTag$1 = "[object GeneratorFunction]", proxyTag = "[object Proxy]";
|
|
2373
|
-
function isFunction$2(value) {
|
|
2374
|
-
if (!isObject$4(value)) {
|
|
2375
|
-
return false;
|
|
2376
|
-
}
|
|
2377
|
-
var tag = baseGetTag$3(value);
|
|
2378
|
-
return tag == funcTag$2 || tag == genTag$1 || tag == asyncTag || tag == proxyTag;
|
|
2379
|
-
}
|
|
2380
|
-
var isFunction_1 = isFunction$2;
|
|
2381
|
-
var root$6 = _root;
|
|
2382
|
-
var coreJsData$1 = root$6["__core-js_shared__"];
|
|
2383
|
-
var _coreJsData = coreJsData$1;
|
|
2384
|
-
var coreJsData = _coreJsData;
|
|
2385
|
-
var maskSrcKey = function() {
|
|
2386
|
-
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
|
|
2387
|
-
return uid ? "Symbol(src)_1." + uid : "";
|
|
2388
|
-
}();
|
|
2389
|
-
function isMasked$1(func) {
|
|
2390
|
-
return !!maskSrcKey && maskSrcKey in func;
|
|
2391
|
-
}
|
|
2392
|
-
var _isMasked = isMasked$1;
|
|
2393
|
-
var funcProto$1 = Function.prototype;
|
|
2394
|
-
var funcToString$1 = funcProto$1.toString;
|
|
2395
|
-
function toSource$2(func) {
|
|
2396
|
-
if (func != null) {
|
|
2397
|
-
try {
|
|
2398
|
-
return funcToString$1.call(func);
|
|
2399
|
-
} catch (e) {
|
|
2400
|
-
}
|
|
2401
|
-
try {
|
|
2402
|
-
return func + "";
|
|
2403
|
-
} catch (e) {
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
|
-
return "";
|
|
2407
|
-
}
|
|
2408
|
-
var _toSource = toSource$2;
|
|
2409
|
-
var isFunction$1 = isFunction_1, isMasked = _isMasked, isObject$3 = isObject_1, toSource$1 = _toSource;
|
|
2410
|
-
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|
2411
|
-
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
2412
|
-
var funcProto = Function.prototype, objectProto$a = Object.prototype;
|
|
2413
|
-
var funcToString = funcProto.toString;
|
|
2414
|
-
var hasOwnProperty$8 = objectProto$a.hasOwnProperty;
|
|
2415
|
-
var reIsNative = RegExp(
|
|
2416
|
-
"^" + funcToString.call(hasOwnProperty$8).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
|
|
2417
|
-
);
|
|
2418
|
-
function baseIsNative$1(value) {
|
|
2419
|
-
if (!isObject$3(value) || isMasked(value)) {
|
|
2420
|
-
return false;
|
|
2421
|
-
}
|
|
2422
|
-
var pattern = isFunction$1(value) ? reIsNative : reIsHostCtor;
|
|
2423
|
-
return pattern.test(toSource$1(value));
|
|
2424
|
-
}
|
|
2425
|
-
var _baseIsNative = baseIsNative$1;
|
|
2426
|
-
function getValue$1(object, key) {
|
|
2427
|
-
return object == null ? void 0 : object[key];
|
|
2428
|
-
}
|
|
2429
|
-
var _getValue = getValue$1;
|
|
2430
|
-
var baseIsNative = _baseIsNative, getValue = _getValue;
|
|
2431
|
-
function getNative$7(object, key) {
|
|
2432
|
-
var value = getValue(object, key);
|
|
2433
|
-
return baseIsNative(value) ? value : void 0;
|
|
2434
|
-
}
|
|
2435
|
-
var _getNative = getNative$7;
|
|
2436
|
-
var getNative$6 = _getNative, root$5 = _root;
|
|
2437
|
-
var Map$4 = getNative$6(root$5, "Map");
|
|
2438
|
-
var _Map = Map$4;
|
|
2439
|
-
var getNative$5 = _getNative;
|
|
2440
|
-
var nativeCreate$4 = getNative$5(Object, "create");
|
|
2441
|
-
var _nativeCreate = nativeCreate$4;
|
|
2442
|
-
var nativeCreate$3 = _nativeCreate;
|
|
2443
|
-
function hashClear$1() {
|
|
2444
|
-
this.__data__ = nativeCreate$3 ? nativeCreate$3(null) : {};
|
|
2445
|
-
this.size = 0;
|
|
2446
|
-
}
|
|
2447
|
-
var _hashClear = hashClear$1;
|
|
2448
|
-
function hashDelete$1(key) {
|
|
2449
|
-
var result = this.has(key) && delete this.__data__[key];
|
|
2450
|
-
this.size -= result ? 1 : 0;
|
|
2451
|
-
return result;
|
|
2452
|
-
}
|
|
2453
|
-
var _hashDelete = hashDelete$1;
|
|
2454
|
-
var nativeCreate$2 = _nativeCreate;
|
|
2455
|
-
var HASH_UNDEFINED$1 = "__lodash_hash_undefined__";
|
|
2456
|
-
var objectProto$9 = Object.prototype;
|
|
2457
|
-
var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
|
|
2458
|
-
function hashGet$1(key) {
|
|
2459
|
-
var data = this.__data__;
|
|
2460
|
-
if (nativeCreate$2) {
|
|
2461
|
-
var result = data[key];
|
|
2462
|
-
return result === HASH_UNDEFINED$1 ? void 0 : result;
|
|
2463
|
-
}
|
|
2464
|
-
return hasOwnProperty$7.call(data, key) ? data[key] : void 0;
|
|
2465
|
-
}
|
|
2466
|
-
var _hashGet = hashGet$1;
|
|
2467
|
-
var nativeCreate$1 = _nativeCreate;
|
|
2468
|
-
var objectProto$8 = Object.prototype;
|
|
2469
|
-
var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
|
|
2470
|
-
function hashHas$1(key) {
|
|
2471
|
-
var data = this.__data__;
|
|
2472
|
-
return nativeCreate$1 ? data[key] !== void 0 : hasOwnProperty$6.call(data, key);
|
|
2473
|
-
}
|
|
2474
|
-
var _hashHas = hashHas$1;
|
|
2475
|
-
var nativeCreate = _nativeCreate;
|
|
2476
|
-
var HASH_UNDEFINED = "__lodash_hash_undefined__";
|
|
2477
|
-
function hashSet$1(key, value) {
|
|
2478
|
-
var data = this.__data__;
|
|
2479
|
-
this.size += this.has(key) ? 0 : 1;
|
|
2480
|
-
data[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value;
|
|
2481
|
-
return this;
|
|
2482
|
-
}
|
|
2483
|
-
var _hashSet = hashSet$1;
|
|
2484
|
-
var hashClear = _hashClear, hashDelete = _hashDelete, hashGet = _hashGet, hashHas = _hashHas, hashSet = _hashSet;
|
|
2485
|
-
function Hash$1(entries) {
|
|
2486
|
-
var index = -1, length = entries == null ? 0 : entries.length;
|
|
2487
|
-
this.clear();
|
|
2488
|
-
while (++index < length) {
|
|
2489
|
-
var entry = entries[index];
|
|
2490
|
-
this.set(entry[0], entry[1]);
|
|
2491
|
-
}
|
|
2492
|
-
}
|
|
2493
|
-
Hash$1.prototype.clear = hashClear;
|
|
2494
|
-
Hash$1.prototype["delete"] = hashDelete;
|
|
2495
|
-
Hash$1.prototype.get = hashGet;
|
|
2496
|
-
Hash$1.prototype.has = hashHas;
|
|
2497
|
-
Hash$1.prototype.set = hashSet;
|
|
2498
|
-
var _Hash = Hash$1;
|
|
2499
|
-
var Hash = _Hash, ListCache$2 = _ListCache, Map$3 = _Map;
|
|
2500
|
-
function mapCacheClear$1() {
|
|
2501
|
-
this.size = 0;
|
|
2502
|
-
this.__data__ = {
|
|
2503
|
-
"hash": new Hash(),
|
|
2504
|
-
"map": new (Map$3 || ListCache$2)(),
|
|
2505
|
-
"string": new Hash()
|
|
2506
|
-
};
|
|
2507
|
-
}
|
|
2508
|
-
var _mapCacheClear = mapCacheClear$1;
|
|
2509
|
-
function isKeyable$1(value) {
|
|
2510
|
-
var type = typeof value;
|
|
2511
|
-
return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null;
|
|
2512
|
-
}
|
|
2513
|
-
var _isKeyable = isKeyable$1;
|
|
2514
|
-
var isKeyable = _isKeyable;
|
|
2515
|
-
function getMapData$4(map, key) {
|
|
2516
|
-
var data = map.__data__;
|
|
2517
|
-
return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
|
|
2518
|
-
}
|
|
2519
|
-
var _getMapData = getMapData$4;
|
|
2520
|
-
var getMapData$3 = _getMapData;
|
|
2521
|
-
function mapCacheDelete$1(key) {
|
|
2522
|
-
var result = getMapData$3(this, key)["delete"](key);
|
|
2523
|
-
this.size -= result ? 1 : 0;
|
|
2524
|
-
return result;
|
|
2525
|
-
}
|
|
2526
|
-
var _mapCacheDelete = mapCacheDelete$1;
|
|
2527
|
-
var getMapData$2 = _getMapData;
|
|
2528
|
-
function mapCacheGet$1(key) {
|
|
2529
|
-
return getMapData$2(this, key).get(key);
|
|
2530
|
-
}
|
|
2531
|
-
var _mapCacheGet = mapCacheGet$1;
|
|
2532
|
-
var getMapData$1 = _getMapData;
|
|
2533
|
-
function mapCacheHas$1(key) {
|
|
2534
|
-
return getMapData$1(this, key).has(key);
|
|
2535
|
-
}
|
|
2536
|
-
var _mapCacheHas = mapCacheHas$1;
|
|
2537
|
-
var getMapData = _getMapData;
|
|
2538
|
-
function mapCacheSet$1(key, value) {
|
|
2539
|
-
var data = getMapData(this, key), size = data.size;
|
|
2540
|
-
data.set(key, value);
|
|
2541
|
-
this.size += data.size == size ? 0 : 1;
|
|
2542
|
-
return this;
|
|
2543
|
-
}
|
|
2544
|
-
var _mapCacheSet = mapCacheSet$1;
|
|
2545
|
-
var mapCacheClear = _mapCacheClear, mapCacheDelete = _mapCacheDelete, mapCacheGet = _mapCacheGet, mapCacheHas = _mapCacheHas, mapCacheSet = _mapCacheSet;
|
|
2546
|
-
function MapCache$1(entries) {
|
|
2547
|
-
var index = -1, length = entries == null ? 0 : entries.length;
|
|
2548
|
-
this.clear();
|
|
2549
|
-
while (++index < length) {
|
|
2550
|
-
var entry = entries[index];
|
|
2551
|
-
this.set(entry[0], entry[1]);
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
2554
|
-
MapCache$1.prototype.clear = mapCacheClear;
|
|
2555
|
-
MapCache$1.prototype["delete"] = mapCacheDelete;
|
|
2556
|
-
MapCache$1.prototype.get = mapCacheGet;
|
|
2557
|
-
MapCache$1.prototype.has = mapCacheHas;
|
|
2558
|
-
MapCache$1.prototype.set = mapCacheSet;
|
|
2559
|
-
var _MapCache = MapCache$1;
|
|
2560
|
-
var ListCache$1 = _ListCache, Map$2 = _Map, MapCache = _MapCache;
|
|
2561
|
-
var LARGE_ARRAY_SIZE = 200;
|
|
2562
|
-
function stackSet$1(key, value) {
|
|
2563
|
-
var data = this.__data__;
|
|
2564
|
-
if (data instanceof ListCache$1) {
|
|
2565
|
-
var pairs = data.__data__;
|
|
2566
|
-
if (!Map$2 || pairs.length < LARGE_ARRAY_SIZE - 1) {
|
|
2567
|
-
pairs.push([key, value]);
|
|
2568
|
-
this.size = ++data.size;
|
|
2569
|
-
return this;
|
|
2570
|
-
}
|
|
2571
|
-
data = this.__data__ = new MapCache(pairs);
|
|
2572
|
-
}
|
|
2573
|
-
data.set(key, value);
|
|
2574
|
-
this.size = data.size;
|
|
2575
|
-
return this;
|
|
2576
|
-
}
|
|
2577
|
-
var _stackSet = stackSet$1;
|
|
2578
|
-
var ListCache = _ListCache, stackClear = _stackClear, stackDelete = _stackDelete, stackGet = _stackGet, stackHas = _stackHas, stackSet = _stackSet;
|
|
2579
|
-
function Stack$1(entries) {
|
|
2580
|
-
var data = this.__data__ = new ListCache(entries);
|
|
2581
|
-
this.size = data.size;
|
|
2582
|
-
}
|
|
2583
|
-
Stack$1.prototype.clear = stackClear;
|
|
2584
|
-
Stack$1.prototype["delete"] = stackDelete;
|
|
2585
|
-
Stack$1.prototype.get = stackGet;
|
|
2586
|
-
Stack$1.prototype.has = stackHas;
|
|
2587
|
-
Stack$1.prototype.set = stackSet;
|
|
2588
|
-
var _Stack = Stack$1;
|
|
2589
|
-
function arrayEach$1(array, iteratee) {
|
|
2590
|
-
var index = -1, length = array == null ? 0 : array.length;
|
|
2591
|
-
while (++index < length) {
|
|
2592
|
-
if (iteratee(array[index], index, array) === false) {
|
|
2593
|
-
break;
|
|
2594
|
-
}
|
|
2595
|
-
}
|
|
2596
|
-
return array;
|
|
2597
|
-
}
|
|
2598
|
-
var _arrayEach = arrayEach$1;
|
|
2599
|
-
var getNative$4 = _getNative;
|
|
2600
|
-
var defineProperty$1 = function() {
|
|
2601
|
-
try {
|
|
2602
|
-
var func = getNative$4(Object, "defineProperty");
|
|
2603
|
-
func({}, "", {});
|
|
2604
|
-
return func;
|
|
2605
|
-
} catch (e) {
|
|
2606
|
-
}
|
|
2607
|
-
}();
|
|
2608
|
-
var _defineProperty = defineProperty$1;
|
|
2609
|
-
var defineProperty = _defineProperty;
|
|
2610
|
-
function baseAssignValue$2(object, key, value) {
|
|
2611
|
-
if (key == "__proto__" && defineProperty) {
|
|
2612
|
-
defineProperty(object, key, {
|
|
2613
|
-
"configurable": true,
|
|
2614
|
-
"enumerable": true,
|
|
2615
|
-
"value": value,
|
|
2616
|
-
"writable": true
|
|
2617
|
-
});
|
|
2618
|
-
} else {
|
|
2619
|
-
object[key] = value;
|
|
2620
|
-
}
|
|
2621
|
-
}
|
|
2622
|
-
var _baseAssignValue = baseAssignValue$2;
|
|
2623
|
-
var baseAssignValue$1 = _baseAssignValue, eq = eq_1;
|
|
2624
|
-
var objectProto$7 = Object.prototype;
|
|
2625
|
-
var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
|
|
2626
|
-
function assignValue$2(object, key, value) {
|
|
2627
|
-
var objValue = object[key];
|
|
2628
|
-
if (!(hasOwnProperty$5.call(object, key) && eq(objValue, value)) || value === void 0 && !(key in object)) {
|
|
2629
|
-
baseAssignValue$1(object, key, value);
|
|
2630
|
-
}
|
|
2631
|
-
}
|
|
2632
|
-
var _assignValue = assignValue$2;
|
|
2633
|
-
var assignValue$1 = _assignValue, baseAssignValue = _baseAssignValue;
|
|
2634
|
-
function copyObject$4(source, props, object, customizer) {
|
|
2635
|
-
var isNew = !object;
|
|
2636
|
-
object || (object = {});
|
|
2637
|
-
var index = -1, length = props.length;
|
|
2638
|
-
while (++index < length) {
|
|
2639
|
-
var key = props[index];
|
|
2640
|
-
var newValue = customizer ? customizer(object[key], source[key], key, object, source) : void 0;
|
|
2641
|
-
if (newValue === void 0) {
|
|
2642
|
-
newValue = source[key];
|
|
2643
|
-
}
|
|
2644
|
-
if (isNew) {
|
|
2645
|
-
baseAssignValue(object, key, newValue);
|
|
2646
|
-
} else {
|
|
2647
|
-
assignValue$1(object, key, newValue);
|
|
2648
|
-
}
|
|
2649
|
-
}
|
|
2650
|
-
return object;
|
|
2651
|
-
}
|
|
2652
|
-
var _copyObject = copyObject$4;
|
|
2653
|
-
function baseTimes$1(n, iteratee) {
|
|
2654
|
-
var index = -1, result = Array(n);
|
|
2655
|
-
while (++index < n) {
|
|
2656
|
-
result[index] = iteratee(index);
|
|
2657
|
-
}
|
|
2658
|
-
return result;
|
|
2659
|
-
}
|
|
2660
|
-
var _baseTimes = baseTimes$1;
|
|
2661
|
-
function isObjectLike$5(value) {
|
|
2662
|
-
return value != null && typeof value == "object";
|
|
2663
|
-
}
|
|
2664
|
-
var isObjectLike_1 = isObjectLike$5;
|
|
2665
|
-
var baseGetTag$2 = _baseGetTag, isObjectLike$4 = isObjectLike_1;
|
|
2666
|
-
var argsTag$2 = "[object Arguments]";
|
|
2667
|
-
function baseIsArguments$1(value) {
|
|
2668
|
-
return isObjectLike$4(value) && baseGetTag$2(value) == argsTag$2;
|
|
2669
|
-
}
|
|
2670
|
-
var _baseIsArguments = baseIsArguments$1;
|
|
2671
|
-
var baseIsArguments = _baseIsArguments, isObjectLike$3 = isObjectLike_1;
|
|
2672
|
-
var objectProto$6 = Object.prototype;
|
|
2673
|
-
var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
|
|
2674
|
-
var propertyIsEnumerable$1 = objectProto$6.propertyIsEnumerable;
|
|
2675
|
-
var isArguments$1 = baseIsArguments(/* @__PURE__ */ function() {
|
|
2676
|
-
return arguments;
|
|
2677
|
-
}()) ? baseIsArguments : function(value) {
|
|
2678
|
-
return isObjectLike$3(value) && hasOwnProperty$4.call(value, "callee") && !propertyIsEnumerable$1.call(value, "callee");
|
|
2679
|
-
};
|
|
2680
|
-
var isArguments_1 = isArguments$1;
|
|
2681
|
-
var isArray$3 = Array.isArray;
|
|
2682
|
-
var isArray_1 = isArray$3;
|
|
2683
|
-
var isBuffer$2 = { exports: {} };
|
|
2684
|
-
function stubFalse() {
|
|
2685
|
-
return false;
|
|
2686
|
-
}
|
|
2687
|
-
var stubFalse_1 = stubFalse;
|
|
2688
|
-
isBuffer$2.exports;
|
|
2689
|
-
(function(module2, exports$1) {
|
|
2690
|
-
var root2 = _root, stubFalse2 = stubFalse_1;
|
|
2691
|
-
var freeExports = exports$1 && !exports$1.nodeType && exports$1;
|
|
2692
|
-
var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
|
|
2693
|
-
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
2694
|
-
var Buffer2 = moduleExports ? root2.Buffer : void 0;
|
|
2695
|
-
var nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0;
|
|
2696
|
-
var isBuffer2 = nativeIsBuffer || stubFalse2;
|
|
2697
|
-
module2.exports = isBuffer2;
|
|
2698
|
-
})(isBuffer$2, isBuffer$2.exports);
|
|
2699
|
-
var isBufferExports = isBuffer$2.exports;
|
|
2700
|
-
var MAX_SAFE_INTEGER$1 = 9007199254740991;
|
|
2701
|
-
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
2702
|
-
function isIndex$1(value, length) {
|
|
2703
|
-
var type = typeof value;
|
|
2704
|
-
length = length == null ? MAX_SAFE_INTEGER$1 : length;
|
|
2705
|
-
return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
|
|
2706
|
-
}
|
|
2707
|
-
var _isIndex = isIndex$1;
|
|
2708
|
-
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
2709
|
-
function isLength$2(value) {
|
|
2710
|
-
return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
2711
|
-
}
|
|
2712
|
-
var isLength_1 = isLength$2;
|
|
2713
|
-
var baseGetTag$1 = _baseGetTag, isLength$1 = isLength_1, isObjectLike$2 = isObjectLike_1;
|
|
2714
|
-
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]";
|
|
2715
|
-
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]";
|
|
2716
|
-
var typedArrayTags = {};
|
|
2717
|
-
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;
|
|
2718
|
-
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;
|
|
2719
|
-
function baseIsTypedArray$1(value) {
|
|
2720
|
-
return isObjectLike$2(value) && isLength$1(value.length) && !!typedArrayTags[baseGetTag$1(value)];
|
|
2721
|
-
}
|
|
2722
|
-
var _baseIsTypedArray = baseIsTypedArray$1;
|
|
2723
|
-
function baseUnary$3(func) {
|
|
2724
|
-
return function(value) {
|
|
2725
|
-
return func(value);
|
|
2726
|
-
};
|
|
2727
|
-
}
|
|
2728
|
-
var _baseUnary = baseUnary$3;
|
|
2729
|
-
var _nodeUtil = { exports: {} };
|
|
2730
|
-
_nodeUtil.exports;
|
|
2731
|
-
(function(module2, exports$1) {
|
|
2732
|
-
var freeGlobal2 = _freeGlobal;
|
|
2733
|
-
var freeExports = exports$1 && !exports$1.nodeType && exports$1;
|
|
2734
|
-
var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
|
|
2735
|
-
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
2736
|
-
var freeProcess = moduleExports && freeGlobal2.process;
|
|
2737
|
-
var nodeUtil2 = function() {
|
|
2738
|
-
try {
|
|
2739
|
-
var types = freeModule && freeModule.require && freeModule.require("util").types;
|
|
2740
|
-
if (types) {
|
|
2741
|
-
return types;
|
|
2742
|
-
}
|
|
2743
|
-
return freeProcess && freeProcess.binding && freeProcess.binding("util");
|
|
2744
|
-
} catch (e) {
|
|
2745
|
-
}
|
|
2746
|
-
}();
|
|
2747
|
-
module2.exports = nodeUtil2;
|
|
2748
|
-
})(_nodeUtil, _nodeUtil.exports);
|
|
2749
|
-
var _nodeUtilExports = _nodeUtil.exports;
|
|
2750
|
-
var baseIsTypedArray = _baseIsTypedArray, baseUnary$2 = _baseUnary, nodeUtil$2 = _nodeUtilExports;
|
|
2751
|
-
var nodeIsTypedArray = nodeUtil$2 && nodeUtil$2.isTypedArray;
|
|
2752
|
-
var isTypedArray$1 = nodeIsTypedArray ? baseUnary$2(nodeIsTypedArray) : baseIsTypedArray;
|
|
2753
|
-
var isTypedArray_1 = isTypedArray$1;
|
|
2754
|
-
var baseTimes = _baseTimes, isArguments = isArguments_1, isArray$2 = isArray_1, isBuffer$1 = isBufferExports, isIndex = _isIndex, isTypedArray = isTypedArray_1;
|
|
2755
|
-
var objectProto$5 = Object.prototype;
|
|
2756
|
-
var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
|
|
2757
|
-
function arrayLikeKeys$2(value, inherited) {
|
|
2758
|
-
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;
|
|
2759
|
-
for (var key in value) {
|
|
2760
|
-
if ((inherited || hasOwnProperty$3.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode.
|
|
2761
|
-
(key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers.
|
|
2762
|
-
isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays.
|
|
2763
|
-
isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties.
|
|
2764
|
-
isIndex(key, length)))) {
|
|
2765
|
-
result.push(key);
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
return result;
|
|
2769
|
-
}
|
|
2770
|
-
var _arrayLikeKeys = arrayLikeKeys$2;
|
|
2771
|
-
var objectProto$4 = Object.prototype;
|
|
2772
|
-
function isPrototype$3(value) {
|
|
2773
|
-
var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto$4;
|
|
2774
|
-
return value === proto;
|
|
2775
|
-
}
|
|
2776
|
-
var _isPrototype = isPrototype$3;
|
|
2777
|
-
function overArg$2(func, transform) {
|
|
2778
|
-
return function(arg) {
|
|
2779
|
-
return func(transform(arg));
|
|
2780
|
-
};
|
|
2781
|
-
}
|
|
2782
|
-
var _overArg = overArg$2;
|
|
2783
|
-
var overArg$1 = _overArg;
|
|
2784
|
-
var nativeKeys$1 = overArg$1(Object.keys, Object);
|
|
2785
|
-
var _nativeKeys = nativeKeys$1;
|
|
2786
|
-
var isPrototype$2 = _isPrototype, nativeKeys = _nativeKeys;
|
|
2787
|
-
var objectProto$3 = Object.prototype;
|
|
2788
|
-
var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
|
|
2789
|
-
function baseKeys$1(object) {
|
|
2790
|
-
if (!isPrototype$2(object)) {
|
|
2791
|
-
return nativeKeys(object);
|
|
2792
|
-
}
|
|
2793
|
-
var result = [];
|
|
2794
|
-
for (var key in Object(object)) {
|
|
2795
|
-
if (hasOwnProperty$2.call(object, key) && key != "constructor") {
|
|
2796
|
-
result.push(key);
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
return result;
|
|
2800
|
-
}
|
|
2801
|
-
var _baseKeys = baseKeys$1;
|
|
2802
|
-
var isFunction = isFunction_1, isLength = isLength_1;
|
|
2803
|
-
function isArrayLike$2(value) {
|
|
2804
|
-
return value != null && isLength(value.length) && !isFunction(value);
|
|
2805
|
-
}
|
|
2806
|
-
var isArrayLike_1 = isArrayLike$2;
|
|
2807
|
-
var arrayLikeKeys$1 = _arrayLikeKeys, baseKeys = _baseKeys, isArrayLike$1 = isArrayLike_1;
|
|
2808
|
-
function keys$3(object) {
|
|
2809
|
-
return isArrayLike$1(object) ? arrayLikeKeys$1(object) : baseKeys(object);
|
|
2810
|
-
}
|
|
2811
|
-
var keys_1 = keys$3;
|
|
2812
|
-
var copyObject$3 = _copyObject, keys$2 = keys_1;
|
|
2813
|
-
function baseAssign$1(object, source) {
|
|
2814
|
-
return object && copyObject$3(source, keys$2(source), object);
|
|
2815
|
-
}
|
|
2816
|
-
var _baseAssign = baseAssign$1;
|
|
2817
|
-
function nativeKeysIn$1(object) {
|
|
2818
|
-
var result = [];
|
|
2819
|
-
if (object != null) {
|
|
2820
|
-
for (var key in Object(object)) {
|
|
2821
|
-
result.push(key);
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
return result;
|
|
2825
|
-
}
|
|
2826
|
-
var _nativeKeysIn = nativeKeysIn$1;
|
|
2827
|
-
var isObject$2 = isObject_1, isPrototype$1 = _isPrototype, nativeKeysIn = _nativeKeysIn;
|
|
2828
|
-
var objectProto$2 = Object.prototype;
|
|
2829
|
-
var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
|
|
2830
|
-
function baseKeysIn$1(object) {
|
|
2831
|
-
if (!isObject$2(object)) {
|
|
2832
|
-
return nativeKeysIn(object);
|
|
2833
|
-
}
|
|
2834
|
-
var isProto = isPrototype$1(object), result = [];
|
|
2835
|
-
for (var key in object) {
|
|
2836
|
-
if (!(key == "constructor" && (isProto || !hasOwnProperty$1.call(object, key)))) {
|
|
2837
|
-
result.push(key);
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
return result;
|
|
2841
|
-
}
|
|
2842
|
-
var _baseKeysIn = baseKeysIn$1;
|
|
2843
|
-
var arrayLikeKeys = _arrayLikeKeys, baseKeysIn = _baseKeysIn, isArrayLike = isArrayLike_1;
|
|
2844
|
-
function keysIn$3(object) {
|
|
2845
|
-
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
|
|
2846
|
-
}
|
|
2847
|
-
var keysIn_1 = keysIn$3;
|
|
2848
|
-
var copyObject$2 = _copyObject, keysIn$2 = keysIn_1;
|
|
2849
|
-
function baseAssignIn$1(object, source) {
|
|
2850
|
-
return object && copyObject$2(source, keysIn$2(source), object);
|
|
2851
|
-
}
|
|
2852
|
-
var _baseAssignIn = baseAssignIn$1;
|
|
2853
|
-
var _cloneBuffer = { exports: {} };
|
|
2854
|
-
_cloneBuffer.exports;
|
|
2855
|
-
(function(module2, exports$1) {
|
|
2856
|
-
var root2 = _root;
|
|
2857
|
-
var freeExports = exports$1 && !exports$1.nodeType && exports$1;
|
|
2858
|
-
var freeModule = freeExports && true && module2 && !module2.nodeType && module2;
|
|
2859
|
-
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
2860
|
-
var Buffer2 = moduleExports ? root2.Buffer : void 0, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : void 0;
|
|
2861
|
-
function cloneBuffer2(buffer, isDeep) {
|
|
2862
|
-
if (isDeep) {
|
|
2863
|
-
return buffer.slice();
|
|
2864
|
-
}
|
|
2865
|
-
var length = buffer.length, result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
|
|
2866
|
-
buffer.copy(result);
|
|
2867
|
-
return result;
|
|
2868
|
-
}
|
|
2869
|
-
module2.exports = cloneBuffer2;
|
|
2870
|
-
})(_cloneBuffer, _cloneBuffer.exports);
|
|
2871
|
-
var _cloneBufferExports = _cloneBuffer.exports;
|
|
2872
|
-
function copyArray$1(source, array) {
|
|
2873
|
-
var index = -1, length = source.length;
|
|
2874
|
-
array || (array = Array(length));
|
|
2875
|
-
while (++index < length) {
|
|
2876
|
-
array[index] = source[index];
|
|
2877
|
-
}
|
|
2878
|
-
return array;
|
|
2879
|
-
}
|
|
2880
|
-
var _copyArray = copyArray$1;
|
|
2881
|
-
function arrayFilter$1(array, predicate) {
|
|
2882
|
-
var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = [];
|
|
2883
|
-
while (++index < length) {
|
|
2884
|
-
var value = array[index];
|
|
2885
|
-
if (predicate(value, index, array)) {
|
|
2886
|
-
result[resIndex++] = value;
|
|
2887
|
-
}
|
|
2888
|
-
}
|
|
2889
|
-
return result;
|
|
2890
|
-
}
|
|
2891
|
-
var _arrayFilter = arrayFilter$1;
|
|
2892
|
-
function stubArray$2() {
|
|
2893
|
-
return [];
|
|
2894
|
-
}
|
|
2895
|
-
var stubArray_1 = stubArray$2;
|
|
2896
|
-
var arrayFilter = _arrayFilter, stubArray$1 = stubArray_1;
|
|
2897
|
-
var objectProto$1 = Object.prototype;
|
|
2898
|
-
var propertyIsEnumerable = objectProto$1.propertyIsEnumerable;
|
|
2899
|
-
var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
|
|
2900
|
-
var getSymbols$3 = !nativeGetSymbols$1 ? stubArray$1 : function(object) {
|
|
2901
|
-
if (object == null) {
|
|
2902
|
-
return [];
|
|
2903
|
-
}
|
|
2904
|
-
object = Object(object);
|
|
2905
|
-
return arrayFilter(nativeGetSymbols$1(object), function(symbol) {
|
|
2906
|
-
return propertyIsEnumerable.call(object, symbol);
|
|
2907
|
-
});
|
|
2908
|
-
};
|
|
2909
|
-
var _getSymbols = getSymbols$3;
|
|
2910
|
-
var copyObject$1 = _copyObject, getSymbols$2 = _getSymbols;
|
|
2911
|
-
function copySymbols$1(source, object) {
|
|
2912
|
-
return copyObject$1(source, getSymbols$2(source), object);
|
|
2913
|
-
}
|
|
2914
|
-
var _copySymbols = copySymbols$1;
|
|
2915
|
-
function arrayPush$2(array, values) {
|
|
2916
|
-
var index = -1, length = values.length, offset = array.length;
|
|
2917
|
-
while (++index < length) {
|
|
2918
|
-
array[offset + index] = values[index];
|
|
2919
|
-
}
|
|
2920
|
-
return array;
|
|
2921
|
-
}
|
|
2922
|
-
var _arrayPush = arrayPush$2;
|
|
2923
|
-
var overArg = _overArg;
|
|
2924
|
-
var getPrototype$2 = overArg(Object.getPrototypeOf, Object);
|
|
2925
|
-
var _getPrototype = getPrototype$2;
|
|
2926
|
-
var arrayPush$1 = _arrayPush, getPrototype$1 = _getPrototype, getSymbols$1 = _getSymbols, stubArray = stubArray_1;
|
|
2927
|
-
var nativeGetSymbols = Object.getOwnPropertySymbols;
|
|
2928
|
-
var getSymbolsIn$2 = !nativeGetSymbols ? stubArray : function(object) {
|
|
2929
|
-
var result = [];
|
|
2930
|
-
while (object) {
|
|
2931
|
-
arrayPush$1(result, getSymbols$1(object));
|
|
2932
|
-
object = getPrototype$1(object);
|
|
2933
|
-
}
|
|
2934
|
-
return result;
|
|
2935
|
-
};
|
|
2936
|
-
var _getSymbolsIn = getSymbolsIn$2;
|
|
2937
|
-
var copyObject = _copyObject, getSymbolsIn$1 = _getSymbolsIn;
|
|
2938
|
-
function copySymbolsIn$1(source, object) {
|
|
2939
|
-
return copyObject(source, getSymbolsIn$1(source), object);
|
|
2940
|
-
}
|
|
2941
|
-
var _copySymbolsIn = copySymbolsIn$1;
|
|
2942
|
-
var arrayPush = _arrayPush, isArray$1 = isArray_1;
|
|
2943
|
-
function baseGetAllKeys$2(object, keysFunc, symbolsFunc) {
|
|
2944
|
-
var result = keysFunc(object);
|
|
2945
|
-
return isArray$1(object) ? result : arrayPush(result, symbolsFunc(object));
|
|
2946
|
-
}
|
|
2947
|
-
var _baseGetAllKeys = baseGetAllKeys$2;
|
|
2948
|
-
var baseGetAllKeys$1 = _baseGetAllKeys, getSymbols = _getSymbols, keys$1 = keys_1;
|
|
2949
|
-
function getAllKeys$1(object) {
|
|
2950
|
-
return baseGetAllKeys$1(object, keys$1, getSymbols);
|
|
2951
|
-
}
|
|
2952
|
-
var _getAllKeys = getAllKeys$1;
|
|
2953
|
-
var baseGetAllKeys = _baseGetAllKeys, getSymbolsIn = _getSymbolsIn, keysIn$1 = keysIn_1;
|
|
2954
|
-
function getAllKeysIn$1(object) {
|
|
2955
|
-
return baseGetAllKeys(object, keysIn$1, getSymbolsIn);
|
|
2956
|
-
}
|
|
2957
|
-
var _getAllKeysIn = getAllKeysIn$1;
|
|
2958
|
-
var getNative$3 = _getNative, root$4 = _root;
|
|
2959
|
-
var DataView$1 = getNative$3(root$4, "DataView");
|
|
2960
|
-
var _DataView = DataView$1;
|
|
2961
|
-
var getNative$2 = _getNative, root$3 = _root;
|
|
2962
|
-
var Promise$2 = getNative$2(root$3, "Promise");
|
|
2963
|
-
var _Promise = Promise$2;
|
|
2964
|
-
var getNative$1 = _getNative, root$2 = _root;
|
|
2965
|
-
var Set$2 = getNative$1(root$2, "Set");
|
|
2966
|
-
var _Set = Set$2;
|
|
2967
|
-
var getNative = _getNative, root$1 = _root;
|
|
2968
|
-
var WeakMap$2 = getNative(root$1, "WeakMap");
|
|
2969
|
-
var _WeakMap = WeakMap$2;
|
|
2970
|
-
var DataView = _DataView, Map$1 = _Map, Promise$1 = _Promise, Set$1 = _Set, WeakMap$1 = _WeakMap, baseGetTag = _baseGetTag, toSource = _toSource;
|
|
2971
|
-
var mapTag$3 = "[object Map]", objectTag$1 = "[object Object]", promiseTag = "[object Promise]", setTag$3 = "[object Set]", weakMapTag$1 = "[object WeakMap]";
|
|
2972
|
-
var dataViewTag$2 = "[object DataView]";
|
|
2973
|
-
var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map$1), promiseCtorString = toSource(Promise$1), setCtorString = toSource(Set$1), weakMapCtorString = toSource(WeakMap$1);
|
|
2974
|
-
var getTag$3 = baseGetTag;
|
|
2975
|
-
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) {
|
|
2976
|
-
getTag$3 = function(value) {
|
|
2977
|
-
var result = baseGetTag(value), Ctor = result == objectTag$1 ? value.constructor : void 0, ctorString = Ctor ? toSource(Ctor) : "";
|
|
2978
|
-
if (ctorString) {
|
|
2979
|
-
switch (ctorString) {
|
|
2980
|
-
case dataViewCtorString:
|
|
2981
|
-
return dataViewTag$2;
|
|
2982
|
-
case mapCtorString:
|
|
2983
|
-
return mapTag$3;
|
|
2984
|
-
case promiseCtorString:
|
|
2985
|
-
return promiseTag;
|
|
2986
|
-
case setCtorString:
|
|
2987
|
-
return setTag$3;
|
|
2988
|
-
case weakMapCtorString:
|
|
2989
|
-
return weakMapTag$1;
|
|
2990
|
-
}
|
|
2991
|
-
}
|
|
2992
|
-
return result;
|
|
2993
|
-
};
|
|
2994
|
-
}
|
|
2995
|
-
var _getTag = getTag$3;
|
|
2996
|
-
var objectProto = Object.prototype;
|
|
2997
|
-
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
2998
|
-
function initCloneArray$1(array) {
|
|
2999
|
-
var length = array.length, result = new array.constructor(length);
|
|
3000
|
-
if (length && typeof array[0] == "string" && hasOwnProperty.call(array, "index")) {
|
|
3001
|
-
result.index = array.index;
|
|
3002
|
-
result.input = array.input;
|
|
3003
|
-
}
|
|
3004
|
-
return result;
|
|
3005
|
-
}
|
|
3006
|
-
var _initCloneArray = initCloneArray$1;
|
|
3007
|
-
var root = _root;
|
|
3008
|
-
var Uint8Array$2 = root.Uint8Array;
|
|
3009
|
-
var _Uint8Array = Uint8Array$2;
|
|
3010
|
-
var Uint8Array$1 = _Uint8Array;
|
|
3011
|
-
function cloneArrayBuffer$3(arrayBuffer) {
|
|
3012
|
-
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|
3013
|
-
new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer));
|
|
3014
|
-
return result;
|
|
3015
|
-
}
|
|
3016
|
-
var _cloneArrayBuffer = cloneArrayBuffer$3;
|
|
3017
|
-
var cloneArrayBuffer$2 = _cloneArrayBuffer;
|
|
3018
|
-
function cloneDataView$1(dataView, isDeep) {
|
|
3019
|
-
var buffer = isDeep ? cloneArrayBuffer$2(dataView.buffer) : dataView.buffer;
|
|
3020
|
-
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
|
|
3021
|
-
}
|
|
3022
|
-
var _cloneDataView = cloneDataView$1;
|
|
3023
|
-
var reFlags = /\w*$/;
|
|
3024
|
-
function cloneRegExp$1(regexp) {
|
|
3025
|
-
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
|
|
3026
|
-
result.lastIndex = regexp.lastIndex;
|
|
3027
|
-
return result;
|
|
3028
|
-
}
|
|
3029
|
-
var _cloneRegExp = cloneRegExp$1;
|
|
3030
|
-
var Symbol$1 = _Symbol;
|
|
3031
|
-
var symbolProto = Symbol$1 ? Symbol$1.prototype : void 0, symbolValueOf = symbolProto ? symbolProto.valueOf : void 0;
|
|
3032
|
-
function cloneSymbol$1(symbol) {
|
|
3033
|
-
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
|
|
3034
|
-
}
|
|
3035
|
-
var _cloneSymbol = cloneSymbol$1;
|
|
3036
|
-
var cloneArrayBuffer$1 = _cloneArrayBuffer;
|
|
3037
|
-
function cloneTypedArray$1(typedArray, isDeep) {
|
|
3038
|
-
var buffer = isDeep ? cloneArrayBuffer$1(typedArray.buffer) : typedArray.buffer;
|
|
3039
|
-
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
3040
|
-
}
|
|
3041
|
-
var _cloneTypedArray = cloneTypedArray$1;
|
|
3042
|
-
var cloneArrayBuffer = _cloneArrayBuffer, cloneDataView = _cloneDataView, cloneRegExp = _cloneRegExp, cloneSymbol = _cloneSymbol, cloneTypedArray = _cloneTypedArray;
|
|
3043
|
-
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]";
|
|
3044
|
-
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]";
|
|
3045
|
-
function initCloneByTag$1(object, tag, isDeep) {
|
|
3046
|
-
var Ctor = object.constructor;
|
|
3047
|
-
switch (tag) {
|
|
3048
|
-
case arrayBufferTag$1:
|
|
3049
|
-
return cloneArrayBuffer(object);
|
|
3050
|
-
case boolTag$1:
|
|
3051
|
-
case dateTag$1:
|
|
3052
|
-
return new Ctor(+object);
|
|
3053
|
-
case dataViewTag$1:
|
|
3054
|
-
return cloneDataView(object, isDeep);
|
|
3055
|
-
case float32Tag$1:
|
|
3056
|
-
case float64Tag$1:
|
|
3057
|
-
case int8Tag$1:
|
|
3058
|
-
case int16Tag$1:
|
|
3059
|
-
case int32Tag$1:
|
|
3060
|
-
case uint8Tag$1:
|
|
3061
|
-
case uint8ClampedTag$1:
|
|
3062
|
-
case uint16Tag$1:
|
|
3063
|
-
case uint32Tag$1:
|
|
3064
|
-
return cloneTypedArray(object, isDeep);
|
|
3065
|
-
case mapTag$2:
|
|
3066
|
-
return new Ctor();
|
|
3067
|
-
case numberTag$1:
|
|
3068
|
-
case stringTag$1:
|
|
3069
|
-
return new Ctor(object);
|
|
3070
|
-
case regexpTag$1:
|
|
3071
|
-
return cloneRegExp(object);
|
|
3072
|
-
case setTag$2:
|
|
3073
|
-
return new Ctor();
|
|
3074
|
-
case symbolTag$1:
|
|
3075
|
-
return cloneSymbol(object);
|
|
3076
|
-
}
|
|
3077
|
-
}
|
|
3078
|
-
var _initCloneByTag = initCloneByTag$1;
|
|
3079
|
-
var isObject$1 = isObject_1;
|
|
3080
|
-
var objectCreate = Object.create;
|
|
3081
|
-
var baseCreate$1 = /* @__PURE__ */ function() {
|
|
3082
|
-
function object() {
|
|
3083
|
-
}
|
|
3084
|
-
return function(proto) {
|
|
3085
|
-
if (!isObject$1(proto)) {
|
|
3086
|
-
return {};
|
|
3087
|
-
}
|
|
3088
|
-
if (objectCreate) {
|
|
3089
|
-
return objectCreate(proto);
|
|
3090
|
-
}
|
|
3091
|
-
object.prototype = proto;
|
|
3092
|
-
var result = new object();
|
|
3093
|
-
object.prototype = void 0;
|
|
3094
|
-
return result;
|
|
3095
|
-
};
|
|
3096
|
-
}();
|
|
3097
|
-
var _baseCreate = baseCreate$1;
|
|
3098
|
-
var baseCreate = _baseCreate, getPrototype = _getPrototype, isPrototype = _isPrototype;
|
|
3099
|
-
function initCloneObject$1(object) {
|
|
3100
|
-
return typeof object.constructor == "function" && !isPrototype(object) ? baseCreate(getPrototype(object)) : {};
|
|
3101
|
-
}
|
|
3102
|
-
var _initCloneObject = initCloneObject$1;
|
|
3103
|
-
var getTag$2 = _getTag, isObjectLike$1 = isObjectLike_1;
|
|
3104
|
-
var mapTag$1 = "[object Map]";
|
|
3105
|
-
function baseIsMap$1(value) {
|
|
3106
|
-
return isObjectLike$1(value) && getTag$2(value) == mapTag$1;
|
|
3107
|
-
}
|
|
3108
|
-
var _baseIsMap = baseIsMap$1;
|
|
3109
|
-
var baseIsMap = _baseIsMap, baseUnary$1 = _baseUnary, nodeUtil$1 = _nodeUtilExports;
|
|
3110
|
-
var nodeIsMap = nodeUtil$1 && nodeUtil$1.isMap;
|
|
3111
|
-
var isMap$1 = nodeIsMap ? baseUnary$1(nodeIsMap) : baseIsMap;
|
|
3112
|
-
var isMap_1 = isMap$1;
|
|
3113
|
-
var getTag$1 = _getTag, isObjectLike = isObjectLike_1;
|
|
3114
|
-
var setTag$1 = "[object Set]";
|
|
3115
|
-
function baseIsSet$1(value) {
|
|
3116
|
-
return isObjectLike(value) && getTag$1(value) == setTag$1;
|
|
3117
|
-
}
|
|
3118
|
-
var _baseIsSet = baseIsSet$1;
|
|
3119
|
-
var baseIsSet = _baseIsSet, baseUnary = _baseUnary, nodeUtil = _nodeUtilExports;
|
|
3120
|
-
var nodeIsSet = nodeUtil && nodeUtil.isSet;
|
|
3121
|
-
var isSet$1 = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
|
|
3122
|
-
var isSet_1 = isSet$1;
|
|
3123
|
-
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;
|
|
3124
|
-
var CLONE_DEEP_FLAG$1 = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG$1 = 4;
|
|
3125
|
-
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]";
|
|
3126
|
-
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]";
|
|
3127
|
-
var cloneableTags = {};
|
|
3128
|
-
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;
|
|
3129
|
-
cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;
|
|
3130
|
-
function baseClone$1(value, bitmask, customizer, key, object, stack) {
|
|
3131
|
-
var result, isDeep = bitmask & CLONE_DEEP_FLAG$1, isFlat = bitmask & CLONE_FLAT_FLAG, isFull = bitmask & CLONE_SYMBOLS_FLAG$1;
|
|
3132
|
-
if (customizer) {
|
|
3133
|
-
result = object ? customizer(value, key, object, stack) : customizer(value);
|
|
3134
|
-
}
|
|
3135
|
-
if (result !== void 0) {
|
|
3136
|
-
return result;
|
|
3137
|
-
}
|
|
3138
|
-
if (!isObject(value)) {
|
|
3139
|
-
return value;
|
|
3140
|
-
}
|
|
3141
|
-
var isArr = isArray(value);
|
|
3142
|
-
if (isArr) {
|
|
3143
|
-
result = initCloneArray(value);
|
|
3144
|
-
if (!isDeep) {
|
|
3145
|
-
return copyArray(value, result);
|
|
3146
|
-
}
|
|
3147
|
-
} else {
|
|
3148
|
-
var tag = getTag(value), isFunc = tag == funcTag || tag == genTag;
|
|
3149
|
-
if (isBuffer(value)) {
|
|
3150
|
-
return cloneBuffer(value, isDeep);
|
|
3151
|
-
}
|
|
3152
|
-
if (tag == objectTag || tag == argsTag || isFunc && !object) {
|
|
3153
|
-
result = isFlat || isFunc ? {} : initCloneObject(value);
|
|
3154
|
-
if (!isDeep) {
|
|
3155
|
-
return isFlat ? copySymbolsIn(value, baseAssignIn(result, value)) : copySymbols(value, baseAssign(result, value));
|
|
3156
|
-
}
|
|
3157
|
-
} else {
|
|
3158
|
-
if (!cloneableTags[tag]) {
|
|
3159
|
-
return object ? value : {};
|
|
3160
|
-
}
|
|
3161
|
-
result = initCloneByTag(value, tag, isDeep);
|
|
3162
|
-
}
|
|
3163
|
-
}
|
|
3164
|
-
stack || (stack = new Stack());
|
|
3165
|
-
var stacked = stack.get(value);
|
|
3166
|
-
if (stacked) {
|
|
3167
|
-
return stacked;
|
|
3168
|
-
}
|
|
3169
|
-
stack.set(value, result);
|
|
3170
|
-
if (isSet(value)) {
|
|
3171
|
-
value.forEach(function(subValue) {
|
|
3172
|
-
result.add(baseClone$1(subValue, bitmask, customizer, subValue, value, stack));
|
|
3173
|
-
});
|
|
3174
|
-
} else if (isMap(value)) {
|
|
3175
|
-
value.forEach(function(subValue, key2) {
|
|
3176
|
-
result.set(key2, baseClone$1(subValue, bitmask, customizer, key2, value, stack));
|
|
3177
|
-
});
|
|
3178
|
-
}
|
|
3179
|
-
var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys;
|
|
3180
|
-
var props = isArr ? void 0 : keysFunc(value);
|
|
3181
|
-
arrayEach(props || value, function(subValue, key2) {
|
|
3182
|
-
if (props) {
|
|
3183
|
-
key2 = subValue;
|
|
3184
|
-
subValue = value[key2];
|
|
3185
|
-
}
|
|
3186
|
-
assignValue(result, key2, baseClone$1(subValue, bitmask, customizer, key2, value, stack));
|
|
3187
|
-
});
|
|
3188
|
-
return result;
|
|
3189
|
-
}
|
|
3190
|
-
var _baseClone = baseClone$1;
|
|
3191
|
-
var baseClone = _baseClone;
|
|
3192
|
-
var CLONE_DEEP_FLAG = 1, CLONE_SYMBOLS_FLAG = 4;
|
|
3193
|
-
function cloneDeep$1(value) {
|
|
3194
|
-
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
|
|
3195
|
-
}
|
|
3196
|
-
var cloneDeep_1 = cloneDeep$1;
|
|
3197
|
-
const cloneDeep = /* @__PURE__ */ getDefaultExportFromCjs(cloneDeep_1);
|
|
3198
2303
|
class CollectionRegistry {
|
|
3199
2304
|
// Normalized runtime layer (used by Data Grid / UI)
|
|
3200
2305
|
collectionsByTableName = /* @__PURE__ */ new Map();
|
|
@@ -3234,15 +2339,21 @@
|
|
|
3234
2339
|
*/
|
|
3235
2340
|
registerMultiple(collections) {
|
|
3236
2341
|
const rawSnapshot = collections.map((c) => removeFunctions(c));
|
|
3237
|
-
if (this.lastRawInputSnapshot && deepEqual(this.lastRawInputSnapshot, rawSnapshot)) {
|
|
2342
|
+
if (this.lastRawInputSnapshot && deepEqual$1(this.lastRawInputSnapshot, rawSnapshot)) {
|
|
3238
2343
|
return false;
|
|
3239
2344
|
}
|
|
3240
2345
|
this.reset();
|
|
2346
|
+
collections.forEach((c) => {
|
|
2347
|
+
if (c.slug) {
|
|
2348
|
+
this.collectionsBySlug.set(c.slug, c);
|
|
2349
|
+
}
|
|
2350
|
+
this.collectionsByTableName.set(getTableName(c), c);
|
|
2351
|
+
});
|
|
3241
2352
|
const normalizedCollections = collections.map((c) => this.normalizeCollection({
|
|
3242
2353
|
...c
|
|
3243
2354
|
}));
|
|
3244
2355
|
normalizedCollections.forEach((c, index) => {
|
|
3245
|
-
const raw =
|
|
2356
|
+
const raw = deepClone(collections[index]);
|
|
3246
2357
|
this.rootCollections.push(c);
|
|
3247
2358
|
this.rawRootCollections.push(raw);
|
|
3248
2359
|
const normalized = this.normalizeCollection(c);
|
|
@@ -3262,7 +2373,7 @@
|
|
|
3262
2373
|
if (!subCollection) return;
|
|
3263
2374
|
this._registerRecursively(this.normalizeCollection({
|
|
3264
2375
|
...subCollection
|
|
3265
|
-
}),
|
|
2376
|
+
}), deepClone(subCollection));
|
|
3266
2377
|
});
|
|
3267
2378
|
}
|
|
3268
2379
|
});
|
|
@@ -3270,7 +2381,7 @@
|
|
|
3270
2381
|
return true;
|
|
3271
2382
|
}
|
|
3272
2383
|
register(collection, rawCollection) {
|
|
3273
|
-
const raw = rawCollection ?
|
|
2384
|
+
const raw = rawCollection ? deepClone(rawCollection) : deepClone(collection);
|
|
3274
2385
|
this.rootCollections.push(collection);
|
|
3275
2386
|
this.rawRootCollections.push(raw);
|
|
3276
2387
|
this._registerRecursively(collection, raw);
|
|
@@ -3294,7 +2405,7 @@
|
|
|
3294
2405
|
if (!subCollection) return;
|
|
3295
2406
|
this._registerRecursively(this.normalizeCollection({
|
|
3296
2407
|
...subCollection
|
|
3297
|
-
}),
|
|
2408
|
+
}), deepClone(subCollection));
|
|
3298
2409
|
});
|
|
3299
2410
|
}
|
|
3300
2411
|
}
|
|
@@ -3316,7 +2427,7 @@
|
|
|
3316
2427
|
if (getDataSourceCapabilities(result.driver).supportsRelations) {
|
|
3317
2428
|
mergedRelations = mergedRelationsRaw.map((r) => {
|
|
3318
2429
|
try {
|
|
3319
|
-
return sanitizeRelation(r, result);
|
|
2430
|
+
return sanitizeRelation(r, result, (slug) => this.get(slug));
|
|
3320
2431
|
} catch {
|
|
3321
2432
|
return r;
|
|
3322
2433
|
}
|
|
@@ -3755,8 +2866,14 @@
|
|
|
3755
2866
|
static buildSingleFilterCondition(column, op, value) {
|
|
3756
2867
|
switch (op) {
|
|
3757
2868
|
case "==":
|
|
2869
|
+
if (value === null || value === void 0) {
|
|
2870
|
+
return drizzleOrm.sql`${column} IS NULL`;
|
|
2871
|
+
}
|
|
3758
2872
|
return drizzleOrm.eq(column, value);
|
|
3759
2873
|
case "!=":
|
|
2874
|
+
if (value === null || value === void 0) {
|
|
2875
|
+
return drizzleOrm.sql`${column} IS NOT NULL`;
|
|
2876
|
+
}
|
|
3760
2877
|
return drizzleOrm.sql`${column} != ${value}`;
|
|
3761
2878
|
case ">":
|
|
3762
2879
|
return drizzleOrm.sql`${column} > ${value}`;
|
|
@@ -4087,7 +3204,10 @@
|
|
|
4087
3204
|
if (p.type === "string" && !p.enum && p.isId !== "uuid") {
|
|
4088
3205
|
const fieldColumn = table[key];
|
|
4089
3206
|
if (fieldColumn) {
|
|
4090
|
-
|
|
3207
|
+
const supportsILike = fieldColumn instanceof pgCore.PgVarchar || fieldColumn instanceof pgCore.PgText || fieldColumn instanceof pgCore.PgChar || fieldColumn && typeof fieldColumn === "object" && !("columnType" in fieldColumn);
|
|
3208
|
+
if (supportsILike) {
|
|
3209
|
+
searchConditions.push(drizzleOrm.ilike(fieldColumn, `%${searchString}%`));
|
|
3210
|
+
}
|
|
4091
3211
|
}
|
|
4092
3212
|
}
|
|
4093
3213
|
}
|
|
@@ -4560,6 +3680,31 @@
|
|
|
4560
3680
|
return result;
|
|
4561
3681
|
}
|
|
4562
3682
|
return value;
|
|
3683
|
+
case "vector": {
|
|
3684
|
+
if (value instanceof Vector) {
|
|
3685
|
+
return value.value;
|
|
3686
|
+
}
|
|
3687
|
+
if (value && typeof value === "object" && "value" in value && Array.isArray(value.value)) {
|
|
3688
|
+
return value.value.map(Number);
|
|
3689
|
+
}
|
|
3690
|
+
if (Array.isArray(value)) {
|
|
3691
|
+
return value.map(Number);
|
|
3692
|
+
}
|
|
3693
|
+
return value;
|
|
3694
|
+
}
|
|
3695
|
+
case "binary":
|
|
3696
|
+
if (typeof value === "string") {
|
|
3697
|
+
if (value.startsWith("data:application/octet-stream;base64,")) {
|
|
3698
|
+
const base64Data = value.split(",")[1];
|
|
3699
|
+
if (base64Data) {
|
|
3700
|
+
return Buffer.from(base64Data, "base64");
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
if (Buffer.isBuffer(value)) {
|
|
3705
|
+
return value;
|
|
3706
|
+
}
|
|
3707
|
+
return value;
|
|
4563
3708
|
case "string":
|
|
4564
3709
|
if (typeof value === "string") {
|
|
4565
3710
|
if (value.startsWith("data:application/octet-stream;base64,")) {
|
|
@@ -4704,18 +3849,36 @@
|
|
|
4704
3849
|
return value;
|
|
4705
3850
|
}
|
|
4706
3851
|
switch (property.type) {
|
|
3852
|
+
case "binary": {
|
|
3853
|
+
let buf = null;
|
|
3854
|
+
if (Buffer.isBuffer(value)) {
|
|
3855
|
+
buf = value;
|
|
3856
|
+
} else if (typeof value === "object" && value !== null) {
|
|
3857
|
+
const rawVal = value;
|
|
3858
|
+
if (rawVal.type === "Buffer" && Array.isArray(rawVal.data)) {
|
|
3859
|
+
buf = Buffer.from(rawVal.data);
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
if (buf) {
|
|
3863
|
+
return `data:application/octet-stream;base64,${buf.toString("base64")}`;
|
|
3864
|
+
}
|
|
3865
|
+
return value;
|
|
3866
|
+
}
|
|
4707
3867
|
case "string": {
|
|
4708
3868
|
if (typeof value === "string") return value;
|
|
4709
|
-
let
|
|
3869
|
+
let isBuffer = false;
|
|
4710
3870
|
let buf = null;
|
|
4711
3871
|
if (Buffer.isBuffer(value)) {
|
|
4712
|
-
|
|
3872
|
+
isBuffer = true;
|
|
4713
3873
|
buf = value;
|
|
4714
|
-
} else if (typeof value === "object" && value !== null
|
|
4715
|
-
|
|
4716
|
-
|
|
3874
|
+
} else if (typeof value === "object" && value !== null) {
|
|
3875
|
+
const rawVal = value;
|
|
3876
|
+
if (rawVal.type === "Buffer" && Array.isArray(rawVal.data)) {
|
|
3877
|
+
isBuffer = true;
|
|
3878
|
+
buf = Buffer.from(rawVal.data);
|
|
3879
|
+
}
|
|
4717
3880
|
}
|
|
4718
|
-
if (
|
|
3881
|
+
if (isBuffer && buf) {
|
|
4719
3882
|
let isPrintable = true;
|
|
4720
3883
|
for (let i = 0; i < buf.length; i++) {
|
|
4721
3884
|
const b = buf[i];
|
|
@@ -4800,8 +3963,27 @@
|
|
|
4800
3963
|
return isNaN(parsed) ? null : parsed;
|
|
4801
3964
|
}
|
|
4802
3965
|
return value;
|
|
4803
|
-
case "
|
|
4804
|
-
let
|
|
3966
|
+
case "vector": {
|
|
3967
|
+
let nums = [];
|
|
3968
|
+
if (typeof value === "string") {
|
|
3969
|
+
nums = value.slice(1, -1).split(",").map(Number);
|
|
3970
|
+
} else if (Array.isArray(value)) {
|
|
3971
|
+
nums = value.map(Number);
|
|
3972
|
+
} else if (value instanceof Vector) {
|
|
3973
|
+
nums = value.value;
|
|
3974
|
+
} else if (typeof value === "object" && value !== null && "value" in value) {
|
|
3975
|
+
const valObj = value;
|
|
3976
|
+
if (Array.isArray(valObj.value)) {
|
|
3977
|
+
nums = valObj.value.map(Number);
|
|
3978
|
+
}
|
|
3979
|
+
}
|
|
3980
|
+
return {
|
|
3981
|
+
__type: "Vector",
|
|
3982
|
+
value: nums
|
|
3983
|
+
};
|
|
3984
|
+
}
|
|
3985
|
+
case "date": {
|
|
3986
|
+
let date;
|
|
4805
3987
|
if (value instanceof Date) {
|
|
4806
3988
|
date = value;
|
|
4807
3989
|
} else if (typeof value === "string" || typeof value === "number") {
|
|
@@ -4819,16 +4001,19 @@
|
|
|
4819
4001
|
return null;
|
|
4820
4002
|
}
|
|
4821
4003
|
default: {
|
|
4822
|
-
let
|
|
4004
|
+
let isBuffer = false;
|
|
4823
4005
|
let buf = null;
|
|
4824
4006
|
if (Buffer.isBuffer(value)) {
|
|
4825
|
-
|
|
4007
|
+
isBuffer = true;
|
|
4826
4008
|
buf = value;
|
|
4827
|
-
} else if (typeof value === "object" && value !== null
|
|
4828
|
-
|
|
4829
|
-
|
|
4009
|
+
} else if (typeof value === "object" && value !== null) {
|
|
4010
|
+
const rawVal = value;
|
|
4011
|
+
if (rawVal.type === "Buffer" && Array.isArray(rawVal.data)) {
|
|
4012
|
+
isBuffer = true;
|
|
4013
|
+
buf = Buffer.from(rawVal.data);
|
|
4014
|
+
}
|
|
4830
4015
|
}
|
|
4831
|
-
if (
|
|
4016
|
+
if (isBuffer && buf) {
|
|
4832
4017
|
let isPrintable = true;
|
|
4833
4018
|
for (let i = 0; i < buf.length; i++) {
|
|
4834
4019
|
const b = buf[i];
|
|
@@ -5616,7 +4801,7 @@
|
|
|
5616
4801
|
if (parentFKValue !== null && parentFKValue !== void 0) {
|
|
5617
4802
|
await tx.update(targetTable).set({
|
|
5618
4803
|
[targetFKColName]: null
|
|
5619
|
-
}).where(drizzleOrm.eq(targetFKCol, parentFKValue));
|
|
4804
|
+
}).where(drizzleOrm.eq(targetFKCol, String(parentFKValue)));
|
|
5620
4805
|
}
|
|
5621
4806
|
continue;
|
|
5622
4807
|
}
|
|
@@ -5625,7 +4810,7 @@
|
|
|
5625
4810
|
if (parentFKValue !== null && parentFKValue !== void 0) {
|
|
5626
4811
|
await tx.update(targetTable).set({
|
|
5627
4812
|
[targetFKColName]: null
|
|
5628
|
-
}).where(drizzleOrm.eq(targetFKCol, parentFKValue));
|
|
4813
|
+
}).where(drizzleOrm.eq(targetFKCol, String(parentFKValue)));
|
|
5629
4814
|
} else {
|
|
5630
4815
|
console.warn(`Cannot set joinPath relation '${relation.relationName}' because parent FK value is null/undefined`);
|
|
5631
4816
|
continue;
|
|
@@ -7702,23 +6887,33 @@
|
|
|
7702
6887
|
client: this.client
|
|
7703
6888
|
};
|
|
7704
6889
|
if (callbacks?.beforeDelete || propertyCallbacks?.beforeDelete) {
|
|
6890
|
+
let preventDefault = false;
|
|
7705
6891
|
if (callbacks?.beforeDelete) {
|
|
7706
|
-
await callbacks.beforeDelete({
|
|
6892
|
+
const result = await callbacks.beforeDelete({
|
|
7707
6893
|
collection: resolvedCollection,
|
|
7708
6894
|
path: entity.path,
|
|
7709
6895
|
entityId: entity.id,
|
|
7710
6896
|
entity,
|
|
7711
6897
|
context: contextForCallback
|
|
7712
6898
|
});
|
|
6899
|
+
if (result === false) {
|
|
6900
|
+
preventDefault = true;
|
|
6901
|
+
}
|
|
7713
6902
|
}
|
|
7714
6903
|
if (propertyCallbacks?.beforeDelete) {
|
|
7715
|
-
await propertyCallbacks.beforeDelete({
|
|
6904
|
+
const result = await propertyCallbacks.beforeDelete({
|
|
7716
6905
|
collection: resolvedCollection,
|
|
7717
6906
|
path: entity.path,
|
|
7718
6907
|
entityId: entity.id,
|
|
7719
6908
|
entity,
|
|
7720
6909
|
context: contextForCallback
|
|
7721
6910
|
});
|
|
6911
|
+
if (result === false) {
|
|
6912
|
+
preventDefault = true;
|
|
6913
|
+
}
|
|
6914
|
+
}
|
|
6915
|
+
if (preventDefault) {
|
|
6916
|
+
return;
|
|
7722
6917
|
}
|
|
7723
6918
|
}
|
|
7724
6919
|
await this.entityService.deleteEntity(entity.path, entity.id, entity.databaseId || resolvedCollection?.databaseId);
|
|
@@ -7791,7 +6986,17 @@
|
|
|
7791
6986
|
}
|
|
7792
6987
|
const targetDb = this.getTargetDb(options?.database);
|
|
7793
6988
|
try {
|
|
7794
|
-
|
|
6989
|
+
let needsRoleSwitch = false;
|
|
6990
|
+
if (options?.role && process.env.DISABLE_DB_ROLE_SWITCHING !== "true") {
|
|
6991
|
+
try {
|
|
6992
|
+
const currentRoleResult = await targetDb.execute(drizzleOrm.sql.raw("SELECT current_user AS role"));
|
|
6993
|
+
const currentRole = currentRoleResult.rows?.[0]?.role;
|
|
6994
|
+
needsRoleSwitch = !!currentRole && currentRole !== options.role;
|
|
6995
|
+
} catch {
|
|
6996
|
+
needsRoleSwitch = true;
|
|
6997
|
+
}
|
|
6998
|
+
}
|
|
6999
|
+
if (needsRoleSwitch && options?.role) {
|
|
7795
7000
|
const safeRole = options.role.replace(/"/g, '""');
|
|
7796
7001
|
return await targetDb.transaction(async (tx) => {
|
|
7797
7002
|
await tx.execute(drizzleOrm.sql.raw(`SET LOCAL ROLE "${safeRole}"`));
|
|
@@ -7829,7 +7034,7 @@
|
|
|
7829
7034
|
return databases;
|
|
7830
7035
|
}
|
|
7831
7036
|
async fetchAvailableRoles() {
|
|
7832
|
-
const result = await this.executeSql("SELECT rolname FROM pg_roles;");
|
|
7037
|
+
const result = await this.executeSql("SELECT rolname FROM pg_roles WHERE pg_has_role(current_user, rolname, 'member') ORDER BY rolname;");
|
|
7833
7038
|
return result.map((r) => r.rolname);
|
|
7834
7039
|
}
|
|
7835
7040
|
async fetchCurrentDatabase() {
|
|
@@ -7998,6 +7203,21 @@
|
|
|
7998
7203
|
* Typed admin capabilities — delegates to the base driver.
|
|
7999
7204
|
*/
|
|
8000
7205
|
admin;
|
|
7206
|
+
get restFetchService() {
|
|
7207
|
+
if (!this.delegate.restFetchService) return void 0;
|
|
7208
|
+
return {
|
|
7209
|
+
fetchCollectionForRest: async (collectionPath, options, include) => {
|
|
7210
|
+
return this.withTransaction(async (delegate) => {
|
|
7211
|
+
return delegate.restFetchService.fetchCollectionForRest(collectionPath, options, include);
|
|
7212
|
+
});
|
|
7213
|
+
},
|
|
7214
|
+
fetchEntityForRest: async (collectionPath, entityId, include, databaseId) => {
|
|
7215
|
+
return this.withTransaction(async (delegate) => {
|
|
7216
|
+
return delegate.restFetchService.fetchEntityForRest(collectionPath, entityId, include, databaseId);
|
|
7217
|
+
});
|
|
7218
|
+
}
|
|
7219
|
+
};
|
|
7220
|
+
}
|
|
8001
7221
|
async withTransaction(operation) {
|
|
8002
7222
|
const pendingNotifications = [];
|
|
8003
7223
|
const result = await this.delegate.db.transaction(async (tx) => {
|
|
@@ -8152,113 +7372,140 @@
|
|
|
8152
7372
|
this.pools.clear();
|
|
8153
7373
|
}
|
|
8154
7374
|
}
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
})
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
})
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
})
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
7375
|
+
function createAuthSchema(rolesSchemaName = "rebase", usersSchemaName = "rebase") {
|
|
7376
|
+
const rolesSchema = rolesSchemaName === "public" ? null : pgCore.pgSchema(rolesSchemaName);
|
|
7377
|
+
const usersSchema2 = usersSchemaName === "public" ? null : pgCore.pgSchema(usersSchemaName);
|
|
7378
|
+
const rolesTableCreator = rolesSchema ? rolesSchema.table.bind(rolesSchema) : pgCore.pgTable;
|
|
7379
|
+
const usersTableCreator = usersSchema2 ? usersSchema2.table.bind(usersSchema2) : pgCore.pgTable;
|
|
7380
|
+
const users2 = usersTableCreator("users", {
|
|
7381
|
+
id: pgCore.uuid("id").defaultRandom().primaryKey(),
|
|
7382
|
+
email: pgCore.varchar("email", {
|
|
7383
|
+
length: 255
|
|
7384
|
+
}).notNull().unique(),
|
|
7385
|
+
passwordHash: pgCore.varchar("password_hash", {
|
|
7386
|
+
length: 255
|
|
7387
|
+
}),
|
|
7388
|
+
// NULL for OAuth-only users
|
|
7389
|
+
displayName: pgCore.varchar("display_name", {
|
|
7390
|
+
length: 255
|
|
7391
|
+
}),
|
|
7392
|
+
photoUrl: pgCore.varchar("photo_url", {
|
|
7393
|
+
length: 500
|
|
7394
|
+
}),
|
|
7395
|
+
emailVerified: pgCore.boolean("email_verified").default(false).notNull(),
|
|
7396
|
+
emailVerificationToken: pgCore.varchar("email_verification_token", {
|
|
7397
|
+
length: 255
|
|
7398
|
+
}),
|
|
7399
|
+
emailVerificationSentAt: pgCore.timestamp("email_verification_sent_at"),
|
|
7400
|
+
metadata: pgCore.jsonb("metadata").$type().default({}).notNull(),
|
|
7401
|
+
createdAt: pgCore.timestamp("created_at").defaultNow().notNull(),
|
|
7402
|
+
updatedAt: pgCore.timestamp("updated_at").defaultNow().notNull()
|
|
7403
|
+
});
|
|
7404
|
+
const roles2 = rolesTableCreator("roles", {
|
|
7405
|
+
id: pgCore.varchar("id", {
|
|
7406
|
+
length: 50
|
|
7407
|
+
}).primaryKey(),
|
|
7408
|
+
// 'admin', 'editor', 'viewer'
|
|
7409
|
+
name: pgCore.varchar("name", {
|
|
7410
|
+
length: 100
|
|
7411
|
+
}).notNull(),
|
|
7412
|
+
isAdmin: pgCore.boolean("is_admin").default(false).notNull(),
|
|
7413
|
+
defaultPermissions: pgCore.jsonb("default_permissions").$type(),
|
|
7414
|
+
collectionPermissions: pgCore.jsonb("collection_permissions").$type(),
|
|
7415
|
+
config: pgCore.jsonb("config").$type()
|
|
7416
|
+
});
|
|
7417
|
+
const userRoles2 = rolesTableCreator("user_roles", {
|
|
7418
|
+
userId: pgCore.uuid("user_id").notNull().references(() => users2.id, {
|
|
7419
|
+
onDelete: "cascade"
|
|
7420
|
+
}),
|
|
7421
|
+
roleId: pgCore.varchar("role_id", {
|
|
7422
|
+
length: 50
|
|
7423
|
+
}).notNull().references(() => roles2.id, {
|
|
7424
|
+
onDelete: "cascade"
|
|
7425
|
+
})
|
|
7426
|
+
}, (table) => ({
|
|
7427
|
+
pk: pgCore.primaryKey({
|
|
7428
|
+
columns: [table.userId, table.roleId]
|
|
7429
|
+
})
|
|
7430
|
+
}));
|
|
7431
|
+
const refreshTokens2 = rolesTableCreator("refresh_tokens", {
|
|
7432
|
+
id: pgCore.uuid("id").defaultRandom().primaryKey(),
|
|
7433
|
+
userId: pgCore.uuid("user_id").notNull().references(() => users2.id, {
|
|
7434
|
+
onDelete: "cascade"
|
|
7435
|
+
}),
|
|
7436
|
+
tokenHash: pgCore.varchar("token_hash", {
|
|
7437
|
+
length: 255
|
|
7438
|
+
}).notNull().unique(),
|
|
7439
|
+
expiresAt: pgCore.timestamp("expires_at").notNull(),
|
|
7440
|
+
userAgent: pgCore.varchar("user_agent", {
|
|
7441
|
+
length: 500
|
|
7442
|
+
}),
|
|
7443
|
+
ipAddress: pgCore.varchar("ip_address", {
|
|
7444
|
+
length: 45
|
|
7445
|
+
}),
|
|
7446
|
+
createdAt: pgCore.timestamp("created_at").defaultNow().notNull()
|
|
7447
|
+
}, (table) => ({
|
|
7448
|
+
uniqueDeviceSession: pgCore.unique("unique_device_session").on(table.userId, table.userAgent, table.ipAddress)
|
|
7449
|
+
}));
|
|
7450
|
+
const passwordResetTokens2 = rolesTableCreator("password_reset_tokens", {
|
|
7451
|
+
id: pgCore.uuid("id").defaultRandom().primaryKey(),
|
|
7452
|
+
userId: pgCore.uuid("user_id").notNull().references(() => users2.id, {
|
|
7453
|
+
onDelete: "cascade"
|
|
7454
|
+
}),
|
|
7455
|
+
tokenHash: pgCore.varchar("token_hash", {
|
|
7456
|
+
length: 255
|
|
7457
|
+
}).notNull().unique(),
|
|
7458
|
+
expiresAt: pgCore.timestamp("expires_at").notNull(),
|
|
7459
|
+
usedAt: pgCore.timestamp("used_at"),
|
|
7460
|
+
createdAt: pgCore.timestamp("created_at").defaultNow().notNull()
|
|
7461
|
+
});
|
|
7462
|
+
const appConfig2 = rolesTableCreator("app_config", {
|
|
7463
|
+
key: pgCore.varchar("key", {
|
|
7464
|
+
length: 100
|
|
7465
|
+
}).primaryKey(),
|
|
7466
|
+
value: pgCore.jsonb("value").notNull(),
|
|
7467
|
+
updatedAt: pgCore.timestamp("updated_at").defaultNow().notNull()
|
|
7468
|
+
});
|
|
7469
|
+
const userIdentities2 = rolesTableCreator("user_identities", {
|
|
7470
|
+
id: pgCore.uuid("id").defaultRandom().primaryKey(),
|
|
7471
|
+
userId: pgCore.uuid("user_id").notNull().references(() => users2.id, {
|
|
7472
|
+
onDelete: "cascade"
|
|
7473
|
+
}),
|
|
7474
|
+
provider: pgCore.varchar("provider", {
|
|
7475
|
+
length: 50
|
|
7476
|
+
}).notNull(),
|
|
7477
|
+
// e.g. 'google', 'linkedin'
|
|
7478
|
+
providerId: pgCore.varchar("provider_id", {
|
|
7479
|
+
length: 255
|
|
7480
|
+
}).notNull(),
|
|
7481
|
+
profileData: pgCore.jsonb("profile_data"),
|
|
7482
|
+
createdAt: pgCore.timestamp("created_at").defaultNow().notNull(),
|
|
7483
|
+
updatedAt: pgCore.timestamp("updated_at").defaultNow().notNull()
|
|
7484
|
+
}, (table) => ({
|
|
7485
|
+
uniqueProviderId: pgCore.unique("unique_provider_id").on(table.provider, table.providerId)
|
|
7486
|
+
}));
|
|
7487
|
+
return {
|
|
7488
|
+
rolesSchema,
|
|
7489
|
+
usersSchema: usersSchema2,
|
|
7490
|
+
users: users2,
|
|
7491
|
+
roles: roles2,
|
|
7492
|
+
userRoles: userRoles2,
|
|
7493
|
+
refreshTokens: refreshTokens2,
|
|
7494
|
+
passwordResetTokens: passwordResetTokens2,
|
|
7495
|
+
appConfig: appConfig2,
|
|
7496
|
+
userIdentities: userIdentities2
|
|
7497
|
+
};
|
|
7498
|
+
}
|
|
7499
|
+
const defaultAuthSchema = createAuthSchema("rebase", "rebase");
|
|
7500
|
+
const rebaseSchema = defaultAuthSchema.rolesSchema;
|
|
7501
|
+
const usersSchema = defaultAuthSchema.usersSchema;
|
|
7502
|
+
const users = defaultAuthSchema.users;
|
|
7503
|
+
const roles = defaultAuthSchema.roles;
|
|
7504
|
+
const userRoles = defaultAuthSchema.userRoles;
|
|
7505
|
+
const refreshTokens = defaultAuthSchema.refreshTokens;
|
|
7506
|
+
const passwordResetTokens = defaultAuthSchema.passwordResetTokens;
|
|
7507
|
+
const appConfig = defaultAuthSchema.appConfig;
|
|
7508
|
+
const userIdentities = defaultAuthSchema.userIdentities;
|
|
8262
7509
|
const usersRelations = drizzleOrm.relations(users, ({
|
|
8263
7510
|
many
|
|
8264
7511
|
}) => ({
|
|
@@ -8441,6 +7688,15 @@
|
|
|
8441
7688
|
}
|
|
8442
7689
|
break;
|
|
8443
7690
|
}
|
|
7691
|
+
case "vector": {
|
|
7692
|
+
const vp = prop;
|
|
7693
|
+
columnDefinition = `vector("${colName}", { dimensions: ${vp.dimensions} })`;
|
|
7694
|
+
break;
|
|
7695
|
+
}
|
|
7696
|
+
case "binary": {
|
|
7697
|
+
columnDefinition = `customType({ dataType() { return 'bytea'; } })("${colName}")`;
|
|
7698
|
+
break;
|
|
7699
|
+
}
|
|
8444
7700
|
case "relation": {
|
|
8445
7701
|
const refProp = prop;
|
|
8446
7702
|
const resolvedRelations = resolveCollectionRelations(collection);
|
|
@@ -8507,7 +7763,7 @@
|
|
|
8507
7763
|
return ` ${propName}: ${columnDefinition}`;
|
|
8508
7764
|
};
|
|
8509
7765
|
const resolveRawSql = (expression) => {
|
|
8510
|
-
const resolved = expression.replace(/\{(\w+)\}/g, (_, col) =>
|
|
7766
|
+
const resolved = expression.replace(/\{(\w+)\}/g, (_, col) => col);
|
|
8511
7767
|
return `sql\`${resolved}\``;
|
|
8512
7768
|
};
|
|
8513
7769
|
const wrapWithRoleCheck = (clause, roles2) => {
|
|
@@ -8519,7 +7775,7 @@
|
|
|
8519
7775
|
const match = sqlExpr.match(/^sql`(.*)`$/s);
|
|
8520
7776
|
return match ? match[1] : sqlExpr;
|
|
8521
7777
|
};
|
|
8522
|
-
const buildUsingClause = (rule) => {
|
|
7778
|
+
const buildUsingClause = (rule, collection) => {
|
|
8523
7779
|
if (rule.using) {
|
|
8524
7780
|
return resolveRawSql(rule.using);
|
|
8525
7781
|
}
|
|
@@ -8527,15 +7783,17 @@
|
|
|
8527
7783
|
return "sql`true`";
|
|
8528
7784
|
}
|
|
8529
7785
|
if (rule.ownerField) {
|
|
8530
|
-
|
|
7786
|
+
const prop = collection.properties?.[rule.ownerField];
|
|
7787
|
+
const colName = resolveColumnName(rule.ownerField, prop);
|
|
7788
|
+
return `sql\`${colName} = auth.uid()\``;
|
|
8531
7789
|
}
|
|
8532
7790
|
return null;
|
|
8533
7791
|
};
|
|
8534
|
-
const buildWithCheckClause = (rule) => {
|
|
7792
|
+
const buildWithCheckClause = (rule, collection) => {
|
|
8535
7793
|
if (rule.withCheck) {
|
|
8536
7794
|
return resolveRawSql(rule.withCheck);
|
|
8537
7795
|
}
|
|
8538
|
-
return buildUsingClause(rule);
|
|
7796
|
+
return buildUsingClause(rule, collection);
|
|
8539
7797
|
};
|
|
8540
7798
|
const getPolicyNameHash = (rule) => {
|
|
8541
7799
|
const data = JSON.stringify({
|
|
@@ -8551,21 +7809,22 @@
|
|
|
8551
7809
|
});
|
|
8552
7810
|
return crypto.createHash("sha1").update(data).digest("hex").substring(0, 7);
|
|
8553
7811
|
};
|
|
8554
|
-
const generatePolicyCode = (
|
|
7812
|
+
const generatePolicyCode = (collection, rule, index) => {
|
|
7813
|
+
const tableName = getTableName(collection);
|
|
8555
7814
|
const ops = rule.operations && rule.operations.length > 0 ? rule.operations : [rule.operation ?? "all"];
|
|
8556
7815
|
const ruleHash = getPolicyNameHash(rule);
|
|
8557
7816
|
return ops.map((op, opIdx) => {
|
|
8558
7817
|
const policyName = rule.name ? ops.length > 1 ? `${rule.name}_${op}` : rule.name : `${tableName}_${op}_${ruleHash}${ops.length > 1 ? `_${opIdx}` : ""}`;
|
|
8559
|
-
return generateSinglePolicyCode(
|
|
7818
|
+
return generateSinglePolicyCode(collection, rule, op, policyName);
|
|
8560
7819
|
}).join("");
|
|
8561
7820
|
};
|
|
8562
|
-
const generateSinglePolicyCode = (
|
|
7821
|
+
const generateSinglePolicyCode = (collection, rule, operation, policyName) => {
|
|
8563
7822
|
const mode = rule.mode ?? "permissive";
|
|
8564
7823
|
const roles2 = rule.roles ? [...rule.roles].sort() : void 0;
|
|
8565
7824
|
const needsUsing = operation !== "insert";
|
|
8566
7825
|
const needsWithCheck = operation !== "select" && operation !== "delete";
|
|
8567
|
-
let usingClause = needsUsing ? buildUsingClause(rule) : null;
|
|
8568
|
-
let withCheckClause = needsWithCheck ? buildWithCheckClause(rule) : null;
|
|
7826
|
+
let usingClause = needsUsing ? buildUsingClause(rule, collection) : null;
|
|
7827
|
+
let withCheckClause = needsWithCheck ? buildWithCheckClause(rule, collection) : null;
|
|
8569
7828
|
if (roles2 && roles2.length > 0) {
|
|
8570
7829
|
if (usingClause) {
|
|
8571
7830
|
usingClause = wrapWithRoleCheck(usingClause, roles2);
|
|
@@ -8634,12 +7893,26 @@
|
|
|
8634
7893
|
const generateSchema = async (collections, stripPolicies = false) => {
|
|
8635
7894
|
let schemaContent = "// This file is auto-generated by the Rebase Drizzle generator. Do not edit manually.\n\n";
|
|
8636
7895
|
const hasUuid = collections.some((c) => c.properties && Object.values(c.properties).some((p) => p.type === "string" && (p.autoValue === "uuid" || p.isId === "uuid")));
|
|
8637
|
-
collections.some((c) => c.properties && Object.values(c.properties).some((p) =>
|
|
7896
|
+
const hasVector = collections.some((c) => c.properties && Object.values(c.properties).some((p) => p.type === "vector"));
|
|
7897
|
+
const hasBinary = collections.some((c) => c.properties && Object.values(c.properties).some((p) => p.type === "binary"));
|
|
8638
7898
|
const pgCoreImports = ["primaryKey", "pgTable", "integer", "varchar", "text", "char", "boolean", "timestamp", "date", "time", "jsonb", "json", "pgEnum", "numeric", "real", "doublePrecision", "bigint", "serial", "bigserial", "pgPolicy"];
|
|
8639
7899
|
if (hasUuid) pgCoreImports.push("uuid");
|
|
7900
|
+
if (hasVector) pgCoreImports.push("vector");
|
|
7901
|
+
if (hasBinary) pgCoreImports.push("customType");
|
|
7902
|
+
const uniqueSchemas = Array.from(new Set(collections.map((c) => isPostgresCollection(c) ? c.schema : void 0).filter(Boolean)));
|
|
7903
|
+
if (uniqueSchemas.length > 0) {
|
|
7904
|
+
pgCoreImports.push("pgSchema");
|
|
7905
|
+
}
|
|
8640
7906
|
schemaContent += `import { ${pgCoreImports.join(", ")} } from 'drizzle-orm/pg-core';
|
|
8641
7907
|
`;
|
|
8642
7908
|
schemaContent += "import { relations as drizzleRelations, sql } from 'drizzle-orm';\n\n";
|
|
7909
|
+
uniqueSchemas.forEach((schema) => {
|
|
7910
|
+
schemaContent += `export const ${schema}Schema = pgSchema("${schema}");
|
|
7911
|
+
`;
|
|
7912
|
+
});
|
|
7913
|
+
if (uniqueSchemas.length > 0) {
|
|
7914
|
+
schemaContent += "\n";
|
|
7915
|
+
}
|
|
8643
7916
|
const exportedTableVars = [];
|
|
8644
7917
|
const exportedEnumVars = [];
|
|
8645
7918
|
const exportedRelationVars = [];
|
|
@@ -8694,6 +7967,9 @@
|
|
|
8694
7967
|
const tableVarName = getTableVarName(tableName);
|
|
8695
7968
|
if (isJunction && relation && sourceCollection && relation.through) {
|
|
8696
7969
|
const targetCollection = relation.target();
|
|
7970
|
+
const schema = (isPostgresCollection(targetCollection) ? targetCollection.schema : void 0) || (isPostgresCollection(sourceCollection) ? sourceCollection.schema : void 0);
|
|
7971
|
+
const tableCreator = schema ? `${schema}Schema.table` : "pgTable";
|
|
7972
|
+
const baseTableName = tableName.includes(".") ? tableName.split(".").pop() : tableName;
|
|
8697
7973
|
const {
|
|
8698
7974
|
sourceColumn,
|
|
8699
7975
|
targetColumn
|
|
@@ -8704,7 +7980,7 @@
|
|
|
8704
7980
|
const targetColType = isNumericId(targetCollection) ? "integer" : getPrimaryKeyProp(targetCollection).isUuid ? "uuid" : "varchar";
|
|
8705
7981
|
const sourceId = getPrimaryKeyName(sourceCollection);
|
|
8706
7982
|
const targetId = getPrimaryKeyName(targetCollection);
|
|
8707
|
-
schemaContent += `export const ${tableVarName} =
|
|
7983
|
+
schemaContent += `export const ${tableVarName} = ${tableCreator}("${baseTableName}", {
|
|
8708
7984
|
`;
|
|
8709
7985
|
schemaContent += ` ${sourceColumn}: ${sourceColType}("${sourceColumn}").notNull().references(() => ${getTableVarName(getTableName(sourceCollection))}.${sourceId}, ${refOptions}),
|
|
8710
7986
|
`;
|
|
@@ -8715,7 +7991,10 @@
|
|
|
8715
7991
|
`;
|
|
8716
7992
|
schemaContent += "}));\n\n";
|
|
8717
7993
|
} else if (!isJunction) {
|
|
8718
|
-
|
|
7994
|
+
const schema = isPostgresCollection(collection) ? collection.schema : void 0;
|
|
7995
|
+
const tableCreator = schema ? `${schema}Schema.table` : "pgTable";
|
|
7996
|
+
const baseTableName = tableName.includes(".") ? tableName.split(".").pop() : tableName;
|
|
7997
|
+
schemaContent += `export const ${tableVarName} = ${tableCreator}("${baseTableName}", {
|
|
8719
7998
|
`;
|
|
8720
7999
|
const columns = /* @__PURE__ */ new Set();
|
|
8721
8000
|
Object.entries(collection.properties ?? {}).forEach(([propName, prop]) => {
|
|
@@ -8731,7 +8010,7 @@
|
|
|
8731
8010
|
if (!stripPolicies && securityRules && securityRules.length > 0) {
|
|
8732
8011
|
schemaContent += "\n}, (table) => ([\n";
|
|
8733
8012
|
securityRules.forEach((rule, idx) => {
|
|
8734
|
-
schemaContent += generatePolicyCode(
|
|
8013
|
+
schemaContent += generatePolicyCode(collection, rule);
|
|
8735
8014
|
});
|
|
8736
8015
|
schemaContent += "])).enableRLS();\n\n";
|
|
8737
8016
|
} else {
|
|
@@ -8776,11 +8055,11 @@
|
|
|
8776
8055
|
references: [${sourceTableVar}.${sourceId}],
|
|
8777
8056
|
relationName: "${owningRelationName}"
|
|
8778
8057
|
})`);
|
|
8779
|
-
const
|
|
8058
|
+
const targetRelationName = inverseRelationName ? inverseRelationName : `${tableName}_${relation.through.targetColumn}`;
|
|
8780
8059
|
tableRelations.push(` "${relation.through.targetColumn}": one(${targetTableVar}, {
|
|
8781
8060
|
fields: [${tableVarName}.${relation.through.targetColumn}],
|
|
8782
8061
|
references: [${targetTableVar}.${targetId}],
|
|
8783
|
-
relationName: "${
|
|
8062
|
+
relationName: "${targetRelationName}"
|
|
8784
8063
|
})`);
|
|
8785
8064
|
}
|
|
8786
8065
|
} else {
|
|
@@ -8879,6 +8158,89 @@ ${tableRelations.join(",\n")}
|
|
|
8879
8158
|
schemaContent += tablesExport + enumsExport + relationsExport;
|
|
8880
8159
|
return schemaContent;
|
|
8881
8160
|
};
|
|
8161
|
+
const defaultUsersCollection = {
|
|
8162
|
+
name: "Users",
|
|
8163
|
+
singularName: "User",
|
|
8164
|
+
slug: "users",
|
|
8165
|
+
table: "users",
|
|
8166
|
+
icon: "Users",
|
|
8167
|
+
group: "Settings",
|
|
8168
|
+
properties: {
|
|
8169
|
+
id: {
|
|
8170
|
+
name: "ID",
|
|
8171
|
+
type: "string",
|
|
8172
|
+
isId: "uuid"
|
|
8173
|
+
},
|
|
8174
|
+
email: {
|
|
8175
|
+
name: "Email",
|
|
8176
|
+
type: "string",
|
|
8177
|
+
validation: {
|
|
8178
|
+
required: true,
|
|
8179
|
+
unique: true
|
|
8180
|
+
}
|
|
8181
|
+
},
|
|
8182
|
+
password_hash: {
|
|
8183
|
+
name: "Password Hash",
|
|
8184
|
+
type: "string",
|
|
8185
|
+
ui: {
|
|
8186
|
+
hideFromCollection: true
|
|
8187
|
+
}
|
|
8188
|
+
},
|
|
8189
|
+
display_name: {
|
|
8190
|
+
name: "Display Name",
|
|
8191
|
+
type: "string"
|
|
8192
|
+
},
|
|
8193
|
+
photo_url: {
|
|
8194
|
+
name: "Photo URL",
|
|
8195
|
+
type: "string"
|
|
8196
|
+
},
|
|
8197
|
+
email_verified: {
|
|
8198
|
+
name: "Email Verified",
|
|
8199
|
+
type: "boolean",
|
|
8200
|
+
defaultValue: false
|
|
8201
|
+
},
|
|
8202
|
+
email_verification_token: {
|
|
8203
|
+
name: "Email Verification Token",
|
|
8204
|
+
type: "string",
|
|
8205
|
+
ui: {
|
|
8206
|
+
hideFromCollection: true
|
|
8207
|
+
}
|
|
8208
|
+
},
|
|
8209
|
+
email_verification_sent_at: {
|
|
8210
|
+
name: "Email Verification Sent At",
|
|
8211
|
+
type: "date",
|
|
8212
|
+
ui: {
|
|
8213
|
+
hideFromCollection: true
|
|
8214
|
+
}
|
|
8215
|
+
},
|
|
8216
|
+
metadata: {
|
|
8217
|
+
name: "Metadata",
|
|
8218
|
+
type: "map",
|
|
8219
|
+
defaultValue: {},
|
|
8220
|
+
ui: {
|
|
8221
|
+
hideFromCollection: true
|
|
8222
|
+
}
|
|
8223
|
+
},
|
|
8224
|
+
created_at: {
|
|
8225
|
+
name: "Created At",
|
|
8226
|
+
type: "date",
|
|
8227
|
+
autoValue: "on_create",
|
|
8228
|
+
ui: {
|
|
8229
|
+
readOnly: true,
|
|
8230
|
+
hideFromCollection: true
|
|
8231
|
+
}
|
|
8232
|
+
},
|
|
8233
|
+
updated_at: {
|
|
8234
|
+
name: "Updated At",
|
|
8235
|
+
type: "date",
|
|
8236
|
+
autoValue: "on_update",
|
|
8237
|
+
ui: {
|
|
8238
|
+
readOnly: true,
|
|
8239
|
+
hideFromCollection: true
|
|
8240
|
+
}
|
|
8241
|
+
}
|
|
8242
|
+
}
|
|
8243
|
+
};
|
|
8882
8244
|
const formatTerminalText = (text, options = {}) => {
|
|
8883
8245
|
let codes = "";
|
|
8884
8246
|
if (options.bold) codes += "\x1B[1m";
|
|
@@ -8941,10 +8303,14 @@ ${tableRelations.join(",\n")}
|
|
|
8941
8303
|
const imported = await dynamicImport(fileUrl);
|
|
8942
8304
|
collections = imported.backendCollections || imported.collections;
|
|
8943
8305
|
}
|
|
8944
|
-
if (!collections || !Array.isArray(collections)
|
|
8945
|
-
|
|
8946
|
-
return;
|
|
8306
|
+
if (!collections || !Array.isArray(collections)) {
|
|
8307
|
+
collections = [];
|
|
8947
8308
|
}
|
|
8309
|
+
const hasUsersCollection = collections.some((c) => c.slug === "users");
|
|
8310
|
+
if (!hasUsersCollection) {
|
|
8311
|
+
collections.push(defaultUsersCollection);
|
|
8312
|
+
}
|
|
8313
|
+
collections.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
8948
8314
|
const schemaContent = await generateSchema(collections);
|
|
8949
8315
|
if (outputPath) {
|
|
8950
8316
|
const outputDir = path.dirname(outputPath);
|
|
@@ -9172,29 +8538,14 @@ ${tableRelations.join(",\n")}
|
|
|
9172
8538
|
},
|
|
9173
8539
|
authContext
|
|
9174
8540
|
});
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
limit: request.limit,
|
|
9184
|
-
startAfter: request.startAfter,
|
|
9185
|
-
searchString: request.searchString
|
|
9186
|
-
});
|
|
9187
|
-
} else {
|
|
9188
|
-
entities = await this.entityService.fetchCollection(request.path, {
|
|
9189
|
-
filter: request.filter,
|
|
9190
|
-
orderBy: request.orderBy,
|
|
9191
|
-
order: request.order,
|
|
9192
|
-
limit: request.limit,
|
|
9193
|
-
startAfter: request.startAfter,
|
|
9194
|
-
databaseId: request.collection?.databaseId,
|
|
9195
|
-
searchString: request.searchString
|
|
9196
|
-
});
|
|
9197
|
-
}
|
|
8541
|
+
const entities = await this.fetchCollectionWithAuth(request.path, {
|
|
8542
|
+
filter: request.filter,
|
|
8543
|
+
orderBy: request.orderBy,
|
|
8544
|
+
order: request.order,
|
|
8545
|
+
limit: request.limit,
|
|
8546
|
+
startAfter: request.startAfter,
|
|
8547
|
+
searchString: request.searchString
|
|
8548
|
+
}, authContext);
|
|
9198
8549
|
this.sendCollectionUpdate(clientId, subscriptionId, entities);
|
|
9199
8550
|
} catch (error) {
|
|
9200
8551
|
this.sendError(clientId, `Failed to subscribe to collection: ${error}`, subscriptionId);
|
|
@@ -9218,16 +8569,7 @@ ${tableRelations.join(",\n")}
|
|
|
9218
8569
|
entityId: request.entityId,
|
|
9219
8570
|
authContext
|
|
9220
8571
|
});
|
|
9221
|
-
|
|
9222
|
-
if (this.driver) {
|
|
9223
|
-
entity = await this.driver.fetchEntity({
|
|
9224
|
-
path: request.path,
|
|
9225
|
-
entityId: request.entityId,
|
|
9226
|
-
collection
|
|
9227
|
-
});
|
|
9228
|
-
} else {
|
|
9229
|
-
entity = await this.entityService.fetchEntity(request.path, request.entityId, request.collection?.databaseId);
|
|
9230
|
-
}
|
|
8572
|
+
const entity = await this.fetchEntityWithAuth(request.path, String(request.entityId), authContext);
|
|
9231
8573
|
this.sendEntityUpdate(clientId, subscriptionId, entity || null);
|
|
9232
8574
|
} catch (error) {
|
|
9233
8575
|
this.sendError(clientId, `Failed to subscribe to entity: ${request.path} ${request.entityId} ${error}`, subscriptionId);
|
|
@@ -9372,87 +8714,77 @@ ${tableRelations.join(",\n")}
|
|
|
9372
8714
|
async fetchCollectionWithAuth(notifyPath, collectionRequest, authContext) {
|
|
9373
8715
|
if (this.driver) {
|
|
9374
8716
|
const collection = this.registry.getCollectionByPath(notifyPath);
|
|
9375
|
-
const
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
8717
|
+
const activeAuth = authContext || {
|
|
8718
|
+
userId: "anon",
|
|
8719
|
+
roles: ["anon"]
|
|
8720
|
+
};
|
|
8721
|
+
return await this.db.transaction(async (tx) => {
|
|
8722
|
+
await tx.execute(drizzleOrm.sql`SELECT set_config('app.user_id', ${activeAuth.userId}, true)`);
|
|
8723
|
+
await tx.execute(drizzleOrm.sql`SELECT set_config('app.user_roles', ${activeAuth.roles.join(",")}, true)`);
|
|
8724
|
+
await tx.execute(drizzleOrm.sql`SELECT set_config('app.jwt', ${JSON.stringify({
|
|
8725
|
+
sub: activeAuth.userId,
|
|
8726
|
+
roles: activeAuth.roles
|
|
8727
|
+
})}, true)`);
|
|
8728
|
+
const txEntityService = new EntityService(tx, this.registry);
|
|
8729
|
+
let fetchedEntities;
|
|
8730
|
+
if (collectionRequest.searchString) {
|
|
8731
|
+
fetchedEntities = await txEntityService.searchEntities(notifyPath, collectionRequest.searchString, {
|
|
8732
|
+
filter: collectionRequest.filter,
|
|
8733
|
+
orderBy: collectionRequest.orderBy,
|
|
8734
|
+
order: collectionRequest.order,
|
|
8735
|
+
limit: collectionRequest.limit,
|
|
8736
|
+
databaseId: collectionRequest.databaseId
|
|
8737
|
+
});
|
|
8738
|
+
} else {
|
|
8739
|
+
fetchedEntities = await txEntityService.fetchCollection(notifyPath, {
|
|
8740
|
+
filter: collectionRequest.filter,
|
|
8741
|
+
orderBy: collectionRequest.orderBy,
|
|
8742
|
+
order: collectionRequest.order,
|
|
8743
|
+
limit: collectionRequest.limit,
|
|
8744
|
+
offset: collectionRequest.offset,
|
|
8745
|
+
startAfter: collectionRequest.startAfter,
|
|
8746
|
+
databaseId: collectionRequest.databaseId
|
|
8747
|
+
});
|
|
8748
|
+
}
|
|
8749
|
+
const registryCollection = this.registry.getCollectionByPath(notifyPath);
|
|
8750
|
+
const resolvedCollection = collection ? {
|
|
8751
|
+
...collection,
|
|
8752
|
+
...registryCollection
|
|
8753
|
+
} : registryCollection;
|
|
8754
|
+
const callbacks = resolvedCollection?.callbacks;
|
|
8755
|
+
const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
|
|
8756
|
+
if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
|
|
8757
|
+
const contextForCallback = {
|
|
8758
|
+
user: {
|
|
8759
|
+
uid: activeAuth.userId,
|
|
8760
|
+
roles: activeAuth.roles
|
|
8761
|
+
},
|
|
8762
|
+
driver: this.driver,
|
|
8763
|
+
data: this.driver && "data" in this.driver ? this.driver.data : void 0
|
|
8764
|
+
};
|
|
8765
|
+
return await Promise.all(fetchedEntities.map(async (entity) => {
|
|
8766
|
+
let processedEntity = entity;
|
|
8767
|
+
if (callbacks?.afterRead) {
|
|
8768
|
+
processedEntity = await callbacks.afterRead({
|
|
8769
|
+
collection: resolvedCollection,
|
|
8770
|
+
path: notifyPath,
|
|
8771
|
+
entity: processedEntity,
|
|
8772
|
+
context: contextForCallback
|
|
8773
|
+
}) ?? processedEntity;
|
|
8774
|
+
}
|
|
8775
|
+
if (propertyCallbacks?.afterRead) {
|
|
8776
|
+
processedEntity = await propertyCallbacks.afterRead({
|
|
8777
|
+
collection: resolvedCollection,
|
|
8778
|
+
path: notifyPath,
|
|
8779
|
+
entity: processedEntity,
|
|
8780
|
+
context: contextForCallback
|
|
8781
|
+
}) ?? processedEntity;
|
|
8782
|
+
}
|
|
8783
|
+
return processedEntity;
|
|
8784
|
+
}));
|
|
8785
|
+
}
|
|
8786
|
+
return fetchedEntities;
|
|
9385
8787
|
});
|
|
9386
|
-
if (authContext) {
|
|
9387
|
-
return await this.db.transaction(async (tx) => {
|
|
9388
|
-
await tx.execute(drizzleOrm.sql`SELECT set_config('app.user_id', ${authContext.userId}, true)`);
|
|
9389
|
-
await tx.execute(drizzleOrm.sql`SELECT set_config('app.user_roles', ${authContext.roles.join(",")}, true)`);
|
|
9390
|
-
await tx.execute(drizzleOrm.sql`SELECT set_config('app.jwt', ${JSON.stringify({
|
|
9391
|
-
sub: authContext.userId,
|
|
9392
|
-
roles: authContext.roles
|
|
9393
|
-
})}, true)`);
|
|
9394
|
-
const txEntityService = new EntityService(tx, this.registry);
|
|
9395
|
-
let fetchedEntities;
|
|
9396
|
-
if (collectionRequest.searchString) {
|
|
9397
|
-
fetchedEntities = await txEntityService.searchEntities(notifyPath, collectionRequest.searchString, {
|
|
9398
|
-
filter: collectionRequest.filter,
|
|
9399
|
-
orderBy: collectionRequest.orderBy,
|
|
9400
|
-
order: collectionRequest.order,
|
|
9401
|
-
limit: collectionRequest.limit,
|
|
9402
|
-
databaseId: collectionRequest.databaseId
|
|
9403
|
-
});
|
|
9404
|
-
} else {
|
|
9405
|
-
fetchedEntities = await txEntityService.fetchCollection(notifyPath, {
|
|
9406
|
-
filter: collectionRequest.filter,
|
|
9407
|
-
orderBy: collectionRequest.orderBy,
|
|
9408
|
-
order: collectionRequest.order,
|
|
9409
|
-
limit: collectionRequest.limit,
|
|
9410
|
-
offset: collectionRequest.offset,
|
|
9411
|
-
startAfter: collectionRequest.startAfter,
|
|
9412
|
-
databaseId: collectionRequest.databaseId
|
|
9413
|
-
});
|
|
9414
|
-
}
|
|
9415
|
-
const registryCollection = this.registry.getCollectionByPath(notifyPath);
|
|
9416
|
-
const resolvedCollection = collection ? {
|
|
9417
|
-
...collection,
|
|
9418
|
-
...registryCollection
|
|
9419
|
-
} : registryCollection;
|
|
9420
|
-
const callbacks = resolvedCollection?.callbacks;
|
|
9421
|
-
const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
|
|
9422
|
-
if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
|
|
9423
|
-
const contextForCallback = {
|
|
9424
|
-
user: {
|
|
9425
|
-
uid: authContext.userId,
|
|
9426
|
-
roles: authContext.roles
|
|
9427
|
-
},
|
|
9428
|
-
driver: this.driver,
|
|
9429
|
-
data: this.driver ? this.driver.data : void 0
|
|
9430
|
-
};
|
|
9431
|
-
return await Promise.all(fetchedEntities.map(async (entity) => {
|
|
9432
|
-
let processedEntity = entity;
|
|
9433
|
-
if (callbacks?.afterRead) {
|
|
9434
|
-
processedEntity = await callbacks.afterRead({
|
|
9435
|
-
collection: resolvedCollection,
|
|
9436
|
-
path: notifyPath,
|
|
9437
|
-
entity: processedEntity,
|
|
9438
|
-
context: contextForCallback
|
|
9439
|
-
}) ?? processedEntity;
|
|
9440
|
-
}
|
|
9441
|
-
if (propertyCallbacks?.afterRead) {
|
|
9442
|
-
processedEntity = await propertyCallbacks.afterRead({
|
|
9443
|
-
collection: resolvedCollection,
|
|
9444
|
-
path: notifyPath,
|
|
9445
|
-
entity: processedEntity,
|
|
9446
|
-
context: contextForCallback
|
|
9447
|
-
}) ?? processedEntity;
|
|
9448
|
-
}
|
|
9449
|
-
return processedEntity;
|
|
9450
|
-
}));
|
|
9451
|
-
}
|
|
9452
|
-
return fetchedEntities;
|
|
9453
|
-
});
|
|
9454
|
-
}
|
|
9455
|
-
return fetchFn();
|
|
9456
8788
|
}
|
|
9457
8789
|
if (collectionRequest.searchString) {
|
|
9458
8790
|
return await this.entityService.searchEntities(notifyPath, collectionRequest.searchString, {
|
|
@@ -9516,60 +8848,56 @@ ${tableRelations.join(",\n")}
|
|
|
9516
8848
|
async fetchEntityWithAuth(notifyPath, entityId, authContext) {
|
|
9517
8849
|
if (this.driver) {
|
|
9518
8850
|
const collection = this.registry.getCollectionByPath(notifyPath);
|
|
9519
|
-
const
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
const
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
context: contextForCallback
|
|
9565
|
-
}) ?? processedEntity;
|
|
9566
|
-
}
|
|
8851
|
+
const activeAuth = authContext || {
|
|
8852
|
+
userId: "anon",
|
|
8853
|
+
roles: ["anon"]
|
|
8854
|
+
};
|
|
8855
|
+
return await this.db.transaction(async (tx) => {
|
|
8856
|
+
await tx.execute(drizzleOrm.sql`SELECT set_config('app.user_id', ${activeAuth.userId}, true)`);
|
|
8857
|
+
await tx.execute(drizzleOrm.sql`SELECT set_config('app.user_roles', ${activeAuth.roles.join(",")}, true)`);
|
|
8858
|
+
await tx.execute(drizzleOrm.sql`SELECT set_config('app.jwt', ${JSON.stringify({
|
|
8859
|
+
sub: activeAuth.userId,
|
|
8860
|
+
roles: activeAuth.roles
|
|
8861
|
+
})}, true)`);
|
|
8862
|
+
const txEntityService = new EntityService(tx, this.registry);
|
|
8863
|
+
let processedEntity = await txEntityService.fetchEntity(notifyPath, entityId, collection?.databaseId);
|
|
8864
|
+
if (processedEntity) {
|
|
8865
|
+
const registryCollection = this.registry.getCollectionByPath(notifyPath);
|
|
8866
|
+
const resolvedCollection = collection ? {
|
|
8867
|
+
...collection,
|
|
8868
|
+
...registryCollection
|
|
8869
|
+
} : registryCollection;
|
|
8870
|
+
const callbacks = resolvedCollection?.callbacks;
|
|
8871
|
+
const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
|
|
8872
|
+
if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
|
|
8873
|
+
const contextForCallback = {
|
|
8874
|
+
user: {
|
|
8875
|
+
uid: activeAuth.userId,
|
|
8876
|
+
roles: activeAuth.roles
|
|
8877
|
+
},
|
|
8878
|
+
driver: this.driver,
|
|
8879
|
+
data: this.driver && "data" in this.driver ? this.driver.data : void 0
|
|
8880
|
+
};
|
|
8881
|
+
if (callbacks?.afterRead) {
|
|
8882
|
+
processedEntity = await callbacks.afterRead({
|
|
8883
|
+
collection: resolvedCollection,
|
|
8884
|
+
path: notifyPath,
|
|
8885
|
+
entity: processedEntity,
|
|
8886
|
+
context: contextForCallback
|
|
8887
|
+
}) ?? processedEntity;
|
|
8888
|
+
}
|
|
8889
|
+
if (propertyCallbacks?.afterRead) {
|
|
8890
|
+
processedEntity = await propertyCallbacks.afterRead({
|
|
8891
|
+
collection: resolvedCollection,
|
|
8892
|
+
path: notifyPath,
|
|
8893
|
+
entity: processedEntity,
|
|
8894
|
+
context: contextForCallback
|
|
8895
|
+
}) ?? processedEntity;
|
|
9567
8896
|
}
|
|
9568
8897
|
}
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
}
|
|
9572
|
-
return fetchFn();
|
|
8898
|
+
}
|
|
8899
|
+
return processedEntity;
|
|
8900
|
+
});
|
|
9573
8901
|
}
|
|
9574
8902
|
return await this.entityService.fetchEntity(notifyPath, entityId);
|
|
9575
8903
|
}
|
|
@@ -9637,6 +8965,31 @@ ${tableRelations.join(",\n")}
|
|
|
9637
8965
|
return parentPaths;
|
|
9638
8966
|
}
|
|
9639
8967
|
// =============================================================================
|
|
8968
|
+
// Lifecycle / Cleanup
|
|
8969
|
+
// =============================================================================
|
|
8970
|
+
/**
|
|
8971
|
+
* Gracefully tear down all realtime resources.
|
|
8972
|
+
*
|
|
8973
|
+
* This MUST be called during process shutdown, **before** `pool.end()`.
|
|
8974
|
+
* It ensures:
|
|
8975
|
+
* 1. All debounced refetch timers are cancelled (prevents queries after pool closes).
|
|
8976
|
+
* 2. All subscription state and callbacks are cleared.
|
|
8977
|
+
* 3. The dedicated LISTEN client (outside the pool) is disconnected.
|
|
8978
|
+
* 4. All WebSocket clients are removed (but not forcefully closed — the
|
|
8979
|
+
* HTTP server close will handle that).
|
|
8980
|
+
*/
|
|
8981
|
+
async destroy() {
|
|
8982
|
+
for (const [key, timer] of this.refetchTimers) {
|
|
8983
|
+
clearTimeout(timer);
|
|
8984
|
+
this.refetchTimers.delete(key);
|
|
8985
|
+
}
|
|
8986
|
+
this._subscriptions.clear();
|
|
8987
|
+
this.subscriptionCallbacks.clear();
|
|
8988
|
+
await this.stopListening();
|
|
8989
|
+
this.clients.clear();
|
|
8990
|
+
this.debugLog("🧹 [RealtimeService] destroy() complete — all resources released.");
|
|
8991
|
+
}
|
|
8992
|
+
// =============================================================================
|
|
9640
8993
|
// Cross-Instance LISTEN/NOTIFY
|
|
9641
8994
|
// =============================================================================
|
|
9642
8995
|
/**
|
|
@@ -9777,8 +9130,23 @@ ${tableRelations.join(",\n")}
|
|
|
9777
9130
|
const WS_RATE_LIMIT = 2e3;
|
|
9778
9131
|
const WS_RATE_WINDOW_MS = 6e4;
|
|
9779
9132
|
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"]);
|
|
9133
|
+
function extractErrorMessage(error) {
|
|
9134
|
+
if (!error) return "Unknown error";
|
|
9135
|
+
if (typeof error === "object") {
|
|
9136
|
+
const err = error;
|
|
9137
|
+
if (err.cause) {
|
|
9138
|
+
return extractErrorMessage(err.cause);
|
|
9139
|
+
}
|
|
9140
|
+
if (typeof err.message === "string") {
|
|
9141
|
+
return err.message;
|
|
9142
|
+
}
|
|
9143
|
+
}
|
|
9144
|
+
return String(error);
|
|
9145
|
+
}
|
|
9780
9146
|
function isAdminSession(session) {
|
|
9781
|
-
if (!session?.user
|
|
9147
|
+
if (!session?.user) return false;
|
|
9148
|
+
if (session.user.isAdmin) return true;
|
|
9149
|
+
if (!session.user.roles) return false;
|
|
9782
9150
|
return session.user.roles.some((r) => {
|
|
9783
9151
|
if (typeof r === "string") return r === "admin";
|
|
9784
9152
|
if (r && typeof r === "object" && "isAdmin" in r) return r.isAdmin;
|
|
@@ -9786,7 +9154,7 @@ ${tableRelations.join(",\n")}
|
|
|
9786
9154
|
return false;
|
|
9787
9155
|
});
|
|
9788
9156
|
}
|
|
9789
|
-
function createPostgresWebSocket(server, realtimeService, driver, authConfig) {
|
|
9157
|
+
function createPostgresWebSocket(server, realtimeService, driver, authConfig, authAdapter) {
|
|
9790
9158
|
const isProduction = process.env.NODE_ENV === "production";
|
|
9791
9159
|
const wsDebug = (...args) => {
|
|
9792
9160
|
if (!isProduction) console.debug(...args);
|
|
@@ -9800,7 +9168,7 @@ ${tableRelations.join(",\n")}
|
|
|
9800
9168
|
}
|
|
9801
9169
|
console.error("❌ [WebSocket Server] Error:", err);
|
|
9802
9170
|
});
|
|
9803
|
-
const requireAuth = authConfig?.requireAuth !== false && authConfig?.jwtSecret;
|
|
9171
|
+
const requireAuth = authAdapter ? true : authConfig?.requireAuth !== false && !!authConfig?.jwtSecret;
|
|
9804
9172
|
wss.on("connection", (ws2) => {
|
|
9805
9173
|
const clientId = `client_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
9806
9174
|
wsDebug(`WebSocket client connected: ${clientId}`);
|
|
@@ -9845,11 +9213,37 @@ ${tableRelations.join(",\n")}
|
|
|
9845
9213
|
sendError("AUTH_ERROR", "INVALID_INPUT", "Token is required");
|
|
9846
9214
|
return;
|
|
9847
9215
|
}
|
|
9848
|
-
|
|
9849
|
-
if (
|
|
9216
|
+
let verifiedUser = null;
|
|
9217
|
+
if (authAdapter) {
|
|
9218
|
+
try {
|
|
9219
|
+
const adapterUser = authAdapter.verifyToken ? await authAdapter.verifyToken(token) : await authAdapter.verifyRequest(new Request("http://localhost/_ws_auth", {
|
|
9220
|
+
headers: {
|
|
9221
|
+
Authorization: `Bearer ${token}`
|
|
9222
|
+
}
|
|
9223
|
+
}));
|
|
9224
|
+
if (adapterUser) {
|
|
9225
|
+
verifiedUser = {
|
|
9226
|
+
userId: adapterUser.uid,
|
|
9227
|
+
roles: adapterUser.roles,
|
|
9228
|
+
isAdmin: adapterUser.isAdmin
|
|
9229
|
+
};
|
|
9230
|
+
}
|
|
9231
|
+
} catch {
|
|
9232
|
+
}
|
|
9233
|
+
} else {
|
|
9234
|
+
const jwtPayload = serverCore.extractUserFromToken(token);
|
|
9235
|
+
if (jwtPayload) {
|
|
9236
|
+
verifiedUser = {
|
|
9237
|
+
userId: jwtPayload.userId,
|
|
9238
|
+
roles: jwtPayload.roles ?? [],
|
|
9239
|
+
isAdmin: (jwtPayload.roles ?? []).some((r) => r === "admin")
|
|
9240
|
+
};
|
|
9241
|
+
}
|
|
9242
|
+
}
|
|
9243
|
+
if (verifiedUser) {
|
|
9850
9244
|
const session = clientSessions.get(clientId);
|
|
9851
9245
|
if (session) {
|
|
9852
|
-
session.user =
|
|
9246
|
+
session.user = verifiedUser;
|
|
9853
9247
|
session.authenticated = true;
|
|
9854
9248
|
}
|
|
9855
9249
|
wsDebug(`[WS] replying AUTH_SUCCESS for requestId ${requestId}`);
|
|
@@ -9857,11 +9251,11 @@ ${tableRelations.join(",\n")}
|
|
|
9857
9251
|
type: "AUTH_SUCCESS",
|
|
9858
9252
|
requestId,
|
|
9859
9253
|
payload: {
|
|
9860
|
-
userId:
|
|
9861
|
-
roles:
|
|
9254
|
+
userId: verifiedUser.userId,
|
|
9255
|
+
roles: verifiedUser.roles
|
|
9862
9256
|
}
|
|
9863
9257
|
}));
|
|
9864
|
-
wsDebug(`🔐 [WebSocket Server] Client ${clientId} authenticated as ${
|
|
9258
|
+
wsDebug(`🔐 [WebSocket Server] Client ${clientId} authenticated as ${verifiedUser.userId}`);
|
|
9865
9259
|
} else {
|
|
9866
9260
|
wsDebug(`[WS] replying AUTH_ERROR for requestId ${requestId} (invalid token)`);
|
|
9867
9261
|
sendError("AUTH_ERROR", "INVALID_TOKEN", "Invalid or expired token");
|
|
@@ -9899,16 +9293,19 @@ ${tableRelations.join(",\n")}
|
|
|
9899
9293
|
}
|
|
9900
9294
|
const getScopedDelegate = async () => {
|
|
9901
9295
|
const session = clientSessions.get(clientId);
|
|
9902
|
-
if (
|
|
9296
|
+
if ("withAuth" in driver && typeof driver.withAuth === "function") {
|
|
9903
9297
|
try {
|
|
9904
|
-
const userForAuth = {
|
|
9298
|
+
const userForAuth = session?.user ? {
|
|
9905
9299
|
uid: session.user.userId,
|
|
9906
9300
|
roles: session.user.roles ?? []
|
|
9301
|
+
} : {
|
|
9302
|
+
uid: "anon",
|
|
9303
|
+
roles: ["anon"]
|
|
9907
9304
|
};
|
|
9908
9305
|
return await driver.withAuth(userForAuth);
|
|
9909
9306
|
} catch (e) {
|
|
9910
|
-
console.error("Failed to create
|
|
9911
|
-
|
|
9307
|
+
console.error("Failed to create RLS scoped delegate for WS request", e);
|
|
9308
|
+
throw new Error("Internal authentication error");
|
|
9912
9309
|
}
|
|
9913
9310
|
}
|
|
9914
9311
|
return driver;
|
|
@@ -10039,24 +9436,29 @@ ${tableRelations.join(",\n")}
|
|
|
10039
9436
|
sql,
|
|
10040
9437
|
options
|
|
10041
9438
|
} = payload;
|
|
10042
|
-
|
|
10043
|
-
|
|
10044
|
-
|
|
10045
|
-
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
|
|
10050
|
-
|
|
9439
|
+
try {
|
|
9440
|
+
const delegate = await getScopedDelegate();
|
|
9441
|
+
const admin = delegate.admin;
|
|
9442
|
+
if (!isSQLAdmin(admin)) {
|
|
9443
|
+
sendError("ERROR", "NOT_SUPPORTED", "SQL execution is not available for this driver.");
|
|
9444
|
+
break;
|
|
9445
|
+
}
|
|
9446
|
+
const result = await admin.executeSql(sql, options);
|
|
9447
|
+
if (process.env.NODE_ENV !== "production") {
|
|
9448
|
+
wsDebug(`⚡ [WebSocket Server] SQL executed. Returned ${Array.isArray(result) ? result.length : "non-array"} rows.`);
|
|
9449
|
+
}
|
|
9450
|
+
const response = {
|
|
9451
|
+
type: "EXECUTE_SQL_SUCCESS",
|
|
9452
|
+
payload: {
|
|
9453
|
+
result
|
|
9454
|
+
},
|
|
9455
|
+
requestId
|
|
9456
|
+
};
|
|
9457
|
+
ws2.send(JSON.stringify(response));
|
|
9458
|
+
} catch (sqlError) {
|
|
9459
|
+
const errMsg = extractErrorMessage(sqlError);
|
|
9460
|
+
sendError("ERROR", "SQL_ERROR", errMsg);
|
|
10051
9461
|
}
|
|
10052
|
-
const response = {
|
|
10053
|
-
type: "EXECUTE_SQL_SUCCESS",
|
|
10054
|
-
payload: {
|
|
10055
|
-
result
|
|
10056
|
-
},
|
|
10057
|
-
requestId
|
|
10058
|
-
};
|
|
10059
|
-
ws2.send(JSON.stringify(response));
|
|
10060
9462
|
}
|
|
10061
9463
|
break;
|
|
10062
9464
|
case "FETCH_DATABASES":
|
|
@@ -10235,7 +9637,10 @@ ${tableRelations.join(",\n")}
|
|
|
10235
9637
|
const authContext = session?.user ? {
|
|
10236
9638
|
userId: session.user.userId,
|
|
10237
9639
|
roles: session.user.roles ?? []
|
|
10238
|
-
} :
|
|
9640
|
+
} : {
|
|
9641
|
+
userId: "anon",
|
|
9642
|
+
roles: ["anon"]
|
|
9643
|
+
};
|
|
10239
9644
|
await realtimeService.handleClientMessage(clientId, {
|
|
10240
9645
|
type,
|
|
10241
9646
|
payload,
|
|
@@ -10379,29 +9784,58 @@ ${tableRelations.join(",\n")}
|
|
|
10379
9784
|
},
|
|
10380
9785
|
config: null
|
|
10381
9786
|
}];
|
|
10382
|
-
async function ensureAuthTablesExist(db) {
|
|
9787
|
+
async function ensureAuthTablesExist(db, registry) {
|
|
10383
9788
|
console.log("🔍 Checking auth tables...");
|
|
10384
9789
|
try {
|
|
9790
|
+
let usersTableName = '"users"';
|
|
9791
|
+
let userIdType = "TEXT";
|
|
9792
|
+
let usersSchema2 = "public";
|
|
9793
|
+
if (registry) {
|
|
9794
|
+
const usersTable = registry.getTable("users");
|
|
9795
|
+
if (usersTable) {
|
|
9796
|
+
const {
|
|
9797
|
+
getTableName: getTableName2
|
|
9798
|
+
} = await import("drizzle-orm");
|
|
9799
|
+
usersSchema2 = pgCore.getTableConfig(usersTable).schema || "public";
|
|
9800
|
+
usersTableName = usersSchema2 === "public" ? `"${getTableName2(usersTable)}"` : `"${usersSchema2}"."${getTableName2(usersTable)}"`;
|
|
9801
|
+
if (usersTable.id) {
|
|
9802
|
+
const col = usersTable.id;
|
|
9803
|
+
const meta = getColumnMeta(col);
|
|
9804
|
+
const columnType = meta.columnType;
|
|
9805
|
+
if (columnType === "PgUUID") {
|
|
9806
|
+
userIdType = "UUID";
|
|
9807
|
+
} else if (columnType === "PgSerial" || columnType === "PgInteger") {
|
|
9808
|
+
userIdType = "INTEGER";
|
|
9809
|
+
} else if (columnType === "PgBigInt" || columnType === "PgBigSerial") {
|
|
9810
|
+
userIdType = "BIGINT";
|
|
9811
|
+
}
|
|
9812
|
+
}
|
|
9813
|
+
}
|
|
9814
|
+
}
|
|
9815
|
+
let rolesSchema = "rebase";
|
|
9816
|
+
if (registry) {
|
|
9817
|
+
const rolesTable = registry.getTable("roles");
|
|
9818
|
+
if (rolesTable) {
|
|
9819
|
+
rolesSchema = pgCore.getTableConfig(rolesTable).schema || "public";
|
|
9820
|
+
}
|
|
9821
|
+
}
|
|
9822
|
+
if (usersSchema2 !== "public") {
|
|
9823
|
+
await db.execute(drizzleOrm.sql`CREATE SCHEMA IF NOT EXISTS ${drizzleOrm.sql.raw(usersSchema2)}`);
|
|
9824
|
+
}
|
|
9825
|
+
if (rolesSchema !== "public" && rolesSchema !== usersSchema2) {
|
|
9826
|
+
await db.execute(drizzleOrm.sql`CREATE SCHEMA IF NOT EXISTS ${drizzleOrm.sql.raw(rolesSchema)}`);
|
|
9827
|
+
}
|
|
10385
9828
|
await db.execute(drizzleOrm.sql`CREATE SCHEMA IF NOT EXISTS rebase`);
|
|
9829
|
+
const userIdentitiesTable = `"${rolesSchema}"."user_identities"`;
|
|
9830
|
+
const rolesTableName = `"${rolesSchema}"."roles"`;
|
|
9831
|
+
const userRolesTableName = `"${rolesSchema}"."user_roles"`;
|
|
9832
|
+
const refreshTokensTableName = `"${rolesSchema}"."refresh_tokens"`;
|
|
9833
|
+
const passwordResetTokensTableName = `"${rolesSchema}"."password_reset_tokens"`;
|
|
9834
|
+
const appConfigTableName = `"${rolesSchema}"."app_config"`;
|
|
10386
9835
|
await db.execute(drizzleOrm.sql`
|
|
10387
|
-
CREATE TABLE IF NOT EXISTS
|
|
9836
|
+
CREATE TABLE IF NOT EXISTS ${drizzleOrm.sql.raw(userIdentitiesTable)} (
|
|
10388
9837
|
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
10389
|
-
|
|
10390
|
-
password_hash TEXT,
|
|
10391
|
-
display_name TEXT,
|
|
10392
|
-
photo_url TEXT,
|
|
10393
|
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
10394
|
-
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
10395
|
-
)
|
|
10396
|
-
`);
|
|
10397
|
-
await db.execute(drizzleOrm.sql`
|
|
10398
|
-
CREATE INDEX IF NOT EXISTS idx_users_email
|
|
10399
|
-
ON rebase.users(email)
|
|
10400
|
-
`);
|
|
10401
|
-
await db.execute(drizzleOrm.sql`
|
|
10402
|
-
CREATE TABLE IF NOT EXISTS rebase.user_identities (
|
|
10403
|
-
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
10404
|
-
user_id TEXT NOT NULL REFERENCES rebase.users(id) ON DELETE CASCADE,
|
|
9838
|
+
user_id ${drizzleOrm.sql.raw(userIdType)} NOT NULL REFERENCES ${drizzleOrm.sql.raw(usersTableName)}(id) ON DELETE CASCADE,
|
|
10405
9839
|
provider TEXT NOT NULL,
|
|
10406
9840
|
provider_id TEXT NOT NULL,
|
|
10407
9841
|
profile_data JSONB,
|
|
@@ -10412,10 +9846,10 @@ ${tableRelations.join(",\n")}
|
|
|
10412
9846
|
`);
|
|
10413
9847
|
await db.execute(drizzleOrm.sql`
|
|
10414
9848
|
CREATE INDEX IF NOT EXISTS idx_user_identities_user
|
|
10415
|
-
ON
|
|
9849
|
+
ON ${drizzleOrm.sql.raw(userIdentitiesTable)}(user_id)
|
|
10416
9850
|
`);
|
|
10417
9851
|
await db.execute(drizzleOrm.sql`
|
|
10418
|
-
CREATE TABLE IF NOT EXISTS
|
|
9852
|
+
CREATE TABLE IF NOT EXISTS ${drizzleOrm.sql.raw(rolesTableName)} (
|
|
10419
9853
|
id TEXT PRIMARY KEY,
|
|
10420
9854
|
name TEXT NOT NULL,
|
|
10421
9855
|
is_admin BOOLEAN DEFAULT FALSE,
|
|
@@ -10426,20 +9860,20 @@ ${tableRelations.join(",\n")}
|
|
|
10426
9860
|
)
|
|
10427
9861
|
`);
|
|
10428
9862
|
await db.execute(drizzleOrm.sql`
|
|
10429
|
-
CREATE TABLE IF NOT EXISTS
|
|
10430
|
-
user_id
|
|
10431
|
-
role_id TEXT NOT NULL REFERENCES
|
|
9863
|
+
CREATE TABLE IF NOT EXISTS ${drizzleOrm.sql.raw(userRolesTableName)} (
|
|
9864
|
+
user_id ${drizzleOrm.sql.raw(userIdType)} NOT NULL REFERENCES ${drizzleOrm.sql.raw(usersTableName)}(id) ON DELETE CASCADE,
|
|
9865
|
+
role_id TEXT NOT NULL REFERENCES ${drizzleOrm.sql.raw(rolesTableName)}(id) ON DELETE CASCADE,
|
|
10432
9866
|
PRIMARY KEY (user_id, role_id)
|
|
10433
9867
|
)
|
|
10434
9868
|
`);
|
|
10435
9869
|
await db.execute(drizzleOrm.sql`
|
|
10436
9870
|
CREATE INDEX IF NOT EXISTS idx_user_roles_user
|
|
10437
|
-
ON
|
|
9871
|
+
ON ${drizzleOrm.sql.raw(userRolesTableName)}(user_id)
|
|
10438
9872
|
`);
|
|
10439
9873
|
await db.execute(drizzleOrm.sql`
|
|
10440
|
-
CREATE TABLE IF NOT EXISTS
|
|
9874
|
+
CREATE TABLE IF NOT EXISTS ${drizzleOrm.sql.raw(refreshTokensTableName)} (
|
|
10441
9875
|
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
10442
|
-
user_id
|
|
9876
|
+
user_id ${drizzleOrm.sql.raw(userIdType)} NOT NULL REFERENCES ${drizzleOrm.sql.raw(usersTableName)}(id) ON DELETE CASCADE,
|
|
10443
9877
|
token_hash TEXT NOT NULL UNIQUE,
|
|
10444
9878
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
10445
9879
|
user_agent TEXT,
|
|
@@ -10450,16 +9884,16 @@ ${tableRelations.join(",\n")}
|
|
|
10450
9884
|
`);
|
|
10451
9885
|
await db.execute(drizzleOrm.sql`
|
|
10452
9886
|
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_hash
|
|
10453
|
-
ON
|
|
9887
|
+
ON ${drizzleOrm.sql.raw(refreshTokensTableName)}(token_hash)
|
|
10454
9888
|
`);
|
|
10455
9889
|
await db.execute(drizzleOrm.sql`
|
|
10456
9890
|
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user
|
|
10457
|
-
ON
|
|
9891
|
+
ON ${drizzleOrm.sql.raw(refreshTokensTableName)}(user_id)
|
|
10458
9892
|
`);
|
|
10459
9893
|
await db.execute(drizzleOrm.sql`
|
|
10460
|
-
CREATE TABLE IF NOT EXISTS
|
|
9894
|
+
CREATE TABLE IF NOT EXISTS ${drizzleOrm.sql.raw(passwordResetTokensTableName)} (
|
|
10461
9895
|
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
|
|
10462
|
-
user_id
|
|
9896
|
+
user_id ${drizzleOrm.sql.raw(userIdType)} NOT NULL REFERENCES ${drizzleOrm.sql.raw(usersTableName)}(id) ON DELETE CASCADE,
|
|
10463
9897
|
token_hash TEXT NOT NULL UNIQUE,
|
|
10464
9898
|
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
10465
9899
|
used_at TIMESTAMP WITH TIME ZONE,
|
|
@@ -10468,20 +9902,19 @@ ${tableRelations.join(",\n")}
|
|
|
10468
9902
|
`);
|
|
10469
9903
|
await db.execute(drizzleOrm.sql`
|
|
10470
9904
|
CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_hash
|
|
10471
|
-
ON
|
|
9905
|
+
ON ${drizzleOrm.sql.raw(passwordResetTokensTableName)}(token_hash)
|
|
10472
9906
|
`);
|
|
10473
9907
|
await db.execute(drizzleOrm.sql`
|
|
10474
9908
|
CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_user
|
|
10475
|
-
ON
|
|
9909
|
+
ON ${drizzleOrm.sql.raw(passwordResetTokensTableName)}(user_id)
|
|
10476
9910
|
`);
|
|
10477
9911
|
await db.execute(drizzleOrm.sql`
|
|
10478
|
-
CREATE TABLE IF NOT EXISTS
|
|
9912
|
+
CREATE TABLE IF NOT EXISTS ${drizzleOrm.sql.raw(appConfigTableName)} (
|
|
10479
9913
|
key TEXT PRIMARY KEY,
|
|
10480
9914
|
value JSONB NOT NULL,
|
|
10481
9915
|
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
10482
9916
|
)
|
|
10483
9917
|
`);
|
|
10484
|
-
await applyInternalMigrations(db);
|
|
10485
9918
|
await db.execute(drizzleOrm.sql`CREATE SCHEMA IF NOT EXISTS auth`);
|
|
10486
9919
|
await db.transaction(async (tx) => {
|
|
10487
9920
|
await tx.execute(drizzleOrm.sql`SELECT pg_advisory_xact_lock(hashtext('rebase_auth_functions_init'))`);
|
|
@@ -10504,15 +9937,15 @@ ${tableRelations.join(",\n")}
|
|
|
10504
9937
|
$$ LANGUAGE sql STABLE
|
|
10505
9938
|
`);
|
|
10506
9939
|
});
|
|
10507
|
-
await seedDefaultRoles(db);
|
|
9940
|
+
await seedDefaultRoles(db, rolesTableName);
|
|
10508
9941
|
console.log("✅ Auth tables ready");
|
|
10509
9942
|
} catch (error) {
|
|
10510
9943
|
console.error("❌ Failed to create auth tables:", error);
|
|
10511
9944
|
console.warn("⚠️ Continuing without creating auth tables.");
|
|
10512
9945
|
}
|
|
10513
9946
|
}
|
|
10514
|
-
async function seedDefaultRoles(db) {
|
|
10515
|
-
const result = await db.execute(drizzleOrm.sql`SELECT COUNT(*) as count FROM
|
|
9947
|
+
async function seedDefaultRoles(db, rolesTableName) {
|
|
9948
|
+
const result = await db.execute(drizzleOrm.sql`SELECT COUNT(*) as count FROM ${drizzleOrm.sql.raw(rolesTableName)}`);
|
|
10516
9949
|
const count = parseInt(result.rows[0]?.count || "0", 10);
|
|
10517
9950
|
if (count > 0) {
|
|
10518
9951
|
console.log(`📋 Found ${count} existing roles`);
|
|
@@ -10521,7 +9954,7 @@ ${tableRelations.join(",\n")}
|
|
|
10521
9954
|
console.log("🌱 Seeding default roles...");
|
|
10522
9955
|
for (const role of DEFAULT_ROLES) {
|
|
10523
9956
|
await db.execute(drizzleOrm.sql`
|
|
10524
|
-
INSERT INTO
|
|
9957
|
+
INSERT INTO ${drizzleOrm.sql.raw(rolesTableName)} (id, name, is_admin, default_permissions, config)
|
|
10525
9958
|
VALUES (
|
|
10526
9959
|
${role.id},
|
|
10527
9960
|
${role.name},
|
|
@@ -10534,142 +9967,156 @@ ${tableRelations.join(",\n")}
|
|
|
10534
9967
|
}
|
|
10535
9968
|
console.log("✅ Default roles created: admin, editor, viewer");
|
|
10536
9969
|
}
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
const columnsCheck = await db.execute(drizzleOrm.sql`
|
|
10546
|
-
SELECT column_name
|
|
10547
|
-
FROM information_schema.columns
|
|
10548
|
-
WHERE table_schema='rebase' AND table_name='users' AND column_name IN ('google_id', 'linkedin_id', 'provider')
|
|
10549
|
-
`);
|
|
10550
|
-
const existingColumns = columnsCheck.rows.map((r) => r.column_name);
|
|
10551
|
-
if (existingColumns.includes("google_id")) {
|
|
10552
|
-
await db.execute(drizzleOrm.sql`
|
|
10553
|
-
INSERT INTO rebase.user_identities (user_id, provider, provider_id)
|
|
10554
|
-
SELECT id, 'google', google_id
|
|
10555
|
-
FROM rebase.users
|
|
10556
|
-
WHERE google_id IS NOT NULL
|
|
10557
|
-
ON CONFLICT (provider, provider_id) DO NOTHING
|
|
10558
|
-
`);
|
|
10559
|
-
}
|
|
10560
|
-
if (existingColumns.includes("linkedin_id")) {
|
|
10561
|
-
await db.execute(drizzleOrm.sql`
|
|
10562
|
-
INSERT INTO rebase.user_identities (user_id, provider, provider_id)
|
|
10563
|
-
SELECT id, 'linkedin', linkedin_id
|
|
10564
|
-
FROM rebase.users
|
|
10565
|
-
WHERE linkedin_id IS NOT NULL
|
|
10566
|
-
ON CONFLICT (provider, provider_id) DO NOTHING
|
|
10567
|
-
`);
|
|
10568
|
-
}
|
|
10569
|
-
if (existingColumns.length > 0) {
|
|
10570
|
-
await db.execute(drizzleOrm.sql`
|
|
10571
|
-
ALTER TABLE rebase.users
|
|
10572
|
-
DROP COLUMN IF EXISTS provider,
|
|
10573
|
-
DROP COLUMN IF EXISTS google_id,
|
|
10574
|
-
DROP COLUMN IF EXISTS linkedin_id
|
|
10575
|
-
`);
|
|
10576
|
-
await db.execute(drizzleOrm.sql`DROP INDEX IF EXISTS rebase.idx_users_google_id`);
|
|
10577
|
-
await db.execute(drizzleOrm.sql`DROP INDEX IF EXISTS rebase.idx_users_linkedin_id`);
|
|
10578
|
-
console.log("✅ Migrated to user_identities and dropped legacy columns.");
|
|
10579
|
-
}
|
|
10580
|
-
await db.execute(drizzleOrm.sql`
|
|
10581
|
-
ALTER TABLE rebase.roles
|
|
10582
|
-
ADD COLUMN IF NOT EXISTS collection_permissions JSONB
|
|
10583
|
-
`);
|
|
10584
|
-
await db.execute(drizzleOrm.sql`
|
|
10585
|
-
ALTER TABLE rebase.refresh_tokens
|
|
10586
|
-
ADD COLUMN IF NOT EXISTS user_agent TEXT,
|
|
10587
|
-
ADD COLUMN IF NOT EXISTS ip_address TEXT
|
|
10588
|
-
`);
|
|
10589
|
-
const constraintCheck = await db.execute(drizzleOrm.sql`
|
|
10590
|
-
SELECT 1 FROM information_schema.table_constraints
|
|
10591
|
-
WHERE constraint_name = 'unique_device_session'
|
|
10592
|
-
AND table_schema = 'rebase'
|
|
10593
|
-
AND table_name = 'refresh_tokens'
|
|
10594
|
-
`);
|
|
10595
|
-
if (constraintCheck.rows.length === 0) {
|
|
10596
|
-
try {
|
|
10597
|
-
await db.execute(drizzleOrm.sql`
|
|
10598
|
-
ALTER TABLE rebase.refresh_tokens
|
|
10599
|
-
ADD CONSTRAINT unique_device_session UNIQUE (user_id, user_agent, ip_address)
|
|
10600
|
-
`);
|
|
10601
|
-
console.log("✅ Added unique_device_session constraint");
|
|
10602
|
-
} catch (e) {
|
|
10603
|
-
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
10604
|
-
if (errorMessage.includes("could not create unique index")) {
|
|
10605
|
-
console.warn("⚠️ Duplicate sessions found, cleaning up before adding constraint...");
|
|
10606
|
-
await db.execute(drizzleOrm.sql`
|
|
10607
|
-
DELETE FROM rebase.refresh_tokens a
|
|
10608
|
-
USING rebase.refresh_tokens b
|
|
10609
|
-
WHERE a.user_id = b.user_id
|
|
10610
|
-
AND COALESCE(a.user_agent, '') = COALESCE(b.user_agent, '')
|
|
10611
|
-
AND COALESCE(a.ip_address, '') = COALESCE(b.ip_address, '')
|
|
10612
|
-
AND a.created_at < b.created_at
|
|
10613
|
-
`);
|
|
10614
|
-
await db.execute(drizzleOrm.sql`
|
|
10615
|
-
ALTER TABLE rebase.refresh_tokens
|
|
10616
|
-
ADD CONSTRAINT unique_device_session UNIQUE (user_id, user_agent, ip_address)
|
|
10617
|
-
`).catch((retryErr) => {
|
|
10618
|
-
const retryMessage = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
10619
|
-
console.error("Failed to add unique_device_session constraint after cleanup:", retryMessage);
|
|
10620
|
-
});
|
|
10621
|
-
} else {
|
|
10622
|
-
console.error("Constraint migration issue:", errorMessage);
|
|
10623
|
-
}
|
|
10624
|
-
}
|
|
10625
|
-
}
|
|
10626
|
-
} catch (error) {
|
|
10627
|
-
console.error("❌ Failed to run internal migrations:", error);
|
|
9970
|
+
function getColumnKey(table, ...keys2) {
|
|
9971
|
+
if (!table) return void 0;
|
|
9972
|
+
for (const key of keys2) {
|
|
9973
|
+
if (key in table) return key;
|
|
9974
|
+
const snake = toSnakeCase(key);
|
|
9975
|
+
if (snake in table) return snake;
|
|
9976
|
+
const camel = camelCase(key);
|
|
9977
|
+
if (camel in table) return camel;
|
|
10628
9978
|
}
|
|
9979
|
+
return void 0;
|
|
9980
|
+
}
|
|
9981
|
+
function getColumn(table, ...keys2) {
|
|
9982
|
+
if (!table) return void 0;
|
|
9983
|
+
const key = getColumnKey(table, ...keys2);
|
|
9984
|
+
return key ? table[key] : void 0;
|
|
10629
9985
|
}
|
|
10630
9986
|
class UserService {
|
|
10631
|
-
constructor(db) {
|
|
9987
|
+
constructor(db, tableOrTables) {
|
|
10632
9988
|
this.db = db;
|
|
9989
|
+
if (tableOrTables && (tableOrTables.users || tableOrTables.roles)) {
|
|
9990
|
+
const tables = tableOrTables;
|
|
9991
|
+
this.usersTable = tables.users || users;
|
|
9992
|
+
this.userIdentitiesTable = tables.userIdentities || userIdentities;
|
|
9993
|
+
this.userRolesTable = tables.userRoles || userRoles;
|
|
9994
|
+
this.rolesTable = tables.roles || roles;
|
|
9995
|
+
} else {
|
|
9996
|
+
const table = tableOrTables;
|
|
9997
|
+
this.usersTable = table || users;
|
|
9998
|
+
this.userIdentitiesTable = userIdentities;
|
|
9999
|
+
this.userRolesTable = userRoles;
|
|
10000
|
+
this.rolesTable = roles;
|
|
10001
|
+
}
|
|
10002
|
+
}
|
|
10003
|
+
usersTable;
|
|
10004
|
+
userIdentitiesTable;
|
|
10005
|
+
userRolesTable;
|
|
10006
|
+
rolesTable;
|
|
10007
|
+
getQualifiedUsersTableName() {
|
|
10008
|
+
const name = drizzleOrm.getTableName(this.usersTable);
|
|
10009
|
+
const schema = pgCore.getTableConfig(this.usersTable).schema || "public";
|
|
10010
|
+
return `"${schema}"."${name}"`;
|
|
10011
|
+
}
|
|
10012
|
+
mapRowToUser(row) {
|
|
10013
|
+
if (!row) return row;
|
|
10014
|
+
const id = row.id ?? row.uid;
|
|
10015
|
+
const email = row.email;
|
|
10016
|
+
const passwordHash = row.password_hash ?? row.passwordHash ?? null;
|
|
10017
|
+
const displayName = row.display_name ?? row.displayName ?? null;
|
|
10018
|
+
const photoUrl = row.photo_url ?? row.photoUrl ?? row.photoURL ?? null;
|
|
10019
|
+
const emailVerified = row.email_verified ?? row.emailVerified ?? false;
|
|
10020
|
+
const emailVerificationToken = row.email_verification_token ?? row.emailVerificationToken ?? null;
|
|
10021
|
+
const emailVerificationSentAt = row.email_verification_sent_at ?? row.emailVerificationSentAt ?? null;
|
|
10022
|
+
const createdAt = row.created_at ?? row.createdAt;
|
|
10023
|
+
const updatedAt = row.updated_at ?? row.updatedAt;
|
|
10024
|
+
const metadata = {
|
|
10025
|
+
...row.metadata || {}
|
|
10026
|
+
};
|
|
10027
|
+
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"]);
|
|
10028
|
+
for (const [key, val] of Object.entries(row)) {
|
|
10029
|
+
if (!knownKeys.has(key)) {
|
|
10030
|
+
const camelKey = camelCase(key);
|
|
10031
|
+
metadata[camelKey] = val;
|
|
10032
|
+
}
|
|
10033
|
+
}
|
|
10034
|
+
return {
|
|
10035
|
+
id,
|
|
10036
|
+
email,
|
|
10037
|
+
passwordHash,
|
|
10038
|
+
displayName,
|
|
10039
|
+
photoUrl,
|
|
10040
|
+
emailVerified,
|
|
10041
|
+
emailVerificationToken,
|
|
10042
|
+
emailVerificationSentAt: emailVerificationSentAt ? new Date(emailVerificationSentAt) : null,
|
|
10043
|
+
createdAt: createdAt ? new Date(createdAt) : /* @__PURE__ */ new Date(),
|
|
10044
|
+
updatedAt: updatedAt ? new Date(updatedAt) : /* @__PURE__ */ new Date(),
|
|
10045
|
+
metadata
|
|
10046
|
+
};
|
|
10047
|
+
}
|
|
10048
|
+
mapPayload(data) {
|
|
10049
|
+
if (!data) return {};
|
|
10050
|
+
const payload = {};
|
|
10051
|
+
const idKey = getColumnKey(this.usersTable, "id") || "id";
|
|
10052
|
+
const emailKey = getColumnKey(this.usersTable, "email") || "email";
|
|
10053
|
+
const passwordHashKey = getColumnKey(this.usersTable, "passwordHash", "password_hash") || "passwordHash";
|
|
10054
|
+
const displayNameKey = getColumnKey(this.usersTable, "displayName", "display_name") || "displayName";
|
|
10055
|
+
const photoUrlKey = getColumnKey(this.usersTable, "photoUrl", "photo_url") || "photoUrl";
|
|
10056
|
+
const emailVerifiedKey = getColumnKey(this.usersTable, "emailVerified", "email_verified") || "emailVerified";
|
|
10057
|
+
const emailVerificationTokenKey = getColumnKey(this.usersTable, "emailVerificationToken", "email_verification_token") || "emailVerificationToken";
|
|
10058
|
+
const emailVerificationSentAtKey = getColumnKey(this.usersTable, "emailVerificationSentAt", "email_verification_sent_at") || "emailVerificationSentAt";
|
|
10059
|
+
const createdAtKey = getColumnKey(this.usersTable, "createdAt", "created_at") || "createdAt";
|
|
10060
|
+
const updatedAtKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
|
|
10061
|
+
const metadataKey = getColumnKey(this.usersTable, "metadata") || "metadata";
|
|
10062
|
+
if ("id" in data) payload[idKey] = data.id;
|
|
10063
|
+
if ("email" in data) payload[emailKey] = data.email;
|
|
10064
|
+
if ("passwordHash" in data) payload[passwordHashKey] = data.passwordHash;
|
|
10065
|
+
if ("displayName" in data) payload[displayNameKey] = data.displayName;
|
|
10066
|
+
if ("photoUrl" in data) payload[photoUrlKey] = data.photoUrl;
|
|
10067
|
+
if ("emailVerified" in data) payload[emailVerifiedKey] = data.emailVerified;
|
|
10068
|
+
if ("emailVerificationToken" in data) payload[emailVerificationTokenKey] = data.emailVerificationToken;
|
|
10069
|
+
if ("emailVerificationSentAt" in data) payload[emailVerificationSentAtKey] = data.emailVerificationSentAt;
|
|
10070
|
+
if ("createdAt" in data) payload[createdAtKey] = data.createdAt;
|
|
10071
|
+
if ("updatedAt" in data) payload[updatedAtKey] = data.updatedAt;
|
|
10072
|
+
const metadata = {
|
|
10073
|
+
...data.metadata || {}
|
|
10074
|
+
};
|
|
10075
|
+
const remainingMetadata = {};
|
|
10076
|
+
for (const [key, val] of Object.entries(metadata)) {
|
|
10077
|
+
const tableColKey = getColumnKey(this.usersTable, key);
|
|
10078
|
+
if (tableColKey && tableColKey !== idKey && tableColKey !== emailKey && tableColKey !== passwordHashKey && tableColKey !== displayNameKey && tableColKey !== photoUrlKey && tableColKey !== emailVerifiedKey && tableColKey !== emailVerificationTokenKey && tableColKey !== emailVerificationSentAtKey && tableColKey !== createdAtKey && tableColKey !== updatedAtKey && tableColKey !== metadataKey) {
|
|
10079
|
+
payload[tableColKey] = val;
|
|
10080
|
+
} else {
|
|
10081
|
+
remainingMetadata[key] = val;
|
|
10082
|
+
}
|
|
10083
|
+
}
|
|
10084
|
+
if (metadataKey in this.usersTable) {
|
|
10085
|
+
payload[metadataKey] = remainingMetadata;
|
|
10086
|
+
}
|
|
10087
|
+
return payload;
|
|
10633
10088
|
}
|
|
10634
10089
|
async createUser(data) {
|
|
10635
|
-
const
|
|
10636
|
-
|
|
10090
|
+
const payload = this.mapPayload(data);
|
|
10091
|
+
const [row] = await this.db.insert(this.usersTable).values(payload).returning();
|
|
10092
|
+
return this.mapRowToUser(row);
|
|
10637
10093
|
}
|
|
10638
10094
|
async getUserById(id) {
|
|
10639
|
-
const
|
|
10640
|
-
|
|
10095
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10096
|
+
if (!idCol) return null;
|
|
10097
|
+
const [row] = await this.db.select().from(this.usersTable).where(drizzleOrm.eq(idCol, id));
|
|
10098
|
+
return row ? this.mapRowToUser(row) : null;
|
|
10641
10099
|
}
|
|
10642
10100
|
async getUserByEmail(email) {
|
|
10643
|
-
const
|
|
10644
|
-
|
|
10101
|
+
const emailCol = getColumn(this.usersTable, "email");
|
|
10102
|
+
if (!emailCol) return null;
|
|
10103
|
+
const [row] = await this.db.select().from(this.usersTable).where(drizzleOrm.eq(emailCol, email.toLowerCase()));
|
|
10104
|
+
return row ? this.mapRowToUser(row) : null;
|
|
10645
10105
|
}
|
|
10646
10106
|
async getUserByIdentity(provider, providerId) {
|
|
10647
|
-
const
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
if (result.rows.length === 0) return null;
|
|
10655
|
-
const row = result.rows[0];
|
|
10656
|
-
return {
|
|
10657
|
-
id: row.id,
|
|
10658
|
-
email: row.email,
|
|
10659
|
-
passwordHash: row.password_hash ?? null,
|
|
10660
|
-
displayName: row.display_name ?? null,
|
|
10661
|
-
photoUrl: row.photo_url ?? null,
|
|
10662
|
-
emailVerified: row.email_verified ?? false,
|
|
10663
|
-
emailVerificationToken: row.email_verification_token ?? null,
|
|
10664
|
-
emailVerificationSentAt: row.email_verification_sent_at ?? null,
|
|
10665
|
-
createdAt: row.created_at,
|
|
10666
|
-
updatedAt: row.updated_at
|
|
10667
|
-
};
|
|
10107
|
+
const userIdCol = getColumn(this.usersTable, "id");
|
|
10108
|
+
if (!userIdCol) return null;
|
|
10109
|
+
const result = await this.db.select({
|
|
10110
|
+
user: this.usersTable
|
|
10111
|
+
}).from(this.usersTable).innerJoin(this.userIdentitiesTable, drizzleOrm.eq(userIdCol, this.userIdentitiesTable.userId)).where(drizzleOrm.sql`${this.userIdentitiesTable.provider} = ${provider} AND ${this.userIdentitiesTable.providerId} = ${providerId}`).limit(1);
|
|
10112
|
+
if (result.length === 0) return null;
|
|
10113
|
+
return this.mapRowToUser(result[0].user);
|
|
10668
10114
|
}
|
|
10669
10115
|
async getUserIdentities(userId) {
|
|
10116
|
+
const schema = pgCore.getTableConfig(this.userIdentitiesTable).schema || "public";
|
|
10670
10117
|
const result = await this.db.execute(drizzleOrm.sql`
|
|
10671
10118
|
SELECT id, user_id, provider, provider_id, profile_data, created_at, updated_at
|
|
10672
|
-
FROM
|
|
10119
|
+
FROM ${drizzleOrm.sql.raw(`"${schema}"."user_identities"`)}
|
|
10673
10120
|
WHERE user_id = ${userId}
|
|
10674
10121
|
`);
|
|
10675
10122
|
return result.rows.map((row) => ({
|
|
@@ -10683,27 +10130,32 @@ ${tableRelations.join(",\n")}
|
|
|
10683
10130
|
}));
|
|
10684
10131
|
}
|
|
10685
10132
|
async linkUserIdentity(userId, provider, providerId, profileData) {
|
|
10686
|
-
await this.db.insert(
|
|
10133
|
+
await this.db.insert(this.userIdentitiesTable).values({
|
|
10687
10134
|
userId,
|
|
10688
10135
|
provider,
|
|
10689
10136
|
providerId,
|
|
10690
10137
|
profileData: profileData || null
|
|
10691
10138
|
}).onConflictDoNothing({
|
|
10692
|
-
target: [
|
|
10139
|
+
target: [this.userIdentitiesTable.provider, this.userIdentitiesTable.providerId]
|
|
10693
10140
|
});
|
|
10694
10141
|
}
|
|
10695
10142
|
async updateUser(id, data) {
|
|
10696
|
-
const
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10143
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10144
|
+
if (!idCol) return null;
|
|
10145
|
+
const payload = this.mapPayload(data);
|
|
10146
|
+
const updatedAtKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
|
|
10147
|
+
payload[updatedAtKey] = /* @__PURE__ */ new Date();
|
|
10148
|
+
const [row] = await this.db.update(this.usersTable).set(payload).where(drizzleOrm.eq(idCol, id)).returning();
|
|
10149
|
+
return row ? this.mapRowToUser(row) : null;
|
|
10701
10150
|
}
|
|
10702
10151
|
async deleteUser(id) {
|
|
10703
|
-
|
|
10152
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10153
|
+
if (!idCol) return;
|
|
10154
|
+
await this.db.delete(this.usersTable).where(drizzleOrm.eq(idCol, id));
|
|
10704
10155
|
}
|
|
10705
10156
|
async listUsers() {
|
|
10706
|
-
|
|
10157
|
+
const rows = await this.db.select().from(this.usersTable);
|
|
10158
|
+
return rows.map((row) => this.mapRowToUser(row));
|
|
10707
10159
|
}
|
|
10708
10160
|
async listUsersPaginated(options) {
|
|
10709
10161
|
const limit = options?.limit ?? 25;
|
|
@@ -10712,49 +10164,40 @@ ${tableRelations.join(",\n")}
|
|
|
10712
10164
|
const orderBy = options?.orderBy || "createdAt";
|
|
10713
10165
|
const orderDir = options?.orderDir || "desc";
|
|
10714
10166
|
const roleId = options?.roleId;
|
|
10715
|
-
const
|
|
10716
|
-
|
|
10717
|
-
displayName: "display_name",
|
|
10718
|
-
createdAt: "created_at",
|
|
10719
|
-
updatedAt: "updated_at",
|
|
10720
|
-
provider: "provider"
|
|
10721
|
-
};
|
|
10722
|
-
const orderColumn = columnMap[orderBy] || "created_at";
|
|
10167
|
+
const orderCol = getColumn(this.usersTable, orderBy);
|
|
10168
|
+
const orderColumn = orderCol ? orderCol.name : "created_at";
|
|
10723
10169
|
const direction = orderDir === "asc" ? drizzleOrm.sql`ASC` : drizzleOrm.sql`DESC`;
|
|
10170
|
+
const emailCol = getColumn(this.usersTable, "email");
|
|
10171
|
+
const emailColumn = emailCol ? emailCol.name : "email";
|
|
10172
|
+
const displayNameCol = getColumn(this.usersTable, "displayName", "display_name");
|
|
10173
|
+
const displayNameColumn = displayNameCol ? displayNameCol.name : "display_name";
|
|
10174
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10175
|
+
const idColumn = idCol ? idCol.name : "id";
|
|
10176
|
+
const usersTableName = this.getQualifiedUsersTableName();
|
|
10177
|
+
const rolesSchema = pgCore.getTableConfig(this.userRolesTable).schema || "public";
|
|
10724
10178
|
const conditions = [];
|
|
10725
10179
|
if (roleId) {
|
|
10726
|
-
conditions.push(drizzleOrm.sql`EXISTS (SELECT 1 FROM
|
|
10180
|
+
conditions.push(drizzleOrm.sql`EXISTS (SELECT 1 FROM ${drizzleOrm.sql.raw(`"${rolesSchema}"."user_roles"`)} ur WHERE ur.user_id = ${drizzleOrm.sql.raw(usersTableName)}.${drizzleOrm.sql.raw(idColumn)} AND ur.role_id = ${roleId})`);
|
|
10727
10181
|
}
|
|
10728
10182
|
if (search) {
|
|
10729
10183
|
const pattern = `%${search}%`;
|
|
10730
|
-
conditions.push(drizzleOrm.sql`(
|
|
10184
|
+
conditions.push(drizzleOrm.sql`(${drizzleOrm.sql.raw(usersTableName)}.${drizzleOrm.sql.raw(emailColumn)} ILIKE ${pattern} OR ${drizzleOrm.sql.raw(usersTableName)}.${drizzleOrm.sql.raw(displayNameColumn)} ILIKE ${pattern})`);
|
|
10731
10185
|
}
|
|
10732
10186
|
const whereClause = conditions.length > 0 ? drizzleOrm.sql`WHERE ${drizzleOrm.sql.join(conditions, drizzleOrm.sql` AND `)}` : drizzleOrm.sql``;
|
|
10733
|
-
const orderByClause = roleId ? drizzleOrm.sql`ORDER BY ${drizzleOrm.sql.raw(orderColumn)} ${direction}` : drizzleOrm.sql`ORDER BY (SELECT count(*) FROM
|
|
10187
|
+
const orderByClause = roleId ? drizzleOrm.sql`ORDER BY ${drizzleOrm.sql.raw(usersTableName)}.${drizzleOrm.sql.raw(orderColumn)} ${direction}` : drizzleOrm.sql`ORDER BY (SELECT count(*) FROM ${drizzleOrm.sql.raw(`"${rolesSchema}"."user_roles"`)} ur WHERE ur.user_id = ${drizzleOrm.sql.raw(usersTableName)}.${drizzleOrm.sql.raw(idColumn)}) DESC, ${drizzleOrm.sql.raw(usersTableName)}.${drizzleOrm.sql.raw(orderColumn)} ${direction}`;
|
|
10734
10188
|
const countResult = await this.db.execute(drizzleOrm.sql`
|
|
10735
|
-
SELECT count(*)::int as total FROM
|
|
10189
|
+
SELECT count(*)::int as total FROM ${drizzleOrm.sql.raw(usersTableName)}
|
|
10736
10190
|
${whereClause}
|
|
10737
10191
|
`);
|
|
10738
10192
|
const total = countResult.rows[0].total;
|
|
10739
10193
|
const dataResult = await this.db.execute(drizzleOrm.sql`
|
|
10740
|
-
SELECT * FROM
|
|
10194
|
+
SELECT * FROM ${drizzleOrm.sql.raw(usersTableName)}
|
|
10741
10195
|
${whereClause}
|
|
10742
10196
|
${orderByClause}
|
|
10743
10197
|
LIMIT ${limit} OFFSET ${offset}
|
|
10744
10198
|
`);
|
|
10745
10199
|
const rows = dataResult.rows;
|
|
10746
|
-
const mappedUsers = rows.map((row) => (
|
|
10747
|
-
id: row.id,
|
|
10748
|
-
email: row.email,
|
|
10749
|
-
passwordHash: row.password_hash ?? row.passwordHash ?? null,
|
|
10750
|
-
displayName: row.display_name ?? row.displayName ?? null,
|
|
10751
|
-
photoUrl: row.photo_url ?? row.photoUrl ?? null,
|
|
10752
|
-
emailVerified: row.email_verified ?? row.emailVerified ?? false,
|
|
10753
|
-
emailVerificationToken: row.email_verification_token ?? row.emailVerificationToken ?? null,
|
|
10754
|
-
emailVerificationSentAt: row.email_verification_sent_at ?? row.emailVerificationSentAt ?? null,
|
|
10755
|
-
createdAt: row.created_at ?? row.createdAt,
|
|
10756
|
-
updatedAt: row.updated_at ?? row.updatedAt
|
|
10757
|
-
}));
|
|
10200
|
+
const mappedUsers = rows.map((row) => this.mapRowToUser(row));
|
|
10758
10201
|
return {
|
|
10759
10202
|
users: mappedUsers,
|
|
10760
10203
|
total,
|
|
@@ -10766,46 +10209,63 @@ ${tableRelations.join(",\n")}
|
|
|
10766
10209
|
* Update user's password hash
|
|
10767
10210
|
*/
|
|
10768
10211
|
async updatePassword(id, passwordHash) {
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10212
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10213
|
+
if (!idCol) return;
|
|
10214
|
+
const passwordHashColKey = getColumnKey(this.usersTable, "passwordHash", "password_hash") || "passwordHash";
|
|
10215
|
+
const updatedAtColKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
|
|
10216
|
+
await this.db.update(this.usersTable).set({
|
|
10217
|
+
[passwordHashColKey]: passwordHash,
|
|
10218
|
+
[updatedAtColKey]: /* @__PURE__ */ new Date()
|
|
10219
|
+
}).where(drizzleOrm.eq(idCol, id));
|
|
10773
10220
|
}
|
|
10774
10221
|
/**
|
|
10775
10222
|
* Set email verification status
|
|
10776
10223
|
*/
|
|
10777
10224
|
async setEmailVerified(id, verified) {
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10225
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10226
|
+
if (!idCol) return;
|
|
10227
|
+
const emailVerifiedColKey = getColumnKey(this.usersTable, "emailVerified", "email_verified") || "emailVerified";
|
|
10228
|
+
const emailVerificationTokenColKey = getColumnKey(this.usersTable, "emailVerificationToken", "email_verification_token") || "emailVerificationToken";
|
|
10229
|
+
const updatedAtColKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
|
|
10230
|
+
await this.db.update(this.usersTable).set({
|
|
10231
|
+
[emailVerifiedColKey]: verified,
|
|
10232
|
+
[emailVerificationTokenColKey]: null,
|
|
10233
|
+
[updatedAtColKey]: /* @__PURE__ */ new Date()
|
|
10234
|
+
}).where(drizzleOrm.eq(idCol, id));
|
|
10783
10235
|
}
|
|
10784
10236
|
/**
|
|
10785
10237
|
* Set email verification token
|
|
10786
10238
|
*/
|
|
10787
10239
|
async setVerificationToken(id, token) {
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10240
|
+
const idCol = getColumn(this.usersTable, "id");
|
|
10241
|
+
if (!idCol) return;
|
|
10242
|
+
const emailVerificationTokenColKey = getColumnKey(this.usersTable, "emailVerificationToken", "email_verification_token") || "emailVerificationToken";
|
|
10243
|
+
const emailVerificationSentAtColKey = getColumnKey(this.usersTable, "emailVerificationSentAt", "email_verification_sent_at") || "emailVerificationSentAt";
|
|
10244
|
+
const updatedAtColKey = getColumnKey(this.usersTable, "updatedAt", "updated_at") || "updatedAt";
|
|
10245
|
+
await this.db.update(this.usersTable).set({
|
|
10246
|
+
[emailVerificationTokenColKey]: token,
|
|
10247
|
+
[emailVerificationSentAtColKey]: token ? /* @__PURE__ */ new Date() : null,
|
|
10248
|
+
[updatedAtColKey]: /* @__PURE__ */ new Date()
|
|
10249
|
+
}).where(drizzleOrm.eq(idCol, id));
|
|
10793
10250
|
}
|
|
10794
10251
|
/**
|
|
10795
10252
|
* Find user by email verification token
|
|
10796
10253
|
*/
|
|
10797
10254
|
async getUserByVerificationToken(token) {
|
|
10798
|
-
const
|
|
10799
|
-
|
|
10255
|
+
const tokenCol = getColumn(this.usersTable, "emailVerificationToken", "email_verification_token");
|
|
10256
|
+
if (!tokenCol) return null;
|
|
10257
|
+
const [row] = await this.db.select().from(this.usersTable).where(drizzleOrm.eq(tokenCol, token));
|
|
10258
|
+
return row ? this.mapRowToUser(row) : null;
|
|
10800
10259
|
}
|
|
10801
10260
|
/**
|
|
10802
10261
|
* Get roles for a user from database
|
|
10803
10262
|
*/
|
|
10804
10263
|
async getUserRoles(userId) {
|
|
10264
|
+
const rolesSchema = pgCore.getTableConfig(this.rolesTable).schema || "public";
|
|
10805
10265
|
const result = await this.db.execute(drizzleOrm.sql`
|
|
10806
10266
|
SELECT r.id, r.name, r.is_admin, r.default_permissions, r.collection_permissions, r.config
|
|
10807
|
-
FROM
|
|
10808
|
-
INNER JOIN
|
|
10267
|
+
FROM ${drizzleOrm.sql.raw(`"${rolesSchema}"."roles"`)} r
|
|
10268
|
+
INNER JOIN ${drizzleOrm.sql.raw(`"${rolesSchema}"."user_roles"`)} ur ON r.id = ur.role_id
|
|
10809
10269
|
WHERE ur.user_id = ${userId}
|
|
10810
10270
|
`);
|
|
10811
10271
|
return result.rows.map((row) => ({
|
|
@@ -10828,10 +10288,11 @@ ${tableRelations.join(",\n")}
|
|
|
10828
10288
|
* Set roles for a user
|
|
10829
10289
|
*/
|
|
10830
10290
|
async setUserRoles(userId, roleIds) {
|
|
10831
|
-
|
|
10291
|
+
const rolesSchema = pgCore.getTableConfig(this.userRolesTable).schema || "public";
|
|
10292
|
+
await this.db.execute(drizzleOrm.sql`DELETE FROM ${drizzleOrm.sql.raw(`"${rolesSchema}"."user_roles"`)} WHERE user_id = ${userId}`);
|
|
10832
10293
|
for (const roleId of roleIds) {
|
|
10833
10294
|
await this.db.execute(drizzleOrm.sql`
|
|
10834
|
-
INSERT INTO
|
|
10295
|
+
INSERT INTO ${drizzleOrm.sql.raw(`"${rolesSchema}"."user_roles"`)} (user_id, role_id)
|
|
10835
10296
|
VALUES (${userId}, ${roleId})
|
|
10836
10297
|
ON CONFLICT DO NOTHING
|
|
10837
10298
|
`);
|
|
@@ -10841,8 +10302,9 @@ ${tableRelations.join(",\n")}
|
|
|
10841
10302
|
* Assign a specific role to new user
|
|
10842
10303
|
*/
|
|
10843
10304
|
async assignDefaultRole(userId, roleId) {
|
|
10305
|
+
const rolesSchema = pgCore.getTableConfig(this.userRolesTable).schema || "public";
|
|
10844
10306
|
await this.db.execute(drizzleOrm.sql`
|
|
10845
|
-
INSERT INTO
|
|
10307
|
+
INSERT INTO ${drizzleOrm.sql.raw(`"${rolesSchema}"."user_roles"`)} (user_id, role_id)
|
|
10846
10308
|
VALUES (${userId}, ${roleId})
|
|
10847
10309
|
ON CONFLICT DO NOTHING
|
|
10848
10310
|
`);
|
|
@@ -10861,13 +10323,25 @@ ${tableRelations.join(",\n")}
|
|
|
10861
10323
|
}
|
|
10862
10324
|
}
|
|
10863
10325
|
class RoleService {
|
|
10864
|
-
constructor(db) {
|
|
10326
|
+
constructor(db, tableOrTables) {
|
|
10865
10327
|
this.db = db;
|
|
10328
|
+
if (tableOrTables && (tableOrTables.roles || tableOrTables.users)) {
|
|
10329
|
+
this.rolesTable = tableOrTables.roles || roles;
|
|
10330
|
+
} else {
|
|
10331
|
+
this.rolesTable = tableOrTables || roles;
|
|
10332
|
+
}
|
|
10333
|
+
}
|
|
10334
|
+
rolesTable;
|
|
10335
|
+
getQualifiedRolesTableName() {
|
|
10336
|
+
const name = drizzleOrm.getTableName(this.rolesTable);
|
|
10337
|
+
const schema = pgCore.getTableConfig(this.rolesTable).schema || "public";
|
|
10338
|
+
return `"${schema}"."${name}"`;
|
|
10866
10339
|
}
|
|
10867
10340
|
async getRoleById(id) {
|
|
10341
|
+
const tableName = this.getQualifiedRolesTableName();
|
|
10868
10342
|
const result = await this.db.execute(drizzleOrm.sql`
|
|
10869
10343
|
SELECT id, name, is_admin, default_permissions, collection_permissions, config
|
|
10870
|
-
FROM
|
|
10344
|
+
FROM ${drizzleOrm.sql.raw(tableName)}
|
|
10871
10345
|
WHERE id = ${id}
|
|
10872
10346
|
`);
|
|
10873
10347
|
if (result.rows.length === 0) return null;
|
|
@@ -10882,9 +10356,10 @@ ${tableRelations.join(",\n")}
|
|
|
10882
10356
|
};
|
|
10883
10357
|
}
|
|
10884
10358
|
async listRoles() {
|
|
10359
|
+
const tableName = this.getQualifiedRolesTableName();
|
|
10885
10360
|
const result = await this.db.execute(drizzleOrm.sql`
|
|
10886
10361
|
SELECT id, name, is_admin, default_permissions, collection_permissions, config
|
|
10887
|
-
FROM
|
|
10362
|
+
FROM ${drizzleOrm.sql.raw(tableName)}
|
|
10888
10363
|
ORDER BY name
|
|
10889
10364
|
`);
|
|
10890
10365
|
return result.rows.map((row) => ({
|
|
@@ -10897,8 +10372,9 @@ ${tableRelations.join(",\n")}
|
|
|
10897
10372
|
}));
|
|
10898
10373
|
}
|
|
10899
10374
|
async createRole(data) {
|
|
10375
|
+
const tableName = this.getQualifiedRolesTableName();
|
|
10900
10376
|
const result = await this.db.execute(drizzleOrm.sql`
|
|
10901
|
-
INSERT INTO
|
|
10377
|
+
INSERT INTO ${drizzleOrm.sql.raw(tableName)} (id, name, is_admin, default_permissions, collection_permissions, config)
|
|
10902
10378
|
VALUES (
|
|
10903
10379
|
${data.id},
|
|
10904
10380
|
${data.name},
|
|
@@ -10922,8 +10398,9 @@ ${tableRelations.join(",\n")}
|
|
|
10922
10398
|
async updateRole(id, data) {
|
|
10923
10399
|
const existing = await this.getRoleById(id);
|
|
10924
10400
|
if (!existing) return null;
|
|
10401
|
+
const tableName = this.getQualifiedRolesTableName();
|
|
10925
10402
|
await this.db.execute(drizzleOrm.sql`
|
|
10926
|
-
UPDATE
|
|
10403
|
+
UPDATE ${drizzleOrm.sql.raw(tableName)}
|
|
10927
10404
|
SET
|
|
10928
10405
|
name = ${data.name ?? existing.name},
|
|
10929
10406
|
is_admin = ${data.isAdmin ?? existing.isAdmin},
|
|
@@ -10935,23 +10412,36 @@ ${tableRelations.join(",\n")}
|
|
|
10935
10412
|
return this.getRoleById(id);
|
|
10936
10413
|
}
|
|
10937
10414
|
async deleteRole(id) {
|
|
10938
|
-
|
|
10415
|
+
const tableName = this.getQualifiedRolesTableName();
|
|
10416
|
+
await this.db.execute(drizzleOrm.sql`DELETE FROM ${drizzleOrm.sql.raw(tableName)} WHERE id = ${id}`);
|
|
10939
10417
|
}
|
|
10940
10418
|
}
|
|
10941
10419
|
class RefreshTokenService {
|
|
10942
|
-
constructor(db) {
|
|
10420
|
+
constructor(db, tableOrTables) {
|
|
10943
10421
|
this.db = db;
|
|
10422
|
+
if (tableOrTables && (tableOrTables.refreshTokens || tableOrTables.users)) {
|
|
10423
|
+
this.refreshTokensTable = tableOrTables.refreshTokens || refreshTokens;
|
|
10424
|
+
} else {
|
|
10425
|
+
this.refreshTokensTable = tableOrTables || refreshTokens;
|
|
10426
|
+
}
|
|
10427
|
+
}
|
|
10428
|
+
refreshTokensTable;
|
|
10429
|
+
getQualifiedRefreshTokensTableName() {
|
|
10430
|
+
const name = drizzleOrm.getTableName(this.refreshTokensTable);
|
|
10431
|
+
const schema = pgCore.getTableConfig(this.refreshTokensTable).schema || "public";
|
|
10432
|
+
return `"${schema}"."${name}"`;
|
|
10944
10433
|
}
|
|
10945
10434
|
async createToken(userId, tokenHash, expiresAt, userAgent, ipAddress) {
|
|
10946
10435
|
const safeUserAgent = userAgent || "";
|
|
10947
10436
|
const safeIpAddress = ipAddress || "";
|
|
10437
|
+
const tableName = this.getQualifiedRefreshTokensTableName();
|
|
10948
10438
|
await this.db.execute(drizzleOrm.sql`
|
|
10949
|
-
DELETE FROM
|
|
10439
|
+
DELETE FROM ${drizzleOrm.sql.raw(tableName)}
|
|
10950
10440
|
WHERE user_id = ${userId}
|
|
10951
10441
|
AND user_agent = ${safeUserAgent}
|
|
10952
10442
|
AND ip_address = ${safeIpAddress}
|
|
10953
10443
|
`);
|
|
10954
|
-
await this.db.insert(
|
|
10444
|
+
await this.db.insert(this.refreshTokensTable).values({
|
|
10955
10445
|
userId,
|
|
10956
10446
|
tokenHash,
|
|
10957
10447
|
expiresAt,
|
|
@@ -10961,51 +10451,63 @@ ${tableRelations.join(",\n")}
|
|
|
10961
10451
|
}
|
|
10962
10452
|
async findByHash(tokenHash) {
|
|
10963
10453
|
const [token] = await this.db.select({
|
|
10964
|
-
id:
|
|
10965
|
-
userId:
|
|
10966
|
-
tokenHash:
|
|
10967
|
-
expiresAt:
|
|
10968
|
-
createdAt:
|
|
10969
|
-
userAgent:
|
|
10970
|
-
ipAddress:
|
|
10971
|
-
}).from(
|
|
10454
|
+
id: this.refreshTokensTable.id,
|
|
10455
|
+
userId: this.refreshTokensTable.userId,
|
|
10456
|
+
tokenHash: this.refreshTokensTable.tokenHash,
|
|
10457
|
+
expiresAt: this.refreshTokensTable.expiresAt,
|
|
10458
|
+
createdAt: this.refreshTokensTable.createdAt,
|
|
10459
|
+
userAgent: this.refreshTokensTable.userAgent,
|
|
10460
|
+
ipAddress: this.refreshTokensTable.ipAddress
|
|
10461
|
+
}).from(this.refreshTokensTable).where(drizzleOrm.eq(this.refreshTokensTable.tokenHash, tokenHash));
|
|
10972
10462
|
return token || null;
|
|
10973
10463
|
}
|
|
10974
10464
|
async deleteByHash(tokenHash) {
|
|
10975
|
-
await this.db.delete(
|
|
10465
|
+
await this.db.delete(this.refreshTokensTable).where(drizzleOrm.eq(this.refreshTokensTable.tokenHash, tokenHash));
|
|
10976
10466
|
}
|
|
10977
10467
|
async deleteAllForUser(userId) {
|
|
10978
|
-
await this.db.delete(
|
|
10468
|
+
await this.db.delete(this.refreshTokensTable).where(drizzleOrm.eq(this.refreshTokensTable.userId, userId));
|
|
10979
10469
|
}
|
|
10980
10470
|
async listForUser(userId) {
|
|
10981
10471
|
const tokens = await this.db.select({
|
|
10982
|
-
id:
|
|
10983
|
-
userId:
|
|
10984
|
-
tokenHash:
|
|
10985
|
-
expiresAt:
|
|
10986
|
-
createdAt:
|
|
10987
|
-
userAgent:
|
|
10988
|
-
ipAddress:
|
|
10989
|
-
}).from(
|
|
10472
|
+
id: this.refreshTokensTable.id,
|
|
10473
|
+
userId: this.refreshTokensTable.userId,
|
|
10474
|
+
tokenHash: this.refreshTokensTable.tokenHash,
|
|
10475
|
+
expiresAt: this.refreshTokensTable.expiresAt,
|
|
10476
|
+
createdAt: this.refreshTokensTable.createdAt,
|
|
10477
|
+
userAgent: this.refreshTokensTable.userAgent,
|
|
10478
|
+
ipAddress: this.refreshTokensTable.ipAddress
|
|
10479
|
+
}).from(this.refreshTokensTable).where(drizzleOrm.eq(this.refreshTokensTable.userId, userId)).orderBy(this.refreshTokensTable.createdAt);
|
|
10990
10480
|
return tokens;
|
|
10991
10481
|
}
|
|
10992
10482
|
async deleteById(id, userId) {
|
|
10993
|
-
await this.db.delete(
|
|
10483
|
+
await this.db.delete(this.refreshTokensTable).where(drizzleOrm.sql`${this.refreshTokensTable.id} = ${id} AND ${this.refreshTokensTable.userId} = ${userId}`);
|
|
10994
10484
|
}
|
|
10995
10485
|
}
|
|
10996
10486
|
class PasswordResetTokenService {
|
|
10997
|
-
constructor(db) {
|
|
10487
|
+
constructor(db, tableOrTables) {
|
|
10998
10488
|
this.db = db;
|
|
10489
|
+
if (tableOrTables && (tableOrTables.passwordResetTokens || tableOrTables.users)) {
|
|
10490
|
+
this.passwordResetTokensTable = tableOrTables.passwordResetTokens || passwordResetTokens;
|
|
10491
|
+
} else {
|
|
10492
|
+
this.passwordResetTokensTable = tableOrTables || passwordResetTokens;
|
|
10493
|
+
}
|
|
10494
|
+
}
|
|
10495
|
+
passwordResetTokensTable;
|
|
10496
|
+
getQualifiedPasswordResetTokensTableName() {
|
|
10497
|
+
const name = drizzleOrm.getTableName(this.passwordResetTokensTable);
|
|
10498
|
+
const schema = pgCore.getTableConfig(this.passwordResetTokensTable).schema || "public";
|
|
10499
|
+
return `"${schema}"."${name}"`;
|
|
10999
10500
|
}
|
|
11000
10501
|
/**
|
|
11001
10502
|
* Create a password reset token
|
|
11002
10503
|
*/
|
|
11003
10504
|
async createToken(userId, tokenHash, expiresAt) {
|
|
10505
|
+
const tableName = this.getQualifiedPasswordResetTokensTableName();
|
|
11004
10506
|
await this.db.execute(drizzleOrm.sql`
|
|
11005
|
-
DELETE FROM
|
|
10507
|
+
DELETE FROM ${drizzleOrm.sql.raw(tableName)}
|
|
11006
10508
|
WHERE user_id = ${userId} AND used_at IS NULL
|
|
11007
10509
|
`);
|
|
11008
|
-
await this.db.insert(
|
|
10510
|
+
await this.db.insert(this.passwordResetTokensTable).values({
|
|
11009
10511
|
userId,
|
|
11010
10512
|
tokenHash,
|
|
11011
10513
|
expiresAt
|
|
@@ -11016,13 +10518,14 @@ ${tableRelations.join(",\n")}
|
|
|
11016
10518
|
*/
|
|
11017
10519
|
async findValidByHash(tokenHash) {
|
|
11018
10520
|
const [token] = await this.db.select({
|
|
11019
|
-
userId:
|
|
11020
|
-
expiresAt:
|
|
11021
|
-
}).from(
|
|
10521
|
+
userId: this.passwordResetTokensTable.userId,
|
|
10522
|
+
expiresAt: this.passwordResetTokensTable.expiresAt
|
|
10523
|
+
}).from(this.passwordResetTokensTable).where(drizzleOrm.eq(this.passwordResetTokensTable.tokenHash, tokenHash));
|
|
11022
10524
|
if (!token) return null;
|
|
10525
|
+
const tableName = this.getQualifiedPasswordResetTokensTableName();
|
|
11023
10526
|
const result = await this.db.execute(drizzleOrm.sql`
|
|
11024
10527
|
SELECT user_id, expires_at
|
|
11025
|
-
FROM
|
|
10528
|
+
FROM ${drizzleOrm.sql.raw(tableName)}
|
|
11026
10529
|
WHERE token_hash = ${tokenHash}
|
|
11027
10530
|
AND used_at IS NULL
|
|
11028
10531
|
AND expires_at > NOW()
|
|
@@ -11038,31 +10541,32 @@ ${tableRelations.join(",\n")}
|
|
|
11038
10541
|
* Mark token as used
|
|
11039
10542
|
*/
|
|
11040
10543
|
async markAsUsed(tokenHash) {
|
|
11041
|
-
await this.db.update(
|
|
10544
|
+
await this.db.update(this.passwordResetTokensTable).set({
|
|
11042
10545
|
usedAt: /* @__PURE__ */ new Date()
|
|
11043
|
-
}).where(drizzleOrm.eq(
|
|
10546
|
+
}).where(drizzleOrm.eq(this.passwordResetTokensTable.tokenHash, tokenHash));
|
|
11044
10547
|
}
|
|
11045
10548
|
/**
|
|
11046
10549
|
* Delete all tokens for a user
|
|
11047
10550
|
*/
|
|
11048
10551
|
async deleteAllForUser(userId) {
|
|
11049
|
-
await this.db.delete(
|
|
10552
|
+
await this.db.delete(this.passwordResetTokensTable).where(drizzleOrm.eq(this.passwordResetTokensTable.userId, userId));
|
|
11050
10553
|
}
|
|
11051
10554
|
/**
|
|
11052
10555
|
* Clean up expired tokens
|
|
11053
10556
|
*/
|
|
11054
10557
|
async deleteExpired() {
|
|
10558
|
+
const tableName = this.getQualifiedPasswordResetTokensTableName();
|
|
11055
10559
|
await this.db.execute(drizzleOrm.sql`
|
|
11056
|
-
DELETE FROM
|
|
10560
|
+
DELETE FROM ${drizzleOrm.sql.raw(tableName)}
|
|
11057
10561
|
WHERE expires_at < NOW()
|
|
11058
10562
|
`);
|
|
11059
10563
|
}
|
|
11060
10564
|
}
|
|
11061
10565
|
class PostgresTokenRepository {
|
|
11062
|
-
constructor(db) {
|
|
10566
|
+
constructor(db, tableOrTables) {
|
|
11063
10567
|
this.db = db;
|
|
11064
|
-
this.refreshTokenService = new RefreshTokenService(db);
|
|
11065
|
-
this.passwordResetTokenService = new PasswordResetTokenService(db);
|
|
10568
|
+
this.refreshTokenService = new RefreshTokenService(db, tableOrTables);
|
|
10569
|
+
this.passwordResetTokenService = new PasswordResetTokenService(db, tableOrTables);
|
|
11066
10570
|
}
|
|
11067
10571
|
refreshTokenService;
|
|
11068
10572
|
passwordResetTokenService;
|
|
@@ -11103,11 +10607,11 @@ ${tableRelations.join(",\n")}
|
|
|
11103
10607
|
}
|
|
11104
10608
|
}
|
|
11105
10609
|
class PostgresAuthRepository {
|
|
11106
|
-
constructor(db) {
|
|
10610
|
+
constructor(db, tableOrTables) {
|
|
11107
10611
|
this.db = db;
|
|
11108
|
-
this.userService = new UserService(db);
|
|
11109
|
-
this.roleService = new RoleService(db);
|
|
11110
|
-
this.tokenRepository = new PostgresTokenRepository(db);
|
|
10612
|
+
this.userService = new UserService(db, tableOrTables);
|
|
10613
|
+
this.roleService = new RoleService(db, tableOrTables);
|
|
10614
|
+
this.tokenRepository = new PostgresTokenRepository(db, tableOrTables);
|
|
11111
10615
|
}
|
|
11112
10616
|
userService;
|
|
11113
10617
|
roleService;
|
|
@@ -11168,8 +10672,7 @@ ${tableRelations.join(",\n")}
|
|
|
11168
10672
|
await this.userService.assignDefaultRole(userId, roleId);
|
|
11169
10673
|
}
|
|
11170
10674
|
async getUserWithRoles(userId) {
|
|
11171
|
-
|
|
11172
|
-
return result;
|
|
10675
|
+
return this.userService.getUserWithRoles(userId);
|
|
11173
10676
|
}
|
|
11174
10677
|
// Role operations (delegate to RoleService)
|
|
11175
10678
|
async getRoleById(id) {
|
|
@@ -11357,6 +10860,24 @@ ${tableRelations.join(",\n")}
|
|
|
11357
10860
|
return result.rowCount ?? 0;
|
|
11358
10861
|
}
|
|
11359
10862
|
}
|
|
10863
|
+
function deepEqual(a, b) {
|
|
10864
|
+
if (a === b) return true;
|
|
10865
|
+
if (a == null || b == null) return false;
|
|
10866
|
+
if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
|
|
10867
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
10868
|
+
if (a.length !== b.length) return false;
|
|
10869
|
+
return a.every((v, i) => deepEqual(v, b[i]));
|
|
10870
|
+
}
|
|
10871
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
10872
|
+
const aObj = a;
|
|
10873
|
+
const bObj = b;
|
|
10874
|
+
const aKeys = Object.keys(aObj);
|
|
10875
|
+
const bKeys = Object.keys(bObj);
|
|
10876
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
10877
|
+
return aKeys.every((k) => deepEqual(aObj[k], bObj[k]));
|
|
10878
|
+
}
|
|
10879
|
+
return false;
|
|
10880
|
+
}
|
|
11360
10881
|
function findChangedFields(oldValues, newValues) {
|
|
11361
10882
|
const changed = [];
|
|
11362
10883
|
const allKeys = /* @__PURE__ */ new Set([...Object.keys(oldValues), ...Object.keys(newValues)]);
|
|
@@ -11366,7 +10887,7 @@ ${tableRelations.join(",\n")}
|
|
|
11366
10887
|
if (key.startsWith("__")) continue;
|
|
11367
10888
|
if (oldVal !== newVal) {
|
|
11368
10889
|
if (typeof oldVal === "object" && oldVal !== null && typeof newVal === "object" && newVal !== null) {
|
|
11369
|
-
if (
|
|
10890
|
+
if (!deepEqual(oldVal, newVal)) {
|
|
11370
10891
|
changed.push(key);
|
|
11371
10892
|
}
|
|
11372
10893
|
} else {
|
|
@@ -11484,14 +11005,32 @@ ${tableRelations.join(",\n")}
|
|
|
11484
11005
|
if (!authConfig) return void 0;
|
|
11485
11006
|
const internals = driverResult.internals;
|
|
11486
11007
|
const db = internals.db;
|
|
11487
|
-
|
|
11008
|
+
const registry = internals.registry;
|
|
11009
|
+
await ensureAuthTablesExist(db, registry);
|
|
11488
11010
|
let emailService;
|
|
11489
11011
|
if (authConfig.email) {
|
|
11490
11012
|
emailService = serverCore.createEmailService(authConfig.email);
|
|
11491
11013
|
}
|
|
11492
|
-
const
|
|
11493
|
-
const
|
|
11494
|
-
|
|
11014
|
+
const customUsersTable = registry?.getTable("users");
|
|
11015
|
+
const customRolesTable = registry?.getTable("roles");
|
|
11016
|
+
let usersSchemaName = "rebase";
|
|
11017
|
+
let rolesSchemaName = "rebase";
|
|
11018
|
+
if (customUsersTable) {
|
|
11019
|
+
usersSchemaName = pgCore.getTableConfig(customUsersTable).schema || "public";
|
|
11020
|
+
}
|
|
11021
|
+
if (customRolesTable) {
|
|
11022
|
+
rolesSchemaName = pgCore.getTableConfig(customRolesTable).schema || "public";
|
|
11023
|
+
}
|
|
11024
|
+
const authTables = createAuthSchema(rolesSchemaName, usersSchemaName);
|
|
11025
|
+
if (customUsersTable) {
|
|
11026
|
+
authTables.users = customUsersTable;
|
|
11027
|
+
}
|
|
11028
|
+
if (customRolesTable) {
|
|
11029
|
+
authTables.roles = customRolesTable;
|
|
11030
|
+
}
|
|
11031
|
+
const userService = new UserService(db, authTables);
|
|
11032
|
+
const roleService = new RoleService(db, authTables);
|
|
11033
|
+
const authRepository = new PostgresAuthRepository(db, authTables);
|
|
11495
11034
|
return {
|
|
11496
11035
|
userService,
|
|
11497
11036
|
roleService,
|
|
@@ -11523,11 +11062,54 @@ ${tableRelations.join(",\n")}
|
|
|
11523
11062
|
},
|
|
11524
11063
|
mountRoutes(app, basePath, driverResult) {
|
|
11525
11064
|
},
|
|
11526
|
-
async initializeWebsockets(server, realtimeService, driver, config) {
|
|
11065
|
+
async initializeWebsockets(server, realtimeService, driver, config, adapter) {
|
|
11527
11066
|
const {
|
|
11528
11067
|
createPostgresWebSocket: createPostgresWebSocket2
|
|
11529
11068
|
} = await Promise.resolve().then(() => websocket);
|
|
11530
|
-
createPostgresWebSocket2(server, realtimeService, driver, config);
|
|
11069
|
+
createPostgresWebSocket2(server, realtimeService, driver, config, adapter);
|
|
11070
|
+
}
|
|
11071
|
+
};
|
|
11072
|
+
}
|
|
11073
|
+
function createPostgresAdapter(pgConfig) {
|
|
11074
|
+
const bootstrapper = createPostgresBootstrapper(pgConfig);
|
|
11075
|
+
return {
|
|
11076
|
+
type: bootstrapper.type,
|
|
11077
|
+
async initializeDriver(config) {
|
|
11078
|
+
return bootstrapper.initializeDriver(config);
|
|
11079
|
+
},
|
|
11080
|
+
async initializeRealtime(driverResult) {
|
|
11081
|
+
if (bootstrapper.initializeRealtime) {
|
|
11082
|
+
return bootstrapper.initializeRealtime({}, driverResult);
|
|
11083
|
+
}
|
|
11084
|
+
return void 0;
|
|
11085
|
+
},
|
|
11086
|
+
async initializeAuth(config, driverResult) {
|
|
11087
|
+
if (bootstrapper.initializeAuth) {
|
|
11088
|
+
return bootstrapper.initializeAuth(config, driverResult);
|
|
11089
|
+
}
|
|
11090
|
+
return void 0;
|
|
11091
|
+
},
|
|
11092
|
+
async initializeHistory(config, driverResult) {
|
|
11093
|
+
if (bootstrapper.initializeHistory) {
|
|
11094
|
+
return bootstrapper.initializeHistory(config, driverResult);
|
|
11095
|
+
}
|
|
11096
|
+
return void 0;
|
|
11097
|
+
},
|
|
11098
|
+
initializeWebsockets(server, realtimeService, driver, config) {
|
|
11099
|
+
if (bootstrapper.initializeWebsockets) {
|
|
11100
|
+
return bootstrapper.initializeWebsockets(server, realtimeService, driver, config);
|
|
11101
|
+
}
|
|
11102
|
+
},
|
|
11103
|
+
getAdmin(driverResult) {
|
|
11104
|
+
if (bootstrapper.getAdmin) {
|
|
11105
|
+
return bootstrapper.getAdmin(driverResult);
|
|
11106
|
+
}
|
|
11107
|
+
return void 0;
|
|
11108
|
+
},
|
|
11109
|
+
mountRoutes(app, basePath, driverResult) {
|
|
11110
|
+
if (bootstrapper.mountRoutes) {
|
|
11111
|
+
bootstrapper.mountRoutes(app, basePath, driverResult);
|
|
11112
|
+
}
|
|
11531
11113
|
}
|
|
11532
11114
|
};
|
|
11533
11115
|
}
|
|
@@ -11541,6 +11123,8 @@ ${tableRelations.join(",\n")}
|
|
|
11541
11123
|
exports2.PostgresRealtimeProvider = PostgresRealtimeProvider;
|
|
11542
11124
|
exports2.RealtimeService = RealtimeService;
|
|
11543
11125
|
exports2.appConfig = appConfig;
|
|
11126
|
+
exports2.createAuthSchema = createAuthSchema;
|
|
11127
|
+
exports2.createPostgresAdapter = createPostgresAdapter;
|
|
11544
11128
|
exports2.createPostgresBootstrapper = createPostgresBootstrapper;
|
|
11545
11129
|
exports2.createPostgresDatabaseConnection = createPostgresDatabaseConnection;
|
|
11546
11130
|
exports2.createPostgresWebSocket = createPostgresWebSocket;
|
|
@@ -11558,6 +11142,7 @@ ${tableRelations.join(",\n")}
|
|
|
11558
11142
|
exports2.userRolesRelations = userRolesRelations;
|
|
11559
11143
|
exports2.users = users;
|
|
11560
11144
|
exports2.usersRelations = usersRelations;
|
|
11145
|
+
exports2.usersSchema = usersSchema;
|
|
11561
11146
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
11562
11147
|
});
|
|
11563
11148
|
//# sourceMappingURL=index.umd.js.map
|