| 45 | } |
| 46 | |
| 47 | export default class Hydro { |
| 48 | constructor({ secret, endpoint, forceDisableMock } = {}) { |
| 49 | // When mocking, the secret isn't important because nothing's actually |
| 50 | // password protected in terms of HTTP authorization. But, the |
| 51 | // secret is used for creating an HMAC payload so it has to be |
| 52 | // a string. |
| 53 | this.secret = secret || process.env.HYDRO_SECRET || (MOCK_HYDRO_POST && '') |
| 54 | this.endpoint = endpoint || process.env.HYDRO_ENDPOINT |
| 55 | // This class is involved in 2 types of jest tests: |
| 56 | // 1. end-to-end tests where jest talks to localhost:4000 (with NODE_ENV===test) |
| 57 | // 2. literal unit tests that might mock the socket stuff |
| 58 | // Because `MOCK_HYDRO_POST = process.env.NODE_ENV === 'test'` gets set |
| 59 | // for either type of jest tests, this additional setting makes it |
| 60 | // possible to override `process.env.NODE_ENV === 'test'` from |
| 61 | // mocking the HTTP calls. |
| 62 | this.forceDisableMock = forceDisableMock |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * Can check if it can actually send to Hydro |
| 67 | */ |
| 68 | maySend() { |
| 69 | return Boolean(this.secret && this.endpoint) || MOCK_HYDRO_POST |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * Generate a SHA256 hash of the payload using the secret |
| 74 | * to authenticate with Hydro |
| 75 | * @param {string} body |
| 76 | */ |
| 77 | generatePayloadHmac(body) { |
| 78 | return crypto.createHmac('sha256', this.secret).update(body).digest('hex') |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Publish a single event to Hydro |
| 83 | * @param {string} schema |
| 84 | * @param {any} value |
| 85 | */ |
| 86 | async publish(schema, value) { |
| 87 | const body = JSON.stringify({ |
| 88 | events: [ |
| 89 | { |
| 90 | schema, |
| 91 | value: JSON.stringify(value), // We must double-encode the value property |
| 92 | cluster: 'potomac', // We only have ability to publish externally to potomac cluster |
| 93 | }, |
| 94 | ], |
| 95 | }) |
| 96 | const token = this.generatePayloadHmac(body) |
| 97 | |
| 98 | const agent = getHttpsAgent() |
| 99 | |
| 100 | const doPost = async () => { |
| 101 | // We *could* exit early on this whole `publish()` method if we know |
| 102 | // we're going to "mock" Hydro anyway, but injecting here, before |
| 103 | // the actual network operation, we make most of this method's code |
| 104 | // execute without actually depending on real network. This is |
nothing calls this directly
no outgoing calls
no test coverage detected