@@ -5,12 +5,14 @@ export type RealtimeEventType = "create" | "update" | "delete";
55
66/**
77 * Payload received when a realtime event occurs.
8+ *
9+ * @typeParam T - The entity type for the data field. Defaults to `any`.
810 */
9- export interface RealtimeEvent {
11+ export interface RealtimeEvent < T = any > {
1012 /** The type of change that occurred */
1113 type : RealtimeEventType ;
1214 /** The entity data */
13- data : any ;
15+ data : T ;
1416 /** The unique identifier of the affected entity */
1517 id : string ;
1618 /** ISO 8601 timestamp of when the event occurred */
@@ -19,15 +21,73 @@ export interface RealtimeEvent {
1921
2022/**
2123 * Callback function invoked when a realtime event occurs.
24+ *
25+ * @typeParam T - The entity type for the event data. Defaults to `any`.
26+ */
27+ export type RealtimeCallback < T = any > = ( event : RealtimeEvent < T > ) => void ;
28+
29+ /**
30+ * Result returned when deleting a single entity.
31+ */
32+ export interface DeleteResult {
33+ /** Whether the deletion was successful */
34+ success : boolean ;
35+ }
36+
37+ /**
38+ * Result returned when deleting multiple entities.
2239 */
23- export type RealtimeCallback = ( event : RealtimeEvent ) => void ;
40+ export interface DeleteManyResult {
41+ /** Whether the deletion was successful */
42+ success : boolean ;
43+ /** Number of entities that were deleted */
44+ deleted : number ;
45+ }
46+
47+ /**
48+ * Result returned when importing entities from a file.
49+ *
50+ * @typeParam T - The entity type for imported records. Defaults to `any`.
51+ */
52+ export interface ImportResult < T = any > {
53+ /** Status of the import operation */
54+ status : "success" | "error" ;
55+ /** Details message, e.g., "Successfully imported 3 entities with RLS enforcement" */
56+ details : string | null ;
57+ /** Array of created entity objects when successful, or null on error */
58+ output : T [ ] | null ;
59+ }
60+
61+ /**
62+ * Sort field type for entity queries.
63+ *
64+ * Supports ascending (no prefix or `'+'`) and descending (`'-'`) sorting.
65+ *
66+ * @typeParam T - The entity type to derive sortable fields from.
67+ *
68+ * @example
69+ * ```typescript
70+ * // Ascending sort (default)
71+ * 'created_date'
72+ * '+created_date'
73+ *
74+ * // Descending sort
75+ * '-created_date'
76+ * ```
77+ */
78+ export type SortField < T > =
79+ | ( keyof T & string )
80+ | `+${keyof T & string } `
81+ | `-${keyof T & string } `;
2482
2583/**
2684 * Entity handler providing CRUD operations for a specific entity type.
2785 *
2886 * Each entity in the app gets a handler with these methods for managing data.
87+ *
88+ * @typeParam T - The entity type. Defaults to `any` for backward compatibility.
2989 */
30- export interface EntityHandler {
90+ export interface EntityHandler < T = any > {
3191 /**
3292 * Lists records with optional pagination and sorting.
3393 *
@@ -36,11 +96,12 @@ export interface EntityHandler {
3696 *
3797 * **Note:** The maximum limit is 5,000 items per request.
3898 *
99+ * @typeParam K - The fields to include in the response. Defaults to all fields.
39100 * @param sort - Sort parameter, such as `'-created_date'` for descending. Defaults to `'-created_date'`.
40101 * @param limit - Maximum number of results to return. Defaults to `50`.
41102 * @param skip - Number of results to skip for pagination. Defaults to `0`.
42103 * @param fields - Array of field names to include in the response. Defaults to all fields.
43- * @returns Promise resolving to an array of records.
104+ * @returns Promise resolving to an array of records with selected fields .
44105 *
45106 * @example
46107 * ```typescript
@@ -67,12 +128,12 @@ export interface EntityHandler {
67128 * const fields = await base44.entities.MyEntity.list('-created_date', 10, 0, ['name', 'status']);
68129 * ```
69130 */
70- list (
71- sort ?: string ,
131+ list < K extends keyof T = keyof T > (
132+ sort ?: SortField < T > ,
72133 limit ?: number ,
73134 skip ?: number ,
74- fields ?: string [ ]
75- ) : Promise < any > ;
135+ fields ?: K [ ]
136+ ) : Promise < Pick < T , K > [ ] > ;
76137
77138 /**
78139 * Filters records based on a query.
@@ -82,14 +143,15 @@ export interface EntityHandler {
82143 *
83144 * **Note:** The maximum limit is 5,000 items per request.
84145 *
146+ * @typeParam K - The fields to include in the response. Defaults to all fields.
85147 * @param query - Query object with field-value pairs. Each key should be a field name
86148 * from your entity schema, and each value is the criteria to match. Records matching all
87149 * specified criteria are returned. Field names are case-sensitive.
88150 * @param sort - Sort parameter, such as `'-created_date'` for descending. Defaults to `'-created_date'`.
89151 * @param limit - Maximum number of results to return. Defaults to `50`.
90152 * @param skip - Number of results to skip for pagination. Defaults to `0`.
91153 * @param fields - Array of field names to include in the response. Defaults to all fields.
92- * @returns Promise resolving to an array of filtered records.
154+ * @returns Promise resolving to an array of filtered records with selected fields .
93155 *
94156 * @example
95157 * ```typescript
@@ -131,13 +193,13 @@ export interface EntityHandler {
131193 * );
132194 * ```
133195 */
134- filter (
135- query : Record < string , any > ,
136- sort ?: string ,
196+ filter < K extends keyof T = keyof T > (
197+ query : Partial < T > ,
198+ sort ?: SortField < T > ,
137199 limit ?: number ,
138200 skip ?: number ,
139- fields ?: string [ ]
140- ) : Promise < any > ;
201+ fields ?: K [ ]
202+ ) : Promise < Pick < T , K > [ ] > ;
141203
142204 /**
143205 * Gets a single record by ID.
@@ -154,7 +216,7 @@ export interface EntityHandler {
154216 * console.log(record.name);
155217 * ```
156218 */
157- get ( id : string ) : Promise < any > ;
219+ get ( id : string ) : Promise < T > ;
158220
159221 /**
160222 * Creates a new record.
@@ -175,7 +237,7 @@ export interface EntityHandler {
175237 * console.log('Created record with ID:', newRecord.id);
176238 * ```
177239 */
178- create ( data : Record < string , any > ) : Promise < any > ;
240+ create ( data : Partial < T > ) : Promise < T > ;
179241
180242 /**
181243 * Updates an existing record.
@@ -205,7 +267,7 @@ export interface EntityHandler {
205267 * });
206268 * ```
207269 */
208- update ( id : string , data : Record < string , any > ) : Promise < any > ;
270+ update ( id : string , data : Partial < T > ) : Promise < T > ;
209271
210272 /**
211273 * Deletes a single record by ID.
@@ -219,10 +281,10 @@ export interface EntityHandler {
219281 * ```typescript
220282 * // Delete a record
221283 * const result = await base44.entities.MyEntity.delete('entity-123');
222- * console.log('Deleted:', result);
284+ * console.log('Deleted:', result.success );
223285 * ```
224286 */
225- delete ( id : string ) : Promise < any > ;
287+ delete ( id : string ) : Promise < DeleteResult > ;
226288
227289 /**
228290 * Deletes multiple records matching a query.
@@ -244,7 +306,7 @@ export interface EntityHandler {
244306 * console.log('Deleted:', result);
245307 * ```
246308 */
247- deleteMany ( query : Record < string , any > ) : Promise < any > ;
309+ deleteMany ( query : Partial < T > ) : Promise < DeleteManyResult > ;
248310
249311 /**
250312 * Creates multiple records in a single request.
@@ -265,7 +327,7 @@ export interface EntityHandler {
265327 * ]);
266328 * ```
267329 */
268- bulkCreate ( data : Record < string , any > [ ] ) : Promise < any > ;
330+ bulkCreate ( data : Partial < T > [ ] ) : Promise < T [ ] > ;
269331
270332 /**
271333 * Imports records from a file.
@@ -274,7 +336,7 @@ export interface EntityHandler {
274336 * The file format should match your entity structure. Requires a browser environment and can't be used in the backend.
275337 *
276338 * @param file - File object to import.
277- * @returns Promise resolving to the import result.
339+ * @returns Promise resolving to the import result containing status, details, and created records .
278340 *
279341 * @example
280342 * ```typescript
@@ -283,12 +345,14 @@ export interface EntityHandler {
283345 * const file = event.target.files?.[0];
284346 * if (file) {
285347 * const result = await base44.entities.MyEntity.importEntities(file);
286- * console.log(`Imported ${result.count} records`);
348+ * if (result.status === 'success' && result.output) {
349+ * console.log(`Imported ${result.output.length} records`);
350+ * }
287351 * }
288352 * };
289353 * ```
290354 */
291- importEntities ( file : File ) : Promise < any > ;
355+ importEntities ( file : File ) : Promise < ImportResult < T > > ;
292356
293357 /**
294358 * Subscribes to realtime updates for all records of this entity type.
@@ -315,7 +379,7 @@ export interface EntityHandler {
315379 * unsubscribe();
316380 * ```
317381 */
318- subscribe ( callback : RealtimeCallback ) : ( ) => void ;
382+ subscribe ( callback : RealtimeCallback < T > ) : ( ) => void ;
319383}
320384
321385/**
@@ -364,5 +428,5 @@ export interface EntitiesModule {
364428 * base44.entities.AnotherEntity
365429 * ```
366430 */
367- [ entityName : string ] : EntityHandler ;
431+ [ entityName : string ] : EntityHandler < any > ;
368432}
0 commit comments