1. /**
  2. * Hashes metadata values for an experiment with defensive checks.
  3. *
  4. * @param {object} metadata - An object containing the metadata values to hash.
  5. * @param {string} hashAlgorithm - The hashing algorithm to use (e.g., 'sha256', 'md5'). Defaults to 'sha256'.
  6. * @returns {Promise<object>} - An object containing the hashed metadata values. Returns an empty object if metadata is invalid.
  7. * @throws {TypeError} If metadata is not an object or hashAlgorithm is not a string.
  8. */
  9. async function hashMetadata(metadata, hashAlgorithm = 'sha256') {
  10. if (typeof metadata !== 'object' || metadata === null) {
  11. console.error("Invalid metadata: Metadata must be an object.");
  12. return {};
  13. }
  14. if (typeof hashAlgorithm !== 'string') {
  15. throw new TypeError("hashAlgorithm must be a string.");
  16. }
  17. const crypto = require('crypto'); // Import crypto module
  18. const hashedMetadata = {};
  19. for (const key in metadata) {
  20. if (Object.hasOwnProperty.call(metadata, key)) {
  21. const value = metadata[key];
  22. if (value === null || value === undefined) {
  23. console.warn(`Skipping key '${key}' because its value is null or undefined.`);
  24. continue; // Skip null/undefined values
  25. }
  26. let data;
  27. if (typeof value === 'string') {
  28. data = Buffer.from(value, 'utf8'); // Ensure string is encoded as Buffer
  29. } else if (typeof value === 'number') {
  30. data = Buffer.from(value.toString()); // Convert number to string and then to Buffer
  31. } else if (Array.isArray(value)) {
  32. let arrayString = JSON.stringify(value);
  33. data = Buffer.from(arrayString, 'utf8');
  34. } else if (typeof value === 'object') {
  35. data = JSON.stringify(value)
  36. data = Buffer.from(data, 'utf8');
  37. }
  38. else {
  39. console.warn(`Skipping key '${key}' because its type is not supported.`);
  40. continue;
  41. }
  42. let hash;
  43. try {
  44. if (hashAlgorithm === 'sha256') {
  45. hash = crypto.createHash('sha256').update(data).digest('hex');
  46. } else if (hashAlgorithm === 'md5') {
  47. hash = crypto.createHash('md5').update(data).digest('hex');
  48. } else {
  49. console.warn(`Unsupported hash algorithm: ${hashAlgorithm}. Defaulting to sha256.`);
  50. hash = crypto.createHash('sha256').update(data).digest('hex');
  51. }
  52. } catch (error) {
  53. console.error(`Error hashing value for key '${key}':`, error);
  54. continue;
  55. }
  56. hashedMetadata[key] = hash;
  57. }
  58. }
  59. return hashedMetadata;
  60. }

Add your comment