@rebasepro/types 0.7.0 → 0.9.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.
Files changed (88) hide show
  1. package/README.md +10 -10
  2. package/dist/controllers/auth.d.ts +1 -1
  3. package/dist/controllers/client.d.ts +237 -7
  4. package/dist/controllers/collection_registry.d.ts +3 -3
  5. package/dist/controllers/customization_controller.d.ts +1 -1
  6. package/dist/controllers/data.d.ts +285 -81
  7. package/dist/controllers/data_driver.d.ts +50 -37
  8. package/dist/controllers/index.d.ts +1 -1
  9. package/dist/controllers/local_config_persistence.d.ts +4 -4
  10. package/dist/controllers/navigation.d.ts +2 -2
  11. package/dist/controllers/registry.d.ts +17 -6
  12. package/dist/controllers/{side_entity_controller.d.ts → side_panel_controller.d.ts} +7 -7
  13. package/dist/controllers/storage.d.ts +39 -0
  14. package/dist/errors.d.ts +64 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.es.js +290 -16
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +305 -18
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/rebase_context.d.ts +8 -4
  21. package/dist/types/auth_adapter.d.ts +9 -6
  22. package/dist/types/backend.d.ts +30 -26
  23. package/dist/types/builders.d.ts +2 -2
  24. package/dist/types/collections.d.ts +211 -136
  25. package/dist/types/component_overrides.d.ts +61 -3
  26. package/dist/types/cron.d.ts +10 -1
  27. package/dist/types/data_source.d.ts +18 -5
  28. package/dist/types/database_adapter.d.ts +4 -3
  29. package/dist/types/entities.d.ts +7 -7
  30. package/dist/types/entity_actions.d.ts +7 -7
  31. package/dist/types/entity_callbacks.d.ts +55 -43
  32. package/dist/types/entity_views.d.ts +3 -3
  33. package/dist/types/filter-operators.d.ts +153 -0
  34. package/dist/types/index.d.ts +3 -2
  35. package/dist/types/modify_collections.d.ts +2 -2
  36. package/dist/types/plugins.d.ts +9 -9
  37. package/dist/types/policy.d.ts +191 -0
  38. package/dist/types/properties.d.ts +153 -43
  39. package/dist/types/property_config.d.ts +1 -1
  40. package/dist/types/relations.d.ts +3 -3
  41. package/dist/types/slots.d.ts +14 -14
  42. package/dist/types/storage_source.d.ts +83 -0
  43. package/dist/types/websockets.d.ts +12 -13
  44. package/dist/users/user.d.ts +21 -9
  45. package/package.json +1 -1
  46. package/src/controllers/auth.tsx +1 -1
  47. package/src/controllers/client.ts +275 -7
  48. package/src/controllers/collection_registry.ts +3 -3
  49. package/src/controllers/customization_controller.tsx +1 -1
  50. package/src/controllers/data.ts +309 -97
  51. package/src/controllers/data_driver.ts +49 -40
  52. package/src/controllers/index.ts +1 -1
  53. package/src/controllers/local_config_persistence.tsx +4 -4
  54. package/src/controllers/navigation.ts +2 -2
  55. package/src/controllers/registry.ts +18 -6
  56. package/src/controllers/{side_entity_controller.tsx → side_panel_controller.tsx} +7 -7
  57. package/src/controllers/storage.ts +60 -1
  58. package/src/errors.ts +80 -0
  59. package/src/index.ts +1 -0
  60. package/src/rebase_context.tsx +8 -4
  61. package/src/types/auth_adapter.ts +9 -6
  62. package/src/types/backend.ts +41 -36
  63. package/src/types/builders.ts +2 -2
  64. package/src/types/collections.ts +256 -172
  65. package/src/types/component_overrides.ts +72 -5
  66. package/src/types/cron.ts +10 -1
  67. package/src/types/data_source.ts +29 -7
  68. package/src/types/database_adapter.ts +4 -3
  69. package/src/types/entities.ts +7 -7
  70. package/src/types/entity_actions.tsx +7 -7
  71. package/src/types/entity_callbacks.ts +58 -47
  72. package/src/types/entity_views.tsx +3 -3
  73. package/src/types/filter-operators.ts +240 -0
  74. package/src/types/index.ts +3 -2
  75. package/src/types/modify_collections.tsx +2 -2
  76. package/src/types/plugins.tsx +9 -9
  77. package/src/types/policy.ts +229 -0
  78. package/src/types/properties.ts +164 -44
  79. package/src/types/property_config.tsx +0 -1
  80. package/src/types/relations.ts +3 -3
  81. package/src/types/slots.tsx +14 -14
  82. package/src/types/storage_source.ts +90 -0
  83. package/src/types/websockets.ts +12 -14
  84. package/src/users/user.ts +22 -9
  85. package/dist/types/backend_hooks.d.ts +0 -109
  86. package/dist/types/entity_overrides.d.ts +0 -10
  87. package/src/types/backend_hooks.ts +0 -114
  88. package/src/types/entity_overrides.tsx +0 -11
package/README.md CHANGED
@@ -14,22 +14,22 @@ Provides the canonical type definitions used across all Rebase packages — both
14
14
 
15
15
  ## Key Exports
16
16
 
17
- ### Collection & Entity Types
17
+ ### Collection & Snapshot Types
18
18
 
19
19
  | Export | Description |
20
20
  |--------|-------------|
21
- | `EntityCollection` | Full collection definition (name, slug, properties, callbacks, security rules, views) |
21
+ | `CollectionConfig` | Full collection definition (name, slug, properties, callbacks, security rules, views) |
22
22
  | `Property` | Union type for all property configurations (text, number, date, reference, array, map, etc.) |
23
- | `Entity` | Generic entity record type |
24
- | `EntityCallbacks` | Lifecycle hooks (`onPreSave`, `onSaveSuccess`, `onDelete`, etc.) |
25
- | `EntityValues` | Record of property values for an entity |
23
+ | `Snapshot` | Generic snapshot record type |
24
+ | `CollectionCallbacks` | Lifecycle hooks (`onPreSave`, `onSaveSuccess`, `onDelete`, etc.) |
25
+ | `SnapshotValues` | Record of property values for a snapshot |
26
26
  | `SecurityRule` | RLS-style access control rule for a collection |
27
27
 
28
28
  ### Backend & Driver Interfaces
29
29
 
30
30
  | Export | Description |
31
31
  |--------|-------------|
32
- | `DataDriver` | Abstract interface for database drivers (`fetchCollection`, `saveEntity`, `deleteEntity`, etc.) |
32
+ | `DataDriver` | Abstract interface for database drivers (`fetchCollection`, `saveSnapshot`, `deleteSnapshot`, etc.) |
33
33
  | `DatabaseAdapter` | Pluggable database adapter interface (used by `server-core`) |
34
34
  | `BackendBootstrapper` | Lifecycle interface for initializing database drivers, auth, history, and realtime |
35
35
  | `DatabaseAdmin` | Admin operations interface (SQL execution, collection stats, table metadata) |
@@ -63,7 +63,7 @@ Provides the canonical type definitions used across all Rebase packages — both
63
63
  | Export | Description |
64
64
  |--------|-------------|
65
65
  | `CronJobDefinition` | Cron job configuration type |
66
- | `BackendHooks` | Server-side hooks for intercepting admin data |
66
+ | `CollectionCallbacks` | Lifecycle callbacks for snapshot CRUD operations |
67
67
  | `PluginConfig` | Plugin system types |
68
68
  | `WebSocketMessage` | WebSocket protocol message types |
69
69
  | `Locale` | Localization types |
@@ -72,7 +72,7 @@ Provides the canonical type definitions used across all Rebase packages — both
72
72
 
73
73
  ```typescript
74
74
  import type {
75
- EntityCollection,
75
+ CollectionConfig,
76
76
  DataDriver,
77
77
  DatabaseAdapter,
78
78
  RebaseUser,
@@ -88,6 +88,6 @@ Every `@rebasepro/*` package depends on this one. Key consumers:
88
88
  |---------|------|
89
89
  | `@rebasepro/server-core` | `DataDriver`, `DatabaseAdapter`, `BackendBootstrapper`, `AuthAdapter` |
90
90
  | `@rebasepro/server-postgresql` | `BackendBootstrapper`, `InitializedDriver`, `RealtimeProvider` |
91
- | `@rebasepro/server-mongodb` | `BackendBootstrapper`, `DataDriver`, `EntityCollection` |
91
+ | `@rebasepro/server-mongodb` | `BackendBootstrapper`, `DataDriver`, `CollectionConfig` |
92
92
  | `@rebasepro/client` | `RebaseClient`, `DataSourceDelegate`, `StorageSource` |
93
- | `@rebasepro/admin` | `EntityCollection`, `Property`, `PluginConfig`, controller interfaces |
93
+ | `@rebasepro/admin` | `CollectionConfig`, `Property`, `PluginConfig`, controller interfaces |
@@ -71,7 +71,7 @@ export type AuthController<USER extends User = User, ExtraData = unknown> = {
71
71
  };
72
72
  /**
73
73
  * Extended auth controller with common optional auth methods.
74
- * Backend implementations (Rebase backend, Firebase, Supabase, etc.)
74
+ * Backend implementations (Rebase backend, Firebase, etc.)
75
75
  * extend this with their own backend-specific extras.
76
76
  * @group Hooks and utilities
77
77
  */
@@ -1,15 +1,19 @@
1
1
  import type { User } from "../users";
2
- import type { RebaseData } from "./data";
2
+ import type { RebaseSdkData } from "./data";
3
3
  import type { EmailService } from "./email";
4
4
  import type { StorageSource } from "./storage";
5
5
  import type { CronJobStatus, CronJobLogEntry } from "../types/cron";
6
6
  import type { ApiKeysAPI } from "../types/api_keys";
7
+ import type { StorageSourceDefinition } from "../types/storage_source";
7
8
  /**
8
9
  * Event type for authentication state changes
9
10
  */
10
11
  export type AuthChangeEvent = "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED";
11
12
  /**
12
- * Standard session interface representing an authenticated state
13
+ * Standard session interface representing an authenticated state.
14
+ *
15
+ * There is exactly one canonical definition of this type (here in
16
+ * `@rebasepro/types`). The `@rebasepro/client` package re-exports it.
13
17
  */
14
18
  export interface RebaseSession {
15
19
  accessToken: string;
@@ -17,6 +21,36 @@ export interface RebaseSession {
17
21
  expiresAt: number;
18
22
  user: User;
19
23
  }
24
+ /**
25
+ * Access and refresh token pair returned by authentication endpoints.
26
+ *
27
+ * Replaces the former `RebaseTokens` (client) and `AuthTokens` (auth) types,
28
+ * which had identical shapes.
29
+ *
30
+ * @group Auth
31
+ */
32
+ export interface AuthTokens {
33
+ accessToken: string;
34
+ refreshToken: string;
35
+ /** Unix timestamp (ms) when the access token expires. */
36
+ accessTokenExpiresAt: number;
37
+ }
38
+ /**
39
+ * A device-level session entry as returned by `GET /auth/sessions`.
40
+ *
41
+ * Represents one refresh-token / device pair. Not to be confused with
42
+ * {@link RebaseSession}, which is the client-side representation of the
43
+ * *current* authenticated state (user + tokens).
44
+ *
45
+ * @group Auth
46
+ */
47
+ export interface DeviceSession {
48
+ id: string;
49
+ userAgent?: string;
50
+ ipAddress?: string;
51
+ createdAt: string;
52
+ isCurrentSession?: boolean;
53
+ }
20
54
  /**
21
55
  * Unified Authentication Client Interface
22
56
  * Pure functional SDK interface, decoupled from UI and React hooks
@@ -30,6 +64,12 @@ export interface AuthClient {
30
64
  * Get the currently active session
31
65
  */
32
66
  getSession(): RebaseSession | null;
67
+ /**
68
+ * Get the current user's active sessions
69
+ */
70
+ getSessions?: () => Promise<DeviceSession[]>;
71
+ revokeSession?: (sessionId: string) => Promise<void>;
72
+ revokeAllSessions?: () => Promise<void>;
33
73
  /**
34
74
  * Sign out the current user and clear local session
35
75
  */
@@ -44,7 +84,14 @@ export interface AuthClient {
44
84
  refreshSession(): Promise<RebaseSession>;
45
85
  }
46
86
  /**
47
- * User record as returned by the Admin API.
87
+ * User record as returned by the Admin API (`GET /admin/users`, etc.).
88
+ *
89
+ * This is a dedicated DTO for admin operations and differs from {@link User}:
90
+ * - `roles` is required (always an array), vs optional on `User`
91
+ * - Includes audit timestamps (`createdAt`, `updatedAt`) as ISO strings
92
+ * - `email` is non-nullable (admin users always have an email)
93
+ *
94
+ * @see User — the canonical client-facing user type
48
95
  * @group Admin
49
96
  */
50
97
  export interface AdminUser {
@@ -52,7 +99,11 @@ export interface AdminUser {
52
99
  email: string;
53
100
  displayName: string | null;
54
101
  photoURL: string | null;
55
- provider: string;
102
+ /**
103
+ * The provider used to authenticate the user (e.g. `"password"`,
104
+ * `"google"`). Named to match the canonical {@link User.providerId}.
105
+ */
106
+ providerId: string;
56
107
  roles: string[];
57
108
  metadata?: Record<string, any>;
58
109
  createdAt: string;
@@ -176,6 +227,31 @@ export interface FunctionsAPI {
176
227
  */
177
228
  invoke<T = unknown>(name: string, payload?: unknown, options?: FunctionInvokeOptions): Promise<T>;
178
229
  }
230
+ /**
231
+ * Configuration for entity history / audit-log tracking.
232
+ *
233
+ * - `true` — enable history with default settings
234
+ * - `{ retention?: number }` — enable with optional retention period in days
235
+ */
236
+ export type HistoryConfig = boolean | {
237
+ retention?: number;
238
+ };
239
+ /**
240
+ * Minimal WebSocket client contract exposed on {@link RebaseClient}.
241
+ *
242
+ * The full implementation (`RebaseWebSocketClient` in `@rebasepro/client`)
243
+ * adds subscription helpers, CRUD-over-WS, SQL execution, etc.
244
+ */
245
+ export interface RebaseWebSocket {
246
+ /** Disconnect the WebSocket and stop reconnecting. */
247
+ disconnect(): void;
248
+ /** Send an authentication token to the server. */
249
+ authenticate(token: string): Promise<void>;
250
+ /** Set a function that lazily resolves the auth token for auto-authentication. */
251
+ setAuthTokenGetter(getter: () => Promise<string | null>): void;
252
+ /** Listen for connection lifecycle events. */
253
+ on(event: "connect" | "disconnect" | "reconnect" | "error", cb: (...args: unknown[]) => void): () => void;
254
+ }
179
255
  /**
180
256
  * The single, canonical Rebase client interface.
181
257
  *
@@ -188,11 +264,46 @@ export interface FunctionsAPI {
188
264
  */
189
265
  export interface RebaseClient<DB = unknown> {
190
266
  /** Unified Data access layer */
191
- data: RebaseData;
267
+ data: RebaseSdkData<DB>;
268
+ /**
269
+ * Admin-scoped, **RLS-bypassing** data accessor.
270
+ *
271
+ * Present on the **server** singleton only (see {@link RebaseServerClient}).
272
+ * It runs with `{ uid: "service", roles: ["admin"] }` — every read and write
273
+ * bypasses row-level-security policies. This is the correct tool for trusted
274
+ * background work (cron jobs, migrations, service-to-service tasks).
275
+ *
276
+ * ⚠️ **Do NOT use it to serve user-facing data.** Inside a request handler,
277
+ * user-scoped queries must go through the request-scoped driver
278
+ * (`c.var.driver`), which carries the caller's identity so RLS applies.
279
+ * Reaching for `dataAsAdmin` (or its alias {@link data}) in a request handler
280
+ * silently exposes every row to every caller.
281
+ *
282
+ * Undefined in the browser SDK.
283
+ */
284
+ dataAsAdmin?: RebaseSdkData<DB>;
192
285
  /** Unified Authentication layer */
193
286
  auth: AuthClient;
194
- /** Unified Storage layer */
287
+ /** Unified Storage layer (default storage source, backward-compatible) */
195
288
  storage?: StorageSource;
289
+ /** Registry of all named storage sources for multi-backend support */
290
+ storageRegistry?: StorageSourceRegistry;
291
+ /**
292
+ * Build a server-backed {@link StorageSource} for a named storage source.
293
+ * The returned source forwards `storageId` to the backend so requests are
294
+ * routed to the matching `StorageController`. Used to lazily wire
295
+ * `transport: "server"` sources on the frontend.
296
+ */
297
+ createStorageSource?(storageId: string): StorageSource;
298
+ /**
299
+ * Discover the storage sources declared on the backend via
300
+ * `GET /api/storage/sources`. Server-transport sources are auto-registered
301
+ * into {@link storageRegistry}; `direct` sources are returned so the app
302
+ * can supply the live {@link StorageSource} instance. The result is cached
303
+ * (a failed call is retryable). This makes the backend the single source of
304
+ * truth for storage-source configuration.
305
+ */
306
+ fetchStorageSources?(): Promise<StorageSourceDefinition[]>;
196
307
  /**
197
308
  * Server-side email service.
198
309
  * Available when SMTP or a custom `sendEmail` function is configured.
@@ -209,7 +320,7 @@ export interface RebaseClient<DB = unknown> {
209
320
  /** Base HTTP URL of the backend server */
210
321
  baseUrl?: string;
211
322
  /** WebSocket client for realtime subscriptions */
212
- ws?: unknown;
323
+ ws?: RebaseWebSocket;
213
324
  /** Set the auth token for subsequent requests */
214
325
  setToken?(token: string | null): void;
215
326
  /** Set a function that lazily resolves the auth token */
@@ -229,3 +340,122 @@ export interface RebaseClient<DB = unknown> {
229
340
  role?: string;
230
341
  }): Promise<Record<string, unknown>[]>;
231
342
  }
343
+ /**
344
+ * The server-side Rebase surface — the shape of the `rebase` singleton exported
345
+ * from `@rebasepro/server-core`.
346
+ *
347
+ * Narrows {@link RebaseClient} to the guarantees that always hold on the server:
348
+ * the admin-scoped {@link dataAsAdmin} accessor, raw {@link sql}, and the
349
+ * {@link email} service are all present (non-optional).
350
+ *
351
+ * **Trust levels.** Both {@link dataAsAdmin} and the deprecated {@link data}
352
+ * alias point at the same admin-scoped, **RLS-bypassing** driver. Prefer
353
+ * `dataAsAdmin` so the privilege is explicit at every call site. For user-scoped
354
+ * queries inside a request handler use the request-scoped driver
355
+ * (`c.var.driver`) instead — never `dataAsAdmin`/`data`.
356
+ */
357
+ export interface RebaseServerClient<DB = unknown> extends RebaseClient<DB> {
358
+ /**
359
+ * @deprecated On the server, prefer {@link dataAsAdmin} for admin scope or
360
+ * the request-scoped driver (`c.var.driver`) for user scope. This alias
361
+ * points at the same admin-scoped, RLS-bypassing accessor as `dataAsAdmin`.
362
+ */
363
+ data: RebaseSdkData<DB>;
364
+ /**
365
+ * Admin-scoped, **RLS-bypassing** data accessor. Always present server-side.
366
+ * See {@link RebaseClient.dataAsAdmin} for the full safety contract.
367
+ */
368
+ dataAsAdmin: RebaseSdkData<DB>;
369
+ /**
370
+ * Server-side email service. Always present server-side (a no-op sender is
371
+ * wired when SMTP is not configured).
372
+ */
373
+ email: EmailService;
374
+ /**
375
+ * Execute raw SQL against the database. Always present server-side for SQL
376
+ * engines.
377
+ */
378
+ sql(query: string, options?: {
379
+ database?: string;
380
+ role?: string;
381
+ }): Promise<Record<string, unknown>[]>;
382
+ }
383
+ /**
384
+ * The browser-side Rebase surface — the shape produced by
385
+ * `createRebaseClient()` in `@rebasepro/client`.
386
+ *
387
+ * Its {@link data} accessor is **user-scoped**: every call carries the signed-in
388
+ * user's token, so backend RLS policies apply. It deliberately omits the
389
+ * server-only members — there is no `sql`, no `email`, and no
390
+ * `dataAsAdmin`, so the RLS-bypassing accessor can never be reached from
391
+ * browser code.
392
+ */
393
+ export interface RebaseBrowserClient<DB = unknown> {
394
+ /** User-scoped data access layer (carries the signed-in user's token). */
395
+ data: RebaseSdkData<DB>;
396
+ /** Unified Authentication layer */
397
+ auth: AuthClient;
398
+ /** Unified Storage layer (default storage source, backward-compatible) */
399
+ storage?: StorageSource;
400
+ /** Registry of all named storage sources for multi-backend support */
401
+ storageRegistry?: StorageSourceRegistry;
402
+ /** Build a server-backed {@link StorageSource} for a named storage source. */
403
+ createStorageSource?(storageId: string): StorageSource;
404
+ /** Discover the storage sources declared on the backend. */
405
+ fetchStorageSources?(): Promise<StorageSourceDefinition[]>;
406
+ /** Admin API for user management */
407
+ admin?: AdminAPI;
408
+ /** Cron job management API */
409
+ cron?: CronAPI;
410
+ /** Custom backend functions API */
411
+ functions?: FunctionsAPI;
412
+ /** Service API keys management API */
413
+ apiKeys?: ApiKeysAPI;
414
+ /** Base HTTP URL of the backend server */
415
+ baseUrl?: string;
416
+ /** WebSocket client for realtime subscriptions */
417
+ ws?: RebaseWebSocket;
418
+ /** Set the auth token for subsequent requests */
419
+ setToken?(token: string | null): void;
420
+ /** Set a function that lazily resolves the auth token */
421
+ setAuthTokenGetter?(getter: () => Promise<string | null>): void;
422
+ /** Set handler called when a request returns 401 */
423
+ setOnUnauthorized?(handler: () => Promise<boolean>): void;
424
+ /** Resolve the current auth token */
425
+ resolveToken?(): Promise<string | null>;
426
+ /** Make a raw HTTP call to the backend */
427
+ call?<T = unknown>(endpoint: string, payload?: unknown): Promise<T>;
428
+ }
429
+ /**
430
+ * Client-side registry for managing multiple storage sources.
431
+ *
432
+ * Mirrors the server-side `StorageRegistry` pattern. Allows collection
433
+ * properties to reference a named storage backend via
434
+ * `StorageConfig.storageSource`.
435
+ *
436
+ * @group Models
437
+ */
438
+ export interface StorageSourceRegistry {
439
+ /**
440
+ * Get a storage source by key.
441
+ * @param key - Storage source key, or undefined/null for default
442
+ * @returns The StorageSource, or undefined if not found
443
+ */
444
+ get(key: string | undefined | null): StorageSource | undefined;
445
+ /**
446
+ * Get the default storage source (key = "(default)").
447
+ * @throws Error if no default storage is registered
448
+ */
449
+ getDefault(): StorageSource;
450
+ /**
451
+ * Get a storage source by key, with fallback to default.
452
+ * @param key - Storage source key, or undefined/null for default
453
+ * @returns The StorageSource (falls back to default if key not found)
454
+ * @throws Error if neither the specified nor default storage exists
455
+ */
456
+ getOrDefault(key: string | undefined | null): StorageSource;
457
+ /** Check if a storage source with the given key exists */
458
+ has(key: string): boolean;
459
+ /** List all registered storage source keys */
460
+ list(): string[];
461
+ }
@@ -1,17 +1,17 @@
1
- import type { EntityCollection } from "../types/collections";
1
+ import type { CollectionConfig } from "../types/collections";
2
2
  import type { EntityReference } from "../types/entities";
3
3
  /**
4
4
  * Controller that provides access to the registered entity collections.
5
5
  * @group Models
6
6
  */
7
- export type CollectionRegistryController<DB = Record<string, unknown>, EC extends EntityCollection = EntityCollection> = {
7
+ export type CollectionRegistryController<DB = Record<string, unknown>, EC extends CollectionConfig = CollectionConfig> = {
8
8
  /**
9
9
  * List of the mapped collections in the CMS.
10
10
  * Each entry relates to a collection in the root database.
11
11
  * Each of the navigation entries in this field
12
12
  * generates an entry in the main menu.
13
13
  */
14
- collections?: EntityCollection[];
14
+ collections?: CollectionConfig[];
15
15
  /**
16
16
  * Is the registry ready to be used
17
17
  */
@@ -24,7 +24,7 @@ export type CustomizationController = {
24
24
  * You can use the key to reference the custom view in
25
25
  * the `entityViews` prop of a collection.
26
26
  *
27
- * You can also define an entity view from the UI.
27
+ * You can also define a entity view from the UI.
28
28
  */
29
29
  entityViews?: EntityCustomView[];
30
30
  /**