@rebasepro/sdk-generator 0.0.1-canary.4d4fb3e
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/LICENSE +6 -0
- package/dist/common/src/collections/CollectionRegistry.d.ts +48 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/data/buildRebaseData.d.ts +14 -0
- package/dist/common/src/index.d.ts +3 -0
- package/dist/common/src/util/builders.d.ts +57 -0
- package/dist/common/src/util/callbacks.d.ts +6 -0
- package/dist/common/src/util/collections.d.ts +11 -0
- package/dist/common/src/util/common.d.ts +2 -0
- package/dist/common/src/util/conditions.d.ts +26 -0
- package/dist/common/src/util/entities.d.ts +36 -0
- package/dist/common/src/util/enums.d.ts +3 -0
- package/dist/common/src/util/index.d.ts +16 -0
- package/dist/common/src/util/navigation_from_path.d.ts +34 -0
- package/dist/common/src/util/navigation_utils.d.ts +20 -0
- package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
- package/dist/common/src/util/paths.d.ts +14 -0
- package/dist/common/src/util/permissions.d.ts +5 -0
- package/dist/common/src/util/references.d.ts +2 -0
- package/dist/common/src/util/relations.d.ts +12 -0
- package/dist/common/src/util/resolutions.d.ts +72 -0
- package/dist/common/src/util/storage.d.ts +24 -0
- package/dist/index.cjs +211 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.es.js +208 -0
- package/dist/index.es.js.map +1 -0
- package/dist/sdk-generator/src/generate-types.d.ts +2 -0
- package/dist/sdk-generator/src/index.d.ts +19 -0
- package/dist/sdk-generator/src/utils.d.ts +22 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
- package/dist/types/src/controllers/auth.d.ts +117 -0
- package/dist/types/src/controllers/client.d.ts +58 -0
- package/dist/types/src/controllers/collection_registry.d.ts +44 -0
- package/dist/types/src/controllers/customization_controller.d.ts +54 -0
- package/dist/types/src/controllers/data.d.ts +141 -0
- package/dist/types/src/controllers/data_driver.d.ts +168 -0
- package/dist/types/src/controllers/database_admin.d.ts +11 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
- package/dist/types/src/controllers/effective_role.d.ts +4 -0
- package/dist/types/src/controllers/index.d.ts +17 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
- package/dist/types/src/controllers/navigation.d.ts +213 -0
- package/dist/types/src/controllers/registry.d.ts +51 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +89 -0
- package/dist/types/src/controllers/snackbar.d.ts +24 -0
- package/dist/types/src/controllers/storage.d.ts +173 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/rebase_context.d.ts +101 -0
- package/dist/types/src/types/backend.d.ts +533 -0
- package/dist/types/src/types/builders.d.ts +14 -0
- package/dist/types/src/types/chips.d.ts +5 -0
- package/dist/types/src/types/collections.d.ts +812 -0
- package/dist/types/src/types/data_source.d.ts +64 -0
- package/dist/types/src/types/entities.d.ts +145 -0
- package/dist/types/src/types/entity_actions.d.ts +98 -0
- package/dist/types/src/types/entity_callbacks.d.ts +173 -0
- package/dist/types/src/types/entity_link_builder.d.ts +7 -0
- package/dist/types/src/types/entity_overrides.d.ts +9 -0
- package/dist/types/src/types/entity_views.d.ts +61 -0
- package/dist/types/src/types/export_import.d.ts +21 -0
- package/dist/types/src/types/index.d.ts +22 -0
- package/dist/types/src/types/locales.d.ts +4 -0
- package/dist/types/src/types/modify_collections.d.ts +5 -0
- package/dist/types/src/types/plugins.d.ts +225 -0
- package/dist/types/src/types/properties.d.ts +1091 -0
- package/dist/types/src/types/property_config.d.ts +70 -0
- package/dist/types/src/types/relations.d.ts +336 -0
- package/dist/types/src/types/slots.d.ts +228 -0
- package/dist/types/src/types/translations.d.ts +826 -0
- package/dist/types/src/types/user_management_delegate.d.ts +120 -0
- package/dist/types/src/types/websockets.d.ts +78 -0
- package/dist/types/src/users/index.d.ts +2 -0
- package/dist/types/src/users/roles.d.ts +22 -0
- package/dist/types/src/users/user.d.ts +46 -0
- package/jest.config.cjs +13 -0
- package/package.json +51 -0
- package/src/generate-types.ts +176 -0
- package/src/index.ts +71 -0
- package/src/json-logic-js.d.ts +8 -0
- package/src/utils.ts +42 -0
- package/test/sdk-generator.test.ts +78 -0
- package/tsconfig.json +26 -0
- package/vite.config.ts +49 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ArrayProperty, MapProperty, StringProperty, NumberProperty, BooleanProperty, DateProperty, GeopointProperty, ReferenceProperty, RelationProperty } from "./properties";
|
|
3
|
+
import { BaseProperty } from "./properties";
|
|
4
|
+
type CMSBasePropertyNoName = Omit<BaseProperty, "name">;
|
|
5
|
+
export type ConfigProperty = (Omit<StringProperty, "name"> & {
|
|
6
|
+
name?: string;
|
|
7
|
+
} & CMSBasePropertyNoName) | (Omit<NumberProperty, "name"> & {
|
|
8
|
+
name?: string;
|
|
9
|
+
} & CMSBasePropertyNoName) | (Omit<BooleanProperty, "name"> & {
|
|
10
|
+
name?: string;
|
|
11
|
+
} & CMSBasePropertyNoName) | (Omit<DateProperty, "name"> & {
|
|
12
|
+
name?: string;
|
|
13
|
+
} & CMSBasePropertyNoName) | (Omit<GeopointProperty, "name"> & {
|
|
14
|
+
name?: string;
|
|
15
|
+
} & CMSBasePropertyNoName) | (Omit<ReferenceProperty, "name"> & {
|
|
16
|
+
name?: string;
|
|
17
|
+
} & CMSBasePropertyNoName) | (Omit<RelationProperty, "name"> & {
|
|
18
|
+
name?: string;
|
|
19
|
+
} & CMSBasePropertyNoName) | (Omit<ArrayProperty, "name" | "of" | "oneOf"> & {
|
|
20
|
+
name?: string;
|
|
21
|
+
of?: ConfigProperty | ConfigProperty[];
|
|
22
|
+
oneOf?: {
|
|
23
|
+
properties: Record<string, ConfigProperty>;
|
|
24
|
+
typeField?: string;
|
|
25
|
+
valueField?: string;
|
|
26
|
+
propertiesOrder?: string[];
|
|
27
|
+
};
|
|
28
|
+
} & CMSBasePropertyNoName) | (Omit<MapProperty, "name" | "properties"> & {
|
|
29
|
+
name?: string;
|
|
30
|
+
properties?: Record<string, ConfigProperty>;
|
|
31
|
+
} & CMSBasePropertyNoName);
|
|
32
|
+
/**
|
|
33
|
+
* This is the configuration object for a property.
|
|
34
|
+
* These configs are generated by default for the properties defined in your
|
|
35
|
+
* collections' configuration, but you can define your own to be used.
|
|
36
|
+
*/
|
|
37
|
+
export type PropertyConfig = {
|
|
38
|
+
/**
|
|
39
|
+
* Key used to identify this property config.
|
|
40
|
+
*/
|
|
41
|
+
key: PropertyConfigId | string;
|
|
42
|
+
/**
|
|
43
|
+
* Name of this field type.
|
|
44
|
+
* This is not the name of the property.
|
|
45
|
+
*/
|
|
46
|
+
name: string;
|
|
47
|
+
/**
|
|
48
|
+
* Default config for the property.
|
|
49
|
+
* This property or builder will be used as the base values for the resulting property.
|
|
50
|
+
* You can also use a builder function to generate the base property.
|
|
51
|
+
*/
|
|
52
|
+
property: ConfigProperty;
|
|
53
|
+
/**
|
|
54
|
+
* Optional icon to be used in the field selector.
|
|
55
|
+
* Use a 24x24 component, in order not to break the layout.
|
|
56
|
+
* Any Rebase icon can be used.
|
|
57
|
+
*/
|
|
58
|
+
Icon?: React.ComponentType;
|
|
59
|
+
/**
|
|
60
|
+
* CSS color, used only in some plugins like the field selector.
|
|
61
|
+
* e.g. "#2d7ff9"
|
|
62
|
+
*/
|
|
63
|
+
color?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Description of this field type.
|
|
66
|
+
*/
|
|
67
|
+
description?: string;
|
|
68
|
+
};
|
|
69
|
+
export type PropertyConfigId = "text_field" | "multiline" | "markdown" | "url" | "email" | "user_select" | "select" | "multi_select" | "number_input" | "number_select" | "multi_number_select" | "file_upload" | "multi_file_upload" | "group" | "key_value" | "reference" | "reference_as_string" | "multi_references" | "relation" | "switch" | "date_time" | "repeat" | "custom_array" | "block";
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { EntityCollection } from "./collections";
|
|
2
|
+
/**
|
|
3
|
+
* @group Models
|
|
4
|
+
*/
|
|
5
|
+
export type OnAction = "cascade" | "restrict" | "no action" | "set null" | "set default";
|
|
6
|
+
/**
|
|
7
|
+
* Extended relation that combines base relation with Rebase UI config
|
|
8
|
+
* @group Models
|
|
9
|
+
*/
|
|
10
|
+
export interface Relation {
|
|
11
|
+
/**
|
|
12
|
+
* The application-level name for this relationship.
|
|
13
|
+
* If not provided, it will be inferred from the target collection path.
|
|
14
|
+
* @example "posts"
|
|
15
|
+
*/
|
|
16
|
+
relationName?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The final collection you want to retrieve records from.
|
|
19
|
+
*/
|
|
20
|
+
target: () => EntityCollection;
|
|
21
|
+
/**
|
|
22
|
+
* The nature of the relationship, determining if one or many records are returned.
|
|
23
|
+
*/
|
|
24
|
+
cardinality: "one" | "many";
|
|
25
|
+
/**
|
|
26
|
+
* Which side owns the persistence for this relationship.
|
|
27
|
+
* - "owning": The foreign key (for one-to-one/many-to-one) or the junction table (for many-to-many) is managed by this collection.
|
|
28
|
+
* - "inverse": The foreign key is on the target collection's table. This side of the relation is typically read-only.
|
|
29
|
+
* Defaults to "owning".
|
|
30
|
+
*/
|
|
31
|
+
direction?: "owning" | "inverse";
|
|
32
|
+
/**
|
|
33
|
+
* The name of the inverse relation.
|
|
34
|
+
* This is only needed when the inverse relation is not the same as the relation name.
|
|
35
|
+
* For example, if the relation name is "posts", the inverse relation name might be "author".
|
|
36
|
+
*/
|
|
37
|
+
inverseRelationName?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Column on THIS table that stores the foreign key to the target.
|
|
40
|
+
* Required when `direction` is "owning" and `cardinality` is "one".
|
|
41
|
+
* @example "author_id"
|
|
42
|
+
*/
|
|
43
|
+
localKey?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Column on the TARGET table that stores the foreign key to this entity.
|
|
46
|
+
* Required when `direction` is "inverse".
|
|
47
|
+
* @example "post_id"
|
|
48
|
+
*/
|
|
49
|
+
foreignKeyOnTarget?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Defines the junction table for a many-to-many relationship.
|
|
52
|
+
* Required when `cardinality` is "many" and `direction` is "owning".
|
|
53
|
+
*
|
|
54
|
+
* @example Simple many-to-many between Users and Roles:
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Users collection
|
|
57
|
+
* {
|
|
58
|
+
* relations: [{
|
|
59
|
+
* relationName: "roles",
|
|
60
|
+
* target: () => rolesCollection,
|
|
61
|
+
* cardinality: "many",
|
|
62
|
+
* through: {
|
|
63
|
+
* table: "user_roles", // Junction table name
|
|
64
|
+
* sourceColumn: "user_id", // Column that references this collection's ID
|
|
65
|
+
* targetColumn: "role_id" // Column that references target collection's ID
|
|
66
|
+
* }
|
|
67
|
+
* }]
|
|
68
|
+
* }
|
|
69
|
+
*
|
|
70
|
+
* // This creates a junction table like:
|
|
71
|
+
* // CREATE TABLE user_roles (
|
|
72
|
+
* // user_id INTEGER REFERENCES users(id),
|
|
73
|
+
* // role_id INTEGER REFERENCES roles(id),
|
|
74
|
+
* // PRIMARY KEY (user_id, role_id)
|
|
75
|
+
* // );
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @example Many-to-many with additional junction table data:
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // Students and Courses with enrollment date
|
|
81
|
+
* {
|
|
82
|
+
* relations: [{
|
|
83
|
+
* relationName: "courses",
|
|
84
|
+
* target: () => coursesCollection,
|
|
85
|
+
* cardinality: "many",
|
|
86
|
+
* through: {
|
|
87
|
+
* table: "enrollments",
|
|
88
|
+
* sourceColumn: "student_id",
|
|
89
|
+
* targetColumn: "course_id"
|
|
90
|
+
* }
|
|
91
|
+
* }]
|
|
92
|
+
* }
|
|
93
|
+
*
|
|
94
|
+
* // Junction table can have additional columns:
|
|
95
|
+
* // CREATE TABLE enrollments (
|
|
96
|
+
* // student_id INTEGER REFERENCES students(id),
|
|
97
|
+
* // course_id INTEGER REFERENCES courses(id),
|
|
98
|
+
* // enrolled_at TIMESTAMP DEFAULT NOW(),
|
|
99
|
+
* // grade VARCHAR(2),
|
|
100
|
+
* // PRIMARY KEY (student_id, course_id)
|
|
101
|
+
* // );
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
through?: {
|
|
105
|
+
table: string;
|
|
106
|
+
sourceColumn: string;
|
|
107
|
+
targetColumn: string;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* An explicit, ordered array of JOINs to perform to get from the source
|
|
111
|
+
* to the target. Used for multi-hop relations, composite keys, or when you need
|
|
112
|
+
* fine-grained control over the join logic.
|
|
113
|
+
*
|
|
114
|
+
* When `joinPath` is provided, it overrides all other relation configuration
|
|
115
|
+
* (localKey, foreignKeyOnTarget, through) and gives you complete control
|
|
116
|
+
* over how tables are joined together.
|
|
117
|
+
*
|
|
118
|
+
* @example Simple one-to-one join (equivalent to localKey):
|
|
119
|
+
* ```typescript
|
|
120
|
+
* // Posts -> Authors relationship
|
|
121
|
+
* {
|
|
122
|
+
* relationName: "author",
|
|
123
|
+
* target: () => authorsCollection,
|
|
124
|
+
* cardinality: "one",
|
|
125
|
+
* joinPath: [
|
|
126
|
+
* {
|
|
127
|
+
* table: "authors",
|
|
128
|
+
* on: {
|
|
129
|
+
* from: "author_id", // Column on posts table
|
|
130
|
+
* to: "id" // Column on authors table
|
|
131
|
+
* }
|
|
132
|
+
* }
|
|
133
|
+
* ]
|
|
134
|
+
* }
|
|
135
|
+
*
|
|
136
|
+
* // Generates: SELECT * FROM posts JOIN authors ON posts.author_id = authors.id
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @example Multi-hop relationship (3 tables):
|
|
140
|
+
* ```typescript
|
|
141
|
+
* // Users -> Permissions through Roles
|
|
142
|
+
* {
|
|
143
|
+
* relationName: "permissions",
|
|
144
|
+
* target: () => permissionsCollection,
|
|
145
|
+
* cardinality: "many",
|
|
146
|
+
* joinPath: [
|
|
147
|
+
* {
|
|
148
|
+
* table: "user_roles",
|
|
149
|
+
* on: {
|
|
150
|
+
* from: "id", // users.id
|
|
151
|
+
* to: "user_id" // user_roles.user_id
|
|
152
|
+
* }
|
|
153
|
+
* },
|
|
154
|
+
* {
|
|
155
|
+
* table: "roles",
|
|
156
|
+
* on: {
|
|
157
|
+
* from: "role_id", // user_roles.role_id
|
|
158
|
+
* to: "id" // roles.id
|
|
159
|
+
* }
|
|
160
|
+
* },
|
|
161
|
+
* {
|
|
162
|
+
* table: "role_permissions",
|
|
163
|
+
* on: {
|
|
164
|
+
* from: "id", // roles.id
|
|
165
|
+
* to: "role_id" // role_permissions.role_id
|
|
166
|
+
* }
|
|
167
|
+
* },
|
|
168
|
+
* {
|
|
169
|
+
* table: "permissions",
|
|
170
|
+
* on: {
|
|
171
|
+
* from: "permission_id", // role_permissions.permission_id
|
|
172
|
+
* to: "id" // permissions.id
|
|
173
|
+
* }
|
|
174
|
+
* }
|
|
175
|
+
* ]
|
|
176
|
+
* }
|
|
177
|
+
*
|
|
178
|
+
* // Generates:
|
|
179
|
+
* // SELECT * FROM users
|
|
180
|
+
* // JOIN user_roles ON users.id = user_roles.user_id
|
|
181
|
+
* // JOIN roles ON user_roles.role_id = roles.id
|
|
182
|
+
* // JOIN role_permissions ON roles.id = role_permissions.role_id
|
|
183
|
+
* // JOIN permissions ON role_permissions.permission_id = permissions.id
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @example Composite key relationship:
|
|
187
|
+
* ```typescript
|
|
188
|
+
* // Orders -> Customer by company_code + region
|
|
189
|
+
* {
|
|
190
|
+
* relationName: "customer",
|
|
191
|
+
* target: () => customersCollection,
|
|
192
|
+
* cardinality: "one",
|
|
193
|
+
* joinPath: [
|
|
194
|
+
* {
|
|
195
|
+
* table: "customers",
|
|
196
|
+
* on: {
|
|
197
|
+
* from: ["company_code", "region_id"], // Multiple columns from orders
|
|
198
|
+
* to: ["code", "region_id"] // Multiple columns on customers
|
|
199
|
+
* }
|
|
200
|
+
* }
|
|
201
|
+
* ]
|
|
202
|
+
* }
|
|
203
|
+
*
|
|
204
|
+
* // Generates:
|
|
205
|
+
* // SELECT * FROM orders
|
|
206
|
+
* // JOIN customers ON orders.company_code = customers.code
|
|
207
|
+
* // AND orders.region_id = customers.region_id
|
|
208
|
+
* ```
|
|
209
|
+
*
|
|
210
|
+
* @example Self-referencing with intermediate table:
|
|
211
|
+
* ```typescript
|
|
212
|
+
* // Users -> Friends (many-to-many self-reference)
|
|
213
|
+
* {
|
|
214
|
+
* relationName: "friends",
|
|
215
|
+
* target: () => usersCollection, // Same collection
|
|
216
|
+
* cardinality: "many",
|
|
217
|
+
* joinPath: [
|
|
218
|
+
* {
|
|
219
|
+
* table: "friendships",
|
|
220
|
+
* on: {
|
|
221
|
+
* from: "id", // users.id
|
|
222
|
+
* to: "user_id" // friendships.user_id
|
|
223
|
+
* }
|
|
224
|
+
* },
|
|
225
|
+
* {
|
|
226
|
+
* table: "users",
|
|
227
|
+
* on: {
|
|
228
|
+
* from: "friend_id", // friendships.friend_id
|
|
229
|
+
* to: "id" // users.id (target)
|
|
230
|
+
* }
|
|
231
|
+
* }
|
|
232
|
+
* ]
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*
|
|
236
|
+
* @example Complex business logic join:
|
|
237
|
+
* ```typescript
|
|
238
|
+
* // Products -> Active Suppliers (only current, non-expired contracts)
|
|
239
|
+
* {
|
|
240
|
+
* relationName: "activeSuppliers",
|
|
241
|
+
* target: () => suppliersCollection,
|
|
242
|
+
* cardinality: "many",
|
|
243
|
+
* joinPath: [
|
|
244
|
+
* {
|
|
245
|
+
* table: "product_supplier_contracts",
|
|
246
|
+
* on: {
|
|
247
|
+
* from: "id", // products.id
|
|
248
|
+
* to: "product_id" // contracts.product_id
|
|
249
|
+
* }
|
|
250
|
+
* },
|
|
251
|
+
* {
|
|
252
|
+
* table: "suppliers",
|
|
253
|
+
* on: {
|
|
254
|
+
* from: "supplier_id", // contracts.supplier_id
|
|
255
|
+
* to: "id" // suppliers.id
|
|
256
|
+
* }
|
|
257
|
+
* }
|
|
258
|
+
* ]
|
|
259
|
+
* // Note: Additional WHERE conditions for active/non-expired
|
|
260
|
+
* // would be handled in the query logic, not in joinPath
|
|
261
|
+
* }
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
joinPath?: JoinStep[];
|
|
265
|
+
/**
|
|
266
|
+
* Action to perform on update.
|
|
267
|
+
*/
|
|
268
|
+
onUpdate?: OnAction;
|
|
269
|
+
/**
|
|
270
|
+
* Action to perform on delete.
|
|
271
|
+
*/
|
|
272
|
+
onDelete?: OnAction;
|
|
273
|
+
overrides?: Partial<EntityCollection>;
|
|
274
|
+
validation?: {
|
|
275
|
+
required?: boolean;
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Defines a single, explicit step in a multi-join path.
|
|
280
|
+
*
|
|
281
|
+
* Each step represents one JOIN operation in the sequence. The `from` columns
|
|
282
|
+
* refer to the previous table in the chain (or the source table for the first step),
|
|
283
|
+
* and the `to` columns refer to the current table being joined.
|
|
284
|
+
*
|
|
285
|
+
* @example Single column join:
|
|
286
|
+
* ```typescript
|
|
287
|
+
* {
|
|
288
|
+
* table: "authors",
|
|
289
|
+
* on: {
|
|
290
|
+
* from: "author_id", // Column from previous table (e.g., posts.author_id)
|
|
291
|
+
* to: "id" // Column from current table (authors.id)
|
|
292
|
+
* }
|
|
293
|
+
* }
|
|
294
|
+
* ```
|
|
295
|
+
*
|
|
296
|
+
* @example Multi-column composite key join:
|
|
297
|
+
* ```typescript
|
|
298
|
+
* {
|
|
299
|
+
* table: "order_items",
|
|
300
|
+
* on: {
|
|
301
|
+
* from: ["order_id", "store_id"], // Multiple columns from previous table
|
|
302
|
+
* to: ["order_id", "store_id"] // Corresponding columns in current table
|
|
303
|
+
* }
|
|
304
|
+
* }
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
export interface JoinStep {
|
|
308
|
+
/**
|
|
309
|
+
* The database table name to join TO in this step.
|
|
310
|
+
* This is the table you're joining into, not the table you're joining from.
|
|
311
|
+
*
|
|
312
|
+
* @example "authors", "user_roles", "product_categories"
|
|
313
|
+
*/
|
|
314
|
+
table: string;
|
|
315
|
+
/**
|
|
316
|
+
* The join condition for this step. Defines how the previous table
|
|
317
|
+
* connects to the current table.
|
|
318
|
+
*
|
|
319
|
+
* - `from`: Column name(s) on the PREVIOUS table in the join chain
|
|
320
|
+
* - `to`: Column name(s) on the CURRENT table (specified in `table`)
|
|
321
|
+
*
|
|
322
|
+
* For the first step, `from` refers to the source collection's table.
|
|
323
|
+
* For subsequent steps, `from` refers to the table from the previous step.
|
|
324
|
+
*
|
|
325
|
+
* Both `from` and `to` support:
|
|
326
|
+
* - Single column: `"user_id"`
|
|
327
|
+
* - Multiple columns: `["company_id", "region_id"]` for composite keys
|
|
328
|
+
*
|
|
329
|
+
* When using arrays, both `from` and `to` must have the same length,
|
|
330
|
+
* and columns are matched by position (index 0 with index 0, etc.).
|
|
331
|
+
*/
|
|
332
|
+
on: {
|
|
333
|
+
from: string | string[];
|
|
334
|
+
to: string | string[];
|
|
335
|
+
};
|
|
336
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CollectionActionsProps, EntityTableController, SelectionController, EntityCollection } from "./collections";
|
|
3
|
+
import { Entity } from "./entities";
|
|
4
|
+
import { PluginFormActionProps, PluginGenericProps, PluginHomePageActionsProps, PluginHomePageAdditionalCardsProps } from "./plugins";
|
|
5
|
+
import { Property } from "./properties";
|
|
6
|
+
import { RebaseContext } from "../rebase_context";
|
|
7
|
+
/**
|
|
8
|
+
* Registry mapping slot names to their component prop types.
|
|
9
|
+
* Each key represents a UI extension point in the CMS.
|
|
10
|
+
* @group Plugins
|
|
11
|
+
*/
|
|
12
|
+
export interface SlotRegistry {
|
|
13
|
+
"home.actions": PluginGenericProps;
|
|
14
|
+
"home.cards": PluginHomePageAdditionalCardsProps;
|
|
15
|
+
"home.children.start": PluginGenericProps;
|
|
16
|
+
"home.children.end": PluginGenericProps;
|
|
17
|
+
"home.collection.actions": PluginHomePageActionsProps;
|
|
18
|
+
/** Rendered below the logo in the sidebar drawer. */
|
|
19
|
+
"navigation.header": NavigationSlotProps;
|
|
20
|
+
/** Rendered above the collapse toggle at the bottom of the drawer. */
|
|
21
|
+
"navigation.footer": NavigationSlotProps;
|
|
22
|
+
"collection.actions": CollectionActionsProps;
|
|
23
|
+
"collection.actions.start": CollectionActionsProps;
|
|
24
|
+
"collection.header.action": CollectionHeaderActionProps;
|
|
25
|
+
"collection.add-column": CollectionAddColumnProps;
|
|
26
|
+
"collection.error": CollectionErrorProps;
|
|
27
|
+
/** Extra widgets rendered inside the collection toolbar row. */
|
|
28
|
+
"collection.toolbar": CollectionToolbarProps;
|
|
29
|
+
/** Custom empty-state component when a collection has no data. */
|
|
30
|
+
"collection.empty-state": CollectionEmptyStateProps;
|
|
31
|
+
"form.actions": PluginFormActionProps;
|
|
32
|
+
"form.actions.top": PluginFormActionProps;
|
|
33
|
+
/** Rendered before the form title / field list. */
|
|
34
|
+
"form.before": PluginFormActionProps;
|
|
35
|
+
/** Rendered after the form field list. */
|
|
36
|
+
"form.after": PluginFormActionProps;
|
|
37
|
+
/** Per-row actions in entity tables (e.g. bulk actions, row context menus). */
|
|
38
|
+
"entity.row.actions": EntityRowActionsProps;
|
|
39
|
+
/** Inject UI before an individual form field. */
|
|
40
|
+
"entity.field.before": EntityFieldSlotProps;
|
|
41
|
+
/** Inject UI after an individual form field. */
|
|
42
|
+
"entity.field.after": EntityFieldSlotProps;
|
|
43
|
+
/** Custom filter sidebar for a collection. */
|
|
44
|
+
"collection.filter-panel": CollectionFilterPanelProps;
|
|
45
|
+
/** Widget rendered on the dashboard / home page. */
|
|
46
|
+
"dashboard.widget": DashboardWidgetProps;
|
|
47
|
+
/** Cross-collection search bar component. */
|
|
48
|
+
"global.search": GlobalSearchProps;
|
|
49
|
+
/** Top-level toolbar actions rendered in the shell toolbar area. */
|
|
50
|
+
"shell.toolbar": ShellToolbarProps;
|
|
51
|
+
"kanban.setup": KanbanSetupProps;
|
|
52
|
+
"kanban.add-column": KanbanAddColumnProps;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Valid slot names for UI extension points.
|
|
56
|
+
* @group Plugins
|
|
57
|
+
*/
|
|
58
|
+
export type SlotName = keyof SlotRegistry;
|
|
59
|
+
/**
|
|
60
|
+
* A single UI component contribution to a named slot.
|
|
61
|
+
* @group Plugins
|
|
62
|
+
*/
|
|
63
|
+
export interface SlotContribution<K extends SlotName = SlotName> {
|
|
64
|
+
/**
|
|
65
|
+
* Which slot to contribute to.
|
|
66
|
+
*/
|
|
67
|
+
slot: K;
|
|
68
|
+
/**
|
|
69
|
+
* The component to render in the slot.
|
|
70
|
+
* Typed loosely so mixed-slot arrays work.
|
|
71
|
+
* Type safety is provided at the `useSlot` call site.
|
|
72
|
+
*/
|
|
73
|
+
Component: React.ComponentType<any>;
|
|
74
|
+
/**
|
|
75
|
+
* Additional props to merge into the slot props before rendering.
|
|
76
|
+
*/
|
|
77
|
+
props?: Record<string, any>;
|
|
78
|
+
/**
|
|
79
|
+
* Ordering hint. Lower values render first. Defaults to 50.
|
|
80
|
+
*/
|
|
81
|
+
order?: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Props for `navigation.header` and `navigation.footer` slots.
|
|
85
|
+
* @group Plugins
|
|
86
|
+
*/
|
|
87
|
+
export interface NavigationSlotProps {
|
|
88
|
+
drawerOpen: boolean;
|
|
89
|
+
drawerHovered: boolean;
|
|
90
|
+
context: RebaseContext;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Props for the `collection.toolbar` slot.
|
|
94
|
+
* @group Plugins
|
|
95
|
+
*/
|
|
96
|
+
export interface CollectionToolbarProps {
|
|
97
|
+
path: string;
|
|
98
|
+
collection: EntityCollection;
|
|
99
|
+
parentCollectionIds: string[];
|
|
100
|
+
tableController: EntityTableController;
|
|
101
|
+
selectionController: SelectionController;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Props for the `collection.empty-state` slot.
|
|
105
|
+
* @group Plugins
|
|
106
|
+
*/
|
|
107
|
+
export interface CollectionEmptyStateProps {
|
|
108
|
+
path: string;
|
|
109
|
+
collection: EntityCollection;
|
|
110
|
+
parentCollectionIds: string[];
|
|
111
|
+
canCreate: boolean;
|
|
112
|
+
onNewClick?: () => void;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Props for the `collection.header.action` slot.
|
|
116
|
+
* @group Plugins
|
|
117
|
+
*/
|
|
118
|
+
export interface CollectionHeaderActionProps {
|
|
119
|
+
property: Property;
|
|
120
|
+
propertyKey: string;
|
|
121
|
+
path: string;
|
|
122
|
+
parentCollectionIds: string[];
|
|
123
|
+
onHover: boolean;
|
|
124
|
+
collection: EntityCollection;
|
|
125
|
+
tableController: EntityTableController;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Props for the `collection.add-column` slot.
|
|
129
|
+
* @group Plugins
|
|
130
|
+
*/
|
|
131
|
+
export interface CollectionAddColumnProps {
|
|
132
|
+
path: string;
|
|
133
|
+
parentCollectionIds: string[];
|
|
134
|
+
collection: EntityCollection;
|
|
135
|
+
tableController: EntityTableController;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Props for the `collection.error` slot.
|
|
139
|
+
* @group Plugins
|
|
140
|
+
*/
|
|
141
|
+
export interface CollectionErrorProps {
|
|
142
|
+
path: string;
|
|
143
|
+
collection: EntityCollection;
|
|
144
|
+
parentCollectionIds?: string[];
|
|
145
|
+
error: Error;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Props for the `kanban.setup` slot.
|
|
149
|
+
* @group Plugins
|
|
150
|
+
*/
|
|
151
|
+
export interface KanbanSetupProps {
|
|
152
|
+
collection: EntityCollection;
|
|
153
|
+
fullPath: string;
|
|
154
|
+
parentCollectionIds: string[];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Props for the `kanban.add-column` slot.
|
|
158
|
+
* @group Plugins
|
|
159
|
+
*/
|
|
160
|
+
export interface KanbanAddColumnProps {
|
|
161
|
+
collection: EntityCollection;
|
|
162
|
+
fullPath: string;
|
|
163
|
+
parentCollectionIds: string[];
|
|
164
|
+
columnProperty: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Props for `entity.row.actions` slot.
|
|
168
|
+
* Rendered for each row in an entity collection table.
|
|
169
|
+
* @group Plugins
|
|
170
|
+
*/
|
|
171
|
+
export interface EntityRowActionsProps {
|
|
172
|
+
entity: Entity;
|
|
173
|
+
entityId: string;
|
|
174
|
+
path: string;
|
|
175
|
+
collection: EntityCollection;
|
|
176
|
+
parentCollectionIds: string[];
|
|
177
|
+
selectionController: SelectionController;
|
|
178
|
+
context: RebaseContext;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Props for `entity.field.before` and `entity.field.after` slots.
|
|
182
|
+
* Rendered around individual form fields in the entity edit view.
|
|
183
|
+
* @group Plugins
|
|
184
|
+
*/
|
|
185
|
+
export interface EntityFieldSlotProps {
|
|
186
|
+
propertyKey: string;
|
|
187
|
+
property: Property;
|
|
188
|
+
path: string;
|
|
189
|
+
entityId?: string | number;
|
|
190
|
+
collection: EntityCollection;
|
|
191
|
+
context: RebaseContext;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Props for `collection.filter-panel` slot.
|
|
195
|
+
* Custom filter sidebar rendered alongside the collection table.
|
|
196
|
+
* @group Plugins
|
|
197
|
+
*/
|
|
198
|
+
export interface CollectionFilterPanelProps {
|
|
199
|
+
path: string;
|
|
200
|
+
collection: EntityCollection;
|
|
201
|
+
parentCollectionIds: string[];
|
|
202
|
+
tableController: EntityTableController;
|
|
203
|
+
context: RebaseContext;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Props for `dashboard.widget` slot.
|
|
207
|
+
* Widgets rendered on the home / dashboard page.
|
|
208
|
+
* @group Plugins
|
|
209
|
+
*/
|
|
210
|
+
export interface DashboardWidgetProps {
|
|
211
|
+
context: RebaseContext;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Props for `global.search` slot.
|
|
215
|
+
* Cross-collection search bar rendered in the app shell.
|
|
216
|
+
* @group Plugins
|
|
217
|
+
*/
|
|
218
|
+
export interface GlobalSearchProps {
|
|
219
|
+
context: RebaseContext;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Props for `shell.toolbar` slot.
|
|
223
|
+
* Actions rendered in the top-level toolbar / app bar area.
|
|
224
|
+
* @group Plugins
|
|
225
|
+
*/
|
|
226
|
+
export interface ShellToolbarProps {
|
|
227
|
+
context: RebaseContext;
|
|
228
|
+
}
|