@rebasepro/server-core 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/src/data/query_builder.d.ts +51 -0
- package/dist/common/src/index.d.ts +1 -0
- package/dist/index.es.js +174 -162
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +174 -162
- package/dist/index.umd.js.map +1 -1
- package/dist/types/src/controllers/data.d.ts +21 -0
- package/jest.config.cjs +4 -1
- package/package.json +6 -6
package/dist/index.umd.js
CHANGED
|
@@ -1156,42 +1156,6 @@
|
|
|
1156
1156
|
});
|
|
1157
1157
|
}
|
|
1158
1158
|
}
|
|
1159
|
-
function getSubcollections(collection) {
|
|
1160
|
-
if (collection.childCollections) {
|
|
1161
|
-
return collection.childCollections() ?? [];
|
|
1162
|
-
}
|
|
1163
|
-
if (getDataSourceCapabilities(collection.driver).supportsSubcollections && collection.subcollections) {
|
|
1164
|
-
return collection.subcollections() ?? [];
|
|
1165
|
-
}
|
|
1166
|
-
if (getDataSourceCapabilities(collection.driver).supportsRelations && collection.relations) {
|
|
1167
|
-
const manyRelations = collection.relations.filter((r) => r.cardinality === "many");
|
|
1168
|
-
return manyRelations.map((r) => {
|
|
1169
|
-
const target = r.target();
|
|
1170
|
-
if (!target) return void 0;
|
|
1171
|
-
const relationKey = r.relationName || target.slug;
|
|
1172
|
-
let customName;
|
|
1173
|
-
if (collection.properties) {
|
|
1174
|
-
const prop = Object.entries(collection.properties).find(([_, p]) => p.type === "relation" && p.relationName === relationKey);
|
|
1175
|
-
if (prop && prop[1].name) {
|
|
1176
|
-
customName = prop[1].name;
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
const baseOverrides = {
|
|
1180
|
-
slug: relationKey
|
|
1181
|
-
};
|
|
1182
|
-
if (customName) {
|
|
1183
|
-
baseOverrides.name = customName;
|
|
1184
|
-
baseOverrides.singularName = customName;
|
|
1185
|
-
}
|
|
1186
|
-
const targetWithOverrides = {
|
|
1187
|
-
...target,
|
|
1188
|
-
...baseOverrides
|
|
1189
|
-
};
|
|
1190
|
-
return r.overrides ? mergeDeep(targetWithOverrides, r.overrides) : targetWithOverrides;
|
|
1191
|
-
}).filter((c) => Boolean(c));
|
|
1192
|
-
}
|
|
1193
|
-
return [];
|
|
1194
|
-
}
|
|
1195
1159
|
function sanitizeRelation(relation, sourceCollection, resolveCollection) {
|
|
1196
1160
|
if (!relation.target) {
|
|
1197
1161
|
throw new Error("Relation is missing a `target` collection.");
|
|
@@ -1223,6 +1187,8 @@
|
|
|
1223
1187
|
} else {
|
|
1224
1188
|
targetCollection = evaluated;
|
|
1225
1189
|
}
|
|
1190
|
+
} else if (rawTarget && typeof rawTarget === "object") {
|
|
1191
|
+
targetCollection = rawTarget;
|
|
1226
1192
|
}
|
|
1227
1193
|
if (!targetCollection) {
|
|
1228
1194
|
throw new Error("Relation is missing a valid `target` collection.");
|
|
@@ -1342,11 +1308,14 @@
|
|
|
1342
1308
|
const registeredRelationNames = /* @__PURE__ */ new Set();
|
|
1343
1309
|
if (relCollection.relations) {
|
|
1344
1310
|
relCollection.relations.forEach((relation) => {
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1311
|
+
try {
|
|
1312
|
+
const normalizedRelation = sanitizeRelation(relation, collection);
|
|
1313
|
+
const relationKey = normalizedRelation.relationName;
|
|
1314
|
+
if (relationKey) {
|
|
1315
|
+
relations[relationKey] = normalizedRelation;
|
|
1316
|
+
registeredRelationNames.add(relationKey);
|
|
1317
|
+
}
|
|
1318
|
+
} catch (e) {
|
|
1350
1319
|
}
|
|
1351
1320
|
});
|
|
1352
1321
|
}
|
|
@@ -1394,12 +1363,8 @@
|
|
|
1394
1363
|
overrides: relProp.overrides
|
|
1395
1364
|
};
|
|
1396
1365
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
console.warn(`Unrecognized relation format for property '${propertyKey}' in collection '${sourceCollection.slug}'`);
|
|
1400
|
-
return void 0;
|
|
1401
|
-
}
|
|
1402
|
-
return relation;
|
|
1366
|
+
console.warn(`Unrecognized or missing relation target for property '${propertyKey}' in collection '${sourceCollection.slug}'`);
|
|
1367
|
+
return void 0;
|
|
1403
1368
|
}
|
|
1404
1369
|
function getTableName(collection) {
|
|
1405
1370
|
if (getDataSourceCapabilities(collection.driver).supportsRelations) {
|
|
@@ -1415,6 +1380,43 @@
|
|
|
1415
1380
|
if (snakeKey !== key && resolvedRelations[snakeKey]) return resolvedRelations[snakeKey];
|
|
1416
1381
|
return void 0;
|
|
1417
1382
|
}
|
|
1383
|
+
function getSubcollections(collection) {
|
|
1384
|
+
if (collection.childCollections) {
|
|
1385
|
+
return collection.childCollections() ?? [];
|
|
1386
|
+
}
|
|
1387
|
+
if (getDataSourceCapabilities(collection.driver).supportsSubcollections && collection.subcollections) {
|
|
1388
|
+
return collection.subcollections() ?? [];
|
|
1389
|
+
}
|
|
1390
|
+
if (getDataSourceCapabilities(collection.driver).supportsRelations) {
|
|
1391
|
+
const resolvedRelations = resolveCollectionRelations(collection);
|
|
1392
|
+
const manyRelations = Object.values(resolvedRelations).filter((r) => r.cardinality === "many");
|
|
1393
|
+
return manyRelations.map((r) => {
|
|
1394
|
+
const target = r.target();
|
|
1395
|
+
if (!target) return void 0;
|
|
1396
|
+
const relationKey = r.relationName || target.slug;
|
|
1397
|
+
let customName;
|
|
1398
|
+
if (collection.properties) {
|
|
1399
|
+
const prop = Object.entries(collection.properties).find(([_, p]) => p.type === "relation" && p.relationName === relationKey);
|
|
1400
|
+
if (prop && prop[1].name) {
|
|
1401
|
+
customName = prop[1].name;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
const baseOverrides = {
|
|
1405
|
+
slug: relationKey
|
|
1406
|
+
};
|
|
1407
|
+
if (customName) {
|
|
1408
|
+
baseOverrides.name = customName;
|
|
1409
|
+
baseOverrides.singularName = customName;
|
|
1410
|
+
}
|
|
1411
|
+
const targetWithOverrides = {
|
|
1412
|
+
...target,
|
|
1413
|
+
...baseOverrides
|
|
1414
|
+
};
|
|
1415
|
+
return r.overrides ? mergeDeep(targetWithOverrides, r.overrides) : targetWithOverrides;
|
|
1416
|
+
}).filter((c) => Boolean(c));
|
|
1417
|
+
}
|
|
1418
|
+
return [];
|
|
1419
|
+
}
|
|
1418
1420
|
var logic = { exports: {} };
|
|
1419
1421
|
(function(module2, exports3) {
|
|
1420
1422
|
(function(root, factory) {
|
|
@@ -2322,8 +2324,18 @@
|
|
|
2322
2324
|
const mergedRelationsRaw = [...extractedRelations];
|
|
2323
2325
|
for (const manual of manualRelations) {
|
|
2324
2326
|
const name2 = manual.relationName;
|
|
2325
|
-
if (!name2
|
|
2327
|
+
if (!name2) {
|
|
2326
2328
|
mergedRelationsRaw.push(manual);
|
|
2329
|
+
} else {
|
|
2330
|
+
const existingIndex = mergedRelationsRaw.findIndex((r) => r.relationName === name2);
|
|
2331
|
+
if (existingIndex === -1) {
|
|
2332
|
+
mergedRelationsRaw.push(manual);
|
|
2333
|
+
} else {
|
|
2334
|
+
mergedRelationsRaw[existingIndex] = {
|
|
2335
|
+
...manual,
|
|
2336
|
+
...mergedRelationsRaw[existingIndex]
|
|
2337
|
+
};
|
|
2338
|
+
}
|
|
2327
2339
|
}
|
|
2328
2340
|
}
|
|
2329
2341
|
let mergedRelations = mergedRelationsRaw;
|
|
@@ -2543,6 +2555,118 @@
|
|
|
2543
2555
|
};
|
|
2544
2556
|
}
|
|
2545
2557
|
}
|
|
2558
|
+
function mapOperator$1(op) {
|
|
2559
|
+
switch (op) {
|
|
2560
|
+
case "==":
|
|
2561
|
+
return "eq";
|
|
2562
|
+
case "!=":
|
|
2563
|
+
return "neq";
|
|
2564
|
+
case ">":
|
|
2565
|
+
return "gt";
|
|
2566
|
+
case ">=":
|
|
2567
|
+
return "gte";
|
|
2568
|
+
case "<":
|
|
2569
|
+
return "lt";
|
|
2570
|
+
case "<=":
|
|
2571
|
+
return "lte";
|
|
2572
|
+
case "array-contains":
|
|
2573
|
+
return "cs";
|
|
2574
|
+
case "array-contains-any":
|
|
2575
|
+
return "csa";
|
|
2576
|
+
case "not-in":
|
|
2577
|
+
return "nin";
|
|
2578
|
+
default:
|
|
2579
|
+
return op;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
class QueryBuilder {
|
|
2583
|
+
constructor(collection) {
|
|
2584
|
+
this.collection = collection;
|
|
2585
|
+
}
|
|
2586
|
+
params = {
|
|
2587
|
+
where: {}
|
|
2588
|
+
};
|
|
2589
|
+
/**
|
|
2590
|
+
* Add a filter condition to your query.
|
|
2591
|
+
* @example
|
|
2592
|
+
* client.collection('users').where('age', '>=', 18).find()
|
|
2593
|
+
*/
|
|
2594
|
+
where(column, operator, value) {
|
|
2595
|
+
if (!this.params.where) {
|
|
2596
|
+
this.params.where = {};
|
|
2597
|
+
}
|
|
2598
|
+
const mappedOp = mapOperator$1(operator);
|
|
2599
|
+
let formattedValue = value;
|
|
2600
|
+
if (Array.isArray(value) && ["in", "nin", "cs", "csa"].includes(mappedOp)) {
|
|
2601
|
+
formattedValue = `(${value.join(",")})`;
|
|
2602
|
+
} else if (value === null) {
|
|
2603
|
+
formattedValue = "null";
|
|
2604
|
+
}
|
|
2605
|
+
this.params.where[column] = mappedOp === "eq" ? String(formattedValue) : `${mappedOp}.${formattedValue}`;
|
|
2606
|
+
return this;
|
|
2607
|
+
}
|
|
2608
|
+
/**
|
|
2609
|
+
* Order the results by a specific column.
|
|
2610
|
+
* @example
|
|
2611
|
+
* client.collection('users').orderBy('createdAt', 'desc').find()
|
|
2612
|
+
*/
|
|
2613
|
+
orderBy(column, ascending = "asc") {
|
|
2614
|
+
this.params.orderBy = `${column}:${ascending}`;
|
|
2615
|
+
return this;
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Limit the number of results returned.
|
|
2619
|
+
*/
|
|
2620
|
+
limit(count) {
|
|
2621
|
+
this.params.limit = count;
|
|
2622
|
+
return this;
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2625
|
+
* Skip the first N results.
|
|
2626
|
+
*/
|
|
2627
|
+
offset(count) {
|
|
2628
|
+
this.params.offset = count;
|
|
2629
|
+
return this;
|
|
2630
|
+
}
|
|
2631
|
+
/**
|
|
2632
|
+
* Set a free-text search string if supported by the backend.
|
|
2633
|
+
*/
|
|
2634
|
+
search(searchString) {
|
|
2635
|
+
this.params.searchString = searchString;
|
|
2636
|
+
return this;
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Include related entities in the response.
|
|
2640
|
+
* Relations will be populated with full entity data instead of just IDs.
|
|
2641
|
+
*
|
|
2642
|
+
* @param relations - Relation names to include, or "*" for all.
|
|
2643
|
+
* @example
|
|
2644
|
+
* // Include specific relations
|
|
2645
|
+
* client.data.posts.include("tags", "author").find()
|
|
2646
|
+
*
|
|
2647
|
+
* // Include all relations
|
|
2648
|
+
* client.data.posts.include("*").find()
|
|
2649
|
+
*/
|
|
2650
|
+
include(...relations) {
|
|
2651
|
+
this.params.include = relations;
|
|
2652
|
+
return this;
|
|
2653
|
+
}
|
|
2654
|
+
/**
|
|
2655
|
+
* Execute the find query and return the results.
|
|
2656
|
+
*/
|
|
2657
|
+
async find() {
|
|
2658
|
+
return this.collection.find(this.params);
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* Listen to realtime updates matching this query.
|
|
2662
|
+
*/
|
|
2663
|
+
listen(onUpdate, onError) {
|
|
2664
|
+
if (!this.collection.listen) {
|
|
2665
|
+
throw new Error("Listen is only available when RebaseClient is configured with a websocketUrl.");
|
|
2666
|
+
}
|
|
2667
|
+
return this.collection.listen(this.params, onUpdate, onError);
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2546
2670
|
class BackendCollectionRegistry extends CollectionRegistry {
|
|
2547
2671
|
/**
|
|
2548
2672
|
* Get the available relation keys for a given collection path.
|
|
@@ -2770,7 +2894,7 @@
|
|
|
2770
2894
|
};
|
|
2771
2895
|
return map2[code2];
|
|
2772
2896
|
}
|
|
2773
|
-
function mapOperator
|
|
2897
|
+
function mapOperator(op) {
|
|
2774
2898
|
switch (op) {
|
|
2775
2899
|
case "eq":
|
|
2776
2900
|
return "==";
|
|
@@ -2815,7 +2939,7 @@
|
|
|
2815
2939
|
if (parts.length >= 2) {
|
|
2816
2940
|
const op = parts[0];
|
|
2817
2941
|
const val = parts.slice(1).join(".");
|
|
2818
|
-
const rebaseOp = mapOperator
|
|
2942
|
+
const rebaseOp = mapOperator(op);
|
|
2819
2943
|
if (rebaseOp) {
|
|
2820
2944
|
let parsedVal = val;
|
|
2821
2945
|
if (val === "true") parsedVal = true;
|
|
@@ -25028,118 +25152,6 @@ ${credentialScope}
|
|
|
25028
25152
|
toggleJob
|
|
25029
25153
|
};
|
|
25030
25154
|
}
|
|
25031
|
-
function mapOperator(op) {
|
|
25032
|
-
switch (op) {
|
|
25033
|
-
case "==":
|
|
25034
|
-
return "eq";
|
|
25035
|
-
case "!=":
|
|
25036
|
-
return "neq";
|
|
25037
|
-
case ">":
|
|
25038
|
-
return "gt";
|
|
25039
|
-
case ">=":
|
|
25040
|
-
return "gte";
|
|
25041
|
-
case "<":
|
|
25042
|
-
return "lt";
|
|
25043
|
-
case "<=":
|
|
25044
|
-
return "lte";
|
|
25045
|
-
case "array-contains":
|
|
25046
|
-
return "cs";
|
|
25047
|
-
case "array-contains-any":
|
|
25048
|
-
return "csa";
|
|
25049
|
-
case "not-in":
|
|
25050
|
-
return "nin";
|
|
25051
|
-
default:
|
|
25052
|
-
return op;
|
|
25053
|
-
}
|
|
25054
|
-
}
|
|
25055
|
-
class QueryBuilder {
|
|
25056
|
-
constructor(collection) {
|
|
25057
|
-
this.collection = collection;
|
|
25058
|
-
}
|
|
25059
|
-
params = {
|
|
25060
|
-
where: {}
|
|
25061
|
-
};
|
|
25062
|
-
/**
|
|
25063
|
-
* Add a filter condition to your query.
|
|
25064
|
-
* @example
|
|
25065
|
-
* client.collection('users').where('age', '>=', 18).find()
|
|
25066
|
-
*/
|
|
25067
|
-
where(column, operator, value) {
|
|
25068
|
-
if (!this.params.where) {
|
|
25069
|
-
this.params.where = {};
|
|
25070
|
-
}
|
|
25071
|
-
const mappedOp = mapOperator(operator);
|
|
25072
|
-
let formattedValue = value;
|
|
25073
|
-
if (Array.isArray(value) && ["in", "nin", "cs", "csa"].includes(mappedOp)) {
|
|
25074
|
-
formattedValue = `(${value.join(",")})`;
|
|
25075
|
-
} else if (value === null) {
|
|
25076
|
-
formattedValue = "null";
|
|
25077
|
-
}
|
|
25078
|
-
this.params.where[column] = mappedOp === "eq" ? String(formattedValue) : `${mappedOp}.${formattedValue}`;
|
|
25079
|
-
return this;
|
|
25080
|
-
}
|
|
25081
|
-
/**
|
|
25082
|
-
* Order the results by a specific column.
|
|
25083
|
-
* @example
|
|
25084
|
-
* client.collection('users').orderBy('createdAt', 'desc').find()
|
|
25085
|
-
*/
|
|
25086
|
-
orderBy(column, ascending = "asc") {
|
|
25087
|
-
this.params.orderBy = `${column}:${ascending}`;
|
|
25088
|
-
return this;
|
|
25089
|
-
}
|
|
25090
|
-
/**
|
|
25091
|
-
* Limit the number of results returned.
|
|
25092
|
-
*/
|
|
25093
|
-
limit(count) {
|
|
25094
|
-
this.params.limit = count;
|
|
25095
|
-
return this;
|
|
25096
|
-
}
|
|
25097
|
-
/**
|
|
25098
|
-
* Skip the first N results.
|
|
25099
|
-
*/
|
|
25100
|
-
offset(count) {
|
|
25101
|
-
this.params.offset = count;
|
|
25102
|
-
return this;
|
|
25103
|
-
}
|
|
25104
|
-
/**
|
|
25105
|
-
* Set a free-text search string if supported by the backend.
|
|
25106
|
-
*/
|
|
25107
|
-
search(searchString) {
|
|
25108
|
-
this.params.searchString = searchString;
|
|
25109
|
-
return this;
|
|
25110
|
-
}
|
|
25111
|
-
/**
|
|
25112
|
-
* Include related entities in the response.
|
|
25113
|
-
* Relations will be populated with full entity data instead of just IDs.
|
|
25114
|
-
*
|
|
25115
|
-
* @param relations - Relation names to include, or "*" for all.
|
|
25116
|
-
* @example
|
|
25117
|
-
* // Include specific relations
|
|
25118
|
-
* client.data.posts.include("tags", "author").find()
|
|
25119
|
-
*
|
|
25120
|
-
* // Include all relations
|
|
25121
|
-
* client.data.posts.include("*").find()
|
|
25122
|
-
*/
|
|
25123
|
-
include(...relations) {
|
|
25124
|
-
this.params.include = relations;
|
|
25125
|
-
return this;
|
|
25126
|
-
}
|
|
25127
|
-
/**
|
|
25128
|
-
* Execute the find query and return the results.
|
|
25129
|
-
*/
|
|
25130
|
-
async find() {
|
|
25131
|
-
return this.collection.find(this.params);
|
|
25132
|
-
}
|
|
25133
|
-
/**
|
|
25134
|
-
* Listen to realtime updates matching this query.
|
|
25135
|
-
*/
|
|
25136
|
-
listen(onUpdate, onError) {
|
|
25137
|
-
if (!this.collection.listen) {
|
|
25138
|
-
throw new Error("Listen is only available when RebaseClient is configured with a websocketUrl.");
|
|
25139
|
-
}
|
|
25140
|
-
return this.collection.listen(this.params, onUpdate, onError);
|
|
25141
|
-
}
|
|
25142
|
-
}
|
|
25143
25155
|
function rowToEntity(row, slug) {
|
|
25144
25156
|
return {
|
|
25145
25157
|
id: row.id,
|