@rebasepro/common 0.9.1-canary.ad25bc0 → 0.9.1-canary.b10dcdf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.es.js +233 -20
- package/dist/index.es.js.map +1 -1
- package/dist/util/identity.d.ts +20 -9
- package/dist/util/index.d.ts +1 -0
- package/dist/util/junction-policies.d.ts +108 -0
- package/package.json +3 -3
- package/src/data/buildRebaseData.ts +5 -1
- package/src/util/identity.ts +20 -9
- package/src/util/index.ts +1 -0
- package/src/util/junction-policies.ts +353 -0
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ALL_WHERE_FILTER_OPS, 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
|
-
import { deepClone, generateForeignKeyName, getIn, isDefaultFieldConfigId, mergeDeep, randomString, removeFunctions, toSnakeCase } from "@rebasepro/utils";
|
|
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";
|
|
5
5
|
//#region src/util/common.ts
|
|
@@ -300,12 +300,17 @@ function parseIdValues(idValue, primaryKeys) {
|
|
|
300
300
|
/**
|
|
301
301
|
* The primary keys of a collection, as declared by its properties.
|
|
302
302
|
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
303
|
+
* This is the only tier both sides can read, because it is the only one written
|
|
304
|
+
* in the config: the postgres driver can also infer keys from the Drizzle
|
|
305
|
+
* schema, which the browser never sees and is never sent — the admin compiles
|
|
306
|
+
* the collection files into its own bundle rather than being served them. A key
|
|
307
|
+
* that lives only in the Drizzle schema is therefore invisible here, and the
|
|
308
|
+
* server says so at boot (`warnOnKeysTheAdminCannotResolve`) naming the `isId`
|
|
309
|
+
* to add.
|
|
310
|
+
*
|
|
311
|
+
* Returns an empty array when a collection declares none, which callers must
|
|
312
|
+
* treat as "not addressable" rather than defaulting to `id`: guessing a key
|
|
313
|
+
* that is not the real one produces confidently wrong addresses.
|
|
309
314
|
*/
|
|
310
315
|
function getDeclaredPrimaryKeys(collection) {
|
|
311
316
|
const properties = collection.properties;
|
|
@@ -330,9 +335,15 @@ function getDeclaredPrimaryKeys(collection) {
|
|
|
330
335
|
* The postgres driver tries, in order: properties marked `isId`; the primary
|
|
331
336
|
* keys of the Drizzle schema; and finally a column literally named `id`. Only
|
|
332
337
|
* the first and last are visible in a `CollectionConfig`, which is what both
|
|
333
|
-
* sides share
|
|
334
|
-
*
|
|
335
|
-
*
|
|
338
|
+
* sides share.
|
|
339
|
+
*
|
|
340
|
+
* So the two agree except on a collection that declares no `isId` and whose key
|
|
341
|
+
* is known only to Drizzle. There, the driver reads the real key, and this
|
|
342
|
+
* either resolves nothing (reported to the console by the caller) or — if the
|
|
343
|
+
* table happens to have an unrelated `id` property — resolves `id`, which is
|
|
344
|
+
* the wrong key and cannot be detected from here: the addresses look right and
|
|
345
|
+
* route wrong. Only the config can settle it, so the server names both cases
|
|
346
|
+
* at boot (`warnOnKeysTheAdminCannotResolve`) with the `isId` to add.
|
|
336
347
|
*/
|
|
337
348
|
function resolvePrimaryKeys(collection) {
|
|
338
349
|
const declared = getDeclaredPrimaryKeys(collection);
|
|
@@ -1791,7 +1802,7 @@ var buildPropertyCallbacks = (properties) => {
|
|
|
1791
1802
|
* Opt out with `disableDefaultPolicies: true` to take full responsibility for
|
|
1792
1803
|
* the collection's RLS.
|
|
1793
1804
|
*/
|
|
1794
|
-
var SERVER_OR_ADMIN_EXPR = policy.or(policy.serverContext(), policy.rolesOverlap(["admin"]));
|
|
1805
|
+
var SERVER_OR_ADMIN_EXPR$1 = policy.or(policy.serverContext(), policy.rolesOverlap(["admin"]));
|
|
1795
1806
|
/** Write operations that must be admin-gated by default on auth collections. */
|
|
1796
1807
|
var DEFAULT_GUARDED_OPS = [
|
|
1797
1808
|
"insert",
|
|
@@ -1804,7 +1815,7 @@ function isAuthCollection(collection) {
|
|
|
1804
1815
|
return auth === true || typeof auth === "object" && auth?.enabled === true;
|
|
1805
1816
|
}
|
|
1806
1817
|
/** The property marked as the row id (falls back to `id`). */
|
|
1807
|
-
function getIdPropertyName(collection) {
|
|
1818
|
+
function getIdPropertyName$1(collection) {
|
|
1808
1819
|
for (const [name, prop] of Object.entries(collection.properties ?? {})) if (prop && typeof prop === "object" && "isId" in prop && prop.isId) return name;
|
|
1809
1820
|
return "id";
|
|
1810
1821
|
}
|
|
@@ -1824,26 +1835,26 @@ function getEffectiveSecurityRules(collection) {
|
|
|
1824
1835
|
injected.push({
|
|
1825
1836
|
name: `${tableName}_default_admin_read`,
|
|
1826
1837
|
operations: ["select"],
|
|
1827
|
-
condition: SERVER_OR_ADMIN_EXPR
|
|
1838
|
+
condition: SERVER_OR_ADMIN_EXPR$1
|
|
1828
1839
|
});
|
|
1829
1840
|
injected.push({
|
|
1830
1841
|
name: `${tableName}_default_admin_write`,
|
|
1831
1842
|
operations: [...DEFAULT_GUARDED_OPS],
|
|
1832
|
-
condition: SERVER_OR_ADMIN_EXPR,
|
|
1833
|
-
check: SERVER_OR_ADMIN_EXPR
|
|
1843
|
+
condition: SERVER_OR_ADMIN_EXPR$1,
|
|
1844
|
+
check: SERVER_OR_ADMIN_EXPR$1
|
|
1834
1845
|
});
|
|
1835
1846
|
if (isAuthCollection(collection)) {
|
|
1836
1847
|
injected.push({
|
|
1837
1848
|
name: `${tableName}_default_self_read`,
|
|
1838
1849
|
operations: ["select"],
|
|
1839
|
-
condition: policy.compare(policy.field(getIdPropertyName(collection)), "eq", policy.authUid())
|
|
1850
|
+
condition: policy.compare(policy.field(getIdPropertyName$1(collection)), "eq", policy.authUid())
|
|
1840
1851
|
});
|
|
1841
1852
|
injected.push({
|
|
1842
1853
|
name: `${tableName}_require_admin_write`,
|
|
1843
1854
|
mode: "restrictive",
|
|
1844
1855
|
operations: [...DEFAULT_GUARDED_OPS],
|
|
1845
|
-
condition: SERVER_OR_ADMIN_EXPR,
|
|
1846
|
-
check: SERVER_OR_ADMIN_EXPR
|
|
1856
|
+
condition: SERVER_OR_ADMIN_EXPR$1,
|
|
1857
|
+
check: SERVER_OR_ADMIN_EXPR$1
|
|
1847
1858
|
});
|
|
1848
1859
|
}
|
|
1849
1860
|
return [...explicit, ...injected];
|
|
@@ -1865,6 +1876,208 @@ function getInjectedSecurityRules(collection) {
|
|
|
1865
1876
|
return getEffectiveSecurityRules(collection).slice(explicitCount);
|
|
1866
1877
|
}
|
|
1867
1878
|
//#endregion
|
|
1879
|
+
//#region src/util/junction-policies.ts
|
|
1880
|
+
var SERVER_OR_ADMIN_EXPR = policy.or(policy.serverContext(), policy.rolesOverlap(["admin"]));
|
|
1881
|
+
/**
|
|
1882
|
+
* Walk every collection's resolved relations and aggregate the junction tables
|
|
1883
|
+
* they declare. Two collections may declare the same junction from opposite
|
|
1884
|
+
* sides (posts→tags and tags→posts through `posts_tags`); both become
|
|
1885
|
+
* `declaringSides` of one spec, so derived write grants consider both.
|
|
1886
|
+
*/
|
|
1887
|
+
function resolveJunctionSpecs(collections) {
|
|
1888
|
+
const specs = /* @__PURE__ */ new Map();
|
|
1889
|
+
for (const collection of collections) {
|
|
1890
|
+
const resolved = resolveCollectionRelations(collection);
|
|
1891
|
+
for (const relation of Object.values(resolved)) {
|
|
1892
|
+
if (!relation.through) continue;
|
|
1893
|
+
const targetCollection = typeof relation.target === "function" ? relation.target() : void 0;
|
|
1894
|
+
if (!targetCollection) continue;
|
|
1895
|
+
const rawName = relation.through.table;
|
|
1896
|
+
const table = rawName.includes(".") ? rawName.split(".").pop() : rawName;
|
|
1897
|
+
const schema = "public";
|
|
1898
|
+
const source = {
|
|
1899
|
+
collection,
|
|
1900
|
+
junctionColumn: relation.through.sourceColumn,
|
|
1901
|
+
relation
|
|
1902
|
+
};
|
|
1903
|
+
const target = {
|
|
1904
|
+
collection: targetCollection,
|
|
1905
|
+
junctionColumn: relation.through.targetColumn
|
|
1906
|
+
};
|
|
1907
|
+
const existing = specs.get(table);
|
|
1908
|
+
if (!existing) specs.set(table, {
|
|
1909
|
+
table,
|
|
1910
|
+
schema,
|
|
1911
|
+
endpoints: [source, target],
|
|
1912
|
+
declaringSides: [source]
|
|
1913
|
+
});
|
|
1914
|
+
else if (!existing.declaringSides.some((s) => s.collection === collection)) existing.declaringSides.push(source);
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
return specs;
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* A synthetic CollectionConfig standing in for the junction during policy
|
|
1921
|
+
* compilation and naming. Its two FK columns carry explicit `columnName`s so
|
|
1922
|
+
* `outerField` operands resolve to the exact columns the CREATE TABLE emitted,
|
|
1923
|
+
* whatever their casing.
|
|
1924
|
+
*/
|
|
1925
|
+
function getJunctionCollectionConfig(spec) {
|
|
1926
|
+
const properties = {};
|
|
1927
|
+
for (const endpoint of spec.endpoints) properties[endpoint.junctionColumn] = {
|
|
1928
|
+
type: "string",
|
|
1929
|
+
columnName: endpoint.junctionColumn
|
|
1930
|
+
};
|
|
1931
|
+
return {
|
|
1932
|
+
slug: spec.table,
|
|
1933
|
+
name: spec.table,
|
|
1934
|
+
table: spec.table,
|
|
1935
|
+
schema: spec.schema,
|
|
1936
|
+
properties
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1939
|
+
/** The property marked as the row id (falls back to `id`). */
|
|
1940
|
+
function getIdPropertyName(collection) {
|
|
1941
|
+
for (const [name, prop] of Object.entries(collection.properties ?? {})) if (prop && typeof prop === "object" && "isId" in prop && prop.isId) return name;
|
|
1942
|
+
return "id";
|
|
1943
|
+
}
|
|
1944
|
+
/** `EXISTS (SELECT 1 FROM endpoint WHERE endpoint.pk = junction.fk [AND extra])`. */
|
|
1945
|
+
function existsEndpoint(endpoint, extra) {
|
|
1946
|
+
const correlation = policy.compare(policy.field(getIdPropertyName(endpoint.collection)), "eq", policy.outerField(endpoint.junctionColumn));
|
|
1947
|
+
return policy.existsIn({
|
|
1948
|
+
collection: endpoint.collection.slug,
|
|
1949
|
+
where: extra ? policy.and(correlation, extra) : correlation
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1952
|
+
/**
|
|
1953
|
+
* Whether a parent-rule expression keeps its meaning when moved inside the
|
|
1954
|
+
* junction's `EXISTS` subquery — and the re-scoped copy if it does.
|
|
1955
|
+
*
|
|
1956
|
+
* Returns `null` when the rule cannot be embedded faithfully: `raw` SQL
|
|
1957
|
+
* anywhere (its `{column}` placeholders would bind to the junction), or an
|
|
1958
|
+
* `outerField` inside a nested `existsIn` (it would bind to the junction while
|
|
1959
|
+
* the author meant the parent, and no operand can express "the middle scope").
|
|
1960
|
+
* Top-level `outerField`s are rewritten to `field`, which is what they meant.
|
|
1961
|
+
*/
|
|
1962
|
+
function embedParentExpression(expr, depth = 0) {
|
|
1963
|
+
switch (expr.kind) {
|
|
1964
|
+
case "raw": return null;
|
|
1965
|
+
case "and":
|
|
1966
|
+
case "or": {
|
|
1967
|
+
const parts = [];
|
|
1968
|
+
for (const child of expr.operands) {
|
|
1969
|
+
const embedded = embedParentExpression(child, depth);
|
|
1970
|
+
if (!embedded) return null;
|
|
1971
|
+
parts.push(embedded);
|
|
1972
|
+
}
|
|
1973
|
+
return expr.kind === "and" ? policy.and(...parts) : policy.or(...parts);
|
|
1974
|
+
}
|
|
1975
|
+
case "not": {
|
|
1976
|
+
const embedded = embedParentExpression(expr.operand, depth);
|
|
1977
|
+
return embedded ? policy.not(embedded) : null;
|
|
1978
|
+
}
|
|
1979
|
+
case "existsIn": {
|
|
1980
|
+
const where = embedParentExpression(expr.where, depth + 1);
|
|
1981
|
+
return where ? policy.existsIn({
|
|
1982
|
+
collection: expr.collection,
|
|
1983
|
+
where
|
|
1984
|
+
}) : null;
|
|
1985
|
+
}
|
|
1986
|
+
case "compare": {
|
|
1987
|
+
const left = embedOperand(expr.left, depth);
|
|
1988
|
+
const right = embedOperand(expr.right, depth);
|
|
1989
|
+
if (!left || !right) return null;
|
|
1990
|
+
return {
|
|
1991
|
+
...expr,
|
|
1992
|
+
left,
|
|
1993
|
+
right
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
default: return expr;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
/** Re-scope an operand, or return `null` if its binding cannot be preserved. */
|
|
2000
|
+
function embedOperand(operand, depth) {
|
|
2001
|
+
if (operand.kind === "outerField") {
|
|
2002
|
+
if (depth === 0) return policy.field(operand.name);
|
|
2003
|
+
return null;
|
|
2004
|
+
}
|
|
2005
|
+
return operand;
|
|
2006
|
+
}
|
|
2007
|
+
/** Does the rule cover the `update` operation? */
|
|
2008
|
+
function coversUpdate(rule) {
|
|
2009
|
+
return getPolicyOperations(rule).some((op) => op === "update" || op === "all");
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* The full derived policy set for a junction table: the locked server/admin
|
|
2013
|
+
* baseline, the endpoint-visibility read grant, inherited write grants, and
|
|
2014
|
+
* inherited restrictive gates. Returns `[]` when every declaring collection set
|
|
2015
|
+
* `disableDefaultPolicies` — the junction is then the author's to police, and
|
|
2016
|
+
* stays locked (RLS is still enabled) until they write policies for it.
|
|
2017
|
+
*/
|
|
2018
|
+
function getJunctionSecurityRules(spec) {
|
|
2019
|
+
if (spec.declaringSides.every((side) => side.collection.disableDefaultPolicies)) return [];
|
|
2020
|
+
const rules = [];
|
|
2021
|
+
rules.push({
|
|
2022
|
+
name: `${spec.table}_default_admin_read`,
|
|
2023
|
+
operations: ["select"],
|
|
2024
|
+
condition: SERVER_OR_ADMIN_EXPR
|
|
2025
|
+
});
|
|
2026
|
+
rules.push({
|
|
2027
|
+
name: `${spec.table}_default_admin_write`,
|
|
2028
|
+
operations: [
|
|
2029
|
+
"insert",
|
|
2030
|
+
"update",
|
|
2031
|
+
"delete"
|
|
2032
|
+
],
|
|
2033
|
+
condition: SERVER_OR_ADMIN_EXPR,
|
|
2034
|
+
check: SERVER_OR_ADMIN_EXPR
|
|
2035
|
+
});
|
|
2036
|
+
rules.push({
|
|
2037
|
+
name: `${spec.table}_default_edge_read`,
|
|
2038
|
+
operations: ["select"],
|
|
2039
|
+
condition: policy.and(existsEndpoint(spec.endpoints[0]), existsEndpoint(spec.endpoints[1]))
|
|
2040
|
+
});
|
|
2041
|
+
const writeGrants = [];
|
|
2042
|
+
for (const side of spec.declaringSides) {
|
|
2043
|
+
const updateRules = ((isPostgresCollectionConfig(side.collection) ? side.collection.securityRules : void 0) ?? []).filter(coversUpdate);
|
|
2044
|
+
const permissive = updateRules.filter((r) => r.mode !== "restrictive");
|
|
2045
|
+
const restrictive = updateRules.filter((r) => r.mode === "restrictive");
|
|
2046
|
+
const embeddedGates = [];
|
|
2047
|
+
let gatesEmbeddable = true;
|
|
2048
|
+
for (const gate of restrictive) {
|
|
2049
|
+
const using = securityRuleToConditions(gate).usingExpr;
|
|
2050
|
+
const embedded = using ? embedParentExpression(using) : null;
|
|
2051
|
+
if (!embedded) {
|
|
2052
|
+
gatesEmbeddable = false;
|
|
2053
|
+
break;
|
|
2054
|
+
}
|
|
2055
|
+
embeddedGates.push(embedded);
|
|
2056
|
+
}
|
|
2057
|
+
if (!gatesEmbeddable) continue;
|
|
2058
|
+
const grants = [];
|
|
2059
|
+
for (const rule of permissive) {
|
|
2060
|
+
const using = securityRuleToConditions(rule).usingExpr;
|
|
2061
|
+
const embedded = using ? embedParentExpression(using) : null;
|
|
2062
|
+
if (embedded) grants.push(embedded);
|
|
2063
|
+
}
|
|
2064
|
+
if (grants.length === 0) continue;
|
|
2065
|
+
const condition = embeddedGates.length > 0 ? policy.and(policy.or(...grants), ...embeddedGates) : policy.or(...grants);
|
|
2066
|
+
writeGrants.push(existsEndpoint(side, condition));
|
|
2067
|
+
}
|
|
2068
|
+
if (writeGrants.length > 0) rules.push({
|
|
2069
|
+
name: `${spec.table}_default_edge_write`,
|
|
2070
|
+
operations: [
|
|
2071
|
+
"insert",
|
|
2072
|
+
"update",
|
|
2073
|
+
"delete"
|
|
2074
|
+
],
|
|
2075
|
+
condition: writeGrants.length === 1 ? writeGrants[0] : policy.or(...writeGrants),
|
|
2076
|
+
check: writeGrants.length === 1 ? writeGrants[0] : policy.or(...writeGrants)
|
|
2077
|
+
});
|
|
2078
|
+
return rules;
|
|
2079
|
+
}
|
|
2080
|
+
//#endregion
|
|
1868
2081
|
//#region src/util/conditions.ts
|
|
1869
2082
|
/**
|
|
1870
2083
|
* Access a nested property from an object via dot notation.
|
|
@@ -3012,7 +3225,7 @@ function createPrimaryKeyResolver(options) {
|
|
|
3012
3225
|
}
|
|
3013
3226
|
if (!warned.has(slug)) {
|
|
3014
3227
|
warned.add(slug);
|
|
3015
|
-
console.warn(`[rebase] Collection '${slug}' declares no primary key, so its rows have no address: detail links, caching and relations will not work for it. Mark the key property with \`isId\` in its collection config.`);
|
|
3228
|
+
console.warn(`[rebase] Collection '${slug}' declares no primary key, so its rows have no address: detail links, caching and relations will not work for it. Mark the key property with \`isId\` in its collection config — the server logs which column to mark at boot, if its schema knows the key.`);
|
|
3016
3229
|
}
|
|
3017
3230
|
return keys;
|
|
3018
3231
|
};
|
|
@@ -3610,6 +3823,6 @@ async function detectJunctionTables(executeSql) {
|
|
|
3610
3823
|
return junctionTables;
|
|
3611
3824
|
}
|
|
3612
3825
|
//#endregion
|
|
3613
|
-
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, addInitialSlash, and, applyPropertyConditions, buildCollection, buildCompositeId, buildConditionContext, buildProperty, buildPropertyCallbacks, buildRebaseData, buildRoutedRebaseData, buildSdkData, canCreateEntity, canDeleteEntity, canEditEntity, canReadCollection, checkOperation, classifyTable, cond, createDataSourceRegistry, createRelationRef, createRelationRefWithData, defaultUsersCollection, defineCollection, deserializeFilter, deserializeLogicalCondition, deserializeOrderBy, detectJunctionTables, enumToObjectEntries, evaluateCondition, evaluatePolicy, findAnonymousGrants, findRelation, fullPathToCollectionSegments, getArrayResolvedProperties, getCollectionBySlugWithin, getCollectionPathsCombinations, getColumnName, getDeclaredPrimaryKeys, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEffectiveSecurityRules, getEntityImagePreviewPropertyKey, getEnumVarName, getInjectedSecurityRules, getLabelOrConfigFrom, getLastSegment, getLocalChangesBackup, getNavigationEntriesFromPath, getParentReferencesFromPath, getPrimaryKeys, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, getTableVarName, isHidden, isPropertyBuilder, isReadOnly, isRebaseInternalTable, normalizeToEntityRelation, or, parseIdValues, policyToPostgres, registerConditionOperations, removeInitialAndTrailingSlashes, removeInitialSlash, removeTrailingSlash, resolveArrayProperties, resolveCollectionPathIds, resolveCollectionRelations, resolveDataSource, resolveDefaultSelectedView, resolveEnumValues, resolveFilterOperators, resolvePrimaryKeys, resolveProperties, resolveProperty, resolvePropertyEnum, resolvePropertyRelation, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource, sanitizeData, sanitizeRelation, securityRuleToConditions, segmentsToStrippedPath, serializeFilter, serializeLogicalCondition, serializeOrderBy, sortProperties, sqlToPolicy, stripCollectionPath, traverseValueProperty, traverseValuesProperties, updateDateAutoValues, wrapAsEntityData, wrapAsSdkData };
|
|
3826
|
+
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, addInitialSlash, and, applyPropertyConditions, 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, getCollectionBySlugWithin, getCollectionPathsCombinations, getColumnName, getDeclaredPrimaryKeys, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEffectiveSecurityRules, getEntityImagePreviewPropertyKey, getEnumVarName, getInjectedSecurityRules, getJunctionCollectionConfig, getJunctionSecurityRules, getLabelOrConfigFrom, getLastSegment, getLocalChangesBackup, getNavigationEntriesFromPath, getParentReferencesFromPath, getPrimaryKeys, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, getTableVarName, isHidden, isPropertyBuilder, isReadOnly, isRebaseInternalTable, normalizeToEntityRelation, or, parseIdValues, policyToPostgres, registerConditionOperations, removeInitialAndTrailingSlashes, removeInitialSlash, removeTrailingSlash, resolveArrayProperties, resolveCollectionPathIds, resolveCollectionRelations, resolveDataSource, resolveDefaultSelectedView, resolveEnumValues, resolveFilterOperators, 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 };
|
|
3614
3827
|
|
|
3615
3828
|
//# sourceMappingURL=index.es.js.map
|