@hiliosai/sdk 0.1.11 → 0.1.14

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 (52) hide show
  1. package/dist/index.d.ts +904 -0
  2. package/dist/index.js +1809 -0
  3. package/package.json +12 -7
  4. package/src/configs/constants.ts +0 -135
  5. package/src/configs/index.ts +0 -2
  6. package/src/configs/moleculer/bulkhead.ts +0 -8
  7. package/src/configs/moleculer/channels.ts +0 -102
  8. package/src/configs/moleculer/circuit-breaker.ts +0 -17
  9. package/src/configs/moleculer/index.ts +0 -85
  10. package/src/configs/moleculer/logger.ts +0 -17
  11. package/src/configs/moleculer/metrics.ts +0 -20
  12. package/src/configs/moleculer/registry.ts +0 -7
  13. package/src/configs/moleculer/retry-policy.ts +0 -17
  14. package/src/configs/moleculer/tracing.ts +0 -6
  15. package/src/configs/moleculer/tracking.ts +0 -6
  16. package/src/configs/permissions.ts +0 -109
  17. package/src/datasources/base.datasource.ts +0 -111
  18. package/src/datasources/extensions/index.ts +0 -11
  19. package/src/datasources/extensions/retry.extension.ts +0 -91
  20. package/src/datasources/extensions/soft-delete.extension.ts +0 -113
  21. package/src/datasources/extensions/tenant.extension.ts +0 -104
  22. package/src/datasources/index.ts +0 -3
  23. package/src/datasources/prisma.datasource.ts +0 -317
  24. package/src/env.ts +0 -12
  25. package/src/errors/auth.error.ts +0 -33
  26. package/src/errors/index.ts +0 -2
  27. package/src/errors/permission.error.ts +0 -17
  28. package/src/index.ts +0 -9
  29. package/src/middlewares/context-helpers.middleware.ts +0 -162
  30. package/src/middlewares/datasource.middleware.ts +0 -73
  31. package/src/middlewares/health.middleware.ts +0 -134
  32. package/src/middlewares/index.ts +0 -5
  33. package/src/middlewares/memoize.middleware.ts +0 -33
  34. package/src/middlewares/permissions.middleware.ts +0 -162
  35. package/src/mixins/datasource.mixin.ts +0 -111
  36. package/src/mixins/index.ts +0 -1
  37. package/src/service/define-integration.ts +0 -404
  38. package/src/service/define-service.ts +0 -61
  39. package/src/types/channels.ts +0 -60
  40. package/src/types/context.ts +0 -64
  41. package/src/types/datasource.ts +0 -23
  42. package/src/types/index.ts +0 -9
  43. package/src/types/integration.ts +0 -28
  44. package/src/types/message.ts +0 -128
  45. package/src/types/platform.ts +0 -39
  46. package/src/types/service.ts +0 -209
  47. package/src/types/tenant.ts +0 -4
  48. package/src/types/user.ts +0 -16
  49. package/src/utils/context-cache.ts +0 -70
  50. package/src/utils/permission-calculator.ts +0 -62
  51. package/tsconfig.json +0 -13
  52. package/tsup.config.ts +0 -6
@@ -0,0 +1,904 @@
1
+ import { Context, ServiceBroker, ServiceSchema as ServiceSchema$1, ServiceSettingSchema, Service, BrokerOptions, ActionSchema, ServiceEvents, ServiceMethods, ServiceHooks } from 'moleculer';
2
+ import env from '@ltv/env';
3
+ export { default as env } from '@ltv/env';
4
+
5
+ interface Tenant {
6
+ id: string;
7
+ name: string;
8
+ }
9
+
10
+ declare const UserRole: {
11
+ readonly OWNER: "OWNER";
12
+ readonly ADMIN: "ADMIN";
13
+ readonly MANAGER: "MANAGER";
14
+ readonly AGENT: "AGENT";
15
+ readonly VIEWER: "VIEWER";
16
+ };
17
+ interface User {
18
+ id: string;
19
+ email: string;
20
+ roles: string[];
21
+ permissions: string[];
22
+ tenantId: string;
23
+ name: string;
24
+ }
25
+
26
+ interface ChannelSendOptions {
27
+ group?: string;
28
+ maxInFlight?: number;
29
+ maxRetries?: number;
30
+ deadLettering?: {
31
+ enabled?: boolean;
32
+ queueName?: string;
33
+ };
34
+ }
35
+ interface SendToChannelMethod {
36
+ (channelName: string, payload: unknown, options?: ChannelSendOptions): Promise<void>;
37
+ }
38
+ interface AppMeta {
39
+ user?: User;
40
+ tenantId?: string;
41
+ tenantName?: string;
42
+ userId?: string;
43
+ channelId?: string;
44
+ requestId?: string;
45
+ userAgent?: string;
46
+ clientIP?: string;
47
+ [key: string]: unknown;
48
+ }
49
+ interface PermissionHelpers {
50
+ hasPermission(permission: string): boolean;
51
+ hasRole(role: string): boolean;
52
+ isTenantMember(): boolean;
53
+ isTenantOwner(): boolean;
54
+ ensureUser(): User;
55
+ ensureTenant(): Tenant;
56
+ getUserPermissions(): Promise<string[]>;
57
+ auditLog(action: string, resource?: unknown, metadata?: Record<string, unknown>): void;
58
+ createError(message: string, code: string, statusCode?: number): Error;
59
+ }
60
+ type AppContext<TDatasources = unknown, TParams = unknown, TMeta extends AppMeta = AppMeta, TLocals = unknown> = Context<TParams, TMeta, TLocals> & PermissionHelpers & {
61
+ datasources: TDatasources;
62
+ broker: Context['broker'] & {
63
+ sendToChannel: SendToChannelMethod;
64
+ };
65
+ };
66
+
67
+ /**
68
+ * Base datasource interface that all datasources should implement
69
+ * Provides common structure and optional lifecycle methods
70
+ */
71
+ interface BaseDatasource<TContext = AppContext> {
72
+ /**
73
+ * Datasource name for identification and logging
74
+ */
75
+ readonly name: string;
76
+ /**
77
+ * Service broker instance for logging, events, and service calls
78
+ * Always available after datasource initialization
79
+ */
80
+ broker: ServiceBroker;
81
+ /**
82
+ * Current service context (only available during action execution)
83
+ * Will be undefined in lifecycle hooks or background tasks
84
+ */
85
+ context?: TContext;
86
+ /**
87
+ * Optional initialization method
88
+ * Called when datasource is instantiated
89
+ */
90
+ init?(): Promise<void> | void;
91
+ /**
92
+ * Optional connection method
93
+ * Called when service starts if implemented
94
+ */
95
+ connect?(): Promise<void> | void;
96
+ /**
97
+ * Optional disconnection method
98
+ * Called when service stops if implemented
99
+ */
100
+ disconnect?(): Promise<void> | void;
101
+ /**
102
+ * Optional health check method
103
+ * Can be used to verify datasource is working correctly
104
+ */
105
+ healthCheck?(): Promise<boolean> | boolean;
106
+ /**
107
+ * Optional method to clear/reset the datasource
108
+ */
109
+ clear?(): Promise<void> | void;
110
+ }
111
+ /**
112
+ * Abstract base class for datasources that provides default implementations
113
+ * @example
114
+ * ```typescript
115
+ * export class UserDatasource extends AbstractDatasource {
116
+ * readonly name = 'users';
117
+ *
118
+ * private users: User[] = [];
119
+ *
120
+ * async findById(id: string): Promise<User | undefined> {
121
+ * this.broker?.logger.info('Finding user by ID:', id);
122
+ * return this.users.find(u => u.id === id);
123
+ * }
124
+ *
125
+ * async healthCheck(): Promise<boolean> {
126
+ * this.broker?.logger.info('Health check for datasource', this.name);
127
+ * return true;
128
+ * }
129
+ * }
130
+ * ```
131
+ */
132
+ declare abstract class AbstractDatasource<TContext = AppContext> implements BaseDatasource<TContext> {
133
+ abstract readonly name: string;
134
+ /**
135
+ * Service broker instance - injected by mixin
136
+ * Always available after initialization
137
+ */
138
+ broker: ServiceBroker;
139
+ /**
140
+ * Current service context - injected per action
141
+ * Only available during action execution
142
+ */
143
+ context?: TContext;
144
+ /**
145
+ * Default health check - always returns true
146
+ * Override for custom health check logic
147
+ */
148
+ healthCheck(): Promise<boolean>;
149
+ /**
150
+ * Default clear method - does nothing
151
+ * Override to implement clearing logic
152
+ */
153
+ clear(): Promise<void>;
154
+ }
155
+
156
+ interface PrismaClientLike {
157
+ $connect(): Promise<void>;
158
+ $disconnect(): Promise<void>;
159
+ $queryRaw: any;
160
+ $transaction: any;
161
+ $extends: any;
162
+ [key: string]: any;
163
+ }
164
+ interface SoftDeleteExtension {
165
+ softDelete: {
166
+ [model: string]: {
167
+ delete: (args: any) => Promise<any>;
168
+ deleteMany: (args: any) => Promise<any>;
169
+ restore: (args: any) => Promise<any>;
170
+ };
171
+ };
172
+ }
173
+ interface AuditTrailExtension {
174
+ $auditTrail: {
175
+ getHistory: (model: string, id: string) => Promise<any[]>;
176
+ getChanges: (model: string, id: string, from?: Date, to?: Date) => Promise<any[]>;
177
+ };
178
+ }
179
+ interface TenantExtension {
180
+ $tenant: {
181
+ setContext: (tenantId: string) => void;
182
+ getCurrentTenant: () => string | null;
183
+ };
184
+ }
185
+ declare global {
186
+ var __prisma: PrismaClientLike | undefined;
187
+ }
188
+ /**
189
+ * Prisma datasource that follows singleton pattern and best practices
190
+ * Supports both provided client instances and automatic initialization
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * // Option 1: Let datasource create singleton client
195
+ * datasources: {
196
+ * prisma: PrismaDatasource
197
+ * }
198
+ *
199
+ * // Option 2: Provide custom client
200
+ * const customClient = new PrismaClient({...});
201
+ * datasources: {
202
+ * prisma: () => new PrismaDatasource(customClient)
203
+ * }
204
+ * ```
205
+ */
206
+ declare class PrismaDatasource<TPrismaClient extends PrismaClientLike = PrismaClientLike, TContext = AppContext> extends AbstractDatasource<TContext> {
207
+ readonly name = "prisma";
208
+ private _client;
209
+ private providedClient;
210
+ constructor(prismaClient?: TPrismaClient);
211
+ /**
212
+ * Get Prisma client instance (singleton pattern)
213
+ */
214
+ get client(): TPrismaClient;
215
+ /**
216
+ * Initialize Prisma client using singleton pattern or provided instance
217
+ */
218
+ private initializePrismaClient;
219
+ /**
220
+ * Create a new Prisma client instance
221
+ * Override this method in subclasses to provide the actual PrismaClient
222
+ */
223
+ protected createClient(): TPrismaClient;
224
+ /**
225
+ * Apply extensions to the Prisma client
226
+ * Override this method to add production extensions like soft delete, audit trails, etc.
227
+ */
228
+ protected applyExtensions(client: TPrismaClient): TPrismaClient;
229
+ /**
230
+ * Get extended client with all applied extensions
231
+ */
232
+ get extendedClient(): TPrismaClient;
233
+ /**
234
+ * Initialize datasource - called after broker injection
235
+ */
236
+ init(): Promise<void>;
237
+ /**
238
+ * Called automatically when context is injected
239
+ * Sets tenant context from service context if available
240
+ */
241
+ private updateTenantFromContext;
242
+ /**
243
+ * Connect to database - called when service starts
244
+ */
245
+ connect(): Promise<void>;
246
+ /**
247
+ * Disconnect from database - called when service stops
248
+ */
249
+ disconnect(): Promise<void>;
250
+ /**
251
+ * Health check - verify database connectivity
252
+ */
253
+ healthCheck(): Promise<boolean>;
254
+ /**
255
+ * Clear/reset data - useful for testing
256
+ */
257
+ clear(): Promise<void>;
258
+ /**
259
+ * Transaction wrapper with proper error handling
260
+ */
261
+ transaction<T>(fn: (tx: TPrismaClient) => Promise<T>, options?: {
262
+ maxWait?: number;
263
+ timeout?: number;
264
+ }): Promise<T>;
265
+ /**
266
+ * Set tenant context for multi-tenant applications
267
+ * Requires tenant extension to be applied
268
+ */
269
+ setTenantContext(tenantId: string): void;
270
+ /**
271
+ * Get current tenant context
272
+ */
273
+ getCurrentTenant(): string | null;
274
+ /**
275
+ * Execute with tenant context (automatically restores previous context)
276
+ */
277
+ withTenant<T>(tenantId: string, fn: () => Promise<T>): Promise<T>;
278
+ }
279
+
280
+ /**
281
+ * Soft Delete Extension for Prisma
282
+ * Automatically handles soft deletes by setting deletedAt instead of removing records
283
+ *
284
+ * Usage:
285
+ * ```typescript
286
+ * import { softDeleteExtension } from './extensions/soft-delete.extension';
287
+ *
288
+ * class MyPrismaDS extends PrismaDatasource<PrismaClient> {
289
+ * protected applyExtensions(client: PrismaClient) {
290
+ * return client.$extends(softDeleteExtension);
291
+ * }
292
+ * }
293
+ * ```
294
+ *
295
+ * Requires models to have `deletedAt DateTime?` field
296
+ */
297
+ declare const softDeleteExtension: {
298
+ name: string;
299
+ query: {
300
+ $allModels: {
301
+ findMany({ args, query }: any): Promise<any>;
302
+ findUnique({ args, query }: any): Promise<any>;
303
+ findFirst({ args, query }: any): Promise<any>;
304
+ delete({ args, query }: any): Promise<any>;
305
+ deleteMany({ args, query }: any): Promise<any>;
306
+ };
307
+ };
308
+ model: {
309
+ $allModels: {
310
+ restore<T>(this: T, where: any): Promise<any>;
311
+ findWithDeleted<T>(this: T, args: any): Promise<any>;
312
+ findDeleted<T>(this: T, args: any): Promise<any>;
313
+ };
314
+ };
315
+ };
316
+
317
+ /**
318
+ * Multi-Tenant Extension for Prisma
319
+ * Automatically filters queries by tenant context for multi-tenant applications
320
+ *
321
+ * Usage:
322
+ * ```typescript
323
+ * import { createTenantExtension } from './extensions/tenant.extension';
324
+ *
325
+ * class MyPrismaDS extends PrismaDatasource<PrismaClient> {
326
+ * protected applyExtensions(client: PrismaClient) {
327
+ * return client.$extends(createTenantExtension());
328
+ * }
329
+ * }
330
+ * ```
331
+ *
332
+ * Requires models to have `tenantId String` field
333
+ */
334
+ declare function createTenantExtension(): {
335
+ name: string;
336
+ client: {
337
+ $setTenant(tenantId: string): void;
338
+ $getCurrentTenant(): string | null;
339
+ $clearTenant(): void;
340
+ };
341
+ query: {
342
+ $allModels: {
343
+ findMany({ args, query }: any): Promise<any>;
344
+ findUnique({ args, query }: any): Promise<any>;
345
+ findFirst({ args, query }: any): Promise<any>;
346
+ create({ args, query }: any): Promise<any>;
347
+ update({ args, query }: any): Promise<any>;
348
+ delete({ args, query }: any): Promise<any>;
349
+ };
350
+ };
351
+ };
352
+
353
+ /**
354
+ * Retry Extension for Prisma Transactions
355
+ * Automatically retries failed transactions with exponential backoff
356
+ *
357
+ * Usage:
358
+ * ```typescript
359
+ * import { retryExtension } from './extensions/retry.extension';
360
+ *
361
+ * class MyPrismaDS extends PrismaDatasource<PrismaClient> {
362
+ * protected applyExtensions(client: PrismaClient) {
363
+ * return client.$extends(retryExtension);
364
+ * }
365
+ * }
366
+ * ```
367
+ */
368
+ declare const retryExtension: {
369
+ name: string;
370
+ client: {
371
+ $retryTransaction<T>(fn: (tx: any) => Promise<T>, options?: {
372
+ maxRetries?: number;
373
+ baseDelay?: number;
374
+ maxDelay?: number;
375
+ retryableErrors?: string[];
376
+ }): Promise<T>;
377
+ };
378
+ };
379
+
380
+ /**
381
+ * Datasource constructor registry type
382
+ * All datasources should implement BaseDatasource interface
383
+ */
384
+ interface DatasourceConstructorRegistry {
385
+ [key: string]: new () => BaseDatasource | object;
386
+ }
387
+ /**
388
+ * Datasource instance registry type
389
+ */
390
+ interface DatasourceInstanceRegistry {
391
+ [key: string]: object;
392
+ }
393
+ /**
394
+ * Datasource context extension
395
+ */
396
+ interface DatasourceContext extends Context {
397
+ datasources: DatasourceInstanceRegistry;
398
+ }
399
+ /**
400
+ * Datasource middleware that injects datasources into the context
401
+ */
402
+ declare function createDatasourceMiddleware(datasources: DatasourceConstructorRegistry): {
403
+ localAction(handler: (...args: unknown[]) => unknown): (this: unknown, ctx: Context) => unknown;
404
+ remoteAction(handler: (...args: unknown[]) => unknown): (this: unknown, ctx: Context) => unknown;
405
+ };
406
+ /**
407
+ * Type helper for services that use datasources
408
+ */
409
+ type ServiceWithDatasources<T extends DatasourceInstanceRegistry> = {
410
+ datasources: T;
411
+ };
412
+
413
+ interface MemoizeMixinOptions {
414
+ ttl?: number;
415
+ }
416
+ declare function MemoizeMixin(options?: MemoizeMixinOptions): ServiceSchema$1<ServiceSettingSchema>;
417
+
418
+ interface HealthCheckOptions {
419
+ port?: number;
420
+ readiness?: {
421
+ path?: string;
422
+ };
423
+ liveness?: {
424
+ path?: string;
425
+ };
426
+ }
427
+ declare const HEALTH_CHECK_DEFAULTS: {
428
+ readonly PORT: number;
429
+ readonly READINESS_PATH: string;
430
+ readonly LIVENESS_PATH: string;
431
+ };
432
+ declare function CreateHealthCheckMiddleware(opts?: HealthCheckOptions): {
433
+ created(broker: Service): void;
434
+ started(): void;
435
+ stopping(): void;
436
+ stopped(): void;
437
+ };
438
+
439
+ declare const PERMISSIONS: {
440
+ readonly AUTHENTICATED: "authenticated";
441
+ readonly OWNER: "OWNER";
442
+ readonly ADMIN: "ADMIN";
443
+ readonly MANAGER: "MANAGER";
444
+ readonly AGENT: "AGENT";
445
+ readonly VIEWER: "VIEWER";
446
+ readonly DEVELOPER: "DEVELOPER";
447
+ readonly TENANT_OWNER: "tenant.owner";
448
+ readonly TENANT_MEMBER: "tenant.member";
449
+ readonly 'users.read': "users.read";
450
+ readonly 'users.write': "users.write";
451
+ readonly 'users.delete': "users.delete";
452
+ readonly 'tenants.read': "tenants.read";
453
+ readonly 'tenants.write': "tenants.write";
454
+ readonly 'tenants.delete': "tenants.delete";
455
+ readonly 'conversations.read': "conversations.read";
456
+ readonly 'conversations.write': "conversations.write";
457
+ readonly 'conversations.delete': "conversations.delete";
458
+ readonly 'messages.read': "messages.read";
459
+ readonly 'messages.write': "messages.write";
460
+ readonly 'settings.read': "settings.read";
461
+ readonly 'settings.write': "settings.write";
462
+ readonly 'config.read': "config.read";
463
+ readonly 'config.write': "config.write";
464
+ readonly 'billing.read': "billing.read";
465
+ readonly 'billing.write': "billing.write";
466
+ };
467
+ declare const ROLE_PERMISSIONS: Record<string, string[]>;
468
+
469
+ declare const configs: BrokerOptions;
470
+
471
+ declare enum IntegrationPlatform {
472
+ WHATSAPP = "whatsapp",
473
+ TELEGRAM = "telegram",
474
+ SLACK = "slack",
475
+ EMAIL = "email",
476
+ SMS = "sms",
477
+ INSTAGRAM = "instagram",
478
+ FACEBOOK = "facebook",
479
+ DISCORD = "discord",
480
+ WEBCHAT = "webchat",
481
+ CUSTOM = "custom"
482
+ }
483
+ declare enum IntegrationStatus {
484
+ CONFIGURED = "CONFIGURED",
485
+ ACTIVE = "ACTIVE",
486
+ INACTIVE = "INACTIVE",
487
+ ERROR = "ERROR",
488
+ SUSPENDED = "SUSPENDED"
489
+ }
490
+ declare enum IntegrationCapability {
491
+ SEND_MESSAGE = "send_message",
492
+ RECEIVE_MESSAGE = "receive_message",
493
+ SEND_IMAGE = "send_image",
494
+ SEND_VIDEO = "send_video",
495
+ SEND_AUDIO = "send_audio",
496
+ SEND_FILE = "send_file",
497
+ SEND_LOCATION = "send_location",
498
+ SEND_BUTTONS = "send_buttons",
499
+ SEND_CAROUSEL = "send_carousel",
500
+ TYPING_INDICATOR = "typing_indicator",
501
+ READ_RECEIPT = "read_receipt",
502
+ GROUP_CHAT = "group_chat",
503
+ REACTIONS = "reactions",
504
+ THREADS = "threads",
505
+ VOICE_CALL = "voice_call",
506
+ VIDEO_CALL = "video_call"
507
+ }
508
+
509
+ interface MessageParticipant {
510
+ id: string;
511
+ name?: string;
512
+ avatar?: string;
513
+ metadata?: Record<string, any>;
514
+ }
515
+ declare enum MessageContentType {
516
+ TEXT = "text",
517
+ IMAGE = "image",
518
+ VIDEO = "video",
519
+ AUDIO = "audio",
520
+ FILE = "file",
521
+ LOCATION = "location",
522
+ BUTTONS = "buttons",
523
+ CAROUSEL = "carousel",
524
+ REACTION = "reaction"
525
+ }
526
+ interface MessageContent {
527
+ type: MessageContentType;
528
+ text?: string;
529
+ media?: {
530
+ url: string;
531
+ mimeType?: string;
532
+ size?: number;
533
+ thumbnail?: string;
534
+ };
535
+ location?: {
536
+ latitude: number;
537
+ longitude: number;
538
+ address?: string;
539
+ };
540
+ buttons?: MessageButton[];
541
+ carousel?: CarouselItem[];
542
+ reaction?: {
543
+ emoji: string;
544
+ messageId: string;
545
+ };
546
+ metadata?: Record<string, any>;
547
+ }
548
+ interface MessageButton {
549
+ id: string;
550
+ text: string;
551
+ type: 'postback' | 'url' | 'call';
552
+ payload?: string;
553
+ url?: string;
554
+ phoneNumber?: string;
555
+ }
556
+ interface CarouselItem {
557
+ title: string;
558
+ subtitle?: string;
559
+ imageUrl?: string;
560
+ buttons?: MessageButton[];
561
+ }
562
+ type MessageDirection = 'incoming' | 'outgoing' | 'internal';
563
+ type MessageType = 'text' | 'image' | 'file' | 'audio' | 'video' | 'location' | 'contact' | 'sticker' | 'template';
564
+ type MessageStatus = 'pending' | 'sent' | 'delivered' | 'read' | 'failed';
565
+ interface Message {
566
+ id: string;
567
+ conversationId: string;
568
+ from: MessageParticipant;
569
+ to: MessageParticipant;
570
+ content: MessageContent;
571
+ direction: MessageDirection;
572
+ type: MessageType;
573
+ status: MessageStatus;
574
+ timestamp: number;
575
+ platform: IntegrationPlatform;
576
+ replyTo?: string;
577
+ threadId?: string;
578
+ attachments?: MessageAttachment[];
579
+ metadata?: Record<string, any>;
580
+ }
581
+ interface MessageAttachment {
582
+ id: string;
583
+ name: string;
584
+ type: string;
585
+ size: number;
586
+ url: string;
587
+ thumbnail?: string;
588
+ metadata?: Record<string, any>;
589
+ }
590
+ interface PlatformMessage<P = any> {
591
+ platform: IntegrationPlatform;
592
+ payload: P;
593
+ }
594
+ interface WebhookEvent<TPayload = any> {
595
+ tenantId: string;
596
+ channelId: string;
597
+ platform: IntegrationPlatform;
598
+ payload: TPayload;
599
+ headers: Record<string, string>;
600
+ timestamp: number;
601
+ }
602
+ interface SendResult {
603
+ success: boolean;
604
+ messageId?: string;
605
+ error?: Error;
606
+ metadata?: Record<string, any>;
607
+ }
608
+
609
+ interface BaseSpec {
610
+ id: string;
611
+ name: string;
612
+ platform: IntegrationPlatform;
613
+ version: string;
614
+ status: IntegrationStatus;
615
+ capabilities: IntegrationCapability[];
616
+ description?: string;
617
+ icon?: string;
618
+ documentationUrl?: string;
619
+ }
620
+ interface IntegrationConfig {
621
+ id: string;
622
+ tenantId: string;
623
+ name: string;
624
+ version: string;
625
+ config: Record<string, unknown>;
626
+ credentials: Record<string, string>;
627
+ createdAt?: Date;
628
+ updatedAt?: Date;
629
+ }
630
+
631
+ /**
632
+ * Utility types for datasources
633
+ */
634
+ /**
635
+ * Extract instance types from a datasource constructor registry
636
+ *
637
+ * @example
638
+ * ```typescript
639
+ * const datasources = {
640
+ * user: UserDatasource,
641
+ * whatsapp: WhatsAppDatasource,
642
+ * };
643
+ *
644
+ * type MyDatasources = DatasourceInstanceTypes<typeof datasources>;
645
+ * // Results in: { user: UserDatasource; whatsapp: WhatsAppDatasource; }
646
+ * ```
647
+ */
648
+ type DatasourceInstanceTypes<T extends Record<string, new (...args: unknown[]) => unknown>> = {
649
+ [K in keyof T]: InstanceType<T[K]>;
650
+ };
651
+
652
+ type InferParamsType<T> = T extends Record<string, any> ? {
653
+ [K in keyof T]: T[K] extends 'string' ? string : T[K] extends 'number' ? number : T[K] extends 'boolean' ? boolean : T[K] extends 'array' ? any[] : T[K] extends 'object' ? Record<string, any> : T[K] extends {
654
+ type: 'string';
655
+ } ? string : T[K] extends {
656
+ type: 'number';
657
+ } ? number : T[K] extends {
658
+ type: 'boolean';
659
+ } ? boolean : T[K] extends {
660
+ type: 'array';
661
+ } ? any[] : T[K] extends {
662
+ type: 'object';
663
+ } ? Record<string, any> : unknown;
664
+ } : unknown;
665
+ type ActionSchemaWithContext<TDatasources = unknown, TParams = unknown> = Pick<ActionSchema, 'name' | 'rest' | 'visibility' | 'service' | 'cache' | 'tracing' | 'bulkhead' | 'circuitBreaker' | 'retryPolicy' | 'fallback' | 'hooks'> & {
666
+ params?: TParams;
667
+ handler: (ctx: AppContext<TDatasources, InferParamsType<TParams>>) => Promise<unknown> | unknown;
668
+ permissions?: string | string[];
669
+ };
670
+ type ActionHandler<TDatasources = unknown> = (ctx: AppContext<TDatasources>) => Promise<unknown> | unknown;
671
+ type ServiceActionsSchema<TDatasources = unknown> = {
672
+ [key: string]: ({
673
+ params?: any;
674
+ handler: (ctx: AppContext<TDatasources, any>) => Promise<unknown> | unknown;
675
+ permissions?: string | string[];
676
+ } & Pick<ActionSchema, 'name' | 'rest' | 'visibility' | 'service' | 'cache' | 'tracing' | 'bulkhead' | 'circuitBreaker' | 'retryPolicy' | 'fallback' | 'hooks'>) | ActionHandler<TDatasources> | false;
677
+ };
678
+ interface ServiceSchema<TSettings = unknown, TDatasources = unknown> extends Omit<ServiceSchema$1<TSettings>, 'actions'> {
679
+ name: string;
680
+ version?: string | number;
681
+ settings?: TSettings;
682
+ actions?: ServiceActionsSchema<TDatasources>;
683
+ events?: ServiceEvents;
684
+ methods?: ServiceMethods;
685
+ hooks?: ServiceHooks;
686
+ dependencies?: string | string[];
687
+ metadata?: Record<string, any>;
688
+ created?: (this: ServiceSchema$1<TSettings>) => void | Promise<void>;
689
+ started?: (this: ServiceSchema$1<TSettings>) => void | Promise<void>;
690
+ stopped?: (this: ServiceSchema$1<TSettings>) => void | Promise<void>;
691
+ }
692
+ type ServiceConfig<TSettings = unknown, TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry> = ServiceSchema<TSettings, DatasourceInstanceTypes<TDatasourceConstructors>> & {
693
+ datasources: TDatasourceConstructors;
694
+ };
695
+ interface IntegrationServiceConfig<TSettings = unknown, TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry, TContext extends AppContext<DatasourceInstanceTypes<TDatasourceConstructors>> = AppContext<DatasourceInstanceTypes<TDatasourceConstructors>>> extends ServiceConfig<TSettings, TDatasourceConstructors> {
696
+ name: string;
697
+ spec: BaseSpec;
698
+ normalize<TPayload = any>(webhook: WebhookEvent<TPayload>): Promise<Message[]>;
699
+ getChannelConfig(ctx: TContext, channelId: string): Promise<IntegrationConfig | null>;
700
+ validateWebhook?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
701
+ sendMessage(ctx: TContext, message: Message, config: IntegrationConfig): Promise<SendResult>;
702
+ verifyWebhook?(params: {
703
+ mode: string;
704
+ token: string;
705
+ challenge: string;
706
+ }): string | null;
707
+ checkHealth?(ctx: TContext, config: IntegrationConfig): Promise<{
708
+ status: 'healthy' | 'unhealthy' | 'degraded';
709
+ message?: string;
710
+ details?: Record<string, any>;
711
+ }>;
712
+ validateCredentials?(credentials: Record<string, string>): Promise<boolean>;
713
+ validateSignature?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
714
+ }
715
+ interface IntegrationServiceSchema<TSettings = unknown> extends ServiceSchema$1<TSettings> {
716
+ spec: BaseSpec;
717
+ normalize<TPayload = any>(webhook: WebhookEvent<TPayload>): Promise<Message[]>;
718
+ getChannelConfig(ctx: AppContext, channelId: string): Promise<IntegrationConfig | null>;
719
+ validateWebhook?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
720
+ sendMessage(ctx: AppContext, message: Message, config: IntegrationConfig): Promise<SendResult>;
721
+ verifyWebhook?(params: {
722
+ mode: string;
723
+ token: string;
724
+ challenge: string;
725
+ }): string | null;
726
+ checkHealth?(ctx: AppContext, config: IntegrationConfig): Promise<{
727
+ status: 'healthy' | 'unhealthy' | 'degraded';
728
+ message?: string;
729
+ details?: Record<string, any>;
730
+ }>;
731
+ validateCredentials?(credentials: Record<string, string>): Promise<boolean>;
732
+ validateSignature?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
733
+ }
734
+
735
+ /**
736
+ * Base namespace for all channels
737
+ */
738
+ declare const NAMESPACE: string;
739
+ declare const CHANNELS: {
740
+ readonly WEBHOOK: {
741
+ readonly PATTERN: `${string}.webhook.*.*`;
742
+ readonly PREFIX: `${string}.webhook`;
743
+ readonly build: (tenantId: string, platform: string) => string;
744
+ };
745
+ readonly PROCESSING: {
746
+ readonly PATTERN: `${string}.processing.*.*`;
747
+ readonly PREFIX: `${string}.processing`;
748
+ readonly build: (tenantId: string, messageType: string) => string;
749
+ };
750
+ readonly RESPONSE: {
751
+ readonly PATTERN: `${string}.response.*.*`;
752
+ readonly PREFIX: `${string}.response`;
753
+ readonly build: (tenantId: string, platform: string) => string;
754
+ };
755
+ readonly SYSTEM: {
756
+ readonly ERRORS: `${string}.system.errors`;
757
+ readonly METRICS: `${string}.system.metrics`;
758
+ readonly HEALTH: `${string}.system.health`;
759
+ readonly INTEGRATION_REGISTERED: `${string}.system.integration.registered`;
760
+ readonly INTEGRATION_UNREGISTERED: `${string}.system.integration.unregistered`;
761
+ };
762
+ readonly DLQ: {
763
+ readonly WEBHOOK_FAILED: `${string}.dlq.webhook.failed`;
764
+ readonly SEND_FAILED: `${string}.dlq.send.failed`;
765
+ readonly PROCESSING_FAILED: `${string}.dlq.processing.failed`;
766
+ readonly buildSendFailed: (platform: string) => string;
767
+ };
768
+ };
769
+ /**
770
+ * Integration-specific channel names
771
+ */
772
+ declare const INTEGRATION_CHANNELS: {
773
+ readonly MESSAGE_RECEIVED: `${string}.processing.message.received`;
774
+ readonly MESSAGE_SENT: `${string}.processing.message.sent`;
775
+ readonly MESSAGE_FAILED: `${string}.processing.message.failed`;
776
+ };
777
+ type IntegrationChannelName = (typeof INTEGRATION_CHANNELS)[keyof typeof INTEGRATION_CHANNELS];
778
+
779
+ /**
780
+ * Channel event payload types for reliable messaging via @moleculer/channels
781
+ */
782
+ interface IntegrationMessageReceivedPayload {
783
+ tenantId: string;
784
+ channelId: string;
785
+ platform: IntegrationPlatform;
786
+ message: Message;
787
+ timestamp: number;
788
+ metadata?: Record<string, unknown>;
789
+ }
790
+ interface IntegrationMessageSentPayload {
791
+ tenantId: string;
792
+ channelId: string;
793
+ platform: IntegrationPlatform;
794
+ messageId?: string;
795
+ metadata?: Record<string, unknown>;
796
+ timestamp: number;
797
+ }
798
+ interface IntegrationMessageFailedPayload {
799
+ tenantId: string;
800
+ channelId: string;
801
+ platform: IntegrationPlatform;
802
+ error: string;
803
+ message?: Message;
804
+ timestamp: number;
805
+ retryCount?: number;
806
+ metadata?: Record<string, unknown>;
807
+ }
808
+ interface IntegrationRegisteredPayload {
809
+ tenantId: string;
810
+ channelId: string;
811
+ platform: IntegrationPlatform;
812
+ config: Record<string, unknown>;
813
+ timestamp: number;
814
+ }
815
+ interface IntegrationUnregisteredPayload {
816
+ tenantId: string;
817
+ channelId: string;
818
+ platform: IntegrationPlatform;
819
+ timestamp: number;
820
+ }
821
+
822
+ type Permission = keyof typeof PERMISSIONS | string | ((ctx: AppContext, action: ActionSchema) => Promise<boolean> | boolean);
823
+ interface ActionWithPermissions extends ActionSchema {
824
+ permissions?: Permission | Permission[];
825
+ }
826
+ declare const PermissionsMiddleware: {
827
+ localAction(handler: (...args: unknown[]) => unknown, action: ActionWithPermissions): ((...args: unknown[]) => unknown) | ((this: Service, ctx: AppContext) => Promise<unknown>);
828
+ };
829
+
830
+ declare const ContextHelpersMiddleware: {
831
+ localAction(handler: (...args: unknown[]) => unknown): (this: unknown, ctx: AppContext) => unknown;
832
+ };
833
+
834
+ /**
835
+ * Define a service
836
+ *
837
+ * @example
838
+ * ```typescript
839
+ * export default defineService({
840
+ * name: 'user',
841
+ *
842
+ * actions: {
843
+ * // Action with schema
844
+ * getUser: {
845
+ * params: {
846
+ * id: 'string'
847
+ * },
848
+ * handler(ctx) {
849
+ * const { tenantId } = ctx.meta;
850
+ *
851
+ * return { id: ctx.params.id, tenantId };
852
+ * }
853
+ * },
854
+ *
855
+ * // Direct handler
856
+ * listUsers(ctx) {
857
+ * return [];
858
+ * }
859
+ * }
860
+ * });
861
+ * ```
862
+ */
863
+ declare function defineService<TSettings = unknown, TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry>(config: ServiceConfig<TSettings, TDatasourceConstructors>): ServiceSchema$1<TSettings>;
864
+
865
+ declare function defineIntegration<TSettings = unknown, TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry>(config: IntegrationServiceConfig<TSettings, TDatasourceConstructors>): IntegrationServiceSchema<TSettings>;
866
+
867
+ declare const nodeEnv: string;
868
+ declare const isDev: boolean;
869
+ declare const isTest: boolean;
870
+ declare const isProd: boolean;
871
+ declare const REDIS_URL: string | undefined;
872
+
873
+ type Env = typeof env;
874
+
875
+ /**
876
+ * Creates a Moleculer mixin for datasource injection
877
+ * Simple mixin that just instantiates datasources and injects them into context
878
+ *
879
+ * @example
880
+ * ```typescript
881
+ * import {DatasourceMixin} from '@pkg/sdk';
882
+ *
883
+ * export default {
884
+ * name: 'users',
885
+ * mixins: [DatasourceMixin({
886
+ * userDb: UserDatasource,
887
+ * cache: CacheDatasource,
888
+ * })],
889
+ * actions: {
890
+ * get: {
891
+ * handler(ctx) {
892
+ * // Access datasources via ctx.datasources
893
+ * return ctx.datasources.userDb.findById(ctx.params.id);
894
+ * }
895
+ * }
896
+ * }
897
+ * }
898
+ * ```
899
+ */
900
+ declare function DatasourceMixin(datasourceConstructors?: DatasourceConstructorRegistry): Partial<ServiceSchema$1>;
901
+
902
+ declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
903
+
904
+ export { AbstractDatasource, type ActionHandler, type ActionSchemaWithContext, type ActionWithPermissions, type AppContext, type AppMeta, type AuditTrailExtension, type BaseDatasource, type BaseSpec, CHANNELS, type CarouselItem, type ChannelSendOptions, ContextHelpersMiddleware, CreateHealthCheckMiddleware, type DatasourceConstructorRegistry, type DatasourceContext, type DatasourceInstanceRegistry, type DatasourceInstanceTypes, DatasourceMixin, type Env, HEALTH_CHECK_DEFAULTS, INTEGRATION_CHANNELS, IntegrationCapability, type IntegrationChannelName, type IntegrationConfig, type IntegrationMessageFailedPayload, type IntegrationMessageReceivedPayload, type IntegrationMessageSentPayload, IntegrationPlatform, type IntegrationRegisteredPayload, type IntegrationServiceConfig, type IntegrationServiceSchema, IntegrationStatus, type IntegrationUnregisteredPayload, MemoizeMixin, type MemoizeMixinOptions, type Message, type MessageAttachment, type MessageButton, type MessageContent, MessageContentType, type MessageDirection, type MessageParticipant, type MessageStatus, type MessageType, NAMESPACE, PERMISSIONS, type Permission, type PermissionHelpers, PermissionsMiddleware, type PlatformMessage, PrismaDatasource, REDIS_URL, ROLE_PERMISSIONS, type SendResult, type SendToChannelMethod, type ServiceActionsSchema, type ServiceConfig, type ServiceSchema, type ServiceWithDatasources, type SoftDeleteExtension, type Tenant, type TenantExtension, type User, UserRole, type WebhookEvent, createDatasourceMiddleware, createTenantExtension, defineIntegration, defineService, isDev, isProd, isTest, configs as moleculer, nodeEnv, omit, retryExtension, softDeleteExtension };