@rebasepro/common 0.10.0 → 0.10.1-canary.0a881d4
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/collections/default-collections.d.ts +6 -90
- package/dist/index.es.js +19 -488
- package/dist/index.es.js.map +1 -1
- package/dist/util/collections.d.ts +1 -9
- package/dist/util/conditions.d.ts +2 -3
- package/dist/util/entities.d.ts +0 -2
- package/dist/util/index.d.ts +0 -5
- package/dist/util/permissions.d.ts +7 -4
- package/dist/util/resolutions.d.ts +5 -5
- package/package.json +4 -6
- package/src/collections/default-collections.ts +16 -32
- package/src/util/collections.ts +0 -28
- package/src/util/conditions.ts +2 -190
- package/src/util/entities.ts +0 -17
- package/src/util/index.ts +0 -5
- package/src/util/permissions.test.ts +9 -14
- package/src/util/permissions.ts +7 -4
- package/src/util/resolutions.ts +15 -7
- package/dist/util/filter-operator-resolution.d.ts +0 -32
- package/dist/util/navigation_from_path.d.ts +0 -34
- package/dist/util/navigation_utils.d.ts +0 -20
- package/dist/util/parent_references_from_path.d.ts +0 -6
- package/dist/util/references.d.ts +0 -2
- package/src/util/filter-operator-resolution.ts +0 -81
- package/src/util/navigation_from_path.ts +0 -122
- package/src/util/navigation_utils.ts +0 -170
- package/src/util/parent_references_from_path.ts +0 -58
- package/src/util/references.ts +0 -48
package/dist/index.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ANONYMOUS_USER_ID, CANONICAL_TO_REST, DEFAULT_DATA_SOURCE_KEY, EntityReference, EntityRelation, NULL_OPS, REST_TO_CANONICAL, getDataSourceCapabilities, getDeclaredSubcollections, isPostgresCollectionConfig, policy, toCanonicalOp } from "@rebasepro/types";
|
|
2
2
|
import { deepClone, generateForeignKeyName, getIn, getPolicyOperations, isDefaultFieldConfigId, mergeDeep, randomString, removeFunctions, toSnakeCase } from "@rebasepro/utils";
|
|
3
3
|
import jsonLogic from "json-logic-js";
|
|
4
4
|
import { deepEqual } from "fast-equals";
|
|
@@ -7,17 +7,6 @@ var DEFAULT_ONE_OF_TYPE = "type";
|
|
|
7
7
|
var DEFAULT_ONE_OF_VALUE = "value";
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/util/entities.ts
|
|
10
|
-
function isReadOnly(property) {
|
|
11
|
-
if (property.ui?.readOnly) return true;
|
|
12
|
-
if (property.type === "date") {
|
|
13
|
-
if (property.autoValue) return true;
|
|
14
|
-
}
|
|
15
|
-
if (property.type === "reference") return !property.path && !("Field" in (property.ui || {}) && property.ui?.Field);
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
function isHidden(property) {
|
|
19
|
-
return typeof property.ui?.disabled === "object" && Boolean(property.ui?.disabled.hidden);
|
|
20
|
-
}
|
|
21
10
|
function isPropertyBuilder(property) {
|
|
22
11
|
return typeof property?.dynamicProps === "function";
|
|
23
12
|
}
|
|
@@ -226,21 +215,6 @@ function sortProperties(properties, propertiesOrder) {
|
|
|
226
215
|
return properties;
|
|
227
216
|
}
|
|
228
217
|
}
|
|
229
|
-
function resolveDefaultSelectedView(defaultSelectedView, params) {
|
|
230
|
-
if (!defaultSelectedView) return;
|
|
231
|
-
else if (typeof defaultSelectedView === "string") return defaultSelectedView;
|
|
232
|
-
else return defaultSelectedView(params);
|
|
233
|
-
}
|
|
234
|
-
function getLocalChangesBackup(collection) {
|
|
235
|
-
if (!collection.localChangesBackup) return "manual_apply";
|
|
236
|
-
return collection.localChangesBackup;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Returns the primary keys for a entity collection by inspecting the properties
|
|
240
|
-
* and finding any properties with `isId`.
|
|
241
|
-
* Fallbacks to `["id"]` if no properties are marked as `isId: true`.
|
|
242
|
-
* @param collection
|
|
243
|
-
*/
|
|
244
218
|
function getPrimaryKeys(collection) {
|
|
245
219
|
const properties = collection.properties;
|
|
246
220
|
if (!properties) return ["id"];
|
|
@@ -724,7 +698,7 @@ function resolveArrayProperties({ propertyKey, property, ignoreMissingFields = f
|
|
|
724
698
|
...props
|
|
725
699
|
});
|
|
726
700
|
}).filter((e) => Boolean(e)) : [];
|
|
727
|
-
} else if (!
|
|
701
|
+
} else if (!property.columnType) throw Error(`The array property (${propertyKey}) needs to declare an 'of' or a 'oneOf' property, or a \`columnType\` such as "text[]"`);
|
|
728
702
|
else return [];
|
|
729
703
|
}
|
|
730
704
|
function getArrayResolvedProperties({ propertyKey, propertyValue, property, ...props }) {
|
|
@@ -1337,245 +1311,6 @@ function canDeleteEntity(collection, authContext, path, entity) {
|
|
|
1337
1311
|
return checkOperation(collection, authContext, entity, "delete");
|
|
1338
1312
|
}
|
|
1339
1313
|
//#endregion
|
|
1340
|
-
//#region src/util/references.ts
|
|
1341
|
-
function getEntityImagePreviewPropertyKey(collection) {
|
|
1342
|
-
for (const key in collection.properties) {
|
|
1343
|
-
const property = collection.properties[key];
|
|
1344
|
-
if (property.type === "string" && property.storage?.acceptedFiles?.includes("image/*")) return key;
|
|
1345
|
-
}
|
|
1346
|
-
for (const key in collection.properties) {
|
|
1347
|
-
const property = collection.properties[key];
|
|
1348
|
-
if (property.type === "array" && !Array.isArray(property.of) && property.of?.type === "string" && property.of.storage?.acceptedFiles?.includes("image/*")) return key;
|
|
1349
|
-
}
|
|
1350
|
-
for (const key in collection.properties) {
|
|
1351
|
-
const property = collection.properties[key];
|
|
1352
|
-
if (property.type === "string" && property.ui?.url === "image") return key;
|
|
1353
|
-
}
|
|
1354
|
-
for (const key in collection.properties) {
|
|
1355
|
-
const property = collection.properties[key];
|
|
1356
|
-
if (property.type === "array" && property.of && !Array.isArray(property.of) && property.of.type === "string" && property.of.ui?.url === "image") return key;
|
|
1357
|
-
}
|
|
1358
|
-
for (const key in collection.properties) {
|
|
1359
|
-
const property = collection.properties[key];
|
|
1360
|
-
if (property.type === "string" && property.storage && !property.storage.acceptedFiles) return key;
|
|
1361
|
-
}
|
|
1362
|
-
for (const key in collection.properties) {
|
|
1363
|
-
const property = collection.properties[key];
|
|
1364
|
-
if (property.type === "array" && !Array.isArray(property.of) && property.of?.type === "string" && property.of.storage && !property.of.storage.acceptedFiles) return key;
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
//#endregion
|
|
1368
|
-
//#region src/util/navigation_utils.ts
|
|
1369
|
-
function removeInitialAndTrailingSlashes(s) {
|
|
1370
|
-
return removeInitialSlash(removeTrailingSlash(s));
|
|
1371
|
-
}
|
|
1372
|
-
function removeInitialSlash(s) {
|
|
1373
|
-
if (s.startsWith("/")) return s.slice(1);
|
|
1374
|
-
else return s;
|
|
1375
|
-
}
|
|
1376
|
-
function removeTrailingSlash(s) {
|
|
1377
|
-
if (s.endsWith("/")) return s.slice(0, -1);
|
|
1378
|
-
else return s;
|
|
1379
|
-
}
|
|
1380
|
-
function addInitialSlash(s) {
|
|
1381
|
-
if (s.startsWith("/")) return s;
|
|
1382
|
-
else return `/${s}`;
|
|
1383
|
-
}
|
|
1384
|
-
function getLastSegment(path) {
|
|
1385
|
-
const cleanPath = removeInitialAndTrailingSlashes(path);
|
|
1386
|
-
if (cleanPath.includes("/")) {
|
|
1387
|
-
const segments = cleanPath.split("/");
|
|
1388
|
-
return segments[segments.length - 1];
|
|
1389
|
-
}
|
|
1390
|
-
return cleanPath;
|
|
1391
|
-
}
|
|
1392
|
-
function resolveCollectionPathIds(path, allCollections) {
|
|
1393
|
-
let remainingPath = removeInitialAndTrailingSlashes(path);
|
|
1394
|
-
if (!remainingPath) return "";
|
|
1395
|
-
let currentCollections = allCollections;
|
|
1396
|
-
const resolvedPathParts = [];
|
|
1397
|
-
while (remainingPath.length > 0) {
|
|
1398
|
-
if (!currentCollections || currentCollections.length === 0) {
|
|
1399
|
-
console.warn(`resolveCollectionPathIds: Path structure implies subcollections, but none found before segment starting with "${remainingPath}" in original path "${path}". Appending remaining original path.`);
|
|
1400
|
-
resolvedPathParts.push(remainingPath);
|
|
1401
|
-
remainingPath = "";
|
|
1402
|
-
break;
|
|
1403
|
-
}
|
|
1404
|
-
let foundMatch = false;
|
|
1405
|
-
const potentialMatches = currentCollections.flatMap((col) => [{
|
|
1406
|
-
col,
|
|
1407
|
-
match: col.slug
|
|
1408
|
-
}]).filter((p) => p.match && remainingPath.startsWith(p.match)).sort((a, b) => b.match.length - a.match.length);
|
|
1409
|
-
if (potentialMatches.length > 0) {
|
|
1410
|
-
const { col: foundCollection, match: matchString } = potentialMatches[0];
|
|
1411
|
-
resolvedPathParts.push(foundCollection.slug);
|
|
1412
|
-
remainingPath = removeInitialSlash(remainingPath.substring(matchString.length));
|
|
1413
|
-
if (remainingPath.length === 0) {
|
|
1414
|
-
foundMatch = true;
|
|
1415
|
-
break;
|
|
1416
|
-
}
|
|
1417
|
-
const idSeparatorIndex = remainingPath.indexOf("/");
|
|
1418
|
-
let entityId;
|
|
1419
|
-
if (idSeparatorIndex > -1) {
|
|
1420
|
-
entityId = remainingPath.substring(0, idSeparatorIndex);
|
|
1421
|
-
remainingPath = remainingPath.substring(idSeparatorIndex + 1);
|
|
1422
|
-
} else {
|
|
1423
|
-
entityId = remainingPath;
|
|
1424
|
-
remainingPath = "";
|
|
1425
|
-
console.warn(`resolveCollectionPathIds: Path seems to end with a entity ID "${entityId}" instead of a collection segment in original path "${path}". This might indicate an invalid input path.`);
|
|
1426
|
-
}
|
|
1427
|
-
resolvedPathParts.push(entityId);
|
|
1428
|
-
currentCollections = getSubcollections(foundCollection);
|
|
1429
|
-
foundMatch = true;
|
|
1430
|
-
if (!currentCollections && remainingPath.length > 0) {
|
|
1431
|
-
console.warn(`resolveCollectionPathIds: Path continues after entity ID "${entityId}", but no subcollections are defined for the preceding collection "${foundCollection.slug}" in path "${path}". Appending remaining original path.`);
|
|
1432
|
-
resolvedPathParts.push(remainingPath);
|
|
1433
|
-
remainingPath = "";
|
|
1434
|
-
break;
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
if (!foundMatch) {
|
|
1438
|
-
console.warn(`resolveCollectionPathIds: Collection definition not found for segment starting with "${remainingPath}" in original path "${path}". Appending remaining original path.`);
|
|
1439
|
-
resolvedPathParts.push(remainingPath);
|
|
1440
|
-
remainingPath = "";
|
|
1441
|
-
break;
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
return resolvedPathParts.join("/");
|
|
1445
|
-
}
|
|
1446
|
-
/**
|
|
1447
|
-
* Find the corresponding view at any depth for a given path.
|
|
1448
|
-
* Note that path or segments of the paths can be collection aliases.
|
|
1449
|
-
* @param slugOrPath
|
|
1450
|
-
* @param collections
|
|
1451
|
-
*/
|
|
1452
|
-
function getCollectionBySlugWithin(slugOrPath, collections) {
|
|
1453
|
-
const subpaths = removeInitialAndTrailingSlashes(slugOrPath).split("/");
|
|
1454
|
-
if (subpaths.length % 2 === 0) throw Error(`getCollectionBySlug: Collection paths must have an odd number of segments: ${slugOrPath}`);
|
|
1455
|
-
const subpathCombinations = getCollectionPathsCombinations(subpaths);
|
|
1456
|
-
let result;
|
|
1457
|
-
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
1458
|
-
const subpathCombination = subpathCombinations[i];
|
|
1459
|
-
const navigationEntry = collections && collections.sort((a, b) => (a.slug ?? "").localeCompare(b.slug ?? "")).find((entry) => entry.slug === subpathCombination);
|
|
1460
|
-
if (navigationEntry) {
|
|
1461
|
-
if (subpathCombination === slugOrPath) result = navigationEntry;
|
|
1462
|
-
else if (getSubcollections(navigationEntry).length > 0) {
|
|
1463
|
-
const newPath = slugOrPath.replace(subpathCombination, "").split("/").slice(2).join("/");
|
|
1464
|
-
if (newPath.length > 0) result = getCollectionBySlugWithin(newPath, getSubcollections(navigationEntry));
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
if (result) break;
|
|
1468
|
-
}
|
|
1469
|
-
return result;
|
|
1470
|
-
}
|
|
1471
|
-
/**
|
|
1472
|
-
* Get the subcollection combinations from a path:
|
|
1473
|
-
* "sites/es/locales" => ["sites/es/locales", "sites"]
|
|
1474
|
-
* @param subpaths
|
|
1475
|
-
*/
|
|
1476
|
-
function getCollectionPathsCombinations(subpaths) {
|
|
1477
|
-
const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.splice(0, subpaths.length - 1) : subpaths;
|
|
1478
|
-
const length = entries.length;
|
|
1479
|
-
const result = [];
|
|
1480
|
-
for (let i = length; i > 0; i = i - 2) result.push(entries.slice(0, i).join("/"));
|
|
1481
|
-
return result;
|
|
1482
|
-
}
|
|
1483
|
-
//#endregion
|
|
1484
|
-
//#region src/util/navigation_from_path.ts
|
|
1485
|
-
function getNavigationEntriesFromPath(props) {
|
|
1486
|
-
const { path, collections = [], currentFullPath } = props;
|
|
1487
|
-
const subpathCombinations = getCollectionPathsCombinations(removeInitialAndTrailingSlashes(path).split("/"));
|
|
1488
|
-
const result = [];
|
|
1489
|
-
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
1490
|
-
const subpathCombination = subpathCombinations[i];
|
|
1491
|
-
const collection = collections && collections.find((entry) => entry.slug === subpathCombination);
|
|
1492
|
-
if (collection) {
|
|
1493
|
-
const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + collection.slug : collection.slug;
|
|
1494
|
-
result.push({
|
|
1495
|
-
type: "collection",
|
|
1496
|
-
id: collection.slug,
|
|
1497
|
-
slug: collectionPath,
|
|
1498
|
-
path: collectionPath,
|
|
1499
|
-
collection
|
|
1500
|
-
});
|
|
1501
|
-
const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
|
|
1502
|
-
const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
|
|
1503
|
-
if (nextSegments.length > 0) {
|
|
1504
|
-
const entityId = nextSegments[0];
|
|
1505
|
-
const path = collectionPath + "/" + entityId;
|
|
1506
|
-
result.push({
|
|
1507
|
-
type: "entity",
|
|
1508
|
-
entityId,
|
|
1509
|
-
slug: collectionPath,
|
|
1510
|
-
path,
|
|
1511
|
-
parentCollection: collection
|
|
1512
|
-
});
|
|
1513
|
-
if (nextSegments.length > 1) {
|
|
1514
|
-
const newPath = nextSegments.slice(1).join("/");
|
|
1515
|
-
if (!collection) throw Error("collection not found resolving path: " + collection);
|
|
1516
|
-
const entityViews = collection.entityViews;
|
|
1517
|
-
const customView = entityViews && entityViews.map((entry) => resolveEntityView(entry, props.contextEntityViews)).filter((v) => v != null).find((entry) => entry.key === newPath);
|
|
1518
|
-
const subcollections = getSubcollections(collection);
|
|
1519
|
-
if (customView) result.push({
|
|
1520
|
-
type: "custom_view",
|
|
1521
|
-
slug: collectionPath,
|
|
1522
|
-
entityId,
|
|
1523
|
-
path: path + "/" + customView.key,
|
|
1524
|
-
view: customView
|
|
1525
|
-
});
|
|
1526
|
-
else if (subcollections) result.push(...getNavigationEntriesFromPath({
|
|
1527
|
-
path: newPath,
|
|
1528
|
-
collections: subcollections,
|
|
1529
|
-
currentFullPath: path,
|
|
1530
|
-
contextEntityViews: props.contextEntityViews
|
|
1531
|
-
}));
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
break;
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
return result;
|
|
1538
|
-
}
|
|
1539
|
-
function resolveEntityView(entityView, contextEntityViews) {
|
|
1540
|
-
if (typeof entityView === "string") return contextEntityViews?.find((entry) => entry.key === entityView);
|
|
1541
|
-
else return entityView;
|
|
1542
|
-
}
|
|
1543
|
-
//#endregion
|
|
1544
|
-
//#region src/util/parent_references_from_path.ts
|
|
1545
|
-
function getParentReferencesFromPath(props) {
|
|
1546
|
-
const { path, collections = [], currentFullPath } = props;
|
|
1547
|
-
const subpathCombinations = getCollectionPathsCombinations(removeInitialAndTrailingSlashes(path).split("/"));
|
|
1548
|
-
const result = [];
|
|
1549
|
-
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
1550
|
-
const subpathCombination = subpathCombinations[i];
|
|
1551
|
-
const collection = collections && collections.find((entry) => entry.slug === subpathCombination);
|
|
1552
|
-
if (collection) {
|
|
1553
|
-
const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + collection.slug : collection.slug;
|
|
1554
|
-
const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
|
|
1555
|
-
const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
|
|
1556
|
-
if (nextSegments.length > 0) {
|
|
1557
|
-
const entityId = nextSegments[0];
|
|
1558
|
-
const path = collectionPath + "/" + entityId;
|
|
1559
|
-
result.push(new EntityReference({
|
|
1560
|
-
id: entityId,
|
|
1561
|
-
path: collectionPath
|
|
1562
|
-
}));
|
|
1563
|
-
if (nextSegments.length > 1) {
|
|
1564
|
-
const newPath = nextSegments.slice(1).join("/");
|
|
1565
|
-
if (!collection) throw Error("collection not found resolving path: " + collection);
|
|
1566
|
-
if (getSubcollections(collection).length > 0) result.push(...getParentReferencesFromPath({
|
|
1567
|
-
path: newPath,
|
|
1568
|
-
collections: getSubcollections(collection),
|
|
1569
|
-
currentFullPath: path
|
|
1570
|
-
}));
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
break;
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
return result;
|
|
1577
|
-
}
|
|
1578
|
-
//#endregion
|
|
1579
1314
|
//#region src/util/builders.ts
|
|
1580
1315
|
/**
|
|
1581
1316
|
* @deprecated Use {@link defineCollection} instead — it infers property
|
|
@@ -2168,171 +1903,6 @@ function buildConditionContext(params) {
|
|
|
2168
1903
|
/**
|
|
2169
1904
|
* Apply PropertyConditions to a resolved property, evaluating all JSON Logic rules.
|
|
2170
1905
|
*/
|
|
2171
|
-
function applyPropertyConditions(property, context) {
|
|
2172
|
-
const { conditions } = property;
|
|
2173
|
-
if (!conditions) return property;
|
|
2174
|
-
const result = { ...property };
|
|
2175
|
-
if (conditions.disabled) {
|
|
2176
|
-
if (evaluateCondition(conditions.disabled, context)) {
|
|
2177
|
-
result.ui = result.ui || {};
|
|
2178
|
-
result.ui.disabled = {
|
|
2179
|
-
clearOnDisabled: conditions.clearOnDisabled ?? false,
|
|
2180
|
-
disabledMessage: conditions.disabledMessage,
|
|
2181
|
-
hidden: false
|
|
2182
|
-
};
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
if (conditions.hidden) {
|
|
2186
|
-
if (evaluateCondition(conditions.hidden, context)) {
|
|
2187
|
-
result.ui = result.ui || {};
|
|
2188
|
-
result.ui.disabled = {
|
|
2189
|
-
...typeof result.ui?.disabled === "object" ? result.ui.disabled : {},
|
|
2190
|
-
hidden: true,
|
|
2191
|
-
clearOnDisabled: conditions.clearOnDisabled ?? false
|
|
2192
|
-
};
|
|
2193
|
-
}
|
|
2194
|
-
}
|
|
2195
|
-
if (conditions.readOnly) {
|
|
2196
|
-
if (evaluateCondition(conditions.readOnly, context)) {
|
|
2197
|
-
result.ui = result.ui || {};
|
|
2198
|
-
result.ui.readOnly = true;
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
if (conditions.required !== void 0) {
|
|
2202
|
-
const isRequired = evaluateCondition(conditions.required, context);
|
|
2203
|
-
result.validation = {
|
|
2204
|
-
...result.validation,
|
|
2205
|
-
required: isRequired,
|
|
2206
|
-
requiredMessage: conditions.requiredMessage
|
|
2207
|
-
};
|
|
2208
|
-
}
|
|
2209
|
-
if (context.isNew && conditions.defaultValue !== void 0) result.defaultValue = evaluateCondition(conditions.defaultValue, context);
|
|
2210
|
-
if ("enum" in result && result.enum && (conditions.enumConditions || conditions.allowedEnumValues || conditions.excludedEnumValues)) result.enum = applyEnumConditions(result.enum, conditions, context);
|
|
2211
|
-
if (result.type === "reference") {
|
|
2212
|
-
if (conditions.referencePath) result.path = evaluateCondition(conditions.referencePath, context);
|
|
2213
|
-
if (conditions.referenceFilter) result.fixedFilter = evaluateCondition(conditions.referenceFilter, context);
|
|
2214
|
-
}
|
|
2215
|
-
if (result.type === "array") {
|
|
2216
|
-
if (conditions.canAddElements !== void 0) result.canAddElements = evaluateCondition(conditions.canAddElements, context);
|
|
2217
|
-
if (conditions.sortable !== void 0) result.sortable = evaluateCondition(conditions.sortable, context);
|
|
2218
|
-
}
|
|
2219
|
-
return result;
|
|
2220
|
-
}
|
|
2221
|
-
/**
|
|
2222
|
-
* Convert an object with numeric keys back to an array.
|
|
2223
|
-
* Firestore stores arrays as {"0": "a", "1": "b"} to avoid nested arrays.
|
|
2224
|
-
*/
|
|
2225
|
-
function objectToArray(obj) {
|
|
2226
|
-
if (Array.isArray(obj)) return obj.map(String);
|
|
2227
|
-
if (obj && typeof obj === "object") {
|
|
2228
|
-
const keys = Object.keys(obj);
|
|
2229
|
-
if (keys.length > 0 && keys.every((k) => !isNaN(Number(k)))) return keys.sort((a, b) => Number(a) - Number(b)).map((k) => obj[k]).filter((v) => typeof v === "string" || typeof v === "number").map(String);
|
|
2230
|
-
}
|
|
2231
|
-
return [];
|
|
2232
|
-
}
|
|
2233
|
-
/**
|
|
2234
|
-
* Apply enum-specific conditions to filter and modify enum values.
|
|
2235
|
-
*/
|
|
2236
|
-
function applyEnumConditions(enumValues, conditions, context) {
|
|
2237
|
-
let result = [...enumValues];
|
|
2238
|
-
if (conditions.allowedEnumValues) {
|
|
2239
|
-
const allowedArray = objectToArray(evaluateCondition(conditions.allowedEnumValues, context));
|
|
2240
|
-
if (allowedArray.length > 0) result = result.filter((ev) => allowedArray.includes(String(ev.id)));
|
|
2241
|
-
}
|
|
2242
|
-
if (conditions.excludedEnumValues) {
|
|
2243
|
-
const excludedArray = objectToArray(evaluateCondition(conditions.excludedEnumValues, context));
|
|
2244
|
-
if (excludedArray.length > 0) result = result.filter((ev) => !excludedArray.includes(String(ev.id)));
|
|
2245
|
-
}
|
|
2246
|
-
if (conditions.enumConditions) result = result.map((ev) => {
|
|
2247
|
-
const evConditions = conditions.enumConditions?.[ev.id];
|
|
2248
|
-
if (!evConditions) return ev;
|
|
2249
|
-
if (evConditions.hidden && evaluateCondition(evConditions.hidden, context)) return null;
|
|
2250
|
-
if (evConditions.disabled && evaluateCondition(evConditions.disabled, context)) return {
|
|
2251
|
-
...ev,
|
|
2252
|
-
disabled: true
|
|
2253
|
-
};
|
|
2254
|
-
return ev;
|
|
2255
|
-
}).filter((ev) => ev !== null);
|
|
2256
|
-
return result;
|
|
2257
|
-
}
|
|
2258
|
-
//#endregion
|
|
2259
|
-
//#region src/util/filter-operator-resolution.ts
|
|
2260
|
-
/**
|
|
2261
|
-
* Default operators offered per property type, before engine capabilities and
|
|
2262
|
-
* per-property narrowing are applied. These mirror what the built-in filter
|
|
2263
|
-
* fields can render.
|
|
2264
|
-
*/
|
|
2265
|
-
var COMPARISON_OPS = [
|
|
2266
|
-
"==",
|
|
2267
|
-
"!=",
|
|
2268
|
-
">",
|
|
2269
|
-
">=",
|
|
2270
|
-
"<",
|
|
2271
|
-
"<="
|
|
2272
|
-
];
|
|
2273
|
-
var NULL_CHECK_OPS = ["is-null", "is-not-null"];
|
|
2274
|
-
var MEMBERSHIP_OPS = ["in", "not-in"];
|
|
2275
|
-
var PATTERN_OPS = [
|
|
2276
|
-
"like",
|
|
2277
|
-
"ilike",
|
|
2278
|
-
"not-like",
|
|
2279
|
-
"not-ilike"
|
|
2280
|
-
];
|
|
2281
|
-
var DEFAULT_OPS_BY_TYPE = {
|
|
2282
|
-
string: [
|
|
2283
|
-
...COMPARISON_OPS,
|
|
2284
|
-
...MEMBERSHIP_OPS,
|
|
2285
|
-
...PATTERN_OPS,
|
|
2286
|
-
...NULL_CHECK_OPS
|
|
2287
|
-
],
|
|
2288
|
-
number: [
|
|
2289
|
-
...COMPARISON_OPS,
|
|
2290
|
-
...MEMBERSHIP_OPS,
|
|
2291
|
-
...NULL_CHECK_OPS
|
|
2292
|
-
],
|
|
2293
|
-
date: [...COMPARISON_OPS, ...NULL_CHECK_OPS],
|
|
2294
|
-
boolean: [
|
|
2295
|
-
"==",
|
|
2296
|
-
"!=",
|
|
2297
|
-
...NULL_CHECK_OPS
|
|
2298
|
-
],
|
|
2299
|
-
reference: [
|
|
2300
|
-
"==",
|
|
2301
|
-
"!=",
|
|
2302
|
-
...MEMBERSHIP_OPS,
|
|
2303
|
-
...NULL_CHECK_OPS
|
|
2304
|
-
],
|
|
2305
|
-
relation: [
|
|
2306
|
-
"==",
|
|
2307
|
-
"!=",
|
|
2308
|
-
...MEMBERSHIP_OPS,
|
|
2309
|
-
...NULL_CHECK_OPS
|
|
2310
|
-
]
|
|
2311
|
-
};
|
|
2312
|
-
/** Operators offered when the property is an *array of* a filterable type. */
|
|
2313
|
-
var ARRAY_OPS = ["array-contains", "array-contains-any"];
|
|
2314
|
-
/**
|
|
2315
|
-
* Resolve which filter operators the UI should offer for a property.
|
|
2316
|
-
*
|
|
2317
|
-
* The result is the **intersection** of three sets:
|
|
2318
|
-
* 1. what the engine can execute — {@link DataSourceCapabilities.filterOperators}
|
|
2319
|
-
* (e.g. Firestore cannot run the LIKE family);
|
|
2320
|
-
* 2. what makes sense for the property type (e.g. no `>` on booleans);
|
|
2321
|
-
* 3. the developer's optional narrowing — `property.ui.filterOperators`.
|
|
2322
|
-
*
|
|
2323
|
-
* Returns an empty array when the property is not filterable (either by
|
|
2324
|
-
* type, or because the developer disabled it with `filterOperators: []`).
|
|
2325
|
-
*
|
|
2326
|
-
* @group Models
|
|
2327
|
-
*/
|
|
2328
|
-
function resolveFilterOperators({ property, isArray, engine }) {
|
|
2329
|
-
const typeDefaults = isArray ? ARRAY_OPS : DEFAULT_OPS_BY_TYPE[property.type] ?? [];
|
|
2330
|
-
if (typeDefaults.length === 0) return [];
|
|
2331
|
-
const engineOps = new Set(getDataSourceCapabilities(engine).filterOperators ?? ALL_WHERE_FILTER_OPS);
|
|
2332
|
-
const narrowing = property.ui?.filterOperators;
|
|
2333
|
-
const narrowingSet = narrowing !== void 0 ? new Set(narrowing) : void 0;
|
|
2334
|
-
return typeDefaults.filter((op) => engineOps.has(op) && (narrowingSet === void 0 || narrowingSet.has(op)));
|
|
2335
|
-
}
|
|
2336
1906
|
//#endregion
|
|
2337
1907
|
//#region src/data/resolveDataSource.ts
|
|
2338
1908
|
/**
|
|
@@ -2694,6 +2264,12 @@ var CollectionRegistry = class {
|
|
|
2694
2264
|
* Prepended to the developer's collections array by the admin and server.
|
|
2695
2265
|
* Slug-based dedup (Map keyed by slug, last-write-wins) lets developers
|
|
2696
2266
|
* override by defining their own collection with `slug: "users"`.
|
|
2267
|
+
*
|
|
2268
|
+
* Schema only — no `admin` block. This package is on the backend's dependency path,
|
|
2269
|
+
* where that field does not exist: `@rebasepro/admin-types` adds it by declaration
|
|
2270
|
+
* merging, and a BaaS install never installs that. The scaffolded
|
|
2271
|
+
* `config/collections/users.ts` carries the presentation for projects that want this
|
|
2272
|
+
* collection in their panel, which is also where it is editable.
|
|
2697
2273
|
*/
|
|
2698
2274
|
var defaultUsersCollection = defineCollection({
|
|
2699
2275
|
name: "Users",
|
|
@@ -2702,10 +2278,6 @@ var defaultUsersCollection = defineCollection({
|
|
|
2702
2278
|
auth: true,
|
|
2703
2279
|
table: "users",
|
|
2704
2280
|
schema: "rebase",
|
|
2705
|
-
icon: "Users",
|
|
2706
|
-
group: "Settings",
|
|
2707
|
-
openEntityMode: "dialog",
|
|
2708
|
-
disableDefaultActions: ["copy"],
|
|
2709
2281
|
securityRules: [{
|
|
2710
2282
|
operation: "select",
|
|
2711
2283
|
roles: ["admin"]
|
|
@@ -2717,13 +2289,11 @@ var defaultUsersCollection = defineCollection({
|
|
|
2717
2289
|
],
|
|
2718
2290
|
roles: ["admin"]
|
|
2719
2291
|
}],
|
|
2720
|
-
sort: ["createdAt", "desc"],
|
|
2721
2292
|
properties: {
|
|
2722
2293
|
id: {
|
|
2723
2294
|
name: "ID",
|
|
2724
2295
|
type: "string",
|
|
2725
|
-
isId: "uuid"
|
|
2726
|
-
ui: { readOnly: true }
|
|
2296
|
+
isId: "uuid"
|
|
2727
2297
|
},
|
|
2728
2298
|
email: {
|
|
2729
2299
|
name: "Email",
|
|
@@ -2742,8 +2312,7 @@ var defaultUsersCollection = defineCollection({
|
|
|
2742
2312
|
photoURL: {
|
|
2743
2313
|
name: "Photo URL",
|
|
2744
2314
|
type: "string",
|
|
2745
|
-
columnName: "photo_url"
|
|
2746
|
-
ui: { url: "image" }
|
|
2315
|
+
columnName: "photo_url"
|
|
2747
2316
|
},
|
|
2748
2317
|
roles: {
|
|
2749
2318
|
name: "Roles",
|
|
@@ -2763,83 +2332,45 @@ var defaultUsersCollection = defineCollection({
|
|
|
2763
2332
|
name: "Password Hash",
|
|
2764
2333
|
type: "string",
|
|
2765
2334
|
columnName: "password_hash",
|
|
2766
|
-
excludeFromApi: true
|
|
2767
|
-
ui: {
|
|
2768
|
-
hideFromCollection: true,
|
|
2769
|
-
disabled: { hidden: true }
|
|
2770
|
-
}
|
|
2335
|
+
excludeFromApi: true
|
|
2771
2336
|
},
|
|
2772
2337
|
emailVerified: {
|
|
2773
2338
|
name: "Email Verified",
|
|
2774
2339
|
type: "boolean",
|
|
2775
2340
|
columnName: "email_verified",
|
|
2776
|
-
defaultValue: false
|
|
2777
|
-
ui: {
|
|
2778
|
-
hideFromCollection: true,
|
|
2779
|
-
disabled: { hidden: true }
|
|
2780
|
-
}
|
|
2341
|
+
defaultValue: false
|
|
2781
2342
|
},
|
|
2782
2343
|
emailVerificationToken: {
|
|
2783
2344
|
name: "Email Verification Token",
|
|
2784
2345
|
type: "string",
|
|
2785
2346
|
columnName: "email_verification_token",
|
|
2786
|
-
excludeFromApi: true
|
|
2787
|
-
ui: {
|
|
2788
|
-
hideFromCollection: true,
|
|
2789
|
-
disabled: { hidden: true }
|
|
2790
|
-
}
|
|
2347
|
+
excludeFromApi: true
|
|
2791
2348
|
},
|
|
2792
2349
|
emailVerificationSentAt: {
|
|
2793
2350
|
name: "Email Verification Sent At",
|
|
2794
2351
|
type: "date",
|
|
2795
|
-
columnName: "email_verification_sent_at"
|
|
2796
|
-
ui: {
|
|
2797
|
-
hideFromCollection: true,
|
|
2798
|
-
disabled: { hidden: true }
|
|
2799
|
-
}
|
|
2352
|
+
columnName: "email_verification_sent_at"
|
|
2800
2353
|
},
|
|
2801
2354
|
metadata: {
|
|
2802
2355
|
name: "Metadata",
|
|
2803
2356
|
type: "map",
|
|
2804
2357
|
keyValue: true,
|
|
2805
2358
|
properties: {},
|
|
2806
|
-
defaultValue: {}
|
|
2807
|
-
ui: {
|
|
2808
|
-
hideFromCollection: true,
|
|
2809
|
-
disabled: { hidden: true }
|
|
2810
|
-
}
|
|
2359
|
+
defaultValue: {}
|
|
2811
2360
|
},
|
|
2812
2361
|
createdAt: {
|
|
2813
2362
|
name: "Created At",
|
|
2814
2363
|
type: "date",
|
|
2815
2364
|
columnName: "created_at",
|
|
2816
|
-
autoValue: "on_create"
|
|
2817
|
-
ui: { readOnly: true }
|
|
2365
|
+
autoValue: "on_create"
|
|
2818
2366
|
},
|
|
2819
2367
|
updatedAt: {
|
|
2820
2368
|
name: "Updated At",
|
|
2821
2369
|
type: "date",
|
|
2822
2370
|
columnName: "updated_at",
|
|
2823
|
-
autoValue: "on_update"
|
|
2824
|
-
ui: {
|
|
2825
|
-
hideFromCollection: true,
|
|
2826
|
-
disabled: { hidden: true }
|
|
2827
|
-
}
|
|
2371
|
+
autoValue: "on_update"
|
|
2828
2372
|
}
|
|
2829
|
-
}
|
|
2830
|
-
listProperties: [
|
|
2831
|
-
"displayName",
|
|
2832
|
-
"email",
|
|
2833
|
-
"roles",
|
|
2834
|
-
"createdAt"
|
|
2835
|
-
],
|
|
2836
|
-
propertiesOrder: [
|
|
2837
|
-
"id",
|
|
2838
|
-
"email",
|
|
2839
|
-
"displayName",
|
|
2840
|
-
"roles",
|
|
2841
|
-
"createdAt"
|
|
2842
|
-
]
|
|
2373
|
+
}
|
|
2843
2374
|
});
|
|
2844
2375
|
//#endregion
|
|
2845
2376
|
//#region src/data/query_builder.ts
|
|
@@ -3825,6 +3356,6 @@ async function detectJunctionTables(executeSql) {
|
|
|
3825
3356
|
return junctionTables;
|
|
3826
3357
|
}
|
|
3827
3358
|
//#endregion
|
|
3828
|
-
export { COLLECTION_PATH_SEPARATOR, COMPOSITE_ID_SEPARATOR, CollectionRegistry, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, JUNCTION_TABLES_SQL, QueryBuilder, REBASE_INTERNAL_PREFIXES, REBASE_INTERNAL_SCHEMAS,
|
|
3359
|
+
export { COLLECTION_PATH_SEPARATOR, COMPOSITE_ID_SEPARATOR, CollectionRegistry, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, JUNCTION_TABLES_SQL, QueryBuilder, REBASE_INTERNAL_PREFIXES, REBASE_INTERNAL_SCHEMAS, and, buildCollection, buildCompositeId, buildConditionContext, buildProperty, buildPropertyCallbacks, buildRebaseData, buildRoutedRebaseData, buildSdkData, canCreateEntity, canDeleteEntity, canEditEntity, canReadCollection, checkOperation, classifyTable, cond, createDataSourceRegistry, createRelationRef, createRelationRefWithData, defaultUsersCollection, defineCollection, deserializeFilter, deserializeLogicalCondition, deserializeOrderBy, detectJunctionTables, embedParentExpression, enumToObjectEntries, evaluateCondition, evaluatePolicy, findAnonymousGrants, findRelation, fullPathToCollectionSegments, getArrayResolvedProperties, getColumnName, getDeclaredPrimaryKeys, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEffectiveSecurityRules, getEnumVarName, getInjectedSecurityRules, getJunctionCollectionConfig, getJunctionSecurityRules, getLabelOrConfigFrom, getPrimaryKeys, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, getTableVarName, isPropertyBuilder, isRebaseInternalTable, normalizeToEntityRelation, or, parseIdValues, policyToPostgres, registerConditionOperations, resolveArrayProperties, resolveCollectionRelations, resolveDataSource, resolveEnumValues, resolveJunctionSpecs, resolvePrimaryKeys, resolveProperties, resolveProperty, resolvePropertyEnum, resolvePropertyRelation, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource, sanitizeData, sanitizeRelation, securityRuleToConditions, segmentsToStrippedPath, serializeFilter, serializeLogicalCondition, serializeOrderBy, sortProperties, sqlToPolicy, stripCollectionPath, traverseValueProperty, traverseValuesProperties, updateDateAutoValues, wrapAsEntityData, wrapAsSdkData };
|
|
3829
3360
|
|
|
3830
3361
|
//# sourceMappingURL=index.es.js.map
|