@6thbridge/utils 1.8.2 → 1.8.3

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 (44) hide show
  1. package/lib/actions/database-session.action.d.ts +13 -0
  2. package/lib/actions/database-session.action.js +77 -0
  3. package/lib/actions/database-session.action.js.map +1 -0
  4. package/lib/actions/database-session.action.test.d.ts +1 -0
  5. package/lib/actions/database-session.action.test.js +137 -0
  6. package/lib/actions/database-session.action.test.js.map +1 -0
  7. package/lib/actions/index.d.ts +2 -0
  8. package/lib/actions/index.js +2 -0
  9. package/lib/actions/index.js.map +1 -1
  10. package/lib/actions/lock.action.d.ts +16 -0
  11. package/lib/actions/lock.action.js +171 -0
  12. package/lib/actions/lock.action.js.map +1 -0
  13. package/lib/actions/lock.action.test.d.ts +1 -0
  14. package/lib/actions/lock.action.test.js +63 -0
  15. package/lib/actions/lock.action.test.js.map +1 -0
  16. package/lib/index.d.ts +1 -0
  17. package/lib/index.js +1 -0
  18. package/lib/index.js.map +1 -1
  19. package/lib/pipelines/index.d.ts +3 -0
  20. package/lib/pipelines/index.js +20 -0
  21. package/lib/pipelines/index.js.map +1 -0
  22. package/lib/pipelines/parallel-pipeline.d.ts +7 -0
  23. package/lib/pipelines/parallel-pipeline.js +49 -0
  24. package/lib/pipelines/parallel-pipeline.js.map +1 -0
  25. package/lib/pipelines/pipeline-step.d.ts +5 -0
  26. package/lib/pipelines/pipeline-step.js +3 -0
  27. package/lib/pipelines/pipeline-step.js.map +1 -0
  28. package/lib/pipelines/pipeline.example.d.ts +2 -0
  29. package/lib/pipelines/pipeline.example.js +96 -0
  30. package/lib/pipelines/pipeline.example.js.map +1 -0
  31. package/lib/pipelines/pipelines.test.d.ts +1 -0
  32. package/lib/pipelines/pipelines.test.js +204 -0
  33. package/lib/pipelines/pipelines.test.js.map +1 -0
  34. package/lib/pipelines/pipelines.typecheck.d.ts +1 -0
  35. package/lib/pipelines/pipelines.typecheck.js +68 -0
  36. package/lib/pipelines/pipelines.typecheck.js.map +1 -0
  37. package/lib/pipelines/serial-pipeline.d.ts +7 -0
  38. package/lib/pipelines/serial-pipeline.js +39 -0
  39. package/lib/pipelines/serial-pipeline.js.map +1 -0
  40. package/lib/tsconfig.tsbuildinfo +1 -1
  41. package/lib/utils/file.d.ts +2 -2
  42. package/lib/utils/file.js.map +1 -1
  43. package/package.json +2 -1
  44. package/readme.md +107 -0
@@ -1,5 +1,5 @@
1
1
  import { PFunctionResult } from '../types';
2
- import { OptionsWithColumns } from 'csv-parse/sync';
2
+ import { Options } from 'csv-parse/sync';
3
3
  import { Sheet2JSONOpts } from 'xlsx';
4
4
  export declare enum FileType {
5
5
  csv = "csv",
@@ -17,7 +17,7 @@ export type ConvertFilePayload = {
17
17
  destination: FileSourceOrDestination;
18
18
  fileType: FileType;
19
19
  sourceFile?: string | Buffer;
20
- destinationFileParams?: OptionsWithColumns<any> | Sheet2JSONOpts | Record<string, any>;
20
+ destinationFileParams?: Options | Sheet2JSONOpts | Record<string, any>;
21
21
  };
22
22
  export declare class FileUtil {
23
23
  static getFileFromURL(url: string): Promise<Buffer>;
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,yCAAyD;AACzD,gDAA0C;AAE1C,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,uBAAW,CAAA;IACX,yBAAa,CAAA;IACb,uBAAW,CAAA;AACb,CAAC,EAJW,QAAQ,wBAAR,QAAQ,QAInB;AAED,IAAY,uBAIX;AAJD,WAAY,uBAAuB;IACjC,sCAAW,CAAA;IACX,sCAAW,CAAA;IACX,wCAAa,CAAA;AACf,CAAC,EAJW,uBAAuB,uCAAvB,uBAAuB,QAIlC;AAWD,MAAa,QAAQ;IACnB,MAAM,CAAO,cAAc,CAAC,GAAW;;YACrC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;KAAA;IAED,MAAM,CAAO,WAAW,CAAC,OAA2B;;YAClD,IAAI,IAAkB,CAAC;YACvB,IAAI,OAAO,CAAC,MAAM,KAAK,uBAAuB,CAAC,GAAG,EAAE,CAAC;gBACnD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,UAAoB,CAAC,CAAC;gBACzD,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YACpC,CAAC;YAED,IAAI,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC,WAAW,KAAK,uBAAuB,CAAC,IAAI,EAAE,CAAC;gBAC7F,OAAO;oBACL,IAAI,EAAE,IAAA,YAAK,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,qBAAgD,CAAC;iBACpG,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,WAAW,KAAK,uBAAuB,CAAC,IAAI,EAAE,CAAC;gBACrH,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACzC,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC7C,MAAM,IAAI,GAAG,cAAI,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,kBAC3C,MAAM,EAAE,CAAC,EACT,GAAG,EAAE,KAAK,EACV,MAAM,EAAE,EAAE,EACV,SAAS,EAAE,KAAK,IACb,OAAO,CAAC,qBAAuC,EAErD,CAAC;gBAEF,OAAO;oBACL,IAAI,EAAE,IAAI;iBACX,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,IAAI;aACX,CAAC;QACJ,CAAC;KAAA;CACF;AA1CD,4BA0CC;AAID,MAAM;AACN,2BAA2B;AAC3B,2BAA2B;AAC3B,yCAAyC;AACzC,4BAA4B;AAC5B,0GAA0G;AAC1G,+CAA+C;AAC/C,6BAA6B;AAC7B,qBAAqB;AACrB,sBAAsB;AACtB,8BAA8B;AAC9B,OAAO;AACP,uBAAuB;AACvB,2BAA2B;AAG3B,2BAA2B;AAC3B,2BAA2B;AAC3B,yCAAyC;AACzC,6BAA6B;AAC7B,0GAA0G;AAC1G,+CAA+C;AAC/C,6BAA6B;AAC7B,qBAAqB;AACrB,oBAAoB;AACpB,8BAA8B;AAC9B,OAAO;AACP,uBAAuB;AACvB,2BAA2B"}
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,yCAAgD;AAChD,gDAA0C;AAE1C,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,uBAAW,CAAA;IACX,yBAAa,CAAA;IACb,uBAAW,CAAA;AACb,CAAC,EAJW,QAAQ,wBAAR,QAAQ,QAInB;AAED,IAAY,uBAIX;AAJD,WAAY,uBAAuB;IACjC,sCAAW,CAAA;IACX,sCAAW,CAAA;IACX,wCAAa,CAAA;AACf,CAAC,EAJW,uBAAuB,uCAAvB,uBAAuB,QAIlC;AAWD,MAAa,QAAQ;IACnB,MAAM,CAAO,cAAc,CAAC,GAAW;;YACrC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;KAAA;IAED,MAAM,CAAO,WAAW,CAAC,OAA2B;;YAClD,IAAI,IAAkB,CAAC;YACvB,IAAI,OAAO,CAAC,MAAM,KAAK,uBAAuB,CAAC,GAAG,EAAE,CAAC;gBACnD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,UAAoB,CAAC,CAAC;gBACzD,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YACpC,CAAC;YAED,IAAI,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC,WAAW,KAAK,uBAAuB,CAAC,IAAI,EAAE,CAAC;gBAC7F,OAAO;oBACL,IAAI,EAAE,IAAA,YAAK,EAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,qBAAgC,CAAC;iBACpF,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,WAAW,KAAK,uBAAuB,CAAC,IAAI,EAAE,CAAC;gBACrH,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjC,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACzC,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC7C,MAAM,IAAI,GAAG,cAAI,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,kBAC3C,MAAM,EAAE,CAAC,EACT,GAAG,EAAE,KAAK,EACV,MAAM,EAAE,EAAE,EACV,SAAS,EAAE,KAAK,IACb,OAAO,CAAC,qBAAuC,EAErD,CAAC;gBAEF,OAAO;oBACL,IAAI,EAAE,IAAI;iBACX,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,IAAI,EAAE,IAAI;aACX,CAAC;QACJ,CAAC;KAAA;CACF;AA1CD,4BA0CC;AAID,MAAM;AACN,2BAA2B;AAC3B,2BAA2B;AAC3B,yCAAyC;AACzC,4BAA4B;AAC5B,0GAA0G;AAC1G,+CAA+C;AAC/C,6BAA6B;AAC7B,qBAAqB;AACrB,sBAAsB;AACtB,8BAA8B;AAC9B,OAAO;AACP,uBAAuB;AACvB,2BAA2B;AAG3B,2BAA2B;AAC3B,2BAA2B;AAC3B,yCAAyC;AACzC,6BAA6B;AAC7B,0GAA0G;AAC1G,+CAA+C;AAC/C,6BAA6B;AAC7B,qBAAqB;AACrB,oBAAoB;AACpB,8BAA8B;AAC9B,OAAO;AACP,uBAAuB;AACvB,2BAA2B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@6thbridge/utils",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "simple interface for the our commonly used functions",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -41,6 +41,7 @@
41
41
  "mongoose-paginate-v2": "^1.9.5",
42
42
  "path-to-regexp": "^8.4.2",
43
43
  "randomstring": "^1.3.1",
44
+ "redlock": "^5.0.0-beta.2",
44
45
  "rollbar": "^3.1.0",
45
46
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
46
47
  "zod": "^4.6.5",
package/readme.md CHANGED
@@ -7,6 +7,7 @@ A comprehensive TypeScript utility library for Node.js applications, providing r
7
7
  - [Core Modules](#core-modules)
8
8
  - [API Reference](#api-reference)
9
9
  - [Examples](#examples)
10
+ - [Pipelines](#pipelines)
10
11
  - [Testing](#testing)
11
12
  - [Contributing](#contributing)
12
13
  - [License](#license)
@@ -290,6 +291,93 @@ LOG_OUT=1
290
291
  # Service URLs
291
292
  USER_SERVICE_URL=http://user-service:3000
292
293
  ```
294
+ ## Pipelines
295
+
296
+ `SerialPipeline` passes each executed step's result to the next step. `ParallelPipeline`
297
+ runs independent steps concurrently with the same initial input and returns named results.
298
+ Both accept the existing `ContextEntity` as the first argument on every invocation; the
299
+ pipeline never stores context.
300
+
301
+ Every step must provide `shouldRun(contextEntity, input): Promise<boolean>` and
302
+ `run(contextEntity, input): Promise<Result>`. Implementers choose the result type.
303
+ Register objects or class instances with `.pipe(name, step)`. Names must be unique.
304
+ Registration returns a new pipeline, so retain the returned instance or chain calls.
305
+
306
+ ### Serial transformations and skipped steps
307
+
308
+ ```typescript
309
+ import { ContextEntity, PipelineStep, SerialPipeline } from '@6thbridge/utils';
310
+
311
+ class MeasureText implements PipelineStep<string, number> {
312
+ constructor(private minimumLength: number) {}
313
+
314
+ async shouldRun(contextEntity: ContextEntity, input: string): Promise<boolean> {
315
+ return input.length >= this.minimumLength;
316
+ }
317
+
318
+ async run(contextEntity: ContextEntity, input: string): Promise<number> {
319
+ return input.length;
320
+ }
321
+ }
322
+
323
+ const pipeline = new SerialPipeline<string>()
324
+ .pipe('measure', new MeasureText(3))
325
+ .pipe('describe', {
326
+ async shouldRun(contextEntity, input) {
327
+ return true;
328
+ },
329
+ async run(contextEntity, input) {
330
+ // input is string | number: skipped measurement forwards the original string.
331
+ return typeof input === 'number' ? `Length: ${input}` : `Unmeasured: ${input}`;
332
+ },
333
+ });
334
+
335
+ const contextEntity = new ContextEntity();
336
+ await pipeline.run(contextEntity, 'hello'); // "Length: 5"
337
+ await pipeline.run(new ContextEntity(), 'hi'); // "Unmeasured: hi"
338
+ ```
339
+
340
+ Serial execution awaits each predicate and result in registration order. A skipped step
341
+ forwards its input unchanged, so downstream input and the final result include the types
342
+ of values that may pass through skipped steps. Class instance methods retain their `this`.
343
+
344
+ ### Named parallel results
345
+
346
+ ```typescript
347
+ import { ContextEntity, ParallelPipeline } from '@6thbridge/utils';
348
+
349
+ const pipeline = new ParallelPipeline<string>()
350
+ .pipe('length', {
351
+ async shouldRun(contextEntity, input) {
352
+ return true;
353
+ },
354
+ async run(contextEntity, input) {
355
+ return input.length;
356
+ },
357
+ })
358
+ .pipe('uppercase', {
359
+ async shouldRun(contextEntity, input) {
360
+ return input.length > 0;
361
+ },
362
+ async run(contextEntity, input) {
363
+ return input.toUpperCase();
364
+ },
365
+ });
366
+
367
+ const results = await pipeline.run(new ContextEntity(), 'hello');
368
+ // { length: 5, uppercase: 'HELLO' }
369
+ // Inferred properties: length?: number; uppercase?: string.
370
+ ```
371
+
372
+ Parallel predicates and executions run independently. Skipped steps are omitted from the
373
+ result object; executed steps returning `undefined` still have a result property. Result
374
+ keys follow registration order regardless of completion order.
375
+
376
+ Both pipelines reject errors from `shouldRun` or `run`. Serial execution stops before the
377
+ next step; already started parallel work continues. Empty serial pipelines return their
378
+ input, and empty parallel pipelines return `{}`. Pipelines can be reused concurrently
379
+ with different contexts and inputs; callers manage any mutable state inside their steps.
380
+
293
381
  ## Testing
294
382
  The library includes comprehensive test suites using Jest:
295
383
  ``` bash
@@ -377,3 +465,22 @@ This project is licensed under the ISC License.
377
465
  ## Support
378
466
  For support and questions, please open an issue on the GitHub repository.
379
467
  **Note**: This library is actively maintained and used in production environments. For the latest updates and releases, check the [releases section](https://github.com/6thbridge/utils/releases).
468
+
469
+ ## Lock and database transaction actions
470
+
471
+ Create these actions with dependencies owned by the consuming service. The package does not create Redis or MongoDB connections.
472
+
473
+ ```ts
474
+ import { DatabaseSessionAction, LockAction } from '@6thbridge/utils';
475
+
476
+ LockAction.configure(redisClient);
477
+ DatabaseSessionAction.configure(transactionRepository.getModel());
478
+
479
+ await DatabaseSessionAction.withTransaction(
480
+ context,
481
+ async (session) => transactionRepository.updateMany(filter, update, { session }),
482
+ { lockKey: ['wallet:123'], lockTTLInSeconds: 10 },
483
+ );
484
+ ```
485
+
486
+ `redisClient` must be an initialized `RedisClient`; `LockAction.configure` creates Redlock with the package retry settings. Every action method takes a `ContextEntity` first and uses its logger. Database sessions run only when `NODE_ENV` is `production`; callbacks receive `null` for the session in other environments. Returned locks need `release()`; sessions need the MongoDB transaction methods.