@rebasepro/common 0.5.0 → 0.6.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/dist/index.es.js +2053 -2415
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +2282 -2534
- package/dist/index.umd.js.map +1 -1
- package/dist/util/entities.d.ts +5 -1
- package/package.json +14 -14
- package/src/collections/CollectionRegistry.ts +1 -1
- package/src/collections/default-collections.ts +21 -9
- package/src/data/query_builder.ts +7 -3
- package/src/util/entities.ts +14 -4
- package/src/util/relations.ts +5 -3
- package/src/util/resolutions.ts +3 -2
package/dist/util/entities.d.ts
CHANGED
|
@@ -29,9 +29,13 @@ export declare function getRelationFrom<M extends Record<string, unknown>>(entit
|
|
|
29
29
|
* Handles EntityRelation class instances, and plain objects
|
|
30
30
|
* with `__type === "relation"` or an `isEntityRelation()` method.
|
|
31
31
|
*
|
|
32
|
+
* When `propertyType` is `"relation"`, also accepts plain objects that
|
|
33
|
+
* have `id` and `path` fields — these are relation-shaped objects from
|
|
34
|
+
* edge cases in the data pipeline (REST fallback, stale cache, custom data source).
|
|
35
|
+
*
|
|
32
36
|
* Returns null if the value cannot be coerced.
|
|
33
37
|
*/
|
|
34
|
-
export declare function normalizeToEntityRelation(value: unknown): EntityRelation | null;
|
|
38
|
+
export declare function normalizeToEntityRelation(value: unknown, propertyType?: string): EntityRelation | null;
|
|
35
39
|
export declare function traverseValuesProperties<M extends Record<string, unknown>>(inputValues: Partial<EntityValues<M>>, properties: Properties, operation: (value: unknown, property: Property) => unknown): EntityValues<M> | undefined;
|
|
36
40
|
export declare function traverseValueProperty(inputValue: unknown, property: Property, operation: (value: unknown, property: Property) => unknown): unknown;
|
|
37
41
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebasepro/common",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/rebaseco"
|
|
@@ -41,27 +41,27 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"fast-equals": "6.0.0",
|
|
43
43
|
"json-logic-js": "^2.0.5",
|
|
44
|
-
"@rebasepro/types": "0.
|
|
45
|
-
"@rebasepro/utils": "0.
|
|
44
|
+
"@rebasepro/types": "0.6.1",
|
|
45
|
+
"@rebasepro/utils": "0.6.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@jest/globals": "^
|
|
48
|
+
"@jest/globals": "^30.4.1",
|
|
49
49
|
"@testing-library/react": "^16.3.2",
|
|
50
50
|
"@testing-library/user-event": "^14.6.1",
|
|
51
|
-
"@types/jest": "^
|
|
52
|
-
"@types/node": "^
|
|
51
|
+
"@types/jest": "^30.0.0",
|
|
52
|
+
"@types/node": "^25.9.3",
|
|
53
53
|
"@types/object-hash": "^3.0.6",
|
|
54
|
-
"@types/react": "^19.2.
|
|
54
|
+
"@types/react": "^19.2.17",
|
|
55
55
|
"@types/react-dom": "^19.2.3",
|
|
56
56
|
"@types/react-measure": "^2.0.12",
|
|
57
|
-
"@vitejs/plugin-react": "^
|
|
57
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
58
58
|
"babel-plugin-react-compiler": "beta",
|
|
59
|
-
"cross-env": "^
|
|
60
|
-
"jest": "^
|
|
61
|
-
"ts-jest": "^29.4.
|
|
62
|
-
"tsd": "^0.
|
|
63
|
-
"typescript": "^
|
|
64
|
-
"vite": "^
|
|
59
|
+
"cross-env": "^10.1.0",
|
|
60
|
+
"jest": "^30.4.2",
|
|
61
|
+
"ts-jest": "^29.4.11",
|
|
62
|
+
"tsd": "^0.33.0",
|
|
63
|
+
"typescript": "^6.0.3",
|
|
64
|
+
"vite": "^8.0.16"
|
|
65
65
|
},
|
|
66
66
|
"files": [
|
|
67
67
|
"dist",
|
|
@@ -258,7 +258,7 @@ export class CollectionRegistry {
|
|
|
258
258
|
joinPath: relProp.joinPath ?? relProp.relation?.joinPath,
|
|
259
259
|
onUpdate: relProp.onUpdate ?? relProp.relation?.onUpdate,
|
|
260
260
|
onDelete: relProp.onDelete ?? relProp.relation?.onDelete,
|
|
261
|
-
overrides: relProp.overrides ?? relProp.relation?.overrides
|
|
261
|
+
overrides: relProp.overrides ?? relProp.relation?.overrides
|
|
262
262
|
});
|
|
263
263
|
}
|
|
264
264
|
} else if (property.type === "map" && property.properties) {
|
|
@@ -11,6 +11,7 @@ export const defaultUsersCollection: PostgresCollection = {
|
|
|
11
11
|
name: "Users",
|
|
12
12
|
singularName: "User",
|
|
13
13
|
slug: "users",
|
|
14
|
+
auth: true,
|
|
14
15
|
table: "users",
|
|
15
16
|
schema: "rebase",
|
|
16
17
|
icon: "Users",
|
|
@@ -18,8 +19,10 @@ export const defaultUsersCollection: PostgresCollection = {
|
|
|
18
19
|
openEntityMode: "dialog",
|
|
19
20
|
disableDefaultActions: ["copy"],
|
|
20
21
|
securityRules: [
|
|
21
|
-
{ operation: "select",
|
|
22
|
-
|
|
22
|
+
{ operation: "select",
|
|
23
|
+
roles: ["admin"] },
|
|
24
|
+
{ operations: ["insert", "update", "delete"],
|
|
25
|
+
roles: ["admin"] }
|
|
23
26
|
],
|
|
24
27
|
sort: ["createdAt", "desc"],
|
|
25
28
|
properties: {
|
|
@@ -32,7 +35,8 @@ export const defaultUsersCollection: PostgresCollection = {
|
|
|
32
35
|
email: {
|
|
33
36
|
name: "Email",
|
|
34
37
|
type: "string",
|
|
35
|
-
validation: { required: true,
|
|
38
|
+
validation: { required: true,
|
|
39
|
+
unique: true }
|
|
36
40
|
},
|
|
37
41
|
displayName: {
|
|
38
42
|
name: "Name",
|
|
@@ -64,32 +68,39 @@ export const defaultUsersCollection: PostgresCollection = {
|
|
|
64
68
|
name: "Password Hash",
|
|
65
69
|
type: "string",
|
|
66
70
|
columnName: "password_hash",
|
|
67
|
-
ui: { hideFromCollection: true,
|
|
71
|
+
ui: { hideFromCollection: true,
|
|
72
|
+
disabled: { hidden: true } }
|
|
68
73
|
},
|
|
69
74
|
emailVerified: {
|
|
70
75
|
name: "Email Verified",
|
|
71
76
|
type: "boolean",
|
|
72
77
|
columnName: "email_verified",
|
|
73
78
|
defaultValue: false,
|
|
74
|
-
ui: { hideFromCollection: true,
|
|
79
|
+
ui: { hideFromCollection: true,
|
|
80
|
+
disabled: { hidden: true } }
|
|
75
81
|
},
|
|
76
82
|
emailVerificationToken: {
|
|
77
83
|
name: "Email Verification Token",
|
|
78
84
|
type: "string",
|
|
79
85
|
columnName: "email_verification_token",
|
|
80
|
-
ui: { hideFromCollection: true,
|
|
86
|
+
ui: { hideFromCollection: true,
|
|
87
|
+
disabled: { hidden: true } }
|
|
81
88
|
},
|
|
82
89
|
emailVerificationSentAt: {
|
|
83
90
|
name: "Email Verification Sent At",
|
|
84
91
|
type: "date",
|
|
85
92
|
columnName: "email_verification_sent_at",
|
|
86
|
-
ui: { hideFromCollection: true,
|
|
93
|
+
ui: { hideFromCollection: true,
|
|
94
|
+
disabled: { hidden: true } }
|
|
87
95
|
},
|
|
88
96
|
metadata: {
|
|
89
97
|
name: "Metadata",
|
|
90
98
|
type: "map",
|
|
99
|
+
keyValue: true,
|
|
100
|
+
properties: {},
|
|
91
101
|
defaultValue: {},
|
|
92
|
-
ui: { hideFromCollection: true,
|
|
102
|
+
ui: { hideFromCollection: true,
|
|
103
|
+
disabled: { hidden: true } }
|
|
93
104
|
},
|
|
94
105
|
createdAt: {
|
|
95
106
|
name: "Created At",
|
|
@@ -103,7 +114,8 @@ export const defaultUsersCollection: PostgresCollection = {
|
|
|
103
114
|
type: "date",
|
|
104
115
|
columnName: "updated_at",
|
|
105
116
|
autoValue: "on_update",
|
|
106
|
-
ui: { hideFromCollection: true,
|
|
117
|
+
ui: { hideFromCollection: true,
|
|
118
|
+
disabled: { hidden: true } }
|
|
107
119
|
}
|
|
108
120
|
},
|
|
109
121
|
listProperties: ["displayName", "email", "roles", "createdAt"],
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { FindParams, Entity, FindResponse, CollectionAccessor, QueryBuilderInterface, FilterOperator, LogicalCondition, WhereValue, FilterCondition } from "@rebasepro/types";
|
|
2
2
|
|
|
3
3
|
export function or(...conditions: (FilterCondition | LogicalCondition)[]): LogicalCondition {
|
|
4
|
-
return { type: "or",
|
|
4
|
+
return { type: "or",
|
|
5
|
+
conditions };
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
export function and(...conditions: (FilterCondition | LogicalCondition)[]): LogicalCondition {
|
|
8
|
-
return { type: "and",
|
|
9
|
+
return { type: "and",
|
|
10
|
+
conditions };
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export function cond(column: string, operator: FilterOperator, value: unknown): FilterCondition {
|
|
12
|
-
return { column,
|
|
14
|
+
return { column,
|
|
15
|
+
operator,
|
|
16
|
+
value };
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export class QueryBuilder<M extends Record<string, unknown> = Record<string, unknown>> implements QueryBuilderInterface<M> {
|
package/src/util/entities.ts
CHANGED
|
@@ -156,9 +156,13 @@ export function getRelationFrom<M extends Record<string, unknown>>(entity: Entit
|
|
|
156
156
|
* Handles EntityRelation class instances, and plain objects
|
|
157
157
|
* with `__type === "relation"` or an `isEntityRelation()` method.
|
|
158
158
|
*
|
|
159
|
+
* When `propertyType` is `"relation"`, also accepts plain objects that
|
|
160
|
+
* have `id` and `path` fields — these are relation-shaped objects from
|
|
161
|
+
* edge cases in the data pipeline (REST fallback, stale cache, custom data source).
|
|
162
|
+
*
|
|
159
163
|
* Returns null if the value cannot be coerced.
|
|
160
164
|
*/
|
|
161
|
-
export function normalizeToEntityRelation(value: unknown): EntityRelation | null {
|
|
165
|
+
export function normalizeToEntityRelation(value: unknown, propertyType?: string): EntityRelation | null {
|
|
162
166
|
if (value instanceof EntityRelation) return value;
|
|
163
167
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
164
168
|
|
|
@@ -167,7 +171,8 @@ export function normalizeToEntityRelation(value: unknown): EntityRelation | null
|
|
|
167
171
|
obj.__type === "relation" ||
|
|
168
172
|
obj.__type === "reference" ||
|
|
169
173
|
(typeof obj.isEntityRelation === "function" && (obj.isEntityRelation as () => boolean)()) ||
|
|
170
|
-
(typeof obj.isEntityReference === "function" && (obj.isEntityReference as () => boolean)())
|
|
174
|
+
(typeof obj.isEntityReference === "function" && (obj.isEntityReference as () => boolean)()) ||
|
|
175
|
+
(propertyType === "relation" && typeof obj.id !== "undefined" && typeof obj.path === "string");
|
|
171
176
|
|
|
172
177
|
if (!isRelationLike) return null;
|
|
173
178
|
|
|
@@ -263,7 +268,9 @@ export interface RelationRefWithData extends RelationRef {
|
|
|
263
268
|
* Replaces inline `{ id, path, __type: "relation" }` object literals.
|
|
264
269
|
*/
|
|
265
270
|
export function createRelationRef(id: string | number, path: string): RelationRef {
|
|
266
|
-
return { id,
|
|
271
|
+
return { id,
|
|
272
|
+
path,
|
|
273
|
+
__type: "relation" };
|
|
267
274
|
}
|
|
268
275
|
|
|
269
276
|
/**
|
|
@@ -271,5 +278,8 @@ export function createRelationRef(id: string | number, path: string): RelationRe
|
|
|
271
278
|
* Used when entity data has been pre-fetched (e.g., via batch loading or JOINs).
|
|
272
279
|
*/
|
|
273
280
|
export function createRelationRefWithData(id: string | number, path: string, data: Entity): RelationRefWithData {
|
|
274
|
-
return { id,
|
|
281
|
+
return { id,
|
|
282
|
+
path,
|
|
283
|
+
__type: "relation",
|
|
284
|
+
data };
|
|
275
285
|
}
|
package/src/util/relations.ts
CHANGED
|
@@ -19,7 +19,8 @@ export function sanitizeRelation(
|
|
|
19
19
|
targetCollection = resolveCollection(rawTarget);
|
|
20
20
|
}
|
|
21
21
|
if (!targetCollection) {
|
|
22
|
-
targetCollection = { slug: rawTarget,
|
|
22
|
+
targetCollection = { slug: rawTarget,
|
|
23
|
+
name: rawTarget } as EntityCollection;
|
|
23
24
|
}
|
|
24
25
|
} else if (typeof rawTarget === "function") {
|
|
25
26
|
const evaluated = rawTarget();
|
|
@@ -28,7 +29,8 @@ export function sanitizeRelation(
|
|
|
28
29
|
targetCollection = resolveCollection(evaluated);
|
|
29
30
|
}
|
|
30
31
|
if (!targetCollection) {
|
|
31
|
-
targetCollection = { slug: evaluated,
|
|
32
|
+
targetCollection = { slug: evaluated,
|
|
33
|
+
name: evaluated } as EntityCollection;
|
|
32
34
|
}
|
|
33
35
|
} else {
|
|
34
36
|
targetCollection = evaluated;
|
|
@@ -295,7 +297,7 @@ export function resolvePropertyRelation({
|
|
|
295
297
|
joinPath: relProp.joinPath,
|
|
296
298
|
onUpdate: relProp.onUpdate,
|
|
297
299
|
onDelete: relProp.onDelete,
|
|
298
|
-
overrides: relProp.overrides
|
|
300
|
+
overrides: relProp.overrides
|
|
299
301
|
} as Relation;
|
|
300
302
|
}
|
|
301
303
|
|
package/src/util/resolutions.ts
CHANGED
|
@@ -354,7 +354,7 @@ export function getSubcollections<M extends Record<string, unknown> = Record<str
|
|
|
354
354
|
if (getDataSourceCapabilities(collection.driver).supportsRelations) {
|
|
355
355
|
const resolvedRelations = resolveCollectionRelations(collection);
|
|
356
356
|
const manyRelations = Object.values(resolvedRelations).filter((r: Relation) => r.cardinality === "many");
|
|
357
|
-
|
|
357
|
+
|
|
358
358
|
return manyRelations.map((r: Relation) => {
|
|
359
359
|
const target = r.target();
|
|
360
360
|
if (!target) return undefined;
|
|
@@ -377,7 +377,8 @@ export function getSubcollections<M extends Record<string, unknown> = Record<str
|
|
|
377
377
|
baseOverrides.singularName = customName;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
const targetWithOverrides = { ...target,
|
|
380
|
+
const targetWithOverrides = { ...target,
|
|
381
|
+
...baseOverrides };
|
|
381
382
|
return (r.overrides ? mergeDeep(targetWithOverrides, r.overrides) : targetWithOverrides) as EntityCollection<Record<string, unknown>>;
|
|
382
383
|
}).filter((c: EntityCollection<Record<string, unknown>> | undefined): c is EntityCollection<Record<string, unknown>> => Boolean(c));
|
|
383
384
|
}
|