Require Node.js 22 · sindresorhus/got@b933476 (original) (raw)

``

1

`+

import process from 'node:process';

`

``

2

`+

import crypto from 'node:crypto';

`

1

3

`import got from '../../dist/source/index.js';

`

2

4

``

``

5

`+

// Signing requests

`

``

6

+

3

7

`/*

`

4

``

`-

`

5

``

`-

`

6

``

`-

`

7

``

`-

`

8

``

`-

`

9

``

`-

`

10

``

`-

`

11

``

`-

`

12

``

`` -

``

13

``

`-

`

``

8

`+

Got supports composing multiple instances together. This is very powerful.

`

``

9

+

``

10

`+

You can create a client that limits download/upload size, then compose it with an instance that signs a request.

`

``

11

+

``

12

`+

It's like plugins without any of the plugin mess.

`

``

13

`+

You just create instances and then compose them together.

`

``

14

+

``

15

`` +

To mix them use instanceA.extend(instanceB, instanceC, ...), that's all.

``

``

16

+

``

17

`+

Let's begin.

`

14

18

`*/

`

15

19

``

16

20

`` // Logging all got(…) calls

``

`@@ -19,8 +23,8 @@ const logger = got.extend({

`

19

23

`(options, next) => {

`

20

24

`` console.log(Sending <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>o</mi><mi>p</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><mi>s</mi><mi mathvariant="normal">.</mi><mi>m</mi><mi>e</mi><mi>t</mi><mi>h</mi><mi>o</mi><mi>d</mi></mrow><mi>t</mi><mi>o</mi></mrow><annotation encoding="application/x-tex">{options.method} to </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">o</span><span class="mord mathnormal">pt</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span></span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span></span></span></span>{options.url});

``

21

25

`return next(options);

`

22

``

`-

}

`

23

``

`-

]

`

``

26

`+

},

`

``

27

`+

],

`

24

28

`});

`

25

29

``

26

30

`// Denying redirects to foreign hosts

`

`@@ -32,9 +36,9 @@ const controlRedirects = got.extend({

`

32

36

`if (options.url.origin !== origin) {

`

33

37

`` throw new Error(Redirection to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>o</mi><mi>p</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><mi>s</mi><mi mathvariant="normal">.</mi><mi>u</mi><mi>r</mi><mi>l</mi><mi mathvariant="normal">.</mi><mi>o</mi><mi>r</mi><mi>i</mi><mi>g</mi><mi>i</mi><mi>n</mi></mrow><mi>i</mi><mi>s</mi><mi>n</mi><mi>o</mi><mi>t</mi><mi>a</mi><mi>l</mi><mi>l</mi><mi>o</mi><mi>w</mi><mi>e</mi><mi>d</mi><mi>f</mi><mi>r</mi><mi>o</mi><mi>m</mi></mrow><annotation encoding="application/x-tex">{options.url.origin} is not allowed from </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal">o</span><span class="mord mathnormal">pt</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">in</span></span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">n</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">ll</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10764em;">df</span><span class="mord mathnormal">ro</span><span class="mord mathnormal">m</span></span></span></span>{origin});

``

34

38

`}

`

35

``

`-

}

`

36

``

`-

]

`

37

``

`-

}

`

``

39

`+

},

`

``

40

`+

],

`

``

41

`+

},

`

38

42

`});

`

39

43

``

40

44

`// Limiting download & upload size

`

`@@ -46,7 +50,7 @@ const limitDownloadUpload = got.extend({

`

46

50

``

47

51

`// Create an AbortController if limits are set and signal not already provided

`

48

52

`let controller;

`

49

``

`-

let signal = options.signal;

`

``

53

`+

let {signal} = options;

`

50

54

``

51

55

`if ((downloadLimit || uploadLimit) && !signal) {

`

52

56

`controller = new AbortController();

`

`@@ -85,25 +89,22 @@ const limitDownloadUpload = got.extend({

`

85

89

`}

`

86

90

``

87

91

`return promiseOrStream;

`

88

``

`-

}

`

89

``

`-

]

`

``

92

`+

},

`

``

93

`+

],

`

90

94

`});

`

91

95

``

92

96

`// No user agent

`

93

97

`const noUserAgent = got.extend({

`

94

98

`headers: {

`

95

``

`-

'user-agent': undefined

`

96

``

`-

}

`

``

99

`+

'user-agent': undefined,

`

``

100

`+

},

`

97

101

`});

`

98

102

``

99

103

`// Custom endpoint

`

100

104

`const httpbin = got.extend({

`

101

``

`-

prefixUrl: 'https://httpbin.org/'

`

``

105

`+

prefixUrl: 'https://httpbin.org/',

`

102

106

`});

`

103

107

``

104

``

`-

// Signing requests

`

105

``

`-

import crypto from 'node:crypto';

`

106

``

-

107

108

`const getMessageSignature = (data, secret) => crypto.createHmac('sha256', secret).update(data).digest('hex').toUpperCase();

`

108

109

`const signRequest = got.extend({

`

109

110

`hooks: {

`

`@@ -112,11 +113,11 @@ const signRequest = got.extend({

`

112

113

`const secret = options.context.secret ?? process.env.SECRET;

`

113

114

``

114

115

`if (secret) {

`

115

``

`-

options.headers['sign'] = getMessageSignature(options.body ?? '', secret);

`

``

116

`+

options.headers.sign = getMessageSignature(options.body ?? '', secret);

`

116

117

`}

`

117

``

`-

}

`

118

``

`-

]

`

119

``

`-

}

`

``

118

`+

},

`

``

119

`+

],

`

``

120

`+

},

`

120

121

`});

`

121

122

``

122

123

`/*

`

`@@ -128,15 +129,15 @@ const merged = got.extend(

`

128

129

`limitDownloadUpload,

`

129

130

`httpbin,

`

130

131

`signRequest,

`

131

``

`-

controlRedirects

`

``

132

`+

controlRedirects,

`

132

133

`);

`

133

134

``

134

135

`// There's no 'user-agent' header :)

`

135

136

`const {headers} = await merged.post('anything', {

`

136

137

`body: 'foobar',

`

137

138

`context: {

`

138

``

`-

secret: 'password'

`

139

``

`-

}

`

``

139

`+

secret: 'password',

`

``

140

`+

},

`

140

141

`}).json();

`

141

142

``

142

143

`console.log(headers);

`

`@@ -149,13 +150,13 @@ console.log(headers);

`

149

150

`// Sign: 'EB0167A1EBF205510BAFF5DA1465537944225F0E0140E1880B746F361FF11DCA'

`

150

151

`// }

`

151

152

``

152

``

`-

const MEGABYTE = 1048576;

`

``

153

`+

const MEGABYTE = 1_048_576;

`

153

154

`try {

`

154

155

`await merged('https://pop-iso.sfo2.cdn.digitaloceanspaces.com/21.04/amd64/intel/5/pop-os_21.04_amd64_intel_5.iso', {

`

155

156

`context: {

`

156

``

`-

downloadLimit: MEGABYTE

`

``

157

`+

downloadLimit: MEGABYTE,

`

157

158

`},

`

158

``

`-

prefixUrl: ''

`

``

159

`+

prefixUrl: '',

`

159

160

`});

`

160

161

`} catch (error) {

`

161

162

`// AbortError: This operation was aborted.

`