@base44-preview/sdk 0.8.53-pr.289.39e1f1f → 0.8.53-pr.289.762dbd5
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/dist/index.d.ts +1 -1
- package/dist/modules/actors.types.d.ts +20 -21
- package/dist/modules/entities.types.d.ts +255 -141
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl } from
|
|
|
4
4
|
export { createClient, createClientFromRequest, Base44Error, getAccessToken, saveAccessToken, removeAccessToken, getLoginUrl, };
|
|
5
5
|
export type { Base44Client, CreateClientAnalyticsConfig, CreateClientConfig, CreateClientOptions, Base44ErrorJSON, };
|
|
6
6
|
export * from "./types.js";
|
|
7
|
-
export type { DeleteManyResult, DeleteResult, EntitiesModule, EntityAggregateResult, EntityAggregateSpec,
|
|
7
|
+
export type { DeleteManyResult, DeleteResult, EntitiesModule, EntityAggregateResult, EntityAggregateSpec, EntityDateBucket, EntityDistinctOptions, EntityFilterOperators, EntityFilterQuery, EntityFilterValue, EntityHandler, EntityListOptions, EntityPage, EntityRecord, EntityTypeRegistry, EntityUpsertOptions, EntityUpsertResult, ImportResult, RealtimeEventType, RealtimeEvent, RealtimeCallback, SortField, UpdateManyResult, } from "./modules/entities.types.js";
|
|
8
8
|
export type { AuthModule, LoginResponse, RegisterParams, VerifyOtpParams, ChangePasswordParams, ResetPasswordParams, User, } from "./modules/auth.types.js";
|
|
9
9
|
export type { IntegrationsModule, IntegrationEndpointFunction, CoreIntegrations, InvokeLLMParams, GenerateImageParams, GenerateImageResult, UploadFileParams, UploadFileResult, SendEmailParams, SendEmailResult, ExtractDataFromUploadedFileParams, ExtractDataFromUploadedFileResult, UploadPrivateFileParams, UploadPrivateFileResult, CreateFileSignedUrlParams, CreateFileSignedUrlResult, } from "./modules/integrations.types.js";
|
|
10
10
|
export type { FunctionsModule, FunctionName, FunctionNameRegistry, } from "./modules/functions.types.js";
|
|
@@ -186,33 +186,32 @@ export interface ActorClient<N extends string = string> {
|
|
|
186
186
|
(instanceId: string): ActorRef<N>;
|
|
187
187
|
}
|
|
188
188
|
/**
|
|
189
|
-
*
|
|
190
|
-
* shared live backend processes where clients can exchange messages in realtime.
|
|
189
|
+
* Actors module for connecting a client to an [actor](/developers/backend/resources/actors/overview) session and exchanging messages.
|
|
191
190
|
*
|
|
192
|
-
*
|
|
191
|
+
* An actor is a long-running backend process that multiple clients connect to simultaneously. A session
|
|
192
|
+
* is a running instance of an actor, identified by the actor name and a session ID. Each
|
|
193
|
+
* session manages its own state, storage, and client connections independently.
|
|
193
194
|
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
195
|
+
* The actors module supports the following functionality:
|
|
196
|
+
*
|
|
197
|
+
* - [`connect()`](#connect): Open a WebSocket connection to a session.
|
|
198
|
+
* - [`subscribe()`](#subscribe): Receive messages from the actor.
|
|
199
|
+
* - [`unsubscribe()`](#unsubscribe): Stop receiving messages from the actor without closing the connection.
|
|
200
|
+
* - [`send()`](#send): Send messages to the actor.
|
|
201
|
+
* - [`close()`](#close): Close the WebSocket connection to the actor.
|
|
202
|
+
*
|
|
203
|
+
* For a sample flow, see
|
|
204
|
+
* [connect a client to a session](/developers/backend/resources/actors/sample-flows#connect-a-client-to-a-session).
|
|
200
205
|
*
|
|
201
206
|
* ## Authentication modes
|
|
202
207
|
*
|
|
203
|
-
* This module is available in anonymous
|
|
204
|
-
*
|
|
205
|
-
*
|
|
208
|
+
* This module is available to use with a client in anonymous or user authentication mode. Access it
|
|
209
|
+
* through `base44.actors`. It isn't available in
|
|
210
|
+
* [service role authentication mode](/developers/references/sdk/getting-started/client#service-role).
|
|
206
211
|
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* const conn = base44.actors.chatRoom("session-1").connect({ id: "tab-1" });
|
|
211
|
-
* const sub = conn.subscribe((msg) => console.log(msg));
|
|
212
|
-
* conn.send({ type: "message", text: "hi" });
|
|
213
|
-
* sub.unsubscribe();
|
|
214
|
-
* conn.close();
|
|
215
|
-
* ```
|
|
212
|
+
* The actor receives each client's [identity](/developers/backend/resources/actors/reference#connections)
|
|
213
|
+
* when the client connects. A client that hasn't logged in connects as anonymous, and a client that
|
|
214
|
+
* has [logged in](/developers/references/sdk/docs/interfaces/auth) connects as authenticated.
|
|
216
215
|
*/
|
|
217
216
|
export type ActorsModule = {
|
|
218
217
|
[K in AllActorNames]: K extends keyof ActorRegistry ? ActorClient<string & K> : ActorClient;
|
|
@@ -58,15 +58,15 @@ export interface UpdateManyResult {
|
|
|
58
58
|
* @typeParam K - The fields to include in each record.
|
|
59
59
|
*/
|
|
60
60
|
export interface EntityListOptions<T, K extends keyof T = keyof T> {
|
|
61
|
-
/** Sort parameter, such as `'-
|
|
61
|
+
/** Sort parameter, such as `'-priority'` for descending. Defaults to `'-created_date'`. */
|
|
62
62
|
sort?: SortField<T>;
|
|
63
63
|
/** Maximum number of records per page, up to 5,000. Defaults to 100. */
|
|
64
64
|
limit?: number;
|
|
65
65
|
/**
|
|
66
|
-
* `next_cursor` from the previous page. Omit or pass `null` for the first page.
|
|
66
|
+
* The `next_cursor` from the previous page. Omit or pass `null` for the first page.
|
|
67
67
|
*
|
|
68
|
-
* The token carries
|
|
69
|
-
* `cursor` and `limit`. Passing
|
|
68
|
+
* The token carries this walk's parameters, so a later page needs only
|
|
69
|
+
* `cursor` and `limit`. Passing different parameters with a cursor is an error.
|
|
70
70
|
*/
|
|
71
71
|
cursor?: string | null;
|
|
72
72
|
/** Array of field names to include in each record. Defaults to all fields. */
|
|
@@ -81,49 +81,52 @@ export interface EntityListOptions<T, K extends keyof T = keyof T> {
|
|
|
81
81
|
* @typeParam K - The field whose distinct values to read.
|
|
82
82
|
*/
|
|
83
83
|
export interface EntityDistinctOptions<T, K extends keyof T = keyof T> {
|
|
84
|
-
/** Field whose distinct values to return, in ascending order.
|
|
84
|
+
/** Field whose distinct values to return, in ascending order. For an array field like `tags`, this returns the distinct individual tags used across records, not the distinct arrays. */
|
|
85
85
|
distinct: K;
|
|
86
86
|
/** Maximum number of values per page, up to 1,000. Defaults to 100. */
|
|
87
87
|
limit?: number;
|
|
88
|
-
/** `next_cursor` from the previous page. Omit or pass `null` for the first page. The token carries
|
|
88
|
+
/** The `next_cursor` from the previous page. Omit or pass `null` for the first page. The token carries this lookup's parameters. */
|
|
89
89
|
cursor?: string | null;
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
-
* One page of
|
|
93
|
-
* {@linkcode EntityHandler.filter | filter()} when called with an options object.
|
|
92
|
+
* One page of items, with a cursor to continue.
|
|
94
93
|
*
|
|
95
|
-
* @typeParam T -
|
|
94
|
+
* @typeParam T - Type of the items.
|
|
96
95
|
*/
|
|
97
96
|
export interface EntityPage<T> {
|
|
98
|
-
/** The page's records in the requested sort order
|
|
97
|
+
/** The page's items. Without `distinct`, these are records in the requested sort order. With `distinct`, these are that field's distinct values instead of records, in ascending order. */
|
|
99
98
|
items: T[];
|
|
100
|
-
/**
|
|
99
|
+
/** A cursor for the next page, or `null` on the last page. Pass it as `cursor` to keep paging. */
|
|
101
100
|
next_cursor: string | null;
|
|
102
101
|
/** Whether records remain after this page. */
|
|
103
102
|
has_more: boolean;
|
|
104
103
|
}
|
|
105
104
|
/**
|
|
106
|
-
*
|
|
105
|
+
* A time bucket to group a date field by, for {@linkcode EntityAggregateSpec.dateBucket | dateBucket}.
|
|
106
|
+
*
|
|
107
|
+
* @typeParam T - Entity record type.
|
|
107
108
|
*/
|
|
108
|
-
export
|
|
109
|
+
export interface EntityDateBucket<T> {
|
|
110
|
+
/** The date field to bucket by: `created_date`, `updated_date`, or a date field of your schema. */
|
|
111
|
+
field: keyof T & string;
|
|
112
|
+
/** Every date field supports `day`, `month` and `year`. The `created_date` and `updated_date` fields also support `week`. */
|
|
113
|
+
unit: "day" | "week" | "month" | "year";
|
|
114
|
+
}
|
|
109
115
|
/**
|
|
110
116
|
* Describes what {@linkcode EntityHandler.aggregate | aggregate()} computes.
|
|
111
117
|
*
|
|
112
|
-
* Name the fields to group by and the measures to compute
|
|
118
|
+
* Name the fields to group by and the measures to compute, and the server does the work and
|
|
113
119
|
* returns one row per group. Field names are the entity's own field names.
|
|
114
120
|
*
|
|
115
121
|
* @typeParam T - Entity record type.
|
|
116
122
|
*/
|
|
117
123
|
export interface EntityAggregateSpec<T> {
|
|
118
|
-
/** Filter applied before grouping,
|
|
124
|
+
/** Filter applied before grouping, matching {@linkcode EntityFilterQuery}. Defaults to all records. */
|
|
119
125
|
query?: EntityFilterQuery<T>;
|
|
120
126
|
/** Field, or up to four fields, to group by. Omit to get one total row. */
|
|
121
127
|
groupBy?: (keyof T & string) | (keyof T & string)[];
|
|
122
|
-
/** Group by a time bucket of a date field.
|
|
123
|
-
dateBucket?:
|
|
124
|
-
field: keyof T & string;
|
|
125
|
-
unit: EntityDateBucketUnit;
|
|
126
|
-
};
|
|
128
|
+
/** Group by a time bucket of a date field. */
|
|
129
|
+
dateBucket?: EntityDateBucket<T>;
|
|
127
130
|
/** Whether to include the number of records per group as `count`. Defaults to `true`. */
|
|
128
131
|
count?: boolean;
|
|
129
132
|
/** Field, or fields, to sum. Each appears in the rows as `sum_<field>`. */
|
|
@@ -134,9 +137,9 @@ export interface EntityAggregateSpec<T> {
|
|
|
134
137
|
min?: (keyof T & string) | (keyof T & string)[];
|
|
135
138
|
/** Field, or fields, to take the maximum of. Each appears in the rows as `max_<field>`. */
|
|
136
139
|
max?: (keyof T & string) | (keyof T & string)[];
|
|
137
|
-
/** Field whose distinct values to count per group, returned as `count_distinct_<field>`. */
|
|
140
|
+
/** Field whose distinct values to count per group, returned as `count_distinct_<field>`. Unlike `distinct` on `list()`/`filter()`, an array field here counts each whole array as one value, not its individual elements. */
|
|
138
141
|
countDistinct?: keyof T & string;
|
|
139
|
-
/** Filter
|
|
142
|
+
/** Filter applied to the computed fields after grouping, not to raw or `groupBy` fields. Supports `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, and `$nin`. With more than one key, a row is kept only when every key's condition holds. For example, grouped by `external_id`, `having: { count: { $gt: 1 } }` keeps only the external ids that appear in more than one record. */
|
|
140
143
|
having?: Record<string, any>;
|
|
141
144
|
/** Computed or group field to sort the rows by, with a `-` prefix for descending. For example `'-count'`. */
|
|
142
145
|
sort?: string;
|
|
@@ -147,9 +150,9 @@ export interface EntityAggregateSpec<T> {
|
|
|
147
150
|
* Rows returned by {@linkcode EntityHandler.aggregate | aggregate()}.
|
|
148
151
|
*/
|
|
149
152
|
export interface EntityAggregateResult {
|
|
150
|
-
/** One row per group
|
|
153
|
+
/** One row per group. Each row has the group fields by name, then `count`, `sum_<field>`, `avg_<field>`, `min_<field>`, `max_<field>` or `count_distinct_<field>`. */
|
|
151
154
|
rows: Record<string, any>[];
|
|
152
|
-
/** `true` when more groups exist than `limit` allowed. */
|
|
155
|
+
/** Set to `true` when more groups exist than `limit` allowed. */
|
|
153
156
|
truncated: boolean;
|
|
154
157
|
}
|
|
155
158
|
/**
|
|
@@ -158,7 +161,7 @@ export interface EntityAggregateResult {
|
|
|
158
161
|
* @typeParam T - Entity record type.
|
|
159
162
|
*/
|
|
160
163
|
export interface EntityUpsertOptions<T> {
|
|
161
|
-
/** Field, or fields, that identify a record. A record whose key values match an existing record updates it
|
|
164
|
+
/** Field, or fields, that identify a record. A record whose key values match an existing record updates it, and any other record is created. */
|
|
162
165
|
key: (keyof T & string) | (keyof T & string)[];
|
|
163
166
|
}
|
|
164
167
|
/**
|
|
@@ -208,19 +211,6 @@ export interface ImportResult<T = any> {
|
|
|
208
211
|
* ```
|
|
209
212
|
*/
|
|
210
213
|
export type SortField<T> = (keyof T & string) | `+${keyof T & string}` | `-${keyof T & string}`;
|
|
211
|
-
/**
|
|
212
|
-
* Entity filter query type system.
|
|
213
|
-
*
|
|
214
|
-
* `EntityFilterQuery<T>` keeps field names tied to the entity schema while
|
|
215
|
-
* allowing Base44's documented filtering syntax. Each field can use an exact
|
|
216
|
-
* value, `null`, an array shorthand for matching any listed value, or a
|
|
217
|
-
* field-level operator object. Root-level `$and`, `$or`, and `$nor` combine
|
|
218
|
-
* nested filter queries.
|
|
219
|
-
*
|
|
220
|
-
* Operator values are typed from the field they filter where possible. For
|
|
221
|
-
* example, numeric fields accept numeric comparison values, string fields
|
|
222
|
-
* accept `$regex`, and array fields accept `$all` and `$size`.
|
|
223
|
-
*/
|
|
224
214
|
/**
|
|
225
215
|
* Value accepted when filtering an entity field.
|
|
226
216
|
*
|
|
@@ -262,12 +252,30 @@ type EntityFilterArrayOperators<T> = [
|
|
|
262
252
|
$size?: number;
|
|
263
253
|
};
|
|
264
254
|
/**
|
|
265
|
-
* Query object accepted by
|
|
255
|
+
* Query object accepted by {@linkcode EntityHandler.filter | filter()},
|
|
256
|
+
* {@linkcode EntityHandler.count | count()}, {@linkcode EntityHandler.deleteMany | deleteMany()},
|
|
257
|
+
* {@linkcode EntityHandler.updateMany | updateMany()}, and the `query` field of
|
|
258
|
+
* `EntityAggregateSpec`.
|
|
259
|
+
*
|
|
260
|
+
* Field keys are typed from the entity schema. Each field can use an exact value, `null`,
|
|
261
|
+
* an array shorthand for matching any of the listed values, or a field-level operator
|
|
262
|
+
* object. Root-level `$and`, `$or`, and `$nor` combine nested filter queries.
|
|
266
263
|
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
264
|
+
* Operator values are typed from the field they filter where possible. For example,
|
|
265
|
+
* numeric fields accept numeric comparison values, string fields accept `$regex`, and
|
|
266
|
+
* array fields accept `$all` and `$size`.
|
|
269
267
|
*
|
|
270
268
|
* @typeParam T - Entity record type.
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* // Exact match, a comparison operator, and a nested $or
|
|
273
|
+
* const query: EntityFilterQuery<Task> = {
|
|
274
|
+
* status: 'open',
|
|
275
|
+
* priority: { $gte: 3 },
|
|
276
|
+
* $or: [{ assignee: 'me' }, { team: 'core' }]
|
|
277
|
+
* };
|
|
278
|
+
* ```
|
|
271
279
|
*/
|
|
272
280
|
export type EntityFilterQuery<T> = {
|
|
273
281
|
[K in keyof T]?: EntityFilterValue<T[K]>;
|
|
@@ -330,23 +338,81 @@ export type EntityRecord = {
|
|
|
330
338
|
*/
|
|
331
339
|
export interface EntityHandler<T = any> {
|
|
332
340
|
/**
|
|
333
|
-
* Lists
|
|
341
|
+
* Lists one cursor page of records, sorted and optionally field-selected.
|
|
342
|
+
*
|
|
343
|
+
* Pass `cursor` from the previous page's `next_cursor` to keep paging, or omit it
|
|
344
|
+
* for the first page. Records added or deleted between pages never shift the boundary.
|
|
345
|
+
*
|
|
346
|
+
* @typeParam K - The fields to include in each record. Defaults to all fields.
|
|
347
|
+
* @param options - Paging options.
|
|
348
|
+
* @returns Promise resolving to a page of records.
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```typescript
|
|
352
|
+
* // Get one page of records
|
|
353
|
+
* const page = await base44.entities.MyEntity.list({ limit: 10 });
|
|
354
|
+
* console.log(page.items);
|
|
355
|
+
* ```
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* ```typescript
|
|
359
|
+
* // Sort records
|
|
360
|
+
* const page = await base44.entities.MyEntity.list({ sort: '-priority', limit: 10 });
|
|
361
|
+
* ```
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```typescript
|
|
365
|
+
* // Only return specific fields
|
|
366
|
+
* const page = await base44.entities.MyEntity.list({ fields: ['name', 'status'], limit: 10 });
|
|
367
|
+
* ```
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```typescript
|
|
371
|
+
* // Walk every record with a cursor
|
|
372
|
+
* const allItems = [];
|
|
373
|
+
* let page = await base44.entities.MyEntity.list({ sort: '-created_date', limit: 1000 });
|
|
374
|
+
* allItems.push(...page.items);
|
|
375
|
+
* while (page.has_more) {
|
|
376
|
+
* page = await base44.entities.MyEntity.list({ cursor: page.next_cursor, limit: 1000 });
|
|
377
|
+
* allItems.push(...page.items);
|
|
378
|
+
* }
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
list<K extends keyof T = keyof T>(options: EntityListOptions<T, K>): Promise<EntityPage<Pick<T, K>>>;
|
|
382
|
+
/**
|
|
383
|
+
* Lists one cursor page of a single field's distinct values, instead of records.
|
|
334
384
|
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
385
|
+
* @typeParam K - The field whose distinct values to read.
|
|
386
|
+
* @param options - Paging options naming the field to read.
|
|
387
|
+
* @returns Promise resolving to a page of distinct values.
|
|
337
388
|
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```typescript
|
|
391
|
+
* // Regular field
|
|
392
|
+
* const { items: categories } = await base44.entities.Product.list({ distinct: 'category' });
|
|
393
|
+
* // categories: ['books', 'electronics', 'toys']
|
|
394
|
+
* ```
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* ```typescript
|
|
398
|
+
* // Array field
|
|
399
|
+
* // Each tag counts once, not each array
|
|
400
|
+
* const { items: tags } = await base44.entities.Product.list({ distinct: 'tags' });
|
|
401
|
+
* // tags: ['bestseller', 'clearance', 'new']
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
list<K extends keyof T>(options: EntityDistinctOptions<T, K>): Promise<EntityPage<T[K]>>;
|
|
405
|
+
/**
|
|
406
|
+
* Lists records as an array, using `skip` for pagination.
|
|
407
|
+
*
|
|
408
|
+
* Kept for existing code. Prefer a cursor for pagination instead.
|
|
343
409
|
*
|
|
344
410
|
* @typeParam K - The fields to include in the response. Defaults to all fields.
|
|
345
|
-
* @param sort - Sort parameter, such as `'-
|
|
411
|
+
* @param sort - Sort parameter, such as `'-priority'` for descending. Defaults to `'-created_date'`.
|
|
346
412
|
* @param limit - Maximum number of results to return. Defaults to `5000`.
|
|
347
|
-
* @param skip - Number of results to skip for pagination. Defaults to `0`.
|
|
413
|
+
* @param skip - Number of results to skip for pagination. Defaults to `0`. Prefer a cursor for loops instead.
|
|
348
414
|
* @param fields - Array of field names to include in the response. Defaults to all fields.
|
|
349
|
-
* @returns Promise resolving to an array of records with selected fields.
|
|
415
|
+
* @returns Promise resolving to an array of records with selected fields.
|
|
350
416
|
*
|
|
351
417
|
* @example
|
|
352
418
|
* ```typescript
|
|
@@ -372,51 +438,101 @@ export interface EntityHandler<T = any> {
|
|
|
372
438
|
* // Get only specific fields
|
|
373
439
|
* const fields = await base44.entities.MyEntity.list('-created_date', 10, 0, ['name', 'status']);
|
|
374
440
|
* ```
|
|
441
|
+
*/
|
|
442
|
+
list<K extends keyof T = keyof T>(sort?: SortField<T>, limit?: number, skip?: number, fields?: K[]): Promise<Pick<T, K>[]>;
|
|
443
|
+
/**
|
|
444
|
+
* Filters and returns one cursor page of matching records, sorted and
|
|
445
|
+
* optionally field-selected.
|
|
446
|
+
*
|
|
447
|
+
* Pass `cursor` from the previous page's `next_cursor` to keep paging, or omit it
|
|
448
|
+
* for the first page. Records added or deleted between pages never shift the boundary.
|
|
449
|
+
*
|
|
450
|
+
* @typeParam K - The fields to include in each record. Defaults to all fields.
|
|
451
|
+
* @param query - Query matching {@linkcode EntityFilterQuery}. Field names are
|
|
452
|
+
* case-sensitive, and records matching every field are returned.
|
|
453
|
+
* @param options - Paging options.
|
|
454
|
+
* @returns Promise resolving to a page of matching records.
|
|
375
455
|
*
|
|
376
456
|
* @example
|
|
377
457
|
* ```typescript
|
|
378
|
-
* //
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
458
|
+
* // Get one page of matching records
|
|
459
|
+
* const page = await base44.entities.Order.filter({ status: 'open' }, { limit: 10 });
|
|
460
|
+
* console.log(page.items);
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```typescript
|
|
465
|
+
* // Sort matching records
|
|
466
|
+
* const page = await base44.entities.Order.filter({ status: 'open' }, { sort: '-priority', limit: 10 });
|
|
467
|
+
* ```
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```typescript
|
|
471
|
+
* // Only return specific fields
|
|
472
|
+
* const page = await base44.entities.Order.filter({ status: 'open' }, { fields: ['status', 'region'], limit: 10 });
|
|
473
|
+
* ```
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* ```typescript
|
|
477
|
+
* // Walk all matching records with a cursor
|
|
478
|
+
* const allOrders = [];
|
|
479
|
+
* let page = await base44.entities.Order.filter(
|
|
480
|
+
* { status: 'open' },
|
|
481
|
+
* { sort: '-created_date', limit: 1000 }
|
|
482
|
+
* );
|
|
483
|
+
* allOrders.push(...page.items);
|
|
382
484
|
* while (page.has_more) {
|
|
383
|
-
* page = await base44.entities.
|
|
384
|
-
*
|
|
485
|
+
* page = await base44.entities.Order.filter({ status: 'open' }, { cursor: page.next_cursor, limit: 1000 });
|
|
486
|
+
* allOrders.push(...page.items);
|
|
385
487
|
* }
|
|
386
488
|
* ```
|
|
489
|
+
*/
|
|
490
|
+
filter<K extends keyof T = keyof T>(query: EntityFilterQuery<T>, options: EntityListOptions<T, K>): Promise<EntityPage<Pick<T, K>>>;
|
|
491
|
+
/**
|
|
492
|
+
* Filters and returns one cursor page of a single field's distinct values
|
|
493
|
+
* among matching records.
|
|
494
|
+
*
|
|
495
|
+
* @typeParam K - The field whose distinct values to read.
|
|
496
|
+
* @param query - Query matching {@linkcode EntityFilterQuery}. Field names are
|
|
497
|
+
* case-sensitive, and records matching every field are returned.
|
|
498
|
+
* @param options - Paging options naming the field to read.
|
|
499
|
+
* @returns Promise resolving to a page of distinct values.
|
|
387
500
|
*
|
|
388
501
|
* @example
|
|
389
502
|
* ```typescript
|
|
390
|
-
* //
|
|
391
|
-
* const { items:
|
|
503
|
+
* // Regular field
|
|
504
|
+
* const { items: regions } = await base44.entities.Order.filter(
|
|
505
|
+
* { status: 'open' },
|
|
506
|
+
* { distinct: 'region' }
|
|
507
|
+
* );
|
|
508
|
+
* // regions: ['east', 'north', 'west']
|
|
509
|
+
* ```
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```typescript
|
|
513
|
+
* // Array field
|
|
514
|
+
* // Each tag counts once, not each array
|
|
515
|
+
* const { items: tags } = await base44.entities.Order.filter(
|
|
516
|
+
* { status: 'open' },
|
|
517
|
+
* { distinct: 'tags' }
|
|
518
|
+
* );
|
|
519
|
+
* // tags: ['gift', 'international', 'rush']
|
|
392
520
|
* ```
|
|
393
521
|
*/
|
|
394
|
-
|
|
395
|
-
list<K extends keyof T>(options: EntityDistinctOptions<T, K>): Promise<EntityPage<T[K]>>;
|
|
396
|
-
list<K extends keyof T = keyof T>(options: EntityListOptions<T, K>): Promise<EntityPage<Pick<T, K>>>;
|
|
522
|
+
filter<K extends keyof T>(query: EntityFilterQuery<T>, options: EntityDistinctOptions<T, K>): Promise<EntityPage<T[K]>>;
|
|
397
523
|
/**
|
|
398
|
-
* Filters records
|
|
399
|
-
*
|
|
400
|
-
* Retrieves records that match specific criteria with support for
|
|
401
|
-
* sorting, pagination, and field selection.
|
|
524
|
+
* Filters records as an array, using `skip` for pagination.
|
|
402
525
|
*
|
|
403
|
-
*
|
|
404
|
-
* one page, pass an {@linkcode EntityListOptions | options object} with a
|
|
405
|
-
* `cursor` instead of `skip`: every page costs the same however deep you are,
|
|
406
|
-
* and records deleted between pages never shift the boundary. `skip` is kept
|
|
407
|
-
* for existing code and is deprecated for loops.
|
|
526
|
+
* Kept for existing code. Prefer a cursor for pagination instead.
|
|
408
527
|
*
|
|
409
528
|
* @typeParam K - The fields to include in the response. Defaults to all fields.
|
|
410
|
-
* @param query - Query
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
* for exact matches, `null` for null values, arrays as shorthand for matching any of the
|
|
414
|
-
* provided values, or documented MongoDB query operators for advanced filtering.
|
|
415
|
-
* @param sort - Sort parameter, such as `'-created_date'` for descending. Defaults to `'-created_date'`.
|
|
529
|
+
* @param query - Query matching {@linkcode EntityFilterQuery}. Field names are
|
|
530
|
+
* case-sensitive, and records matching every field are returned.
|
|
531
|
+
* @param sort - Sort parameter, such as `'-priority'` for descending. Defaults to `'-created_date'`.
|
|
416
532
|
* @param limit - Maximum number of results to return. Defaults to `5000`.
|
|
417
|
-
* @param skip - Number of results to skip for pagination. Defaults to `0`.
|
|
533
|
+
* @param skip - Number of results to skip for pagination. Defaults to `0`. Prefer a cursor for loops instead.
|
|
418
534
|
* @param fields - Array of field names to include in the response. Defaults to all fields.
|
|
419
|
-
* @returns Promise resolving to an array of filtered records with selected fields.
|
|
535
|
+
* @returns Promise resolving to an array of filtered records with selected fields.
|
|
420
536
|
*
|
|
421
537
|
* @example
|
|
422
538
|
* ```typescript
|
|
@@ -493,34 +609,8 @@ export interface EntityHandler<T = any> {
|
|
|
493
609
|
* ['name', 'priority']
|
|
494
610
|
* );
|
|
495
611
|
* ```
|
|
496
|
-
*
|
|
497
|
-
* @example
|
|
498
|
-
* ```typescript
|
|
499
|
-
* // Walk all matching records with a cursor. Pass an options object as the
|
|
500
|
-
* // second argument to get a page with `next_cursor` and `has_more`.
|
|
501
|
-
* let page = await base44.entities.Order.filter(
|
|
502
|
-
* { status: 'open' },
|
|
503
|
-
* { sort: '-created_date', limit: 1000 }
|
|
504
|
-
* );
|
|
505
|
-
* await exportRows(page.items);
|
|
506
|
-
* while (page.has_more) {
|
|
507
|
-
* page = await base44.entities.Order.filter({ status: 'open' }, { cursor: page.next_cursor, limit: 1000 });
|
|
508
|
-
* await exportRows(page.items);
|
|
509
|
-
* }
|
|
510
|
-
* ```
|
|
511
|
-
*
|
|
512
|
-
* @example
|
|
513
|
-
* ```typescript
|
|
514
|
-
* // Distinct values of one field among the matching records
|
|
515
|
-
* const { items: agents } = await base44.entities.Order.filter(
|
|
516
|
-
* { status: 'open' },
|
|
517
|
-
* { distinct: 'agent_id' }
|
|
518
|
-
* );
|
|
519
|
-
* ```
|
|
520
612
|
*/
|
|
521
613
|
filter<K extends keyof T = keyof T>(query: EntityFilterQuery<T>, sort?: SortField<T>, limit?: number, skip?: number, fields?: K[]): Promise<Pick<T, K>[]>;
|
|
522
|
-
filter<K extends keyof T>(query: EntityFilterQuery<T>, options: EntityDistinctOptions<T, K>): Promise<EntityPage<T[K]>>;
|
|
523
|
-
filter<K extends keyof T = keyof T>(query: EntityFilterQuery<T>, options: EntityListOptions<T, K>): Promise<EntityPage<Pick<T, K>>>;
|
|
524
614
|
/**
|
|
525
615
|
* Gets a single record by ID.
|
|
526
616
|
*
|
|
@@ -612,9 +702,7 @@ export interface EntityHandler<T = any> {
|
|
|
612
702
|
*
|
|
613
703
|
* Permanently removes all records that match the provided query.
|
|
614
704
|
*
|
|
615
|
-
* @param query - Query
|
|
616
|
-
* from your entity schema, and each value is the criteria to match. Records matching all
|
|
617
|
-
* specified criteria will be deleted. Field names are case-sensitive.
|
|
705
|
+
* @param query - Query matching {@linkcode EntityFilterQuery}. Every matching record is deleted.
|
|
618
706
|
* @returns Promise resolving to the deletion result.
|
|
619
707
|
*
|
|
620
708
|
* @example
|
|
@@ -664,12 +752,7 @@ export interface EntityHandler<T = any> {
|
|
|
664
752
|
* To update a single record by ID, use {@linkcode update | update()} instead. To update
|
|
665
753
|
* multiple specific records with different data each, use {@linkcode bulkUpdate | bulkUpdate()}.
|
|
666
754
|
*
|
|
667
|
-
* @param query - Query
|
|
668
|
-
* pairs for exact matches, or
|
|
669
|
-
* [MongoDB query operators](https://www.mongodb.com/docs/manual/reference/operator/query/)
|
|
670
|
-
* for advanced filtering. Supported query operators include `$eq`, `$ne`, `$gt`,
|
|
671
|
-
* `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$and`, `$or`, `$not`, `$nor`,
|
|
672
|
-
* `$exists`, `$regex`, `$all`, `$elemMatch`, and `$size`.
|
|
755
|
+
* @param query - Query matching {@linkcode EntityFilterQuery}, selecting which records to update.
|
|
673
756
|
* @param data - Update operation object containing one or more
|
|
674
757
|
* [MongoDB update operators](https://www.mongodb.com/docs/manual/reference/operator/update/).
|
|
675
758
|
* Each field may only appear in one operator per call.
|
|
@@ -731,23 +814,30 @@ export interface EntityHandler<T = any> {
|
|
|
731
814
|
* Counts the records that match a query.
|
|
732
815
|
*
|
|
733
816
|
* Returns the number of records the current user can read, without fetching them.
|
|
734
|
-
* Use it for totals, badges and "page N of M"
|
|
735
|
-
* measuring the array.
|
|
817
|
+
* Use it for totals, badges and "page N of M".
|
|
736
818
|
*
|
|
737
|
-
* @param query -
|
|
819
|
+
* @param query - Query matching {@linkcode EntityFilterQuery}. Defaults to all records.
|
|
738
820
|
* @returns Promise resolving to the number of matching records.
|
|
739
821
|
*
|
|
740
822
|
* @example
|
|
741
823
|
* ```typescript
|
|
742
|
-
* //
|
|
824
|
+
* // Count matching records
|
|
743
825
|
* const open = await base44.entities.Task.count({ status: 'open' });
|
|
744
826
|
* ```
|
|
745
827
|
*
|
|
746
828
|
* @example
|
|
747
829
|
* ```typescript
|
|
748
|
-
* //
|
|
830
|
+
* // Count all records
|
|
749
831
|
* const total = await base44.entities.Task.count();
|
|
750
832
|
* ```
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* ```typescript
|
|
836
|
+
* // Page N of M
|
|
837
|
+
* const pageSize = 20;
|
|
838
|
+
* const total = await base44.entities.Task.count({ status: 'open' });
|
|
839
|
+
* const totalPages = Math.ceil(total / pageSize);
|
|
840
|
+
* ```
|
|
751
841
|
*/
|
|
752
842
|
count(query?: EntityFilterQuery<T>): Promise<number>;
|
|
753
843
|
/**
|
|
@@ -757,7 +847,7 @@ export interface EntityHandler<T = any> {
|
|
|
757
847
|
* and adding up in the browser. The server groups the records you can read and
|
|
758
848
|
* returns one row per group, up to 1,000 rows.
|
|
759
849
|
*
|
|
760
|
-
* @param spec - What to group by and what to compute.
|
|
850
|
+
* @param spec - What to group by and what to compute.
|
|
761
851
|
* @returns Promise resolving to the rows and a `truncated` flag.
|
|
762
852
|
*
|
|
763
853
|
* @example
|
|
@@ -769,58 +859,78 @@ export interface EntityHandler<T = any> {
|
|
|
769
859
|
* sum: 'amount',
|
|
770
860
|
* sort: '-sum_amount'
|
|
771
861
|
* });
|
|
772
|
-
* // rows: [
|
|
862
|
+
* // rows: [
|
|
863
|
+
* // { agent_id: 'a1', count: 42, sum_amount: 18250 },
|
|
864
|
+
* // { agent_id: 'a2', count: 37, sum_amount: 15400 },
|
|
865
|
+
* // ...
|
|
866
|
+
* // ]
|
|
773
867
|
* ```
|
|
774
868
|
*
|
|
775
869
|
* @example
|
|
776
870
|
* ```typescript
|
|
777
|
-
* //
|
|
778
|
-
* const { rows } = await base44.entities.
|
|
871
|
+
* // Tasks created per day
|
|
872
|
+
* const { rows } = await base44.entities.Task.aggregate({
|
|
779
873
|
* dateBucket: { field: 'created_date', unit: 'day' }
|
|
780
874
|
* });
|
|
875
|
+
* // rows: [
|
|
876
|
+
* // { created_date: '2026-09-01', count: 8 },
|
|
877
|
+
* // { created_date: '2026-09-02', count: 11 },
|
|
878
|
+
* // ...
|
|
879
|
+
* // ]
|
|
781
880
|
* ```
|
|
782
881
|
*
|
|
783
882
|
* @example
|
|
784
883
|
* ```typescript
|
|
785
884
|
* // Find duplicated external ids
|
|
786
|
-
* const { rows } = await base44.entities.
|
|
885
|
+
* const { rows } = await base44.entities.Order.aggregate({
|
|
787
886
|
* groupBy: 'external_id',
|
|
788
887
|
* having: { count: { $gt: 1 } }
|
|
789
888
|
* });
|
|
889
|
+
* // rows: [
|
|
890
|
+
* // { external_id: 'ext-42', count: 3 },
|
|
891
|
+
* // { external_id: 'ext-77', count: 2 }
|
|
892
|
+
* // ]
|
|
790
893
|
* ```
|
|
791
894
|
*
|
|
792
895
|
* @example
|
|
793
896
|
* ```typescript
|
|
794
|
-
* // Unique
|
|
795
|
-
* const { rows } = await base44.entities.
|
|
796
|
-
* groupBy: '
|
|
797
|
-
* countDistinct: '
|
|
897
|
+
* // Unique customers per product
|
|
898
|
+
* const { rows } = await base44.entities.Order.aggregate({
|
|
899
|
+
* groupBy: 'product_id',
|
|
900
|
+
* countDistinct: 'customer_id'
|
|
798
901
|
* });
|
|
902
|
+
* // rows: [
|
|
903
|
+
* // { product_id: 'p1', count_distinct_customer_id: 86 },
|
|
904
|
+
* // { product_id: 'p2', count_distinct_customer_id: 34 }
|
|
905
|
+
* // ]
|
|
799
906
|
* ```
|
|
800
907
|
*/
|
|
801
908
|
aggregate(spec: EntityAggregateSpec<T>): Promise<EntityAggregateResult>;
|
|
802
909
|
/**
|
|
803
|
-
* Creates or updates records by a key of
|
|
910
|
+
* Creates or updates records by a key you define, instead of by `id`.
|
|
804
911
|
*
|
|
805
|
-
* Use this
|
|
806
|
-
*
|
|
807
|
-
*
|
|
808
|
-
*
|
|
912
|
+
* Use this whenever records have a natural key, such as an ID from another system or a
|
|
913
|
+
* one-per-user record keyed by `user_id`, so you don't have to look up each record first
|
|
914
|
+
* to decide between create and update. Name the field, or fields, that identify a record,
|
|
915
|
+
* and the server updates the records whose key already exists and creates the rest, in
|
|
916
|
+
* one call.
|
|
809
917
|
*
|
|
810
918
|
* You can upsert up to 500 records per request. When two records in one call share a
|
|
811
919
|
* key, the last one wins. Updates merge the given fields into the existing record, like
|
|
812
920
|
* {@linkcode update | update()}.
|
|
813
921
|
*
|
|
814
|
-
* @param records - Array of record data objects. Each must carry a value
|
|
815
|
-
*
|
|
922
|
+
* @param records - Array of record data objects. Each must carry a value, not an object or
|
|
923
|
+
* array, for every field named in `options.key`, to find or create by. Other fields are
|
|
924
|
+
* optional, and only the ones you include are merged into a matched record, like `update()`.
|
|
925
|
+
* @param options - The key field or fields.
|
|
816
926
|
* @returns Promise resolving to the counts and the written records.
|
|
817
927
|
*
|
|
818
928
|
* @example
|
|
819
929
|
* ```typescript
|
|
820
|
-
* // Sync
|
|
821
|
-
* const result = await base44.entities.
|
|
822
|
-
*
|
|
823
|
-
* { key: '
|
|
930
|
+
* // Sync by sku
|
|
931
|
+
* const result = await base44.entities.Product.upsert(
|
|
932
|
+
* supplierCatalog.map(p => ({ sku: p.sku, name: p.name, price: p.price })),
|
|
933
|
+
* { key: 'sku' }
|
|
824
934
|
* );
|
|
825
935
|
* console.log(`${result.created} new, ${result.updated} updated`);
|
|
826
936
|
* ```
|
|
@@ -828,7 +938,11 @@ export interface EntityHandler<T = any> {
|
|
|
828
938
|
* @example
|
|
829
939
|
* ```typescript
|
|
830
940
|
* // Compound key
|
|
831
|
-
* await base44.entities.Inventory.upsert(
|
|
941
|
+
* const result = await base44.entities.Inventory.upsert(
|
|
942
|
+
* warehouseFeed.map(row => ({ sku: row.sku, warehouse: row.warehouseCode, quantity: row.qty })),
|
|
943
|
+
* { key: ['sku', 'warehouse'] }
|
|
944
|
+
* );
|
|
945
|
+
* console.log(`${result.created} new, ${result.updated} updated`);
|
|
832
946
|
* ```
|
|
833
947
|
*/
|
|
834
948
|
upsert(records: Partial<T>[], options: EntityUpsertOptions<T>): Promise<EntityUpsertResult<T>>;
|