@hiliosai/sdk 0.1.12 → 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.
- package/dist/index.d.ts +904 -0
- package/dist/index.js +1809 -0
- package/package.json +11 -2
- package/src/configs/constants.ts +0 -135
- package/src/configs/index.ts +0 -2
- package/src/configs/moleculer/bulkhead.ts +0 -8
- package/src/configs/moleculer/channels.ts +0 -102
- package/src/configs/moleculer/circuit-breaker.ts +0 -17
- package/src/configs/moleculer/index.ts +0 -98
- package/src/configs/moleculer/logger.ts +0 -17
- package/src/configs/moleculer/metrics.ts +0 -20
- package/src/configs/moleculer/registry.ts +0 -7
- package/src/configs/moleculer/retry-policy.ts +0 -17
- package/src/configs/moleculer/tracing.ts +0 -6
- package/src/configs/moleculer/tracking.ts +0 -6
- package/src/configs/permissions.ts +0 -109
- package/src/datasources/base.datasource.ts +0 -111
- package/src/datasources/extensions/index.ts +0 -11
- package/src/datasources/extensions/retry.extension.ts +0 -91
- package/src/datasources/extensions/soft-delete.extension.ts +0 -114
- package/src/datasources/extensions/tenant.extension.ts +0 -105
- package/src/datasources/index.ts +0 -3
- package/src/datasources/prisma.datasource.ts +0 -317
- package/src/env.ts +0 -12
- package/src/errors/auth.error.ts +0 -33
- package/src/errors/index.ts +0 -2
- package/src/errors/permission.error.ts +0 -17
- package/src/index.ts +0 -10
- package/src/middlewares/context-helpers.middleware.ts +0 -162
- package/src/middlewares/datasource.middleware.ts +0 -73
- package/src/middlewares/health.middleware.ts +0 -134
- package/src/middlewares/index.ts +0 -5
- package/src/middlewares/memoize.middleware.ts +0 -33
- package/src/middlewares/permissions.middleware.ts +0 -162
- package/src/mixins/datasource.mixin.ts +0 -111
- package/src/mixins/index.ts +0 -1
- package/src/service/define-integration.ts +0 -404
- package/src/service/define-service.ts +0 -58
- package/src/types/channels.ts +0 -60
- package/src/types/context.ts +0 -64
- package/src/types/datasource.ts +0 -23
- package/src/types/index.ts +0 -9
- package/src/types/integration.ts +0 -28
- package/src/types/message.ts +0 -128
- package/src/types/platform.ts +0 -39
- package/src/types/service.ts +0 -209
- package/src/types/tenant.ts +0 -4
- package/src/types/user.ts +0 -16
- package/src/utils/context-cache.ts +0 -70
- package/src/utils/index.ts +0 -8
- package/src/utils/permission-calculator.ts +0 -62
- package/tsconfig.json +0 -13
- package/tsup.config.ts +0 -5
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
import {CHANNEL_CONFIG, INTEGRATION_CHANNELS} from '../configs/constants';
|
|
4
|
-
import type {DatasourceConstructorRegistry} from '../middlewares/datasource.middleware';
|
|
5
|
-
import {
|
|
6
|
-
type IntegrationMessageFailedPayload,
|
|
7
|
-
type IntegrationMessageReceivedPayload,
|
|
8
|
-
type IntegrationMessageSentPayload,
|
|
9
|
-
} from '../types/channels';
|
|
10
|
-
import type {AppContext} from '../types/context';
|
|
11
|
-
import type {IntegrationConfig} from '../types/integration';
|
|
12
|
-
import type {Message, SendResult, WebhookEvent} from '../types/message';
|
|
13
|
-
import type {DatasourceInstanceTypes} from '../types/datasource';
|
|
14
|
-
import type {
|
|
15
|
-
IntegrationServiceConfig,
|
|
16
|
-
IntegrationServiceSchema,
|
|
17
|
-
} from '../types/service';
|
|
18
|
-
import {defineService} from './define-service';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Security helpers for webhook validation
|
|
22
|
-
*/
|
|
23
|
-
const SecurityHelpers = {
|
|
24
|
-
/**
|
|
25
|
-
* Secure comparison using Node.js crypto.timingSafeEqual
|
|
26
|
-
*/
|
|
27
|
-
secureCompare(a: string, b: string): boolean {
|
|
28
|
-
try {
|
|
29
|
-
return crypto.timingSafeEqual(
|
|
30
|
-
Buffer.from(a, 'utf8'),
|
|
31
|
-
Buffer.from(b, 'utf8')
|
|
32
|
-
);
|
|
33
|
-
} catch {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Validate webhook timestamp to prevent replay attacks
|
|
40
|
-
*/
|
|
41
|
-
validateTimestamp(timestamp: number, maxAgeMs = 5 * 60 * 1000): boolean {
|
|
42
|
-
return Date.now() - timestamp <= maxAgeMs;
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Retry mechanism with exponential backoff
|
|
48
|
-
*/
|
|
49
|
-
async function executeWithRetry<T>(
|
|
50
|
-
operation: () => Promise<T>,
|
|
51
|
-
maxRetries = 3,
|
|
52
|
-
baseDelayMs = 1000,
|
|
53
|
-
context = 'operation'
|
|
54
|
-
): Promise<T> {
|
|
55
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
56
|
-
try {
|
|
57
|
-
return await operation();
|
|
58
|
-
} catch (error: unknown) {
|
|
59
|
-
if (attempt === maxRetries) {
|
|
60
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
61
|
-
throw new Error(
|
|
62
|
-
`${context} failed after ${maxRetries} retries: ${err.message}`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const delay = baseDelayMs * Math.pow(2, attempt);
|
|
67
|
-
const jitter = Math.random() * 1000;
|
|
68
|
-
await new Promise((resolve) => setTimeout(resolve, delay + jitter));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
throw new Error('Retry logic error');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function defineIntegration<
|
|
75
|
-
TSettings = unknown,
|
|
76
|
-
TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry
|
|
77
|
-
>(
|
|
78
|
-
config: IntegrationServiceConfig<TSettings, TDatasourceConstructors>
|
|
79
|
-
): IntegrationServiceSchema<TSettings> {
|
|
80
|
-
// Type alias for inferred datasource instances
|
|
81
|
-
type TDatasources = DatasourceInstanceTypes<TDatasourceConstructors>;
|
|
82
|
-
|
|
83
|
-
// Create actions from integration methods
|
|
84
|
-
const actions = {
|
|
85
|
-
i_receiveWebhook: {
|
|
86
|
-
rest: {
|
|
87
|
-
method: 'POST' as const,
|
|
88
|
-
path: '/:channelId',
|
|
89
|
-
},
|
|
90
|
-
params: {
|
|
91
|
-
channelId: 'string',
|
|
92
|
-
payload: 'object',
|
|
93
|
-
headers: 'object',
|
|
94
|
-
timestamp: 'number',
|
|
95
|
-
},
|
|
96
|
-
async handler(
|
|
97
|
-
ctx: AppContext<
|
|
98
|
-
TDatasources,
|
|
99
|
-
{
|
|
100
|
-
channelId: string;
|
|
101
|
-
payload: object;
|
|
102
|
-
headers: object;
|
|
103
|
-
timestamp: number;
|
|
104
|
-
}
|
|
105
|
-
>
|
|
106
|
-
): Promise<{success: boolean; messages: number; failed: number}> {
|
|
107
|
-
const {channelId, payload, headers, timestamp} = ctx.params;
|
|
108
|
-
|
|
109
|
-
// TODO: Look up channel configuration by channelId
|
|
110
|
-
// const channel = await getChannelConfig(channelId);
|
|
111
|
-
// For now, we'll construct webhook from meta
|
|
112
|
-
|
|
113
|
-
const webhook: WebhookEvent = {
|
|
114
|
-
tenantId: ctx.meta.tenantId ?? 'unknown', // Should come from channel lookup
|
|
115
|
-
channelId,
|
|
116
|
-
platform: config.spec.platform,
|
|
117
|
-
payload, // Raw webhook payload from gateway
|
|
118
|
-
headers: headers as Record<string, string>,
|
|
119
|
-
timestamp,
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// Validate timestamp to prevent replay attacks
|
|
123
|
-
if (!SecurityHelpers.validateTimestamp(webhook.timestamp)) {
|
|
124
|
-
throw new Error('Webhook timestamp too old - possible replay attack');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Validate webhook if method exists
|
|
128
|
-
if (config.validateWebhook) {
|
|
129
|
-
const isValid = await config.validateWebhook(webhook);
|
|
130
|
-
if (!isValid) {
|
|
131
|
-
throw new Error('Invalid webhook payload format');
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Validate signature if method exists
|
|
136
|
-
if (config.validateSignature) {
|
|
137
|
-
const isValidSignature = config.validateSignature(webhook);
|
|
138
|
-
if (!isValidSignature) {
|
|
139
|
-
throw new Error('Webhook signature validation failed');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Normalize the message
|
|
144
|
-
const normalizedMessages = await config.normalize(webhook);
|
|
145
|
-
|
|
146
|
-
// Process each message with reliable delivery (parallel)
|
|
147
|
-
const results = await Promise.allSettled(
|
|
148
|
-
normalizedMessages.map(async (message) => {
|
|
149
|
-
const payload: IntegrationMessageReceivedPayload = {
|
|
150
|
-
tenantId: webhook.tenantId,
|
|
151
|
-
channelId: webhook.channelId,
|
|
152
|
-
platform: webhook.platform,
|
|
153
|
-
message,
|
|
154
|
-
timestamp: Date.now(),
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
// Send to reliable message channel (NATS JetStream)
|
|
158
|
-
return ctx.broker.sendToChannel(
|
|
159
|
-
INTEGRATION_CHANNELS.MESSAGE_RECEIVED,
|
|
160
|
-
payload,
|
|
161
|
-
CHANNEL_CONFIG.HIGH_PRIORITY
|
|
162
|
-
);
|
|
163
|
-
})
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
// Count successful vs failed messages
|
|
167
|
-
const successful = results.filter(
|
|
168
|
-
(result) => result.status === 'fulfilled'
|
|
169
|
-
).length;
|
|
170
|
-
const failed = results.filter(
|
|
171
|
-
(result) => result.status === 'rejected'
|
|
172
|
-
).length;
|
|
173
|
-
|
|
174
|
-
// Log failures for monitoring (but don't fail the entire webhook)
|
|
175
|
-
if (failed > 0) {
|
|
176
|
-
const failures = results
|
|
177
|
-
.filter((result) => result.status === 'rejected')
|
|
178
|
-
.map((result) => (result as PromiseRejectedResult).reason);
|
|
179
|
-
|
|
180
|
-
ctx.broker.logger.warn(
|
|
181
|
-
`Webhook processing partial failure: ${failed}/${normalizedMessages.length} messages failed`,
|
|
182
|
-
{failures}
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return {success: true, messages: successful, failed};
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
|
|
190
|
-
i_sendMessage: {
|
|
191
|
-
rest: {
|
|
192
|
-
method: 'POST' as const,
|
|
193
|
-
path: '/send',
|
|
194
|
-
},
|
|
195
|
-
params: {
|
|
196
|
-
message: 'object',
|
|
197
|
-
channelId: 'string',
|
|
198
|
-
},
|
|
199
|
-
async handler(
|
|
200
|
-
ctx: AppContext<
|
|
201
|
-
TDatasources,
|
|
202
|
-
{
|
|
203
|
-
message: Message;
|
|
204
|
-
channelId: string;
|
|
205
|
-
}
|
|
206
|
-
>
|
|
207
|
-
): Promise<SendResult> {
|
|
208
|
-
const {message, channelId} = ctx.params;
|
|
209
|
-
|
|
210
|
-
// Load channel configuration
|
|
211
|
-
const integrationConfig = await config.getChannelConfig(ctx, channelId);
|
|
212
|
-
if (!integrationConfig) {
|
|
213
|
-
throw new Error(`Channel configuration not found: ${channelId}`);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Send the message with retry mechanism (transformation happens inside sendMessage)
|
|
217
|
-
const result: SendResult = await executeWithRetry(
|
|
218
|
-
() => config.sendMessage(ctx, message, integrationConfig),
|
|
219
|
-
3,
|
|
220
|
-
1000,
|
|
221
|
-
`Send message via ${config.spec.platform}`
|
|
222
|
-
);
|
|
223
|
-
|
|
224
|
-
// Send reliable events based on result (with error handling)
|
|
225
|
-
try {
|
|
226
|
-
if (result.success) {
|
|
227
|
-
const sentPayload: IntegrationMessageSentPayload = {
|
|
228
|
-
tenantId: integrationConfig.tenantId,
|
|
229
|
-
channelId,
|
|
230
|
-
platform: config.spec.platform,
|
|
231
|
-
messageId: result.messageId,
|
|
232
|
-
metadata: result.metadata,
|
|
233
|
-
timestamp: Date.now(),
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
await ctx.broker.sendToChannel(
|
|
237
|
-
INTEGRATION_CHANNELS.MESSAGE_SENT,
|
|
238
|
-
sentPayload,
|
|
239
|
-
CHANNEL_CONFIG.DEFAULTS
|
|
240
|
-
);
|
|
241
|
-
} else {
|
|
242
|
-
const failedPayload: IntegrationMessageFailedPayload = {
|
|
243
|
-
tenantId: integrationConfig.tenantId,
|
|
244
|
-
channelId,
|
|
245
|
-
platform: config.spec.platform,
|
|
246
|
-
error: result.error?.message ?? 'Unknown error',
|
|
247
|
-
message,
|
|
248
|
-
timestamp: Date.now(),
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
await ctx.broker.sendToChannel(
|
|
252
|
-
INTEGRATION_CHANNELS.MESSAGE_FAILED,
|
|
253
|
-
failedPayload,
|
|
254
|
-
CHANNEL_CONFIG.DEFAULTS
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
} catch (channelError: unknown) {
|
|
258
|
-
// Log channel error but don't fail the send operation
|
|
259
|
-
const err =
|
|
260
|
-
channelError instanceof Error
|
|
261
|
-
? channelError
|
|
262
|
-
: new Error(String(channelError));
|
|
263
|
-
ctx.broker.logger.warn('Failed to send message event to channel', {
|
|
264
|
-
error: err.message,
|
|
265
|
-
messageId: result.messageId,
|
|
266
|
-
platform: config.spec.platform,
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return result;
|
|
271
|
-
},
|
|
272
|
-
},
|
|
273
|
-
|
|
274
|
-
i_healthCheck: {
|
|
275
|
-
rest: {
|
|
276
|
-
method: 'GET' as const,
|
|
277
|
-
path: '/health',
|
|
278
|
-
},
|
|
279
|
-
params: {
|
|
280
|
-
config: {type: 'object', optional: true},
|
|
281
|
-
},
|
|
282
|
-
async handler(
|
|
283
|
-
ctx: AppContext<TDatasources, {config?: IntegrationConfig}>
|
|
284
|
-
): Promise<unknown> {
|
|
285
|
-
try {
|
|
286
|
-
if (config.checkHealth) {
|
|
287
|
-
const integrationConfig = ctx.params.config;
|
|
288
|
-
if (integrationConfig) {
|
|
289
|
-
return await config.checkHealth(ctx, integrationConfig);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
status: 'healthy',
|
|
295
|
-
message: `${config.spec.name} integration is running`,
|
|
296
|
-
details: {
|
|
297
|
-
id: config.spec.id,
|
|
298
|
-
version: config.spec.version,
|
|
299
|
-
timestamp: new Date().toISOString(),
|
|
300
|
-
capabilities: config.spec.capabilities,
|
|
301
|
-
},
|
|
302
|
-
};
|
|
303
|
-
} catch (error: unknown) {
|
|
304
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
305
|
-
return {
|
|
306
|
-
status: 'unhealthy',
|
|
307
|
-
message: err.message,
|
|
308
|
-
details: {
|
|
309
|
-
id: config.spec.id,
|
|
310
|
-
timestamp: new Date().toISOString(),
|
|
311
|
-
},
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
},
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
i_verifyWebhook: {
|
|
318
|
-
rest: {
|
|
319
|
-
method: 'GET' as const,
|
|
320
|
-
path: '/:tenantId',
|
|
321
|
-
},
|
|
322
|
-
params: {
|
|
323
|
-
tenantId: 'string',
|
|
324
|
-
mode: 'string',
|
|
325
|
-
token: 'string',
|
|
326
|
-
challenge: 'string',
|
|
327
|
-
},
|
|
328
|
-
handler(
|
|
329
|
-
ctx: AppContext<
|
|
330
|
-
TDatasources,
|
|
331
|
-
{tenantId: string; mode: string; token: string; challenge: string}
|
|
332
|
-
>
|
|
333
|
-
): string {
|
|
334
|
-
if (config.verifyWebhook) {
|
|
335
|
-
const result: string | null = config.verifyWebhook(ctx.params);
|
|
336
|
-
return result ?? '';
|
|
337
|
-
}
|
|
338
|
-
return ctx.params.challenge;
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
|
|
342
|
-
i_validateCredentials: {
|
|
343
|
-
params: {
|
|
344
|
-
credentials: 'object',
|
|
345
|
-
},
|
|
346
|
-
async handler(
|
|
347
|
-
ctx: AppContext<TDatasources, {credentials: Record<string, string>}>
|
|
348
|
-
): Promise<boolean> {
|
|
349
|
-
if (config.validateCredentials) {
|
|
350
|
-
return await config.validateCredentials(ctx.params.credentials);
|
|
351
|
-
}
|
|
352
|
-
return true;
|
|
353
|
-
},
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
// Add any custom actions
|
|
358
|
-
if (config.actions) {
|
|
359
|
-
Object.assign(actions, config.actions);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Use defineService to get all the mixins and proper setup
|
|
363
|
-
const baseService = defineService<TSettings, TDatasourceConstructors>({
|
|
364
|
-
name: config.name,
|
|
365
|
-
version: config.version,
|
|
366
|
-
settings: config.settings as TSettings,
|
|
367
|
-
dependencies: config.dependencies,
|
|
368
|
-
datasources: config.datasources,
|
|
369
|
-
metadata: {
|
|
370
|
-
...config.metadata,
|
|
371
|
-
spec: config.spec,
|
|
372
|
-
},
|
|
373
|
-
actions,
|
|
374
|
-
events: config.events ?? {},
|
|
375
|
-
methods: {
|
|
376
|
-
...(config.methods ?? {}),
|
|
377
|
-
// Add integration-specific methods to the service methods (filter out undefined)
|
|
378
|
-
// Required methods - no need for conditional
|
|
379
|
-
normalize: config.normalize,
|
|
380
|
-
getChannelConfig: config.getChannelConfig,
|
|
381
|
-
sendMessage: config.sendMessage,
|
|
382
|
-
// Optional methods
|
|
383
|
-
...(config.validateWebhook && {validateWebhook: config.validateWebhook}),
|
|
384
|
-
...(config.verifyWebhook && {verifyWebhook: config.verifyWebhook}),
|
|
385
|
-
...(config.checkHealth && {checkHealth: config.checkHealth}),
|
|
386
|
-
...(config.validateCredentials && {
|
|
387
|
-
validateCredentials: config.validateCredentials,
|
|
388
|
-
}),
|
|
389
|
-
...(config.validateSignature && {
|
|
390
|
-
validateSignature: config.validateSignature,
|
|
391
|
-
}),
|
|
392
|
-
},
|
|
393
|
-
created: config.created,
|
|
394
|
-
started: config.started,
|
|
395
|
-
stopped: config.stopped,
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
// Return the service schema - integration methods are available via service methods
|
|
399
|
-
return {
|
|
400
|
-
...baseService,
|
|
401
|
-
// Only add the integration spec
|
|
402
|
-
spec: config.spec,
|
|
403
|
-
} as IntegrationServiceSchema<TSettings>;
|
|
404
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type {ServiceSchema as MoleculerServiceSchema} from 'moleculer';
|
|
2
|
-
|
|
3
|
-
import {MemoizeMixin} from '../middlewares';
|
|
4
|
-
import type {DatasourceConstructorRegistry} from '../middlewares/datasource.middleware';
|
|
5
|
-
import {DatasourceMixin} from '../mixins';
|
|
6
|
-
import type {ServiceConfig} from '../types/service';
|
|
7
|
-
import {omit} from '../utils';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Define a service
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* export default defineService({
|
|
15
|
-
* name: 'user',
|
|
16
|
-
*
|
|
17
|
-
* actions: {
|
|
18
|
-
* // Action with schema
|
|
19
|
-
* getUser: {
|
|
20
|
-
* params: {
|
|
21
|
-
* id: 'string'
|
|
22
|
-
* },
|
|
23
|
-
* handler(ctx) {
|
|
24
|
-
* const { tenantId } = ctx.meta;
|
|
25
|
-
*
|
|
26
|
-
* return { id: ctx.params.id, tenantId };
|
|
27
|
-
* }
|
|
28
|
-
* },
|
|
29
|
-
*
|
|
30
|
-
* // Direct handler
|
|
31
|
-
* listUsers(ctx) {
|
|
32
|
-
* return [];
|
|
33
|
-
* }
|
|
34
|
-
* }
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export function defineService<
|
|
39
|
-
TSettings = unknown,
|
|
40
|
-
TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry
|
|
41
|
-
>(
|
|
42
|
-
config: ServiceConfig<TSettings, TDatasourceConstructors>
|
|
43
|
-
): MoleculerServiceSchema<TSettings> {
|
|
44
|
-
const propsToOmit = ['datasources'];
|
|
45
|
-
const serviceSchema = omit(
|
|
46
|
-
config,
|
|
47
|
-
propsToOmit
|
|
48
|
-
) as unknown as MoleculerServiceSchema<TSettings>;
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
...serviceSchema,
|
|
52
|
-
mixins: [
|
|
53
|
-
DatasourceMixin(config.datasources),
|
|
54
|
-
MemoizeMixin(),
|
|
55
|
-
...(serviceSchema.mixins ?? []),
|
|
56
|
-
],
|
|
57
|
-
};
|
|
58
|
-
}
|
package/src/types/channels.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type {IntegrationPlatform} from './platform';
|
|
2
|
-
import type {Message} from './message';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Channel event payload types for reliable messaging via @moleculer/channels
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// Integration message events
|
|
9
|
-
export interface IntegrationMessageReceivedPayload {
|
|
10
|
-
tenantId: string;
|
|
11
|
-
channelId: string;
|
|
12
|
-
platform: IntegrationPlatform;
|
|
13
|
-
message: Message;
|
|
14
|
-
timestamp: number;
|
|
15
|
-
metadata?: Record<string, unknown>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface IntegrationMessageSentPayload {
|
|
19
|
-
tenantId: string;
|
|
20
|
-
channelId: string;
|
|
21
|
-
platform: IntegrationPlatform;
|
|
22
|
-
messageId?: string;
|
|
23
|
-
metadata?: Record<string, unknown>;
|
|
24
|
-
timestamp: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface IntegrationMessageFailedPayload {
|
|
28
|
-
tenantId: string;
|
|
29
|
-
channelId: string;
|
|
30
|
-
platform: IntegrationPlatform;
|
|
31
|
-
error: string; // Serialized error message
|
|
32
|
-
message?: Message;
|
|
33
|
-
timestamp: number;
|
|
34
|
-
retryCount?: number;
|
|
35
|
-
metadata?: Record<string, unknown>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// System events
|
|
39
|
-
export interface IntegrationRegisteredPayload {
|
|
40
|
-
tenantId: string;
|
|
41
|
-
channelId: string;
|
|
42
|
-
platform: IntegrationPlatform;
|
|
43
|
-
config: Record<string, unknown>;
|
|
44
|
-
timestamp: number;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface IntegrationUnregisteredPayload {
|
|
48
|
-
tenantId: string;
|
|
49
|
-
channelId: string;
|
|
50
|
-
platform: IntegrationPlatform;
|
|
51
|
-
timestamp: number;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Re-export constants to avoid duplication
|
|
55
|
-
export {
|
|
56
|
-
CHANNELS,
|
|
57
|
-
INTEGRATION_CHANNELS,
|
|
58
|
-
NAMESPACE,
|
|
59
|
-
type IntegrationChannelName,
|
|
60
|
-
} from '../configs/constants';
|
package/src/types/context.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type {Context} from 'moleculer';
|
|
2
|
-
import type {Tenant} from './tenant';
|
|
3
|
-
import type {User} from './user';
|
|
4
|
-
|
|
5
|
-
// Moleculer Channels types
|
|
6
|
-
export interface ChannelSendOptions {
|
|
7
|
-
group?: string;
|
|
8
|
-
maxInFlight?: number;
|
|
9
|
-
maxRetries?: number;
|
|
10
|
-
deadLettering?: {
|
|
11
|
-
enabled?: boolean;
|
|
12
|
-
queueName?: string;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface SendToChannelMethod {
|
|
17
|
-
(
|
|
18
|
-
channelName: string,
|
|
19
|
-
payload: unknown,
|
|
20
|
-
options?: ChannelSendOptions
|
|
21
|
-
): Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface AppMeta {
|
|
25
|
-
user?: User;
|
|
26
|
-
tenantId?: string;
|
|
27
|
-
tenantName?: string;
|
|
28
|
-
userId?: string;
|
|
29
|
-
channelId?: string;
|
|
30
|
-
requestId?: string;
|
|
31
|
-
userAgent?: string;
|
|
32
|
-
clientIP?: string;
|
|
33
|
-
[key: string]: unknown;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface PermissionHelpers {
|
|
37
|
-
hasPermission(permission: string): boolean;
|
|
38
|
-
hasRole(role: string): boolean;
|
|
39
|
-
isTenantMember(): boolean;
|
|
40
|
-
isTenantOwner(): boolean;
|
|
41
|
-
ensureUser(): User;
|
|
42
|
-
ensureTenant(): Tenant;
|
|
43
|
-
// New enhanced helpers
|
|
44
|
-
getUserPermissions(): Promise<string[]>;
|
|
45
|
-
auditLog(
|
|
46
|
-
action: string,
|
|
47
|
-
resource?: unknown,
|
|
48
|
-
metadata?: Record<string, unknown>
|
|
49
|
-
): void;
|
|
50
|
-
createError(message: string, code: string, statusCode?: number): Error;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export type AppContext<
|
|
54
|
-
TDatasources = unknown,
|
|
55
|
-
TParams = unknown,
|
|
56
|
-
TMeta extends AppMeta = AppMeta,
|
|
57
|
-
TLocals = unknown
|
|
58
|
-
> = Context<TParams, TMeta, TLocals> &
|
|
59
|
-
PermissionHelpers & {
|
|
60
|
-
datasources: TDatasources;
|
|
61
|
-
broker: Context['broker'] & {
|
|
62
|
-
sendToChannel: SendToChannelMethod;
|
|
63
|
-
};
|
|
64
|
-
};
|
package/src/types/datasource.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility types for datasources
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Extract instance types from a datasource constructor registry
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* const datasources = {
|
|
11
|
-
* user: UserDatasource,
|
|
12
|
-
* whatsapp: WhatsAppDatasource,
|
|
13
|
-
* };
|
|
14
|
-
*
|
|
15
|
-
* type MyDatasources = DatasourceInstanceTypes<typeof datasources>;
|
|
16
|
-
* // Results in: { user: UserDatasource; whatsapp: WhatsAppDatasource; }
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
export type DatasourceInstanceTypes<
|
|
20
|
-
T extends Record<string, new (...args: unknown[]) => unknown>
|
|
21
|
-
> = {
|
|
22
|
-
[K in keyof T]: InstanceType<T[K]>;
|
|
23
|
-
};
|
package/src/types/index.ts
DELETED
package/src/types/integration.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
IntegrationCapability,
|
|
3
|
-
IntegrationPlatform,
|
|
4
|
-
IntegrationStatus,
|
|
5
|
-
} from './platform';
|
|
6
|
-
|
|
7
|
-
export interface BaseSpec {
|
|
8
|
-
id: string;
|
|
9
|
-
name: string;
|
|
10
|
-
platform: IntegrationPlatform;
|
|
11
|
-
version: string;
|
|
12
|
-
status: IntegrationStatus;
|
|
13
|
-
capabilities: IntegrationCapability[];
|
|
14
|
-
description?: string;
|
|
15
|
-
icon?: string;
|
|
16
|
-
documentationUrl?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface IntegrationConfig {
|
|
20
|
-
id: string;
|
|
21
|
-
tenantId: string;
|
|
22
|
-
name: string;
|
|
23
|
-
version: string;
|
|
24
|
-
config: Record<string, unknown>;
|
|
25
|
-
credentials: Record<string, string>;
|
|
26
|
-
createdAt?: Date;
|
|
27
|
-
updatedAt?: Date;
|
|
28
|
-
}
|