@baasix/types 1.0.1
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/README.md +242 -0
- package/dist/index.d.mts +2065 -0
- package/dist/index.d.ts +2065 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
- package/src/auth.ts +281 -0
- package/src/cache.ts +66 -0
- package/src/common.ts +241 -0
- package/src/files.ts +191 -0
- package/src/index.ts +309 -0
- package/src/notification.ts +52 -0
- package/src/plugin.ts +711 -0
- package/src/query.ts +443 -0
- package/src/response.ts +71 -0
- package/src/schema.ts +343 -0
- package/src/spatial.ts +37 -0
- package/src/workflow.ts +146 -0
package/src/files.ts
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File & Asset Types
|
|
3
|
+
* Shared across core, sdk, and app packages
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// File Types
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* File metadata
|
|
12
|
+
*/
|
|
13
|
+
export interface FileMetadata {
|
|
14
|
+
id: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
filename: string;
|
|
18
|
+
mimeType: string;
|
|
19
|
+
size: number;
|
|
20
|
+
width?: number;
|
|
21
|
+
height?: number;
|
|
22
|
+
duration?: number;
|
|
23
|
+
storage: string;
|
|
24
|
+
path: string;
|
|
25
|
+
isPublic?: boolean;
|
|
26
|
+
uploadedBy?: string;
|
|
27
|
+
tenant_Id?: string;
|
|
28
|
+
createdAt: string;
|
|
29
|
+
updatedAt?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* File data (internal use)
|
|
35
|
+
*/
|
|
36
|
+
export interface FileData {
|
|
37
|
+
buffer: Buffer;
|
|
38
|
+
filename: string;
|
|
39
|
+
mimetype: string;
|
|
40
|
+
size: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Upload options
|
|
45
|
+
*/
|
|
46
|
+
export interface UploadOptions {
|
|
47
|
+
title?: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
folder?: string;
|
|
50
|
+
storage?: "local" | "s3";
|
|
51
|
+
isPublic?: boolean;
|
|
52
|
+
metadata?: Record<string, unknown>;
|
|
53
|
+
onProgress?: (progress: number) => void;
|
|
54
|
+
/** Request timeout in milliseconds (default: 30000). Set to 0 for no timeout. */
|
|
55
|
+
timeout?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Internal uploaded file (from express-fileupload)
|
|
60
|
+
*/
|
|
61
|
+
export interface InternalUploadedFile {
|
|
62
|
+
name: string;
|
|
63
|
+
data: Buffer;
|
|
64
|
+
size: number;
|
|
65
|
+
encoding: string;
|
|
66
|
+
tempFilePath: string;
|
|
67
|
+
truncated: boolean;
|
|
68
|
+
mimetype: string;
|
|
69
|
+
md5: string;
|
|
70
|
+
mv: (path: string) => Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Asset Transform Types
|
|
75
|
+
// ============================================================================
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Asset transform options
|
|
79
|
+
*/
|
|
80
|
+
export interface AssetTransformOptions {
|
|
81
|
+
width?: number;
|
|
82
|
+
height?: number;
|
|
83
|
+
fit?: "cover" | "contain" | "fill" | "inside" | "outside";
|
|
84
|
+
quality?: number;
|
|
85
|
+
format?: "jpeg" | "png" | "webp" | "avif";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Asset query parameters (from HTTP query string)
|
|
90
|
+
* Values can be string | number since they come from query params
|
|
91
|
+
*/
|
|
92
|
+
export interface AssetQuery {
|
|
93
|
+
width?: string | number;
|
|
94
|
+
height?: string | number;
|
|
95
|
+
fit?: "cover" | "contain" | "fill" | "inside" | "outside" | string;
|
|
96
|
+
quality?: string | number;
|
|
97
|
+
format?: string;
|
|
98
|
+
withoutEnlargement?: string | boolean;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Processed image result
|
|
103
|
+
*/
|
|
104
|
+
export interface ProcessedImage {
|
|
105
|
+
buffer: Buffer;
|
|
106
|
+
/** Content type (e.g., 'image/jpeg') or format (e.g., 'jpeg') */
|
|
107
|
+
contentType?: string;
|
|
108
|
+
format?: string;
|
|
109
|
+
width?: number;
|
|
110
|
+
height?: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ============================================================================
|
|
114
|
+
// Storage Types
|
|
115
|
+
// ============================================================================
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Storage provider type
|
|
119
|
+
*/
|
|
120
|
+
export type StorageProvider = "local" | "s3" | "gcs" | "azure";
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Storage adapter interface
|
|
124
|
+
*/
|
|
125
|
+
export interface StorageAdapter {
|
|
126
|
+
getItem(key: string): string | null | Promise<string | null>;
|
|
127
|
+
setItem(key: string, value: string): void | Promise<void>;
|
|
128
|
+
removeItem(key: string): void | Promise<void>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Import/Export Types
|
|
133
|
+
// ============================================================================
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Uploaded file interface (from multipart form)
|
|
137
|
+
*/
|
|
138
|
+
export interface UploadedFile {
|
|
139
|
+
originalname: string;
|
|
140
|
+
mimetype: string;
|
|
141
|
+
buffer: Buffer;
|
|
142
|
+
size: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Import options
|
|
147
|
+
*/
|
|
148
|
+
export interface ImportOptions {
|
|
149
|
+
collection: string;
|
|
150
|
+
file?: UploadedFile;
|
|
151
|
+
data?: unknown[];
|
|
152
|
+
format?: "csv" | "json";
|
|
153
|
+
mapping?: Record<string, string>;
|
|
154
|
+
skipValidation?: boolean;
|
|
155
|
+
batchSize?: number;
|
|
156
|
+
onProgress?: (processed: number, total: number) => void;
|
|
157
|
+
onError?: (error: Error, row: unknown, index: number) => void;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Export options
|
|
162
|
+
*/
|
|
163
|
+
export interface ExportOptions {
|
|
164
|
+
collection: string;
|
|
165
|
+
format?: "csv" | "json";
|
|
166
|
+
fields?: string[];
|
|
167
|
+
filter?: Record<string, unknown>;
|
|
168
|
+
limit?: number;
|
|
169
|
+
offset?: number;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Import result
|
|
174
|
+
*/
|
|
175
|
+
export interface ImportResult {
|
|
176
|
+
success: boolean;
|
|
177
|
+
imported: number;
|
|
178
|
+
failed: number;
|
|
179
|
+
errors: Array<{ row: number; error: string; data?: unknown }>;
|
|
180
|
+
duration: number;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Export result
|
|
185
|
+
*/
|
|
186
|
+
export interface ExportResult {
|
|
187
|
+
success: boolean;
|
|
188
|
+
data: string | unknown[];
|
|
189
|
+
count: number;
|
|
190
|
+
format: string;
|
|
191
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @baasix/types
|
|
3
|
+
* Shared TypeScript types for Baasix packages
|
|
4
|
+
*
|
|
5
|
+
* This package provides common type definitions used across:
|
|
6
|
+
* - @baasix/core (backend)
|
|
7
|
+
* - @baasix/sdk (client SDK)
|
|
8
|
+
* - @baasix/cli (command-line interface)
|
|
9
|
+
* - @baasix/app (admin panel)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Auth Types
|
|
14
|
+
// ============================================================================
|
|
15
|
+
export type {
|
|
16
|
+
// User types
|
|
17
|
+
User,
|
|
18
|
+
UserWithPassword,
|
|
19
|
+
UserWithRolesAndPermissions,
|
|
20
|
+
// Role & Permission types
|
|
21
|
+
Role,
|
|
22
|
+
PermissionAction,
|
|
23
|
+
Permission,
|
|
24
|
+
PermissionData,
|
|
25
|
+
CreatePermissionData,
|
|
26
|
+
// Tenant types
|
|
27
|
+
Tenant,
|
|
28
|
+
// Session & Token types
|
|
29
|
+
Session,
|
|
30
|
+
AuthTokens,
|
|
31
|
+
JWTPayload,
|
|
32
|
+
// Accountability
|
|
33
|
+
Accountability,
|
|
34
|
+
// Auth request/response types
|
|
35
|
+
LoginCredentials,
|
|
36
|
+
RegisterData,
|
|
37
|
+
AuthResponse,
|
|
38
|
+
AuthStateEvent,
|
|
39
|
+
AuthState,
|
|
40
|
+
MagicLinkOptions,
|
|
41
|
+
PasswordResetOptions,
|
|
42
|
+
// OAuth types
|
|
43
|
+
OAuth2Tokens,
|
|
44
|
+
OAuth2UserInfo,
|
|
45
|
+
// Auth mode
|
|
46
|
+
AuthMode,
|
|
47
|
+
} from "./auth";
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Schema Types
|
|
51
|
+
// ============================================================================
|
|
52
|
+
export type {
|
|
53
|
+
// Field types
|
|
54
|
+
FieldType,
|
|
55
|
+
DefaultValueType,
|
|
56
|
+
FieldValidationRules,
|
|
57
|
+
FieldValues,
|
|
58
|
+
FieldDefinition,
|
|
59
|
+
FlattenedField,
|
|
60
|
+
FieldInfo,
|
|
61
|
+
// Schema types
|
|
62
|
+
IndexDefinition,
|
|
63
|
+
SchemaDefinition,
|
|
64
|
+
SchemaInfo,
|
|
65
|
+
SchemaValidation,
|
|
66
|
+
FieldValidation,
|
|
67
|
+
ValidationResult,
|
|
68
|
+
// Relationship types
|
|
69
|
+
RelationshipType,
|
|
70
|
+
AssociationType,
|
|
71
|
+
RelationshipDefinition,
|
|
72
|
+
AssociationDefinition,
|
|
73
|
+
IncludeConfig,
|
|
74
|
+
ProcessedInclude,
|
|
75
|
+
} from "./schema";
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Query Types (includes Report & Stats query types)
|
|
79
|
+
// ============================================================================
|
|
80
|
+
export type {
|
|
81
|
+
// Filter types
|
|
82
|
+
FilterOperator,
|
|
83
|
+
OperatorName,
|
|
84
|
+
FilterValue,
|
|
85
|
+
FilterCondition,
|
|
86
|
+
LogicalFilter,
|
|
87
|
+
Filter,
|
|
88
|
+
FilterObject,
|
|
89
|
+
// Sort types
|
|
90
|
+
SortDirection,
|
|
91
|
+
Sort,
|
|
92
|
+
SortItem,
|
|
93
|
+
SortObject,
|
|
94
|
+
// Pagination types
|
|
95
|
+
PaginationOptions,
|
|
96
|
+
PaginationMetadata,
|
|
97
|
+
// Aggregation types
|
|
98
|
+
AggregateFunction,
|
|
99
|
+
AggregateConfig,
|
|
100
|
+
Aggregate,
|
|
101
|
+
AggregateMapping,
|
|
102
|
+
DatePart,
|
|
103
|
+
DateTruncPrecision,
|
|
104
|
+
// Query parameters
|
|
105
|
+
QueryParams,
|
|
106
|
+
QueryOptions,
|
|
107
|
+
QueryContext,
|
|
108
|
+
// Report query types
|
|
109
|
+
ReportConfig,
|
|
110
|
+
ReportResult,
|
|
111
|
+
ReportQuery,
|
|
112
|
+
// Stats query types
|
|
113
|
+
StatsQuery,
|
|
114
|
+
StatsResult,
|
|
115
|
+
} from "./query";
|
|
116
|
+
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// Response Types
|
|
119
|
+
// ============================================================================
|
|
120
|
+
export type {
|
|
121
|
+
PaginatedResponse,
|
|
122
|
+
SingleResponse,
|
|
123
|
+
MutationResponse,
|
|
124
|
+
DeleteResponse,
|
|
125
|
+
BulkResponse,
|
|
126
|
+
ReadResult,
|
|
127
|
+
ErrorResponse,
|
|
128
|
+
} from "./response";
|
|
129
|
+
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// File Types (includes Import/Export types)
|
|
132
|
+
// ============================================================================
|
|
133
|
+
export type {
|
|
134
|
+
// File metadata
|
|
135
|
+
FileMetadata,
|
|
136
|
+
FileData,
|
|
137
|
+
UploadOptions,
|
|
138
|
+
InternalUploadedFile,
|
|
139
|
+
// Asset types
|
|
140
|
+
AssetTransformOptions,
|
|
141
|
+
AssetQuery,
|
|
142
|
+
ProcessedImage,
|
|
143
|
+
// Storage types
|
|
144
|
+
StorageProvider,
|
|
145
|
+
StorageAdapter,
|
|
146
|
+
// Import/Export types
|
|
147
|
+
UploadedFile,
|
|
148
|
+
ImportOptions,
|
|
149
|
+
ExportOptions,
|
|
150
|
+
ImportResult,
|
|
151
|
+
ExportResult,
|
|
152
|
+
} from "./files";
|
|
153
|
+
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// Workflow Types
|
|
156
|
+
// ============================================================================
|
|
157
|
+
export type {
|
|
158
|
+
WorkflowTriggerType,
|
|
159
|
+
WorkflowStatus,
|
|
160
|
+
Workflow,
|
|
161
|
+
WorkflowFlowData,
|
|
162
|
+
WorkflowTrigger,
|
|
163
|
+
WorkflowNode,
|
|
164
|
+
WorkflowNodeData,
|
|
165
|
+
WorkflowEdge,
|
|
166
|
+
WorkflowExecutionStatus,
|
|
167
|
+
WorkflowExecution,
|
|
168
|
+
WorkflowExecutionLog,
|
|
169
|
+
} from "./workflow";
|
|
170
|
+
|
|
171
|
+
// ============================================================================
|
|
172
|
+
// Notification Types
|
|
173
|
+
// ============================================================================
|
|
174
|
+
export type {
|
|
175
|
+
NotificationType,
|
|
176
|
+
Notification,
|
|
177
|
+
NotificationOptions,
|
|
178
|
+
SendNotificationData,
|
|
179
|
+
} from "./notification";
|
|
180
|
+
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Spatial/GeoJSON Types
|
|
183
|
+
// ============================================================================
|
|
184
|
+
export type {
|
|
185
|
+
GeoJSONPoint,
|
|
186
|
+
GeoJSONLineString,
|
|
187
|
+
GeoJSONPolygon,
|
|
188
|
+
GeoJSONGeometry,
|
|
189
|
+
} from "./spatial";
|
|
190
|
+
|
|
191
|
+
// ============================================================================
|
|
192
|
+
// Cache Types
|
|
193
|
+
// ============================================================================
|
|
194
|
+
export type {
|
|
195
|
+
CacheConfig,
|
|
196
|
+
CacheSetOptions,
|
|
197
|
+
CacheStrategy,
|
|
198
|
+
CacheEntry,
|
|
199
|
+
ICacheAdapter,
|
|
200
|
+
} from "./cache";
|
|
201
|
+
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// Common Types
|
|
204
|
+
// ============================================================================
|
|
205
|
+
export type {
|
|
206
|
+
// Base types
|
|
207
|
+
BaseItem,
|
|
208
|
+
TimestampedItem,
|
|
209
|
+
SoftDeletableItem,
|
|
210
|
+
// Utility types
|
|
211
|
+
DeepPartial,
|
|
212
|
+
CollectionItem,
|
|
213
|
+
WithRequired,
|
|
214
|
+
WithOptional,
|
|
215
|
+
KeysOfType,
|
|
216
|
+
AnyRecord,
|
|
217
|
+
// Settings types
|
|
218
|
+
Settings,
|
|
219
|
+
TenantSettings,
|
|
220
|
+
// Task types
|
|
221
|
+
BackgroundTask,
|
|
222
|
+
// Hook types
|
|
223
|
+
HookEvent,
|
|
224
|
+
HookContext,
|
|
225
|
+
HookHandler,
|
|
226
|
+
Hook,
|
|
227
|
+
// HTTP types
|
|
228
|
+
HttpMethod,
|
|
229
|
+
// Mail types
|
|
230
|
+
MailOptions,
|
|
231
|
+
SenderConfig,
|
|
232
|
+
// Seed types
|
|
233
|
+
SeedData,
|
|
234
|
+
SeedResult,
|
|
235
|
+
} from "./common";
|
|
236
|
+
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// Plugin Types
|
|
239
|
+
// ============================================================================
|
|
240
|
+
export type {
|
|
241
|
+
// Express types (actual Express types from @types/express)
|
|
242
|
+
Request,
|
|
243
|
+
Response,
|
|
244
|
+
NextFunction,
|
|
245
|
+
Express,
|
|
246
|
+
Router,
|
|
247
|
+
// Express type aliases
|
|
248
|
+
ExpressRequest,
|
|
249
|
+
ExpressResponse,
|
|
250
|
+
ExpressNextFunction,
|
|
251
|
+
ExpressApp,
|
|
252
|
+
ExpressRouter,
|
|
253
|
+
// Express-compatible types (can be used without importing express)
|
|
254
|
+
PluginRequest,
|
|
255
|
+
PluginResponse,
|
|
256
|
+
PluginNextFunction,
|
|
257
|
+
PluginApp,
|
|
258
|
+
PluginRouter,
|
|
259
|
+
// Service interfaces
|
|
260
|
+
ServiceOptions,
|
|
261
|
+
IItemsService,
|
|
262
|
+
IPermissionService,
|
|
263
|
+
IMailService,
|
|
264
|
+
IStorageService,
|
|
265
|
+
ISettingsService,
|
|
266
|
+
ISocketService,
|
|
267
|
+
IRealtimeService,
|
|
268
|
+
ITasksService,
|
|
269
|
+
IWorkflowService,
|
|
270
|
+
IMigrationService,
|
|
271
|
+
IHooksManager,
|
|
272
|
+
HookFunction,
|
|
273
|
+
ICacheService,
|
|
274
|
+
IFilesService,
|
|
275
|
+
IAssetsService,
|
|
276
|
+
INotificationService,
|
|
277
|
+
IReportService,
|
|
278
|
+
IStatsService,
|
|
279
|
+
// Plugin types
|
|
280
|
+
PluginType,
|
|
281
|
+
PluginMeta,
|
|
282
|
+
PluginSchemaDefinition,
|
|
283
|
+
PluginRouteContext,
|
|
284
|
+
PluginRouteHandler,
|
|
285
|
+
PluginRoute,
|
|
286
|
+
PluginHookEvent,
|
|
287
|
+
PluginHookContext,
|
|
288
|
+
PluginHookHandler,
|
|
289
|
+
PluginHook,
|
|
290
|
+
PluginContext,
|
|
291
|
+
PluginServiceFactory,
|
|
292
|
+
PluginService,
|
|
293
|
+
AuthProviderType,
|
|
294
|
+
OAuth2Config,
|
|
295
|
+
PluginAuthProvider,
|
|
296
|
+
PluginMiddleware,
|
|
297
|
+
PluginSchedule,
|
|
298
|
+
PluginDefinition,
|
|
299
|
+
PluginFactory,
|
|
300
|
+
BaasixPlugin,
|
|
301
|
+
LoadedPlugin,
|
|
302
|
+
PluginManagerOptions,
|
|
303
|
+
StartServerOptions,
|
|
304
|
+
// Express-typed plugin types (for core package)
|
|
305
|
+
ExpressPluginRouteHandler,
|
|
306
|
+
ExpressPluginRoute,
|
|
307
|
+
ExpressPluginMiddleware,
|
|
308
|
+
ExpressPluginContext,
|
|
309
|
+
} from "./plugin";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification Types
|
|
3
|
+
* Shared across core, sdk, and app packages
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Notification Types
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Notification type
|
|
12
|
+
*/
|
|
13
|
+
export type NotificationType = "info" | "success" | "warning" | "error" | string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Notification
|
|
17
|
+
*/
|
|
18
|
+
export interface Notification {
|
|
19
|
+
id: string;
|
|
20
|
+
type: NotificationType;
|
|
21
|
+
title: string;
|
|
22
|
+
message: string;
|
|
23
|
+
data?: Record<string, unknown>;
|
|
24
|
+
seen: boolean;
|
|
25
|
+
user_Id: string;
|
|
26
|
+
tenant_Id?: string;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Notification options (for creating)
|
|
33
|
+
*/
|
|
34
|
+
export interface NotificationOptions {
|
|
35
|
+
type?: NotificationType;
|
|
36
|
+
title: string;
|
|
37
|
+
message: string;
|
|
38
|
+
data?: Record<string, unknown>;
|
|
39
|
+
userIds?: string[];
|
|
40
|
+
tenant_Id?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Send notification data
|
|
45
|
+
*/
|
|
46
|
+
export interface SendNotificationData {
|
|
47
|
+
type?: NotificationType;
|
|
48
|
+
title: string;
|
|
49
|
+
message: string;
|
|
50
|
+
data?: Record<string, unknown>;
|
|
51
|
+
userIds: string[];
|
|
52
|
+
}
|