@rebasepro/types 0.0.1-canary.f81da60 → 0.1.2

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.
@@ -130,4 +130,19 @@ export interface RebaseClient<DB = unknown> {
130
130
 
131
131
  /** Admin API for user and role management */
132
132
  admin?: AdminAPI;
133
+
134
+ /**
135
+ * The base HTTP URL of the backend server.
136
+ * Exposed by the SDK client (`@rebasepro/client`) and used to auto-derive
137
+ * the `ApiConfigProvider` URL.
138
+ */
139
+ baseUrl?: string;
140
+
141
+ /**
142
+ * WebSocket client for realtime subscriptions and admin capabilities.
143
+ * Exposed by the SDK client (`@rebasepro/client`). The shape is intentionally
144
+ * left as `unknown` in the base interface — callers should narrow via feature
145
+ * detection (e.g. `typeof ws.executeSql === "function"`).
146
+ */
147
+ ws?: unknown;
133
148
  }
@@ -172,17 +172,18 @@ export interface AppView {
172
172
  hideFromNavigation?: boolean;
173
173
 
174
174
  /**
175
- * Component to be rendered. This can be any React component, and can use
176
- * any of the provided hooks
175
+ * Navigation group for this view.
176
+ * Views sharing the same group name will be visually grouped
177
+ * together in the drawer and home page. If not set, the view
178
+ * falls into the default "Views" group.
177
179
  */
178
- view: React.ReactNode;
180
+ group?: string;
179
181
 
180
182
  /**
181
- * Optional field used to group top level navigation entries under a
182
- * navigation view.
183
- * This prop is ignored for admin views.
183
+ * Component to be rendered. This can be any React component, and can use
184
+ * any of the provided hooks
184
185
  */
185
- group?: string;
186
+ view: React.ReactNode;
186
187
 
187
188
  /**
188
189
  * If true, a wildcard route (slug/*) is automatically registered
@@ -227,6 +228,17 @@ export interface NavigationGroupMapping {
227
228
  * List of collection ids or view paths that belong to this group.
228
229
  */
229
230
  entries: string[];
231
+ /**
232
+ * Configure which groups start collapsed.
233
+ * Set to `true` to collapse in both drawer and home page,
234
+ * or use an object to control each independently.
235
+ *
236
+ * @defaultValue false (expanded)
237
+ */
238
+ collapsedByDefault?: boolean | {
239
+ drawer?: boolean;
240
+ home?: boolean;
241
+ };
230
242
  }
231
243
 
232
244
  export interface NavigationEntry {
@@ -3,7 +3,7 @@ import type { EntityCollection } from "../types/collections";
3
3
  import type { EntityCollectionsBuilder } from "../types/builders";
4
4
  import type { EntityCustomView } from "../types/entity_views";
5
5
  import type { EntityAction } from "../types/entity_actions";
6
- import type { AppView } from "./navigation";
6
+ import type { AppView, NavigationGroupMapping } from "./navigation";
7
7
 
8
8
  /**
9
9
  * Options to enable the built-in collection editor.
@@ -28,6 +28,15 @@ export interface RebaseCMSConfig<EC extends EntityCollection = any> {
28
28
  entityActions?: EntityAction[];
29
29
  plugins?: any[];
30
30
 
31
+ /**
32
+ * Centralized configuration for how collections and views are grouped
33
+ * in the navigation sidebar and home page.
34
+ * Each mapping defines a named group and the collection/view slugs
35
+ * that belong to it. The array order determines group display order.
36
+ * Entry order within each group determines card order.
37
+ */
38
+ navigationGroupMappings?: NavigationGroupMapping[];
39
+
31
40
  /**
32
41
  * Enable the built-in visual collection/schema editor.
33
42
  * Pass `true` for zero-config, or an options object for fine-grained control.
@@ -73,6 +73,14 @@ export interface EntitySidePanelProps<M extends Record<string, unknown> = Record
73
73
  * Allow the user to open the entity fullscreen
74
74
  */
75
75
  allowFullScreen?: boolean;
76
+
77
+ /**
78
+ * Pre-populate the form with these values when creating a new entity.
79
+ * Only applied when `entityId` is not set (i.e. the form is in "new" mode).
80
+ * Useful for actions that fetch data from an external source (e.g. a URL)
81
+ * and want to pre-fill the document before the user saves.
82
+ */
83
+ defaultValues?: Partial<M>;
76
84
  }
77
85
 
78
86
  /**
@@ -3,6 +3,7 @@ import type { AuthController } from "./controllers/auth";
3
3
  import type { StorageSource } from "./controllers/storage";
4
4
  import type { UserConfigurationPersistence } from "./controllers/local_config_persistence";
5
5
  import type { DatabaseAdmin } from "./types/backend";
6
+ import type { RebaseClient } from "./controllers/client";
6
7
 
7
8
  import type { RebaseData } from "./controllers/data";
8
9
  import type { User } from "./users";
@@ -16,6 +17,23 @@ import type { UserManagementDelegate } from "./types/user_management_delegate";
16
17
  */
17
18
  export type RebaseCallContext<USER extends User = User> = {
18
19
 
20
+ /**
21
+ * The Rebase client instance.
22
+ * Available in all entity callbacks (beforeSave, afterSave, afterRead,
23
+ * beforeDelete, afterDelete) and in CollectionActionsProps via context.
24
+ * Use it to call backend functions, access data, storage, etc.
25
+ *
26
+ * @example
27
+ * // In a beforeSave callback:
28
+ * const result = await context.client.functions.invoke('my-function', { ... });
29
+ *
30
+ * @example
31
+ * // In a CollectionAction component:
32
+ * const { client } = props.context;
33
+ * const result = await client.functions.invoke('extract-job', { url });
34
+ */
35
+ client: RebaseClient<any>;
36
+
19
37
  /**
20
38
  * Unified data access — `context.data.products.create(...)`.
21
39
  * Access any collection as a dynamic property.
@@ -10,6 +10,7 @@ import type { RebaseContext } from "../rebase_context";
10
10
  import type { Relation } from "./relations";
11
11
  import type { EntityCustomView } from "./entity_views";
12
12
  import type { EntityAction } from "./entity_actions";
13
+ import type { ComponentRef } from "./component_ref";
13
14
 
14
15
  /**
15
16
  * Base interface containing all driver-agnostic collection properties.
@@ -99,6 +100,9 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
99
100
 
100
101
  /**
101
102
  * Navigation group for this collection.
103
+ * Collections sharing the same group name will be visually grouped
104
+ * together in the drawer and home page. If not set, the collection
105
+ * falls into the default "Views" group.
102
106
  */
103
107
  group?: string;
104
108
 
@@ -351,7 +355,7 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
351
355
  /**
352
356
  * Builder for the collection actions rendered in the toolbar
353
357
  */
354
- Actions?: React.ComponentType<any>[];
358
+ Actions?: ComponentRef<CollectionActionsProps>[];
355
359
 
356
360
 
357
361
  }
@@ -584,6 +588,22 @@ export interface CollectionActionsProps<M extends Record<string, unknown> = Reco
584
588
  */
585
589
  collectionEntitiesCount?: number;
586
590
 
591
+ /**
592
+ * Programmatically open the new-document form for this collection,
593
+ * optionally pre-populating it with initial field values.
594
+ * The form opens in the same mode configured for the collection
595
+ * (side panel, full screen, or split).
596
+ *
597
+ * This is the primary hook for workflows that need to create a document
598
+ * from external data — e.g. fetching content from a URL, importing from
599
+ * a third-party API, or duplicating from another system.
600
+ *
601
+ * @example
602
+ * // Inside a custom CollectionAction component:
603
+ * openNewDocument({ title: "Fetched title", body: "..." });
604
+ */
605
+ openNewDocument: (defaultValues?: Record<string, unknown>) => void;
606
+
587
607
  }
588
608
 
589
609
  /**
@@ -0,0 +1,57 @@
1
+ import type React from "react";
2
+
3
+ /**
4
+ * Internal marker for a lazily-loaded component reference.
5
+ * Created by the Vite transform plugin when converting string paths
6
+ * to deferred `import()` calls. Users should NOT create these manually.
7
+ *
8
+ * @internal
9
+ */
10
+ export interface LazyComponentRef<P = unknown> {
11
+ readonly __rebaseLazy: true;
12
+ readonly load: () => Promise<{ default: React.ComponentType<P> }>;
13
+ }
14
+
15
+ /**
16
+ * A reference to a React component that can be provided in three forms:
17
+ *
18
+ * 1. **String path** (recommended for collection configs):
19
+ * ```ts
20
+ * Field: "../../frontend/src/components/MyField"
21
+ * ```
22
+ * The Vite plugin transforms this into a `LazyComponentRef` at build time.
23
+ * On the backend, the string stays inert and is never evaluated.
24
+ *
25
+ * 2. **Lazy import function**:
26
+ * ```ts
27
+ * Field: () => import("../../frontend/src/components/MyField")
28
+ * ```
29
+ * Standard ES dynamic import. Backend never calls the function.
30
+ *
31
+ * 3. **Direct component reference** (use only in frontend-only code):
32
+ * ```ts
33
+ * Field: MyFieldComponent
34
+ * ```
35
+ * Importing a component at the top level will pull React into the
36
+ * backend runtime — only safe in code that the backend never imports.
37
+ *
38
+ * @group Types
39
+ */
40
+ export type ComponentRef<P = unknown> =
41
+ | React.ComponentType<P>
42
+ | LazyComponentRef<P>
43
+ | (() => Promise<{ default: React.ComponentType<P> }>)
44
+ | string;
45
+
46
+ /**
47
+ * Type guard: checks if a value is a `LazyComponentRef` produced by the
48
+ * Vite transform plugin.
49
+ */
50
+ export function isLazyComponentRef<P = unknown>(ref: unknown): ref is LazyComponentRef<P> {
51
+ return (
52
+ typeof ref === "object" &&
53
+ ref !== null &&
54
+ "__rebaseLazy" in ref &&
55
+ (ref as Record<string, unknown>).__rebaseLazy === true
56
+ );
57
+ }
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import type { Entity, EntityValues } from "./entities";
3
3
  import type { EntityCollection } from "./collections";
4
4
  import type { FormexController } from "./formex";
5
+ import type { ComponentRef } from "./component_ref";
5
6
 
6
7
  /**
7
8
  * Context passed to custom fields and entity views.
@@ -61,7 +62,7 @@ export type EntityCustomView<M extends Record<string, unknown> = Record<string,
61
62
  name: string;
62
63
  tabComponent?: React.ReactNode;
63
64
  includeActions?: boolean | "bottom";
64
- Builder?: React.ComponentType<EntityCustomViewParams<M>>;
65
+ Builder?: ComponentRef<EntityCustomViewParams<M>>;
65
66
  position?: "start" | "end";
66
67
  };
67
68
 
@@ -25,3 +25,4 @@ export * from "./entity_views";
25
25
  export * from "./data_source";
26
26
  export * from "./cron";
27
27
  export * from "./backend_hooks";
28
+ export * from "./component_ref";
@@ -1,5 +1,7 @@
1
1
  import React from "react";
2
2
 
3
+ import type { ComponentRef } from "./component_ref";
4
+
3
5
  import type { EntityReference, EntityRelation, EntityValues, GeoPoint, Entity } from "./entities";
4
6
  import type { Relation, JoinStep, OnAction } from "./relations";
5
7
  import type { EntityCollection, FilterValues } from "./collections";
@@ -144,8 +146,8 @@ export interface BaseUIConfig<CustomProps = unknown> {
144
146
  disabled?: boolean | PropertyDisabledConfig;
145
147
  widthPercentage?: number;
146
148
  customProps?: CustomProps;
147
- Field?: React.ComponentType<any>;
148
- Preview?: React.ComponentType<any>;
149
+ Field?: ComponentRef<any>;
150
+ Preview?: ComponentRef<any>;
149
151
  }
150
152
 
151
153
  export interface BaseProperty<CustomProps = unknown> {
@@ -168,6 +170,19 @@ export interface BaseProperty<CustomProps = unknown> {
168
170
  */
169
171
  propertyConfig?: string;
170
172
 
173
+ /**
174
+ * Explicit database column name. When set, this value is used as-is
175
+ * for the SQL column name, bypassing any snake_case conversion of
176
+ * the property key.
177
+ *
178
+ * This is automatically populated by `rebase schema introspect`
179
+ * to guarantee an exact match with the live database schema.
180
+ *
181
+ * For manually-authored collections you can omit this — the framework
182
+ * will derive the column name from the property key via `toSnakeCase()`.
183
+ */
184
+ columnName?: string;
185
+
171
186
 
172
187
 
173
188
  /**
@@ -61,6 +61,8 @@ export interface RebaseTranslations {
61
61
  all_entries_loaded: string;
62
62
  create_your_first_entry: string;
63
63
  no_results_filter_sort: string;
64
+ /** Shown when a text search yields no results. Supports `{{search}}` interpolation. */
65
+ no_results_search?: string;
64
66
  add: string;
65
67
  remove: string;
66
68
  copy_id: string;