@mikro-orm/core 6.5.6-dev.0 → 6.5.6-dev.10

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.
@@ -264,6 +264,29 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
264
264
  upsertMany<Entity extends object, Fields extends string = any>(entityNameOrEntity: EntityName<Entity> | Entity[], data?: (EntityData<Entity> | NoInfer<Entity>)[], options?: UpsertManyOptions<Entity, Fields>): Promise<Entity[]>;
265
265
  /**
266
266
  * Runs your callback wrapped inside a database transaction.
267
+ *
268
+ * If a transaction is already active, a new savepoint (nested transaction) will be created by default. This behavior
269
+ * can be controlled via the `propagation` option. Use the provided EntityManager instance for all operations that
270
+ * should be part of the transaction. You can safely use a global EntityManager instance from a DI container, as this
271
+ * method automatically creates an async context for the transaction.
272
+ *
273
+ * **Concurrency note:** When running multiple transactions concurrently (e.g. in parallel requests or jobs), use the
274
+ * `clear: true` option. This ensures the callback runs in a clear fork of the EntityManager, providing full isolation
275
+ * between concurrent transactional handlers. Using `clear: true` is an alternative to forking explicitly and calling
276
+ * the method on the new fork – it already provides the necessary isolation for safe concurrent usage.
277
+ *
278
+ * **Propagation note:** Changes made within a transaction (whether top-level or nested) are always propagated to the
279
+ * parent context, unless the parent context is a global one. If you want to avoid that, fork the EntityManager first
280
+ * and then call this method on the fork.
281
+ *
282
+ * **Example:**
283
+ * ```ts
284
+ * await em.transactional(async (em) => {
285
+ * const author = new Author('Jon');
286
+ * em.persist(author);
287
+ * // flush is called automatically at the end of the callback
288
+ * });
289
+ * ```
267
290
  */
268
291
  transactional<T>(cb: (em: this) => T | Promise<T>, options?: TransactionOptions): Promise<T>;
269
292
  /**
package/EntityManager.js CHANGED
@@ -499,18 +499,24 @@ class EntityManager {
499
499
  flushMode: enums_1.FlushMode.COMMIT,
500
500
  });
501
501
  const em = this.getContext();
502
- if (reloaded) {
503
- for (const e of fork.unitOfWork.getIdentityMap()) {
504
- const ref = em.getReference(e.constructor.name, (0, entity_1.helper)(e).getPrimaryKey());
505
- const data = this.comparator.prepareEntity(e);
506
- em.config.getHydrator(this.metadata).hydrate(ref, (0, entity_1.helper)(ref).__meta, (0, entity_1.helper)(e).serialize({ ignoreSerializers: true, includeHidden: true }), em.entityFactory, 'full', false, true);
507
- (0, entity_1.helper)(ref).__originalEntityData = data;
508
- }
509
- }
510
- else {
502
+ if (!reloaded) {
511
503
  em.unitOfWork.unsetIdentity(entity);
504
+ return null;
512
505
  }
513
- return reloaded ? entity : reloaded;
506
+ let found = false;
507
+ for (const e of fork.unitOfWork.getIdentityMap()) {
508
+ const ref = em.getReference(e.constructor.name, (0, entity_1.helper)(e).getPrimaryKey());
509
+ const data = (0, entity_1.helper)(e).serialize({ ignoreSerializers: true, includeHidden: true });
510
+ em.config.getHydrator(this.metadata).hydrate(ref, (0, entity_1.helper)(ref).__meta, data, em.entityFactory, 'full', false, true);
511
+ (0, entity_1.helper)(ref).__originalEntityData = this.comparator.prepareEntity(e);
512
+ found ||= ref === entity;
513
+ }
514
+ if (!found) {
515
+ const data = (0, entity_1.helper)(reloaded).serialize({ ignoreSerializers: true, includeHidden: true });
516
+ em.config.getHydrator(this.metadata).hydrate(entity, (0, entity_1.helper)(entity).__meta, data, em.entityFactory, 'full', false, true);
517
+ (0, entity_1.helper)(entity).__originalEntityData = this.comparator.prepareEntity(reloaded);
518
+ }
519
+ return entity;
514
520
  }
515
521
  /**
516
522
  * Finds first entity matching your `where` query.
@@ -965,6 +971,29 @@ class EntityManager {
965
971
  }
966
972
  /**
967
973
  * Runs your callback wrapped inside a database transaction.
974
+ *
975
+ * If a transaction is already active, a new savepoint (nested transaction) will be created by default. This behavior
976
+ * can be controlled via the `propagation` option. Use the provided EntityManager instance for all operations that
977
+ * should be part of the transaction. You can safely use a global EntityManager instance from a DI container, as this
978
+ * method automatically creates an async context for the transaction.
979
+ *
980
+ * **Concurrency note:** When running multiple transactions concurrently (e.g. in parallel requests or jobs), use the
981
+ * `clear: true` option. This ensures the callback runs in a clear fork of the EntityManager, providing full isolation
982
+ * between concurrent transactional handlers. Using `clear: true` is an alternative to forking explicitly and calling
983
+ * the method on the new fork – it already provides the necessary isolation for safe concurrent usage.
984
+ *
985
+ * **Propagation note:** Changes made within a transaction (whether top-level or nested) are always propagated to the
986
+ * parent context, unless the parent context is a global one. If you want to avoid that, fork the EntityManager first
987
+ * and then call this method on the fork.
988
+ *
989
+ * **Example:**
990
+ * ```ts
991
+ * await em.transactional(async (em) => {
992
+ * const author = new Author('Jon');
993
+ * em.persist(author);
994
+ * // flush is called automatically at the end of the callback
995
+ * });
996
+ * ```
968
997
  */
969
998
  async transactional(cb, options = {}) {
970
999
  const em = this.getContext(false);
@@ -3,12 +3,13 @@ export declare class FileCacheAdapter implements SyncCacheAdapter {
3
3
  private readonly options;
4
4
  private readonly baseDir;
5
5
  private readonly pretty;
6
+ private readonly hashAlgorithm;
6
7
  private readonly VERSION;
7
8
  private cache;
8
9
  constructor(options: {
9
10
  cacheDir: string;
10
11
  combined?: boolean | string;
11
- }, baseDir: string, pretty?: boolean);
12
+ }, baseDir: string, pretty?: boolean, hashAlgorithm?: 'md5' | 'sha256');
12
13
  /**
13
14
  * @inheritDoc
14
15
  */
@@ -11,12 +11,14 @@ class FileCacheAdapter {
11
11
  options;
12
12
  baseDir;
13
13
  pretty;
14
+ hashAlgorithm;
14
15
  VERSION = Utils_1.Utils.getORMVersion();
15
16
  cache = {};
16
- constructor(options, baseDir, pretty = false) {
17
+ constructor(options, baseDir, pretty = false, hashAlgorithm = 'md5') {
17
18
  this.options = options;
18
19
  this.baseDir = baseDir;
19
20
  this.pretty = pretty;
21
+ this.hashAlgorithm = hashAlgorithm;
20
22
  }
21
23
  /**
22
24
  * @inheritDoc
@@ -84,7 +86,7 @@ class FileCacheAdapter {
84
86
  return null;
85
87
  }
86
88
  const contents = (0, fs_extra_1.readFileSync)(origin);
87
- return Utils_1.Utils.hash(contents.toString() + this.VERSION);
89
+ return Utils_1.Utils.hash(contents.toString() + this.VERSION, undefined, this.hashAlgorithm);
88
90
  }
89
91
  }
90
92
  exports.FileCacheAdapter = FileCacheAdapter;
@@ -465,23 +465,20 @@ class EntityLoader {
465
465
  }
466
466
  getChildReferences(entities, prop, options, ref) {
467
467
  const filtered = this.filterCollections(entities, prop.name, options, ref);
468
- const children = [];
469
468
  if (prop.kind === enums_1.ReferenceKind.ONE_TO_MANY) {
470
- children.push(...filtered.map(e => e[prop.name].owner));
469
+ return filtered.map(e => e[prop.name].owner);
471
470
  }
472
- else if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner) {
473
- children.push(...filtered.reduce((a, b) => {
471
+ if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && prop.owner) {
472
+ return filtered.reduce((a, b) => {
474
473
  a.push(...b[prop.name].getItems());
475
474
  return a;
476
- }, []));
477
- }
478
- else if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY) { // inverse side
479
- children.push(...filtered);
475
+ }, []);
480
476
  }
481
- else { // MANY_TO_ONE or ONE_TO_ONE
482
- children.push(...this.filterReferences(entities, prop.name, options, ref));
477
+ if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY) { // inverse side
478
+ return filtered;
483
479
  }
484
- return children;
480
+ // MANY_TO_ONE or ONE_TO_ONE
481
+ return this.filterReferences(entities, prop.name, options, ref);
485
482
  }
486
483
  filterCollections(entities, field, options, ref) {
487
484
  if (options.refresh) {
@@ -443,6 +443,9 @@ export declare class OneToOneOptionsBuilder<TargetValue extends object> extends
443
443
  deferMode(deferMode: DeferMode | `${DeferMode}`): OneToOneOptionsBuilder<TargetValue>;
444
444
  }
445
445
  declare const propertyBuilders: {
446
+ bigint: <Mode extends "bigint" | "number" | "string" = "bigint">(mode?: Mode) => PropertyOptionsBuilder<(Mode extends "bigint" ? bigint : Mode extends "number" ? number : string) & {}>;
447
+ array: <T = string>(toJsValue?: (i: string) => T, toDbValue?: (i: T) => string) => PropertyOptionsBuilder<T[]>;
448
+ decimal: <Mode extends "number" | "string" = "string">(mode?: Mode) => PropertyOptionsBuilder<NonNullable<Mode extends "number" ? number : string>>;
446
449
  json: <T>() => PropertyOptionsBuilder<T>;
447
450
  formula: <T>(formula: string | ((alias: string) => string)) => PropertyOptionsBuilder<T>;
448
451
  type: <T extends PropertyValueType>(type: T) => PropertyOptionsBuilder<InferPropertyValueType<T>>;
@@ -455,10 +458,8 @@ declare const propertyBuilders: {
455
458
  date: () => PropertyOptionsBuilder<string>;
456
459
  time: () => PropertyOptionsBuilder<any>;
457
460
  datetime: () => PropertyOptionsBuilder<Date>;
458
- bigint: () => PropertyOptionsBuilder<NonNullable<string | number | bigint | null | undefined>>;
459
461
  blob: () => PropertyOptionsBuilder<NonNullable<Uint8Array<ArrayBufferLike> | Buffer<ArrayBufferLike> | null>>;
460
462
  uint8array: () => PropertyOptionsBuilder<Uint8Array<ArrayBufferLike>>;
461
- array: () => PropertyOptionsBuilder<unknown[]>;
462
463
  enumArray: () => PropertyOptionsBuilder<(string | number)[]>;
463
464
  integer: () => PropertyOptionsBuilder<number>;
464
465
  smallint: () => PropertyOptionsBuilder<number>;
@@ -467,7 +468,6 @@ declare const propertyBuilders: {
467
468
  float: () => PropertyOptionsBuilder<number>;
468
469
  double: () => PropertyOptionsBuilder<NonNullable<string | number>>;
469
470
  boolean: () => PropertyOptionsBuilder<NonNullable<boolean | null | undefined>>;
470
- decimal: () => PropertyOptionsBuilder<NonNullable<string | number>>;
471
471
  character: () => PropertyOptionsBuilder<string>;
472
472
  string: () => PropertyOptionsBuilder<string>;
473
473
  uuid: () => PropertyOptionsBuilder<string>;
@@ -481,6 +481,9 @@ export declare function defineEntity<Properties extends Record<string, any>>(met
481
481
  }): EntitySchema<InferEntityFromProperties<Properties>, never>;
482
482
  export declare namespace defineEntity {
483
483
  var properties: {
484
+ bigint: <Mode extends "bigint" | "number" | "string" = "bigint">(mode?: Mode) => PropertyOptionsBuilder<(Mode extends "bigint" ? bigint : Mode extends "number" ? number : string) & {}>;
485
+ array: <T = string>(toJsValue?: (i: string) => T, toDbValue?: (i: T) => string) => PropertyOptionsBuilder<T[]>;
486
+ decimal: <Mode extends "number" | "string" = "string">(mode?: Mode) => PropertyOptionsBuilder<NonNullable<Mode extends "number" ? number : string>>;
484
487
  json: <T>() => PropertyOptionsBuilder<T>;
485
488
  formula: <T>(formula: string | ((alias: string) => string)) => PropertyOptionsBuilder<T>;
486
489
  type: <T extends PropertyValueType>(type: T) => PropertyOptionsBuilder<InferPropertyValueType<T>>;
@@ -493,10 +496,8 @@ export declare namespace defineEntity {
493
496
  date: () => PropertyOptionsBuilder<string>;
494
497
  time: () => PropertyOptionsBuilder<any>;
495
498
  datetime: () => PropertyOptionsBuilder<Date>;
496
- bigint: () => PropertyOptionsBuilder<NonNullable<string | number | bigint | null | undefined>>;
497
499
  blob: () => PropertyOptionsBuilder<NonNullable<Uint8Array<ArrayBufferLike> | Buffer<ArrayBufferLike> | null>>;
498
500
  uint8array: () => PropertyOptionsBuilder<Uint8Array<ArrayBufferLike>>;
499
- array: () => PropertyOptionsBuilder<unknown[]>;
500
501
  enumArray: () => PropertyOptionsBuilder<(string | number)[]>;
501
502
  integer: () => PropertyOptionsBuilder<number>;
502
503
  smallint: () => PropertyOptionsBuilder<number>;
@@ -505,7 +506,6 @@ export declare namespace defineEntity {
505
506
  float: () => PropertyOptionsBuilder<number>;
506
507
  double: () => PropertyOptionsBuilder<NonNullable<string | number>>;
507
508
  boolean: () => PropertyOptionsBuilder<NonNullable<boolean | null | undefined>>;
508
- decimal: () => PropertyOptionsBuilder<NonNullable<string | number>>;
509
509
  character: () => PropertyOptionsBuilder<string>;
510
510
  string: () => PropertyOptionsBuilder<string>;
511
511
  uuid: () => PropertyOptionsBuilder<string>;
@@ -635,6 +635,9 @@ function createPropertyBuilders(options) {
635
635
  }
636
636
  const propertyBuilders = {
637
637
  ...createPropertyBuilders(types_1.types),
638
+ bigint: (mode) => new PropertyOptionsBuilder({ type: new types_1.types.bigint(mode) }),
639
+ array: (toJsValue = i => i, toDbValue = i => i) => new PropertyOptionsBuilder({ type: new types_1.types.array(toJsValue, toDbValue) }),
640
+ decimal: (mode) => new PropertyOptionsBuilder({ type: new types_1.types.decimal(mode) }),
638
641
  json: () => new PropertyOptionsBuilder({ type: types_1.types.json }),
639
642
  formula: (formula) => new PropertyOptionsBuilder({ formula }),
640
643
  type: (type) => new PropertyOptionsBuilder({ type }),
@@ -1136,7 +1136,7 @@ class MetadataDiscovery {
1136
1136
  if (prop.fieldNames?.length === 1 && !prop.customType) {
1137
1137
  [types_1.BigIntType, types_1.DoubleType, types_1.DecimalType, types_1.IntervalType, types_1.DateType]
1138
1138
  .filter(type => mappedType instanceof type)
1139
- .forEach(type => prop.customType = new type());
1139
+ .forEach((type) => prop.customType = new type());
1140
1140
  }
1141
1141
  if (prop.customType && !prop.columnTypes) {
1142
1142
  const mappedType = this.getMappedType({ columnTypes: [prop.customType.getColumnType(prop, this.platform)] });
@@ -13,7 +13,7 @@ class MetadataStorage {
13
13
  this.metadata = Utils_1.Utils.copy(metadata, false);
14
14
  }
15
15
  static getMetadata(entity, path) {
16
- const key = entity && path ? entity + '-' + Utils_1.Utils.hash(path) : null;
16
+ const key = entity && path ? entity + '-' + Utils_1.Utils.hash(path, undefined, 'sha256') : null;
17
17
  if (key && !MetadataStorage.metadata[key]) {
18
18
  MetadataStorage.metadata[key] = new typings_1.EntityMetadata({ className: entity, path });
19
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "6.5.6-dev.0",
3
+ "version": "6.5.6-dev.10",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -64,7 +64,7 @@
64
64
  "esprima": "4.0.1",
65
65
  "fs-extra": "11.3.2",
66
66
  "globby": "11.1.0",
67
- "mikro-orm": "6.5.6-dev.0",
67
+ "mikro-orm": "6.5.6-dev.10",
68
68
  "reflect-metadata": "0.2.2"
69
69
  }
70
70
  }
@@ -5,13 +5,15 @@ import type { EntityProperty } from '../typings';
5
5
  * This type will automatically convert string values returned from the database to native JS bigints (default)
6
6
  * or numbers (safe only for values up to `Number.MAX_SAFE_INTEGER`), or strings, depending on the `mode`.
7
7
  */
8
- export declare class BigIntType extends Type<string | bigint | number | null | undefined, string | null | undefined> {
9
- mode?: "bigint" | "number" | "string" | undefined;
10
- constructor(mode?: "bigint" | "number" | "string" | undefined);
11
- convertToDatabaseValue(value: string | bigint | null | undefined): string | null | undefined;
12
- convertToJSValue(value: string | bigint | null | undefined): bigint | number | string | null | undefined;
13
- toJSON(value: string | bigint | null | undefined): string | bigint | null | undefined;
8
+ export declare class BigIntType<Mode extends 'bigint' | 'number' | 'string' = 'bigint'> extends Type<JSTypeByMode<Mode> | null | undefined, string | null | undefined> {
9
+ mode?: Mode | undefined;
10
+ constructor(mode?: Mode | undefined);
11
+ convertToDatabaseValue(value: JSTypeByMode<Mode> | null | undefined): string | null | undefined;
12
+ convertToJSValue(value: string | bigint | null | undefined): JSTypeByMode<Mode> | null | undefined;
13
+ toJSON(value: JSTypeByMode<Mode> | null | undefined): JSTypeByMode<Mode> | null | undefined;
14
14
  getColumnType(prop: EntityProperty, platform: Platform): string;
15
15
  compareAsType(): string;
16
16
  compareValues(a: string, b: string): boolean;
17
17
  }
18
+ type JSTypeByMode<Mode extends 'bigint' | 'number' | 'string'> = Mode extends 'bigint' ? bigint : Mode extends 'number' ? number : string;
19
+ export {};
@@ -4,12 +4,14 @@ import type { EntityProperty } from '../typings';
4
4
  /**
5
5
  * Type that maps an SQL DECIMAL to a JS string or number.
6
6
  */
7
- export declare class DecimalType extends Type<string | number, string> {
8
- mode?: "number" | "string" | undefined;
9
- constructor(mode?: "number" | "string" | undefined);
10
- convertToJSValue(value: string): number | string;
7
+ export declare class DecimalType<Mode extends 'number' | 'string' = 'string'> extends Type<JSTypeByMode<Mode>, string> {
8
+ mode?: Mode | undefined;
9
+ constructor(mode?: Mode | undefined);
10
+ convertToJSValue(value: string): JSTypeByMode<Mode>;
11
11
  compareValues(a: string, b: string): boolean;
12
12
  private format;
13
13
  getColumnType(prop: EntityProperty, platform: Platform): string;
14
14
  compareAsType(): string;
15
15
  }
16
+ type JSTypeByMode<Mode extends 'number' | 'string'> = Mode extends 'number' ? number : string;
17
+ export {};
@@ -81,6 +81,7 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
81
81
  ensureDatabase: true;
82
82
  ensureIndexes: false;
83
83
  batchSize: number;
84
+ hashAlgorithm: "md5";
84
85
  debug: false;
85
86
  ignoreDeprecations: false;
86
87
  verbose: false;
@@ -103,6 +104,8 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
103
104
  disableForeignKeys: false;
104
105
  createForeignKeyConstraints: true;
105
106
  ignoreSchema: never[];
107
+ skipTables: never[];
108
+ skipColumns: {};
106
109
  };
107
110
  embeddables: {
108
111
  prefixMode: "absolute";
@@ -395,6 +398,8 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
395
398
  disableForeignKeys?: boolean;
396
399
  createForeignKeyConstraints?: boolean;
397
400
  ignoreSchema?: string[];
401
+ skipTables?: (string | RegExp)[];
402
+ skipColumns?: Dictionary<(string | RegExp)[]>;
398
403
  managementDbName?: string;
399
404
  };
400
405
  embeddables: {
@@ -423,6 +428,7 @@ export interface MikroORMOptions<D extends IDatabaseDriver = IDatabaseDriver, EM
423
428
  };
424
429
  seeder: SeederOptions;
425
430
  preferReadReplicas: boolean;
431
+ hashAlgorithm: 'md5' | 'sha256';
426
432
  dynamicImportProvider: (id: string) => Promise<unknown>;
427
433
  }
428
434
  export type Options<D extends IDatabaseDriver = IDatabaseDriver, EM extends D[typeof EntityManagerType] & EntityManager = D[typeof EntityManagerType] & EntityManager> = Pick<MikroORMOptions<D, EM>, Exclude<keyof MikroORMOptions<D, EM>, keyof typeof Configuration.DEFAULTS>> & Partial<MikroORMOptions<D, EM>>;
@@ -75,6 +75,7 @@ class Configuration {
75
75
  ensureDatabase: true,
76
76
  ensureIndexes: false,
77
77
  batchSize: 300,
78
+ hashAlgorithm: 'md5',
78
79
  debug: false,
79
80
  ignoreDeprecations: false,
80
81
  verbose: false,
@@ -97,6 +98,8 @@ class Configuration {
97
98
  disableForeignKeys: false,
98
99
  createForeignKeyConstraints: true,
99
100
  ignoreSchema: [],
101
+ skipTables: [],
102
+ skipColumns: {},
100
103
  },
101
104
  embeddables: {
102
105
  prefixMode: 'absolute',
@@ -266,7 +269,7 @@ class Configuration {
266
269
  * Gets instance of metadata CacheAdapter. (cached)
267
270
  */
268
271
  getMetadataCacheAdapter() {
269
- return this.getCachedService(this.options.metadataCache.adapter, this.options.metadataCache.options, this.options.baseDir, this.options.metadataCache.pretty);
272
+ return this.getCachedService(this.options.metadataCache.adapter, this.options.metadataCache.options, this.options.baseDir, this.options.metadataCache.pretty, this.options.hashAlgorithm);
270
273
  }
271
274
  /**
272
275
  * Gets instance of CacheAdapter for result cache. (cached)
package/utils/Utils.d.ts CHANGED
@@ -204,7 +204,7 @@ export declare class Utils {
204
204
  * If either `path` or `baseDir` are `file:` URLs, they are converted to local paths.
205
205
  */
206
206
  static absolutePath(path: string, baseDir?: string): string;
207
- static hash(data: string, length?: number): string;
207
+ static hash(data: string, length?: number, algorithm?: 'md5' | 'sha256'): string;
208
208
  static runIfNotEmpty(clause: () => any, data: any): void;
209
209
  static defaultValue<T extends Dictionary>(prop: T, option: keyof T, defaultValue: any): void;
210
210
  static findDuplicates<T>(items: T[]): T[];
package/utils/Utils.js CHANGED
@@ -805,8 +805,9 @@ class Utils {
805
805
  }
806
806
  return Utils.normalizePath(path);
807
807
  }
808
- static hash(data, length) {
809
- const hash = (0, node_crypto_1.createHash)('md5').update(data).digest('hex');
808
+ static hash(data, length, algorithm) {
809
+ const hashAlgorithm = algorithm || 'sha256';
810
+ const hash = (0, node_crypto_1.createHash)(hashAlgorithm).update(data).digest('hex');
810
811
  if (length) {
811
812
  return hash.substring(0, length);
812
813
  }