userIntegrations.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. Object.defineProperty(exports, '__esModule', { value: true });
  2. /**
  3. * Recursively traverses an object to update an existing nested key.
  4. * Note: The provided key path must include existing properties,
  5. * the function will not create objects while traversing.
  6. *
  7. * @param obj An object to update
  8. * @param value The value to update the nested key with
  9. * @param keyPath The path to the key to update ex. fizz.buzz.foo
  10. */
  11. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  12. function setNestedKey(obj, keyPath, value) {
  13. // Ex. foo.bar.zoop will extract foo and bar.zoop
  14. const match = keyPath.match(/([a-z_]+)\.(.*)/i);
  15. // The match will be null when there's no more recursing to do, i.e., when we've reached the right level of the object
  16. if (match === null) {
  17. obj[keyPath] = value;
  18. } else {
  19. // `match[1]` is the initial segment of the path, and `match[2]` is the remainder of the path
  20. const innerObj = obj[match[1]];
  21. setNestedKey(innerObj, match[2], value);
  22. }
  23. }
  24. /**
  25. * Enforces inclusion of a given integration with specified options in an integration array originally determined by the
  26. * user, by either including the given default instance or by patching an existing user instance with the given options.
  27. *
  28. * Ideally this would happen when integrations are set up, but there isn't currently a mechanism there for merging
  29. * options from a default integration instance with those from a user-provided instance of the same integration, only
  30. * for allowing the user to override a default instance entirely. (TODO: Fix that.)
  31. *
  32. * @param defaultIntegrationInstance An instance of the integration with the correct options already set
  33. * @param userIntegrations Integrations defined by the user.
  34. * @param forcedOptions Options with which to patch an existing user-derived instance on the integration.
  35. * @returns A final integrations array.
  36. *
  37. * @deprecated This will be removed in v8.
  38. */
  39. function addOrUpdateIntegration(
  40. defaultIntegrationInstance,
  41. userIntegrations,
  42. forcedOptions = {},
  43. ) {
  44. return (
  45. Array.isArray(userIntegrations)
  46. ? addOrUpdateIntegrationInArray(defaultIntegrationInstance, userIntegrations, forcedOptions)
  47. : addOrUpdateIntegrationInFunction(
  48. defaultIntegrationInstance,
  49. // Somehow TS can't figure out that not being an array makes this necessarily a function
  50. userIntegrations ,
  51. forcedOptions,
  52. )
  53. ) ;
  54. }
  55. function addOrUpdateIntegrationInArray(
  56. defaultIntegrationInstance,
  57. userIntegrations,
  58. forcedOptions,
  59. ) {
  60. const userInstance = userIntegrations.find(integration => integration.name === defaultIntegrationInstance.name);
  61. if (userInstance) {
  62. for (const [keyPath, value] of Object.entries(forcedOptions)) {
  63. setNestedKey(userInstance, keyPath, value);
  64. }
  65. return userIntegrations;
  66. }
  67. return [...userIntegrations, defaultIntegrationInstance];
  68. }
  69. function addOrUpdateIntegrationInFunction(
  70. defaultIntegrationInstance,
  71. userIntegrationsFunc,
  72. forcedOptions,
  73. ) {
  74. const wrapper = defaultIntegrations => {
  75. const userFinalIntegrations = userIntegrationsFunc(defaultIntegrations);
  76. // There are instances where we want the user to be able to prevent an integration from appearing at all, which they
  77. // would do by providing a function which filters out the integration in question. If that's happened in one of
  78. // those cases, don't add our default back in.
  79. if (defaultIntegrationInstance.allowExclusionByUser) {
  80. const userFinalInstance = userFinalIntegrations.find(
  81. integration => integration.name === defaultIntegrationInstance.name,
  82. );
  83. if (!userFinalInstance) {
  84. return userFinalIntegrations;
  85. }
  86. }
  87. return addOrUpdateIntegrationInArray(defaultIntegrationInstance, userFinalIntegrations, forcedOptions);
  88. };
  89. return wrapper;
  90. }
  91. exports.addOrUpdateIntegration = addOrUpdateIntegration;
  92. //# sourceMappingURL=userIntegrations.js.map