@rebasepro/common 0.3.0 → 0.5.0
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/README.md +73 -220
- package/dist/collections/default-collections.d.ts +5 -8
- package/dist/data/query_builder.d.ts +6 -2
- package/dist/index.es.js +153 -78
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +153 -78
- package/dist/index.umd.js.map +1 -1
- package/dist/util/permissions.d.ts +14 -6
- package/package.json +3 -3
- package/src/collections/CollectionRegistry.ts +1 -1
- package/src/collections/default-collections.ts +62 -30
- package/src/data/buildRebaseData.ts +28 -8
- package/src/data/query_builder.ts +37 -27
- package/src/util/permissions.ts +25 -21
package/dist/index.es.js
CHANGED
|
@@ -907,14 +907,14 @@ function evaluateRule(rule, auth, entity) {
|
|
|
907
907
|
if (rule.withCheck && !evaluateAST(rule.withCheck, auth, entity)) return false;
|
|
908
908
|
return true;
|
|
909
909
|
}
|
|
910
|
-
function checkOperation(collection,
|
|
910
|
+
function checkOperation(collection, authContext, entity, targetOperation) {
|
|
911
911
|
const securityRules = getDataSourceCapabilities(collection.driver).supportsRLS ? collection.securityRules : void 0;
|
|
912
912
|
if (!securityRules || securityRules.length === 0) {
|
|
913
913
|
return true;
|
|
914
914
|
}
|
|
915
915
|
const applicableRules = securityRules.filter((r) => r.operation === targetOperation || r.operation === "all" || r.operations?.includes(targetOperation) || r.operations?.includes("all"));
|
|
916
916
|
if (applicableRules.length === 0) return false;
|
|
917
|
-
const userRoleIds =
|
|
917
|
+
const userRoleIds = authContext.user?.roles ?? [];
|
|
918
918
|
const userRoles = [...userRoleIds, "public"];
|
|
919
919
|
const roleApplicableRules = applicableRules.filter((rule) => {
|
|
920
920
|
if (!rule.roles || rule.roles.length === 0) return true;
|
|
@@ -925,7 +925,7 @@ function checkOperation(collection, authController, entity, targetOperation) {
|
|
|
925
925
|
let deniedByRestrictive = false;
|
|
926
926
|
for (const rule of roleApplicableRules) {
|
|
927
927
|
const mode = rule.mode || "permissive";
|
|
928
|
-
const passed = evaluateRule(rule,
|
|
928
|
+
const passed = evaluateRule(rule, authContext, entity);
|
|
929
929
|
if (mode === "restrictive" && !passed) {
|
|
930
930
|
deniedByRestrictive = true;
|
|
931
931
|
break;
|
|
@@ -942,17 +942,17 @@ function checkOperation(collection, authController, entity, targetOperation) {
|
|
|
942
942
|
return false;
|
|
943
943
|
}
|
|
944
944
|
}
|
|
945
|
-
function canReadCollection(collection,
|
|
946
|
-
return checkOperation(collection,
|
|
945
|
+
function canReadCollection(collection, authContext) {
|
|
946
|
+
return checkOperation(collection, authContext, null, "select");
|
|
947
947
|
}
|
|
948
|
-
function canEditEntity(collection,
|
|
949
|
-
return checkOperation(collection,
|
|
948
|
+
function canEditEntity(collection, authContext, path, entity) {
|
|
949
|
+
return checkOperation(collection, authContext, entity, "update");
|
|
950
950
|
}
|
|
951
|
-
function canCreateEntity(collection,
|
|
952
|
-
return checkOperation(collection,
|
|
951
|
+
function canCreateEntity(collection, authContext, path, entity) {
|
|
952
|
+
return checkOperation(collection, authContext, entity, "insert");
|
|
953
953
|
}
|
|
954
|
-
function canDeleteEntity(collection,
|
|
955
|
-
return checkOperation(collection,
|
|
954
|
+
function canDeleteEntity(collection, authContext, path, entity) {
|
|
955
|
+
return checkOperation(collection, authContext, entity, "delete");
|
|
956
956
|
}
|
|
957
957
|
function getEntityImagePreviewPropertyKey(collection) {
|
|
958
958
|
for (const key in collection.properties) {
|
|
@@ -1971,11 +1971,24 @@ const defaultUsersCollection = {
|
|
|
1971
1971
|
schema: "rebase",
|
|
1972
1972
|
icon: "Users",
|
|
1973
1973
|
group: "Settings",
|
|
1974
|
+
openEntityMode: "dialog",
|
|
1975
|
+
disableDefaultActions: ["copy"],
|
|
1976
|
+
securityRules: [{
|
|
1977
|
+
operation: "select",
|
|
1978
|
+
roles: ["admin"]
|
|
1979
|
+
}, {
|
|
1980
|
+
operations: ["insert", "update", "delete"],
|
|
1981
|
+
roles: ["admin"]
|
|
1982
|
+
}],
|
|
1983
|
+
sort: ["createdAt", "desc"],
|
|
1974
1984
|
properties: {
|
|
1975
1985
|
id: {
|
|
1976
1986
|
name: "ID",
|
|
1977
1987
|
type: "string",
|
|
1978
|
-
isId: "uuid"
|
|
1988
|
+
isId: "uuid",
|
|
1989
|
+
ui: {
|
|
1990
|
+
readOnly: true
|
|
1991
|
+
}
|
|
1979
1992
|
},
|
|
1980
1993
|
email: {
|
|
1981
1994
|
name: "Email",
|
|
@@ -1985,38 +1998,77 @@ const defaultUsersCollection = {
|
|
|
1985
1998
|
unique: true
|
|
1986
1999
|
}
|
|
1987
2000
|
},
|
|
1988
|
-
|
|
1989
|
-
name: "
|
|
2001
|
+
displayName: {
|
|
2002
|
+
name: "Name",
|
|
1990
2003
|
type: "string",
|
|
1991
|
-
|
|
1992
|
-
|
|
2004
|
+
columnName: "display_name",
|
|
2005
|
+
validation: {
|
|
2006
|
+
required: true
|
|
1993
2007
|
}
|
|
1994
2008
|
},
|
|
1995
|
-
|
|
1996
|
-
name: "Display Name",
|
|
1997
|
-
type: "string"
|
|
1998
|
-
},
|
|
1999
|
-
photo_url: {
|
|
2009
|
+
photoURL: {
|
|
2000
2010
|
name: "Photo URL",
|
|
2001
|
-
type: "string"
|
|
2011
|
+
type: "string",
|
|
2012
|
+
columnName: "photo_url",
|
|
2013
|
+
url: "image"
|
|
2014
|
+
},
|
|
2015
|
+
roles: {
|
|
2016
|
+
name: "Roles",
|
|
2017
|
+
type: "array",
|
|
2018
|
+
columnType: "text[]",
|
|
2019
|
+
of: {
|
|
2020
|
+
name: "Role",
|
|
2021
|
+
type: "string",
|
|
2022
|
+
enum: {
|
|
2023
|
+
admin: "Admin",
|
|
2024
|
+
editor: "Editor",
|
|
2025
|
+
viewer: "Viewer"
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2002
2028
|
},
|
|
2003
|
-
|
|
2029
|
+
passwordHash: {
|
|
2030
|
+
name: "Password Hash",
|
|
2031
|
+
type: "string",
|
|
2032
|
+
columnName: "password_hash",
|
|
2033
|
+
ui: {
|
|
2034
|
+
hideFromCollection: true,
|
|
2035
|
+
disabled: {
|
|
2036
|
+
hidden: true
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
},
|
|
2040
|
+
emailVerified: {
|
|
2004
2041
|
name: "Email Verified",
|
|
2005
2042
|
type: "boolean",
|
|
2006
|
-
|
|
2043
|
+
columnName: "email_verified",
|
|
2044
|
+
defaultValue: false,
|
|
2045
|
+
ui: {
|
|
2046
|
+
hideFromCollection: true,
|
|
2047
|
+
disabled: {
|
|
2048
|
+
hidden: true
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2007
2051
|
},
|
|
2008
|
-
|
|
2052
|
+
emailVerificationToken: {
|
|
2009
2053
|
name: "Email Verification Token",
|
|
2010
2054
|
type: "string",
|
|
2055
|
+
columnName: "email_verification_token",
|
|
2011
2056
|
ui: {
|
|
2012
|
-
hideFromCollection: true
|
|
2057
|
+
hideFromCollection: true,
|
|
2058
|
+
disabled: {
|
|
2059
|
+
hidden: true
|
|
2060
|
+
}
|
|
2013
2061
|
}
|
|
2014
2062
|
},
|
|
2015
|
-
|
|
2063
|
+
emailVerificationSentAt: {
|
|
2016
2064
|
name: "Email Verification Sent At",
|
|
2017
2065
|
type: "date",
|
|
2066
|
+
columnName: "email_verification_sent_at",
|
|
2018
2067
|
ui: {
|
|
2019
|
-
hideFromCollection: true
|
|
2068
|
+
hideFromCollection: true,
|
|
2069
|
+
disabled: {
|
|
2070
|
+
hidden: true
|
|
2071
|
+
}
|
|
2020
2072
|
}
|
|
2021
2073
|
},
|
|
2022
2074
|
metadata: {
|
|
@@ -2024,52 +2076,55 @@ const defaultUsersCollection = {
|
|
|
2024
2076
|
type: "map",
|
|
2025
2077
|
defaultValue: {},
|
|
2026
2078
|
ui: {
|
|
2027
|
-
hideFromCollection: true
|
|
2079
|
+
hideFromCollection: true,
|
|
2080
|
+
disabled: {
|
|
2081
|
+
hidden: true
|
|
2082
|
+
}
|
|
2028
2083
|
}
|
|
2029
2084
|
},
|
|
2030
|
-
|
|
2085
|
+
createdAt: {
|
|
2031
2086
|
name: "Created At",
|
|
2032
2087
|
type: "date",
|
|
2088
|
+
columnName: "created_at",
|
|
2033
2089
|
autoValue: "on_create",
|
|
2034
2090
|
ui: {
|
|
2035
|
-
readOnly: true
|
|
2036
|
-
hideFromCollection: true
|
|
2091
|
+
readOnly: true
|
|
2037
2092
|
}
|
|
2038
2093
|
},
|
|
2039
|
-
|
|
2094
|
+
updatedAt: {
|
|
2040
2095
|
name: "Updated At",
|
|
2041
2096
|
type: "date",
|
|
2097
|
+
columnName: "updated_at",
|
|
2042
2098
|
autoValue: "on_update",
|
|
2043
2099
|
ui: {
|
|
2044
|
-
|
|
2045
|
-
|
|
2100
|
+
hideFromCollection: true,
|
|
2101
|
+
disabled: {
|
|
2102
|
+
hidden: true
|
|
2103
|
+
}
|
|
2046
2104
|
}
|
|
2047
2105
|
}
|
|
2048
|
-
}
|
|
2106
|
+
},
|
|
2107
|
+
listProperties: ["displayName", "email", "roles", "createdAt"],
|
|
2108
|
+
propertiesOrder: ["id", "email", "displayName", "roles", "createdAt"]
|
|
2049
2109
|
};
|
|
2050
|
-
function
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
case "not-in":
|
|
2069
|
-
return "nin";
|
|
2070
|
-
default:
|
|
2071
|
-
return op;
|
|
2072
|
-
}
|
|
2110
|
+
function or(...conditions) {
|
|
2111
|
+
return {
|
|
2112
|
+
type: "or",
|
|
2113
|
+
conditions
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
2116
|
+
function and(...conditions) {
|
|
2117
|
+
return {
|
|
2118
|
+
type: "and",
|
|
2119
|
+
conditions
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
function cond(column, operator, value) {
|
|
2123
|
+
return {
|
|
2124
|
+
column,
|
|
2125
|
+
operator,
|
|
2126
|
+
value
|
|
2127
|
+
};
|
|
2073
2128
|
}
|
|
2074
2129
|
class QueryBuilder {
|
|
2075
2130
|
constructor(collection) {
|
|
@@ -2078,23 +2133,30 @@ class QueryBuilder {
|
|
|
2078
2133
|
params = {
|
|
2079
2134
|
where: {}
|
|
2080
2135
|
};
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
where(column, operator, value) {
|
|
2136
|
+
where(columnOrCondition, operator, value) {
|
|
2137
|
+
if (typeof columnOrCondition === "object" && columnOrCondition !== null && "type" in columnOrCondition) {
|
|
2138
|
+
this.params.logical = columnOrCondition;
|
|
2139
|
+
return this;
|
|
2140
|
+
}
|
|
2087
2141
|
if (!this.params.where) {
|
|
2088
2142
|
this.params.where = {};
|
|
2089
2143
|
}
|
|
2090
|
-
const
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2144
|
+
const column = columnOrCondition;
|
|
2145
|
+
const condition = [operator, value];
|
|
2146
|
+
const existing = this.params.where[column];
|
|
2147
|
+
if (existing === void 0) {
|
|
2148
|
+
this.params.where[column] = condition;
|
|
2149
|
+
} else if (Array.isArray(existing) && existing.length > 0 && Array.isArray(existing[0])) {
|
|
2150
|
+
this.params.where[column].push(condition);
|
|
2151
|
+
} else {
|
|
2152
|
+
let firstCondition;
|
|
2153
|
+
if (Array.isArray(existing) && existing.length === 2 && typeof existing[0] === "string") {
|
|
2154
|
+
firstCondition = existing;
|
|
2155
|
+
} else {
|
|
2156
|
+
firstCondition = ["==", existing];
|
|
2157
|
+
}
|
|
2158
|
+
this.params.where[column] = [firstCondition, condition];
|
|
2096
2159
|
}
|
|
2097
|
-
this.params.where[column] = mappedOp === "eq" ? String(formattedValue) : `${mappedOp}.${formattedValue}`;
|
|
2098
2160
|
return this;
|
|
2099
2161
|
}
|
|
2100
2162
|
/**
|
|
@@ -2196,10 +2258,13 @@ function convertWhereToFilter(where) {
|
|
|
2196
2258
|
filter[field] = ["==", rawValue];
|
|
2197
2259
|
continue;
|
|
2198
2260
|
}
|
|
2199
|
-
if (Array.isArray(rawValue)
|
|
2200
|
-
const [
|
|
2201
|
-
const
|
|
2202
|
-
|
|
2261
|
+
if (Array.isArray(rawValue)) {
|
|
2262
|
+
const conditions = Array.isArray(rawValue[0]) ? rawValue : [rawValue];
|
|
2263
|
+
const mappedConditions = conditions.map(([rawOp, val]) => {
|
|
2264
|
+
const mappedOp = operatorMap[rawOp] ?? "==";
|
|
2265
|
+
return [mappedOp, val];
|
|
2266
|
+
});
|
|
2267
|
+
filter[field] = Array.isArray(rawValue[0]) ? mappedConditions : mappedConditions[0];
|
|
2203
2268
|
continue;
|
|
2204
2269
|
}
|
|
2205
2270
|
if (typeof rawValue === "string") {
|
|
@@ -2293,6 +2358,9 @@ function createDriverAccessor(driver, slug) {
|
|
|
2293
2358
|
}
|
|
2294
2359
|
});
|
|
2295
2360
|
},
|
|
2361
|
+
deleteAll: driver.deleteAll ? async () => {
|
|
2362
|
+
return driver.deleteAll(slug);
|
|
2363
|
+
} : void 0,
|
|
2296
2364
|
count: driver.countEntities ? async (params) => {
|
|
2297
2365
|
return driver.countEntities({
|
|
2298
2366
|
path: slug,
|
|
@@ -2334,8 +2402,12 @@ function createDriverAccessor(driver, slug) {
|
|
|
2334
2402
|
});
|
|
2335
2403
|
} : void 0,
|
|
2336
2404
|
// Fluent Query Builder
|
|
2337
|
-
where(
|
|
2338
|
-
|
|
2405
|
+
where(columnOrCondition, operator, value) {
|
|
2406
|
+
const builder = new QueryBuilder(accessor);
|
|
2407
|
+
if (typeof columnOrCondition === "object") {
|
|
2408
|
+
return builder.where(columnOrCondition);
|
|
2409
|
+
}
|
|
2410
|
+
return builder.where(columnOrCondition, operator, value);
|
|
2339
2411
|
},
|
|
2340
2412
|
orderBy(column, ascending) {
|
|
2341
2413
|
return new QueryBuilder(accessor).orderBy(column, ascending);
|
|
@@ -2385,6 +2457,7 @@ export {
|
|
|
2385
2457
|
DEFAULT_ONE_OF_VALUE,
|
|
2386
2458
|
QueryBuilder,
|
|
2387
2459
|
addInitialSlash,
|
|
2460
|
+
and,
|
|
2388
2461
|
applyPropertyConditions,
|
|
2389
2462
|
buildAdditionalFieldDelegate,
|
|
2390
2463
|
buildCollection,
|
|
@@ -2402,6 +2475,7 @@ export {
|
|
|
2402
2475
|
canEditEntity,
|
|
2403
2476
|
canReadCollection,
|
|
2404
2477
|
checkOperation,
|
|
2478
|
+
cond,
|
|
2405
2479
|
createRelationRef,
|
|
2406
2480
|
createRelationRefWithData,
|
|
2407
2481
|
defaultUsersCollection,
|
|
@@ -2433,6 +2507,7 @@ export {
|
|
|
2433
2507
|
isPropertyBuilder,
|
|
2434
2508
|
isReadOnly,
|
|
2435
2509
|
normalizeToEntityRelation,
|
|
2510
|
+
or,
|
|
2436
2511
|
registerConditionOperations,
|
|
2437
2512
|
removeInitialAndTrailingSlashes,
|
|
2438
2513
|
removeInitialSlash,
|