• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SmoothIntegration / sdk-node / 13233305537

10 Feb 2025 04:04AM UTC coverage: 81.553% (+0.4%) from 81.188%
13233305537

push

github

thimovss
document_type can now also be a single DocumentType, rather than always requiring an array

39 of 53 branches covered (73.58%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 1 file covered. (100.0%)

129 of 153 relevant lines covered (84.31%)

21.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.3
/src/HTTP.ts
1
import { createHmac } from 'node:crypto';
14✔
2

3
import Client, { SIError } from './index';
14✔
4

5
export default class HTTP {
14✔
6
    _client: Client;
7

8
    constructor(client: Client) {
9
        this._client = client;
62✔
10
    }
11

12
    private async generateHMAC(request: Request, requestBody?: RequestInit['body']): Promise<[string, string]> {
13
        const timestamp: string = new Date().toISOString();
61✔
14
        const hmac = createHmac('sha256', this._client.clientSecret);
61✔
15
        hmac.update(`${this._client.clientId}${request.method}${request.url}${timestamp}`);
61✔
16
        if (requestBody) {
61✔
17
            hmac.update(requestBody.toString());
8✔
18
        }
19
        return [hmac.digest('hex'), timestamp];
61✔
20
    }
21

22
    /**
23
     * Makes an authenticated HTTP request to the Smooth Integration API.
24
     * @param url {string} endpoint path, @example '/cdc'
25
     * @param input {RequestInit} any additional request options you want to pass to the request.
26
     *  Required headers like Content-Type and all HMAC Auth headers do not need to be passed.
27
     */
28
    public async fetch<T>(url: string, input?: RequestInit): Promise<T> {
29
        const request: Request = new Request(this._client.apiUrl + url, input);
61✔
30

31
        // Sign the request with HMAC signature, Timestamp, and Organisation ID
32
        const [hmac, timestamp] = await this.generateHMAC(request, input?.body);
61✔
33
        request.headers.set('X-Signature', hmac);
61✔
34
        request.headers.set('X-Organisation', this._client.clientId);
61✔
35
        request.headers.set('X-Timestamp', timestamp);
61✔
36
        request.headers.set('Content-Type', 'application/json; charset=utf-8');
61✔
37

38
        let response: Response;
39
        try {
61✔
40
            response = await fetch(request);
61✔
41
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
        } catch (error: any) {
43
            throw new SIError(error.message || 'Network Error', error);
1!
44
        }
45

46
        let body;
47
        try {
60✔
48
            body = await response.json();
60✔
49
        } catch (error: unknown) {
50
            throw new SIError('Invalid JSON Received', error);
1✔
51
        }
52

53
        if (!response.ok) {
59✔
54
            if (response.status >= 500) {
27✔
55
                throw new SIError(response.statusText);
9✔
56
            } else {
57
                // TODO: check for error code, could be we receive errors like 400 from the external system when users make proxy requests, which we do not want to throw as an SIError
58
                throw new SIError(response.statusText + ': ' + body.message);
18✔
59
            }
60
        }
61

62
        return body;
32✔
63
    }
64
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc