Skip to content

Commit 74fff59

Browse files
kfirstriozsay
andauthored
[Feature]: Types registry support (#117)
* Refactor entities module to support generic entity types and improve type safety * Extend EntitiesModule with typed Todo handler for improved type safety in entities tests * Enhance entity handling with typed sorting and import results - Introduced `SortField` type for improved sorting parameter handling in list and filter methods. - Updated `importEntities` method to return a structured `ImportResult` type, providing detailed import status and output. - Modified list and filter methods to support generic field selection, enhancing type safety and flexibility. * add support to augment the types of the sdk * cleanups * align comments * update entities and function TypeRegistry in tests * added EntityRecord * added type registry for connectors --------- Co-authored-by: Oz Sayag <ozs@wix.com>
1 parent d7994d1 commit 74fff59

File tree

7 files changed

+105
-24
lines changed

7 files changed

+105
-24
lines changed

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export * from "./types.js";
3636
export type {
3737
EntitiesModule,
3838
EntityHandler,
39+
EntityRecord,
40+
EntityTypeRegistry,
3941
RealtimeEventType,
4042
RealtimeEvent,
4143
RealtimeCallback,
@@ -71,10 +73,14 @@ export type {
7173
CreateFileSignedUrlResult,
7274
} from "./modules/integrations.types.js";
7375

74-
export type { FunctionsModule } from "./modules/functions.types.js";
76+
export type {
77+
FunctionsModule,
78+
FunctionNameRegistry,
79+
} from "./modules/functions.types.js";
7580

7681
export type {
7782
AgentsModule,
83+
AgentNameRegistry,
7884
AgentConversation,
7985
AgentMessage,
8086
AgentMessageReasoning,

src/modules/agents.types.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@ import { AxiosInstance } from "axios";
22
import { RoomsSocket } from "../utils/socket-utils.js";
33
import { ModelFilterParams } from "../types.js";
44

5+
/**
6+
* Registry of agent names.
7+
* Augment this interface to enable autocomplete for agent names.
8+
*/
9+
export interface AgentNameRegistry {}
10+
11+
/**
12+
* Agent name type - uses registry keys if augmented, otherwise string.
13+
*/
14+
export type AgentName = keyof AgentNameRegistry extends never
15+
? string
16+
: keyof AgentNameRegistry;
17+
518
/**
619
* Reasoning information for an agent message.
720
*
@@ -135,7 +148,7 @@ export interface AgentMessage {
135148
*/
136149
export interface CreateConversationParams {
137150
/** The name of the agent to create a conversation with. */
138-
agent_name: string;
151+
agent_name: AgentName;
139152
/** Optional metadata to attach to the conversation. */
140153
metadata?: Record<string, any>;
141154
}
@@ -376,5 +389,5 @@ When receiving messages through this function, tool call data is truncated for e
376389
* // User can open this URL to start a WhatsApp conversation
377390
* ```
378391
*/
379-
getWhatsAppConnectURL(agentName: string): string;
392+
getWhatsAppConnectURL(agentName: AgentName): string;
380393
}

src/modules/connectors.types.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
/**
2+
* Registry of connector integration types.
3+
* Augment this interface to enable autocomplete for connector integration types.
4+
*/
5+
export interface ConnectorIntegrationTypeRegistry {}
6+
17
/**
28
* The type of external integration/connector, such as `'googlecalendar'`, `'slack'`, or `'github'`.
9+
* Uses registry keys if augmented, otherwise falls back to string.
310
*/
4-
export type ConnectorIntegrationType = string;
11+
export type ConnectorIntegrationType = keyof ConnectorIntegrationTypeRegistry extends never
12+
? string
13+
: keyof ConnectorIntegrationTypeRegistry;
514

615
/**
716
* Response from the connectors access token endpoint.

src/modules/entities.types.ts

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,37 @@ export type SortField<T> =
8080
| `+${keyof T & string}`
8181
| `-${keyof T & string}`;
8282

83+
/**
84+
* Fields added by the server to every entity record (id, dates, created_by, etc.).
85+
*/
86+
interface ServerEntityFields {
87+
/** Unique identifier of the record */
88+
id: string;
89+
/** ISO 8601 timestamp when the record was created */
90+
created_date: string;
91+
/** ISO 8601 timestamp when the record was last updated */
92+
updated_date: string;
93+
/** Email of the user who created the record (may be hidden in some responses) */
94+
created_by?: string | null;
95+
/** ID of the user who created the record */
96+
created_by_id?: string | null;
97+
/** Whether the record is sample/seed data */
98+
is_sample?: boolean;
99+
}
100+
101+
/**
102+
* Registry mapping entity names to their TypeScript types.
103+
* Augment this interface with your entity schema (user-defined fields only).
104+
*/
105+
export interface EntityTypeRegistry {}
106+
107+
/**
108+
* Full record type for each entity: schema fields + server-injected fields (id, created_date, etc.).
109+
*/
110+
export type EntityRecord = {
111+
[K in keyof EntityTypeRegistry]: EntityTypeRegistry[K] & ServerEntityFields;
112+
};
113+
83114
/**
84115
* Entity handler providing CRUD operations for a specific entity type.
85116
*
@@ -303,7 +334,7 @@ export interface EntityHandler<T = any> {
303334
* status: 'completed',
304335
* priority: 'low'
305336
* });
306-
* console.log('Deleted:', result);
337+
* console.log('Deleted:', result.deleted);
307338
* ```
308339
*/
309340
deleteMany(query: Partial<T>): Promise<DeleteManyResult>;
@@ -382,6 +413,20 @@ export interface EntityHandler<T = any> {
382413
subscribe(callback: RealtimeCallback<T>): () => void;
383414
}
384415

416+
/**
417+
* Typed entities module - maps registry keys to typed handlers (full record type).
418+
*/
419+
type TypedEntitiesModule = {
420+
[K in keyof EntityTypeRegistry]: EntityHandler<EntityRecord[K]>;
421+
};
422+
423+
/**
424+
* Dynamic entities module - allows any entity name with untyped handler.
425+
*/
426+
type DynamicEntitiesModule = {
427+
[entityName: string]: EntityHandler<any>;
428+
};
429+
385430
/**
386431
* Entities module for managing app data.
387432
*
@@ -415,18 +460,4 @@ export interface EntityHandler<T = any> {
415460
* const allUsers = await base44.asServiceRole.entities.User.list();
416461
* ```
417462
*/
418-
export interface EntitiesModule {
419-
/**
420-
* Access any entity by name.
421-
*
422-
* Use this to access entities defined in the app.
423-
*
424-
* @example
425-
* ```typescript
426-
* // Access entities dynamically
427-
* base44.entities.MyEntity
428-
* base44.entities.AnotherEntity
429-
* ```
430-
*/
431-
[entityName: string]: EntityHandler<any>;
432-
}
463+
export type EntitiesModule = TypedEntitiesModule & DynamicEntitiesModule;

src/modules/functions.types.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
/**
2+
* Registry of function names.
3+
* Augment this interface to enable autocomplete for function names.
4+
*/
5+
export interface FunctionNameRegistry {}
6+
7+
/**
8+
* Function name type - uses registry keys if augmented, otherwise string.
9+
*/
10+
export type FunctionName = keyof FunctionNameRegistry extends never
11+
? string
12+
: keyof FunctionNameRegistry;
13+
114
/**
215
* Functions module for invoking custom backend functions.
316
*
@@ -46,5 +59,5 @@ export interface FunctionsModule {
4659
* };
4760
* ```
4861
*/
49-
invoke(functionName: string, data: Record<string, any>): Promise<any>;
62+
invoke(functionName: FunctionName, data?: Record<string, any>): Promise<any>;
5063
}

tests/unit/entities.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ interface Todo {
1212
completed: boolean;
1313
}
1414

15-
// Declaration merging: extend EntitiesModule with typed Todo handler
15+
// Module augmentation: register Todo type in EntityTypeRegistry
1616
declare module "../../src/modules/entities.types.ts" {
17-
interface EntitiesModule {
18-
Todo: EntityHandler<Todo>;
17+
interface EntityTypeRegistry {
18+
Todo: Todo;
1919
}
2020
}
2121

tests/unit/functions.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ import { describe, test, expect, beforeEach, afterEach } from "vitest";
22
import nock from "nock";
33
import { createClient } from "../../src/index.ts";
44

5+
// Module augmentation: register function names in FunctionNameRegistry
6+
declare module "../../src/modules/functions.types.ts" {
7+
interface FunctionNameRegistry {
8+
sendNotification: true;
9+
processOrder: true;
10+
generateReport: true;
11+
}
12+
}
13+
514
describe("Functions Module", () => {
615
let base44: ReturnType<typeof createClient>;
716
let scope;

0 commit comments

Comments
 (0)