@autofleet/sheilta 2.2.8 → 2.4.0

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/lib/index.d.cts CHANGED
@@ -1,9 +1,15 @@
1
- import { Op, literal } from "sequelize";
2
- import { Handler } from "express";
1
+ import { Model, ModelStatic, Op, Sequelize, WhereOptions, literal } from "sequelize";
2
+ import { Handler, Router } from "express";
3
3
  import { LoggerInstanceManager } from "@autofleet/logger";
4
+ import { RedisClientType, createClient } from "redis";
5
+ import rabbit from "@autofleet/rabbit";
6
+ import { z, z as z$1 } from "zod/v3";
7
+ import { EventEmitter } from "node:events";
4
8
 
5
- //#region src/operators/index.d.ts
9
+ //#region rolldown:runtime
6
10
 
11
+ //#endregion
12
+ //#region src/operators/index.d.ts
7
13
  declare const formatOperators: (sequelize?: {
8
14
  Op: typeof Op;
9
15
  }) => Record<string, symbol>;
@@ -180,7 +186,7 @@ interface QueryHandlerOptions {
180
186
  count: number;
181
187
  }, queryValues: QueryValues) => any;
182
188
  }
183
- type Asyncify<T extends (...a: any[]) => any> = (...a: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
189
+ type Asyncify$1<T extends (...a: any[]) => any> = (...a: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
184
190
  declare const queryHandler: ({
185
191
  model,
186
192
  logger,
@@ -190,7 +196,417 @@ declare const queryHandler: ({
190
196
  additionalScopes,
191
197
  modifyQueryValues,
192
198
  onRowsRetrieved
193
- }: QueryHandlerOptions) => Asyncify<Handler>;
199
+ }: QueryHandlerOptions) => Asyncify$1<Handler>;
200
+ //#endregion
201
+ //#region src/bulker/src/types.d.ts
202
+ type Id = string | number;
203
+ interface JobMetadata {
204
+ status: string;
205
+ total: number;
206
+ action: string;
207
+ }
208
+ interface ConsumeOptions {
209
+ enableRabbitTrace?: boolean;
210
+ [key: string]: any;
211
+ }
212
+ interface JobStatus {
213
+ jobId: string;
214
+ status: string;
215
+ action: string;
216
+ total: number;
217
+ queued: number;
218
+ processed: number;
219
+ succeeded: number;
220
+ failed: number;
221
+ errors: any[];
222
+ createdAt?: string;
223
+ updatedAt?: string;
224
+ duration: {
225
+ startTime: string | null;
226
+ endTime: string | null;
227
+ durationMs: number | null;
228
+ };
229
+ }
230
+ type MessageAck = () => Promise<void>;
231
+ type MessageNack = (err?: Error, requeue?: boolean) => Promise<void>;
232
+ type BulkPerIdHandler<T = any> = (args: {
233
+ jobId?: string;
234
+ id: Id;
235
+ payload: T;
236
+ }, ack: MessageAck, nack: MessageNack) => Promise<void>;
237
+ interface AdditionalIdsHookData<T = any> {
238
+ rawPayload: {
239
+ query: Record<string, any>;
240
+ include?: any[];
241
+ searchTerm: string;
242
+ };
243
+ payload: T;
244
+ }
245
+ interface BulkRouteOptions<T = any> {
246
+ /** e.g. "change-state" - the action identifier sent in request body */
247
+ action: string;
248
+ /** Sequelize model from which to scan IDs */
249
+ model: Model<any, any> | ModelStatic<any> | any;
250
+ modelScopes: string[];
251
+ /** Per-ID handler that performs the operation */
252
+ consumer: BulkPerIdHandler<T>;
253
+ consumerOptions?: ConsumeOptions;
254
+ rabbitQueueName?: string;
255
+ payloadSchema?: z.ZodType<T>;
256
+ /** Identity Scopes to be provided and are used and validated from the query.query object */
257
+ identityScopes?: string[];
258
+ queryFunction?: (reqBody: any) => Promise<Record<string, any>[]>;
259
+ idField?: string;
260
+ pageSize?: number;
261
+ workerConcurrency?: number;
262
+ jobAttempts?: number;
263
+ jobBackoffMs?: number;
264
+ removeOnComplete?: boolean | number;
265
+ removeOnFail?: boolean | number;
266
+ /** Inject tenant/RBAC filters (AND-ed with user query) */
267
+ contextWhere?: (payload: T) => WhereOptions;
268
+ /**
269
+ * Hook to provide additional IDs that will be OR-ed with the main query.
270
+ * This is useful when you need to manually fetch additional IDs based on the raw request body.
271
+ * The returned IDs will be included in the where clause using an OR statement.
272
+ *
273
+ * @example
274
+ * additionalIdsHook: async (data) => {
275
+ * const { rawPayload, payload } = reqBody;
276
+ * if (!rawPayload.searchTerm) return [];
277
+ * const filters = rawPayload?.query?.fleetId ? { fleetId: query.query.fleetId } : {};
278
+ * const labelIds = await searchDriversByLabelsValue(rawPayload.searchTerm, filters);
279
+ * const vendorIds = await searchDriversByVendorName(rawPayload.searchTerm, filters);
280
+ * return [...labelIds, ...vendorIds];
281
+ * }
282
+ */
283
+ additionalIdsHook?: (data: AdditionalIdsHookData) => Promise<Id[]>;
284
+ }
285
+ interface BulkRouterEvents$1 {
286
+ "job:created": (data: {
287
+ jobId: string;
288
+ action: string;
289
+ total: number;
290
+ }) => void;
291
+ "job:started": (data: {
292
+ jobId: string;
293
+ action: string;
294
+ }) => void;
295
+ "job:queued": (data: {
296
+ jobId: string;
297
+ action: string;
298
+ queued: number;
299
+ total: number;
300
+ }) => void;
301
+ "job:completed": (data: {
302
+ jobId: string;
303
+ action: string;
304
+ processed: number;
305
+ failed: number;
306
+ duration: number;
307
+ }) => void;
308
+ "job:canceled": (data: {
309
+ jobId: string;
310
+ action: string;
311
+ }) => void;
312
+ "job:failed": (data: {
313
+ jobId: string;
314
+ action: string;
315
+ error: string;
316
+ }) => void;
317
+ "item:processing": (data: {
318
+ jobId: string;
319
+ action: string;
320
+ id: string | number;
321
+ }) => void;
322
+ "item:processed": (data: {
323
+ jobId: string;
324
+ action: string;
325
+ id: string | number;
326
+ }) => void;
327
+ "item:failed": (data: {
328
+ jobId: string;
329
+ action: string;
330
+ id: string | number;
331
+ error: string;
332
+ }) => void;
333
+ "item:retrying": (data: {
334
+ jobId: string;
335
+ action: string;
336
+ id: string | number;
337
+ }) => void;
338
+ "worker:started": (data: {
339
+ action: string;
340
+ queueName: string;
341
+ }) => void;
342
+ "worker:error": (data: {
343
+ action: string;
344
+ error: string;
345
+ }) => void;
346
+ "scan:page": (data: {
347
+ jobId: string;
348
+ action: string;
349
+ pageNumber: number;
350
+ itemsInPage: number;
351
+ }) => void;
352
+ }
353
+ /**
354
+ * Interface for event emitters with the emitEvent helper method
355
+ */
356
+ interface IBulkEventEmitter {
357
+ emitEvent<K extends keyof BulkRouterEvents$1>(event: K, ...args: Parameters<BulkRouterEvents$1[K]>): void;
358
+ }
359
+ //#endregion
360
+ //#region src/bulker/src/BulkRoute.d.ts
361
+ type Asyncify<T extends (...a: any[]) => any> = (...a: Parameters<T>) => Promise<Awaited<ReturnType<T>>>;
362
+ declare class BulkRoute<T = any> {
363
+ private readonly bulker;
364
+ private readonly opts;
365
+ readonly action: string;
366
+ private readonly model;
367
+ private readonly consumer;
368
+ private readonly idField;
369
+ private readonly pageSize;
370
+ private readonly rabbitQueueName;
371
+ private readonly rabbit;
372
+ private readonly consumerOptions;
373
+ private readonly queryFunction?;
374
+ private readonly payloadSchema?;
375
+ private readonly identityScopeSchema;
376
+ private readonly modelScopes;
377
+ constructor(bulker: Bulker, opts: BulkRouteOptions<T>);
378
+ bulkHandler: Asyncify<Handler>;
379
+ /** Get user jobs - public method for BulkRouter to use */
380
+ getUserJobs(userId: string, limit?: number): Promise<(JobStatus | null)[]>;
381
+ private rabbitScanAndEnqueue;
382
+ startRabbitWorker(): Promise<void>;
383
+ }
384
+ //#endregion
385
+ //#region src/bulker/src/BulkRouter.d.ts
386
+ declare class BulkRouter {
387
+ private readonly bulker;
388
+ private readonly router;
389
+ private routes;
390
+ private actionsToRouteMap;
391
+ private staticRoute;
392
+ constructor(bulker: Bulker, router?: Router, staticRoute?: string);
393
+ private registerStaticRoutes;
394
+ addAction<T = any>(actionName: string, opts: Omit<BulkRouteOptions<T>, "action">): BulkRoute<T>;
395
+ private bulkHandler;
396
+ private getJobHandler;
397
+ private cancelJobHandler;
398
+ private getMyJobsHandler;
399
+ /** Get the configured router instance */
400
+ getRouter(): Router;
401
+ }
402
+ //#endregion
403
+ //#region src/bulker/src/events.d.ts
404
+ interface BulkRouterEvents {
405
+ "job:created": (data: {
406
+ jobId: string;
407
+ action: string;
408
+ total: number;
409
+ }) => void;
410
+ "job:started": (data: {
411
+ jobId: string;
412
+ action: string;
413
+ }) => void;
414
+ "job:queued": (data: {
415
+ jobId: string;
416
+ action: string;
417
+ queued: number;
418
+ total: number;
419
+ }) => void;
420
+ "job:completed": (data: {
421
+ jobId: string;
422
+ action: string;
423
+ processed: number;
424
+ failed: number;
425
+ duration: number;
426
+ }) => void;
427
+ "job:canceled": (data: {
428
+ jobId: string;
429
+ action: string;
430
+ }) => void;
431
+ "job:failed": (data: {
432
+ jobId: string;
433
+ action: string;
434
+ error: string;
435
+ }) => void;
436
+ "item:processing": (data: {
437
+ jobId: string;
438
+ action: string;
439
+ id: string | number;
440
+ }) => void;
441
+ "item:processed": (data: {
442
+ jobId: string;
443
+ action: string;
444
+ id: string | number;
445
+ }) => void;
446
+ "item:failed": (data: {
447
+ jobId: string;
448
+ action: string;
449
+ id: string | number;
450
+ error: string;
451
+ }) => void;
452
+ "item:retrying": (data: {
453
+ jobId: string;
454
+ action: string;
455
+ id: string | number;
456
+ }) => void;
457
+ "worker:started": (data: {
458
+ action: string;
459
+ queueName: string;
460
+ }) => void;
461
+ "worker:error": (data: {
462
+ action: string;
463
+ error: string;
464
+ }) => void;
465
+ "scan:page": (data: {
466
+ jobId: string;
467
+ action: string;
468
+ pageNumber: number;
469
+ itemsInPage: number;
470
+ }) => void;
471
+ }
472
+ interface BulkEventEmitter extends EventEmitter {
473
+ on<K extends keyof BulkRouterEvents>(event: K, listener: BulkRouterEvents[K]): this;
474
+ once<K extends keyof BulkRouterEvents>(event: K, listener: BulkRouterEvents[K]): this;
475
+ off<K extends keyof BulkRouterEvents>(event: K, listener: BulkRouterEvents[K]): this;
476
+ removeListener<K extends keyof BulkRouterEvents>(event: K, listener: BulkRouterEvents[K]): this;
477
+ emit<K extends keyof BulkRouterEvents>(event: K, ...args: Parameters<BulkRouterEvents[K]>): boolean;
478
+ }
479
+ interface EmitsBulkEvents {
480
+ emitEvent<K extends keyof BulkRouterEvents>(event: K, ...args: Parameters<BulkRouterEvents[K]>): void;
481
+ }
482
+ //#endregion
483
+ //#region src/bulker/src/JobManager.d.ts
484
+ /**
485
+ * Manages all job-related operations in Redis
486
+ * Centralizes job creation, status updates, cancellation, and user job tracking
487
+ */
488
+ declare class JobManager {
489
+ private eventEmitter?;
490
+ private readonly redis;
491
+ private readonly defaults;
492
+ constructor(redis: RedisClientType, defaults?: {
493
+ maxJobsPerUser?: number;
494
+ jobTtlSeconds?: number;
495
+ errorLogLimit?: number;
496
+ });
497
+ /** Set event emitter for emitting job events */
498
+ setEventEmitter(emitter: EmitsBulkEvents): void;
499
+ /** Generate Redis key for job */
500
+ static jobKey(jobId: string): string;
501
+ /** Generate Redis key for user jobs list */
502
+ static userJobsKey(userId: string): string;
503
+ /**
504
+ * Initialize a new job in Redis
505
+ */
506
+ initJob(jobId: string, meta: JobMetadata): Promise<void>;
507
+ /**
508
+ * Get job status from Redis
509
+ */
510
+ getJob(jobId: string): Promise<JobStatus | null>;
511
+ /**
512
+ * Set a single field on a job
513
+ */
514
+ setJobField(jobId: string, field: string, value: string): Promise<boolean>;
515
+ /**
516
+ * Set multiple fields on a job
517
+ */
518
+ setJobFields(jobId: string, fields: Record<string, string>): Promise<boolean>;
519
+ /**
520
+ * Increment a counter field on a job
521
+ */
522
+ incrJobField(jobId: string, field: "queued" | "processed" | "succeeded" | "failed", by?: number): Promise<number>;
523
+ /**
524
+ * Get a single field from a job
525
+ */
526
+ getJobField(jobId: string, field: string): Promise<string | undefined>;
527
+ /**
528
+ * Cancel a job
529
+ */
530
+ cancelJob(jobId: string): Promise<boolean>;
531
+ /**
532
+ * Mark job as completed (for jobs with no items to process)
533
+ */
534
+ completeEmptyJob(jobId: string): Promise<void>;
535
+ /**
536
+ * Handle successful message processing (ack)
537
+ * Uses Redis Lua script for atomic operation
538
+ */
539
+ ack(jobId: string): Promise<void>;
540
+ /**
541
+ * Handle failed message processing (nack)
542
+ * Uses Redis Lua script for atomic operation
543
+ */
544
+ nack(jobId: string, errorMsg: string, data: any): Promise<void>;
545
+ /**
546
+ * Add a job to user's job list
547
+ */
548
+ addUserJob(userId: string, jobId: string): Promise<void>;
549
+ /**
550
+ * Remove a job from user's job list
551
+ */
552
+ removeUserJob(userId: string, jobId: string): Promise<void>;
553
+ /**
554
+ * Get all jobs for a user
555
+ */
556
+ getUserJobs(userId: string, limit?: number): Promise<(JobStatus | null)[]>;
557
+ }
558
+ //#endregion
559
+ //#region src/bulker/src/Errors.d.ts
560
+ declare class BulkerError extends Error {
561
+ readonly retryable: boolean;
562
+ constructor(message: string, retryable?: boolean);
563
+ static isBulkerError(err: unknown): err is BulkerError;
564
+ static wrap(err: unknown, message?: string, retryable?: boolean): BulkerError;
565
+ static retryable(message: string): BulkerError;
566
+ static nonRetryable(message: string): BulkerError;
567
+ }
568
+ declare namespace index_d_exports {
569
+ export { BulkEventEmitter, BulkRoute, BulkRouteOptions, BulkRouterEvents$1 as BulkRouterEvents, Bulker, BulkerError, BulkerInit, IBulkEventEmitter, JobManager, JobMetadata, JobStatus, z$1 as z };
570
+ }
571
+ interface BulkerInit {
572
+ sequelize: Sequelize;
573
+ logger: LoggerInstanceManager;
574
+ rabbit: rabbit;
575
+ redis: RedisClientType | ReturnType<typeof createClient> | {
576
+ host: string;
577
+ port?: number;
578
+ password?: string;
579
+ db?: number;
580
+ };
581
+ getUserId?: () => string | null;
582
+ emitEvents?: boolean;
583
+ defaults?: {
584
+ pageSize?: number;
585
+ maxJobsPerUser?: number;
586
+ idField?: string;
587
+ workerConcurrency?: number;
588
+ jobTtlSeconds?: number;
589
+ errorLogLimit?: number;
590
+ };
591
+ }
592
+ declare class Bulker extends EventEmitter implements BulkEventEmitter {
593
+ readonly sequelize: Sequelize;
594
+ readonly logger: BulkerInit["logger"];
595
+ readonly redis: RedisClientType;
596
+ readonly rabbit: rabbit;
597
+ readonly defaults: Required<NonNullable<BulkerInit["defaults"]>>;
598
+ readonly jobManager: JobManager;
599
+ private readonly bulkRouters;
600
+ getUserId: BulkerInit["getUserId"];
601
+ readonly eventsEnabled: boolean;
602
+ constructor(init: BulkerInit);
603
+ createBulkRouter(router?: Router, staticRoute?: string): BulkRouter;
604
+ /**
605
+ * Emit event only if events are enabled.
606
+ * Centralizes the eventsEnabled check to avoid repetition.
607
+ */
608
+ emitEvent<K extends keyof BulkRouterEvents>(event: K, ...args: Parameters<BulkRouterEvents[K]>): void;
609
+ }
194
610
  //#endregion
195
- export { type LiteralAttribute, type MiddlewareValidationOption, formatOperators, generateFilterReplacements, queryFormatMiddleware, queryHandler, queryValidationMiddleware, validatePayload };
611
+ export { index_d_exports as Bulker, type LiteralAttribute, type MiddlewareValidationOption, formatOperators, generateFilterReplacements, queryFormatMiddleware, queryHandler, queryValidationMiddleware, validatePayload };
196
612
  //# sourceMappingURL=index.d.cts.map