@depup/got 14.6.6-depup.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +36 -0
  2. package/changes.json +30 -0
  3. package/dist/source/as-promise/index.d.ts +3 -0
  4. package/dist/source/as-promise/index.js +204 -0
  5. package/dist/source/as-promise/types.d.ts +37 -0
  6. package/dist/source/as-promise/types.js +17 -0
  7. package/dist/source/core/calculate-retry-delay.d.ts +4 -0
  8. package/dist/source/core/calculate-retry-delay.js +29 -0
  9. package/dist/source/core/diagnostics-channel.d.ts +89 -0
  10. package/dist/source/core/diagnostics-channel.js +49 -0
  11. package/dist/source/core/errors.d.ts +102 -0
  12. package/dist/source/core/errors.js +147 -0
  13. package/dist/source/core/index.d.ts +192 -0
  14. package/dist/source/core/index.js +1339 -0
  15. package/dist/source/core/options.d.ts +1564 -0
  16. package/dist/source/core/options.js +1838 -0
  17. package/dist/source/core/parse-link-header.d.ts +4 -0
  18. package/dist/source/core/parse-link-header.js +33 -0
  19. package/dist/source/core/response.d.ts +109 -0
  20. package/dist/source/core/response.js +41 -0
  21. package/dist/source/core/timed-out.d.ts +31 -0
  22. package/dist/source/core/timed-out.js +136 -0
  23. package/dist/source/core/utils/defer-to-connect.d.ts +9 -0
  24. package/dist/source/core/utils/defer-to-connect.js +44 -0
  25. package/dist/source/core/utils/get-body-size.d.ts +2 -0
  26. package/dist/source/core/utils/get-body-size.js +37 -0
  27. package/dist/source/core/utils/is-client-request.d.ts +4 -0
  28. package/dist/source/core/utils/is-client-request.js +4 -0
  29. package/dist/source/core/utils/is-form-data.d.ts +7 -0
  30. package/dist/source/core/utils/is-form-data.js +4 -0
  31. package/dist/source/core/utils/is-unix-socket-url.d.ts +17 -0
  32. package/dist/source/core/utils/is-unix-socket-url.js +25 -0
  33. package/dist/source/core/utils/options-to-url.d.ts +12 -0
  34. package/dist/source/core/utils/options-to-url.js +48 -0
  35. package/dist/source/core/utils/proxy-events.d.ts +2 -0
  36. package/dist/source/core/utils/proxy-events.js +15 -0
  37. package/dist/source/core/utils/timer.d.ts +31 -0
  38. package/dist/source/core/utils/timer.js +162 -0
  39. package/dist/source/core/utils/unhandle.d.ts +10 -0
  40. package/dist/source/core/utils/unhandle.js +20 -0
  41. package/dist/source/core/utils/url-to-options.d.ts +14 -0
  42. package/dist/source/core/utils/url-to-options.js +22 -0
  43. package/dist/source/core/utils/weakable-map.d.ts +7 -0
  44. package/dist/source/core/utils/weakable-map.js +24 -0
  45. package/dist/source/create.d.ts +3 -0
  46. package/dist/source/create.js +188 -0
  47. package/dist/source/index.d.ts +16 -0
  48. package/dist/source/index.js +22 -0
  49. package/dist/source/types.d.ts +314 -0
  50. package/dist/source/types.js +1 -0
  51. package/license +9 -0
  52. package/package.json +197 -0
  53. package/readme.md +478 -0
@@ -0,0 +1,162 @@
1
+ import { errorMonitor } from 'node:events';
2
+ import { types } from 'node:util';
3
+ import deferToConnect from './defer-to-connect.js';
4
+ const timer = (request) => {
5
+ if (request.timings) {
6
+ return request.timings;
7
+ }
8
+ const timings = {
9
+ start: Date.now(),
10
+ socket: undefined,
11
+ lookup: undefined,
12
+ connect: undefined,
13
+ secureConnect: undefined,
14
+ upload: undefined,
15
+ response: undefined,
16
+ end: undefined,
17
+ error: undefined,
18
+ abort: undefined,
19
+ phases: {
20
+ wait: undefined,
21
+ dns: undefined,
22
+ tcp: undefined,
23
+ tls: undefined,
24
+ request: undefined,
25
+ firstByte: undefined,
26
+ download: undefined,
27
+ total: undefined,
28
+ },
29
+ };
30
+ request.timings = timings;
31
+ const handleError = (origin) => {
32
+ origin.once(errorMonitor, () => {
33
+ timings.error = Date.now();
34
+ timings.phases.total = timings.error - timings.start;
35
+ });
36
+ };
37
+ handleError(request);
38
+ const onAbort = () => {
39
+ timings.abort = Date.now();
40
+ timings.phases.total = timings.abort - timings.start;
41
+ };
42
+ request.prependOnceListener('abort', onAbort);
43
+ const onSocket = (socket) => {
44
+ timings.socket = Date.now();
45
+ timings.phases.wait = timings.socket - timings.start;
46
+ if (types.isProxy(socket)) {
47
+ // HTTP/2: The socket is a proxy, so connection events won't fire.
48
+ // We can't measure connection timings, so leave them undefined.
49
+ // This prevents NaN in phases.request calculation.
50
+ return;
51
+ }
52
+ // Check if socket is already connected (reused from connection pool)
53
+ const socketAlreadyConnected = socket.writable && !socket.connecting;
54
+ if (socketAlreadyConnected) {
55
+ // Socket reuse detected: the socket was already connected from a previous request.
56
+ // For reused sockets, set all connection timestamps to socket time since no new
57
+ // connection was made for THIS request. But preserve phase durations from the
58
+ // original connection so they're not lost.
59
+ timings.lookup = timings.socket;
60
+ timings.connect = timings.socket;
61
+ if (socket.__initial_connection_timings__) {
62
+ // Restore the phase timings from the initial connection
63
+ timings.phases.dns = socket.__initial_connection_timings__.dnsPhase;
64
+ timings.phases.tcp = socket.__initial_connection_timings__.tcpPhase;
65
+ timings.phases.tls = socket.__initial_connection_timings__.tlsPhase;
66
+ // Set secureConnect timestamp if there was TLS
67
+ if (timings.phases.tls !== undefined) {
68
+ timings.secureConnect = timings.socket;
69
+ }
70
+ }
71
+ else {
72
+ // Socket reused but no initial timings stored (e.g., from external code)
73
+ // Set phases to 0
74
+ timings.phases.dns = 0;
75
+ timings.phases.tcp = 0;
76
+ }
77
+ return;
78
+ }
79
+ const lookupListener = () => {
80
+ timings.lookup = Date.now();
81
+ timings.phases.dns = timings.lookup - timings.socket;
82
+ };
83
+ socket.prependOnceListener('lookup', lookupListener);
84
+ deferToConnect(socket, {
85
+ connect() {
86
+ timings.connect = Date.now();
87
+ if (timings.lookup === undefined) {
88
+ // No DNS lookup occurred (e.g., connecting to an IP address directly)
89
+ // Set lookup to socket time (no time elapsed for DNS)
90
+ socket.removeListener('lookup', lookupListener);
91
+ timings.lookup = timings.socket;
92
+ timings.phases.dns = 0;
93
+ }
94
+ timings.phases.tcp = timings.connect - timings.lookup;
95
+ // If lookup and connect happen at the EXACT same time (tcp = 0),
96
+ // DNS was served from cache and the dns value is just event loop overhead.
97
+ // Set dns to 0 to indicate no actual DNS resolution occurred.
98
+ // Fixes https://github.com/szmarczak/http-timer/issues/35
99
+ if (timings.phases.tcp === 0 && timings.phases.dns && timings.phases.dns > 0) {
100
+ timings.phases.dns = 0;
101
+ }
102
+ // Store connection phase timings on socket for potential reuse
103
+ if (!socket.__initial_connection_timings__) {
104
+ socket.__initial_connection_timings__ = {
105
+ dnsPhase: timings.phases.dns,
106
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- TypeScript can't prove this is defined due to callback structure
107
+ tcpPhase: timings.phases.tcp,
108
+ };
109
+ }
110
+ },
111
+ secureConnect() {
112
+ timings.secureConnect = Date.now();
113
+ timings.phases.tls = timings.secureConnect - timings.connect;
114
+ // Update stored timings with TLS phase timing
115
+ if (socket.__initial_connection_timings__) {
116
+ socket.__initial_connection_timings__.tlsPhase = timings.phases.tls;
117
+ }
118
+ },
119
+ });
120
+ };
121
+ if (request.socket) {
122
+ onSocket(request.socket);
123
+ }
124
+ else {
125
+ request.prependOnceListener('socket', onSocket);
126
+ }
127
+ const onUpload = () => {
128
+ timings.upload = Date.now();
129
+ // Calculate request phase if we have connection timings
130
+ const secureOrConnect = timings.secureConnect ?? timings.connect;
131
+ if (secureOrConnect !== undefined) {
132
+ timings.phases.request = timings.upload - secureOrConnect;
133
+ }
134
+ // If both are undefined (HTTP/2), phases.request stays undefined (not NaN)
135
+ };
136
+ if (request.writableFinished) {
137
+ onUpload();
138
+ }
139
+ else {
140
+ request.prependOnceListener('finish', onUpload);
141
+ }
142
+ request.prependOnceListener('response', (response) => {
143
+ timings.response = Date.now();
144
+ timings.phases.firstByte = timings.response - timings.upload;
145
+ response.timings = timings;
146
+ handleError(response);
147
+ response.prependOnceListener('end', () => {
148
+ request.off('abort', onAbort);
149
+ response.off('aborted', onAbort);
150
+ if (timings.phases.total !== undefined) {
151
+ // Aborted or errored
152
+ return;
153
+ }
154
+ timings.end = Date.now();
155
+ timings.phases.download = timings.end - timings.response;
156
+ timings.phases.total = timings.end - timings.start;
157
+ });
158
+ response.prependOnceListener('aborted', onAbort);
159
+ });
160
+ return timings;
161
+ };
162
+ export default timer;
@@ -0,0 +1,10 @@
1
+ import type { EventEmitter } from 'node:events';
2
+ type Origin = EventEmitter;
3
+ type Event = string | symbol;
4
+ type AnyFunction = (...arguments_: any[]) => void;
5
+ type Unhandler = {
6
+ once: (origin: Origin, event: Event, function_: AnyFunction) => void;
7
+ unhandleAll: () => void;
8
+ };
9
+ export default function unhandle(): Unhandler;
10
+ export {};
@@ -0,0 +1,20 @@
1
+ // When attaching listeners, it's very easy to forget about them.
2
+ // Especially if you do error handling and set timeouts.
3
+ // So instead of checking if it's proper to throw an error on every timeout ever,
4
+ // use this simple tool which will remove all listeners you have attached.
5
+ export default function unhandle() {
6
+ const handlers = [];
7
+ return {
8
+ once(origin, event, function_) {
9
+ origin.once(event, function_);
10
+ handlers.push({ origin, event, fn: function_ });
11
+ },
12
+ unhandleAll() {
13
+ for (const handler of handlers) {
14
+ const { origin, event, fn } = handler;
15
+ origin.removeListener(event, fn);
16
+ }
17
+ handlers.length = 0;
18
+ },
19
+ };
20
+ }
@@ -0,0 +1,14 @@
1
+ import type { UrlWithStringQuery } from 'node:url';
2
+ export type LegacyUrlOptions = {
3
+ protocol: string;
4
+ hostname: string;
5
+ host: string;
6
+ hash: string | null;
7
+ search: string | null;
8
+ pathname: string;
9
+ href: string;
10
+ path: string;
11
+ port?: number;
12
+ auth?: string;
13
+ };
14
+ export default function urlToOptions(url: URL | UrlWithStringQuery): LegacyUrlOptions;
@@ -0,0 +1,22 @@
1
+ import is from '@sindresorhus/is';
2
+ export default function urlToOptions(url) {
3
+ // Cast to URL
4
+ url = url;
5
+ const options = {
6
+ protocol: url.protocol,
7
+ hostname: is.string(url.hostname) && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
8
+ host: url.host,
9
+ hash: url.hash,
10
+ search: url.search,
11
+ pathname: url.pathname,
12
+ href: url.href,
13
+ path: `${url.pathname || ''}${url.search || ''}`,
14
+ };
15
+ if (is.string(url.port) && url.port.length > 0) {
16
+ options.port = Number(url.port);
17
+ }
18
+ if (url.username || url.password) {
19
+ options.auth = `${url.username || ''}:${url.password || ''}`;
20
+ }
21
+ return options;
22
+ }
@@ -0,0 +1,7 @@
1
+ export default class WeakableMap<K, V> {
2
+ weakMap: WeakMap<Record<string, unknown>, V>;
3
+ map: Map<K, V>;
4
+ set(key: K, value: V): void;
5
+ get(key: K): V | undefined;
6
+ has(key: K): boolean;
7
+ }
@@ -0,0 +1,24 @@
1
+ export default class WeakableMap {
2
+ weakMap = new WeakMap();
3
+ map = new Map();
4
+ set(key, value) {
5
+ if (typeof key === 'object') {
6
+ this.weakMap.set(key, value);
7
+ }
8
+ else {
9
+ this.map.set(key, value);
10
+ }
11
+ }
12
+ get(key) {
13
+ if (typeof key === 'object') {
14
+ return this.weakMap.get(key);
15
+ }
16
+ return this.map.get(key);
17
+ }
18
+ has(key) {
19
+ if (typeof key === 'object') {
20
+ return this.weakMap.has(key);
21
+ }
22
+ return this.map.has(key);
23
+ }
24
+ }
@@ -0,0 +1,3 @@
1
+ import type { Got, InstanceDefaults } from './types.js';
2
+ declare const create: (defaults: InstanceDefaults) => Got;
3
+ export default create;
@@ -0,0 +1,188 @@
1
+ import { setTimeout as delay } from 'node:timers/promises';
2
+ import is, { assert } from '@sindresorhus/is';
3
+ import asPromise from './as-promise/index.js';
4
+ import Request from './core/index.js';
5
+ import Options from './core/options.js';
6
+ const isGotInstance = (value) => is.function(value);
7
+ const aliases = [
8
+ 'get',
9
+ 'post',
10
+ 'put',
11
+ 'patch',
12
+ 'head',
13
+ 'delete',
14
+ ];
15
+ const create = (defaults) => {
16
+ defaults = {
17
+ options: new Options(undefined, undefined, defaults.options),
18
+ handlers: [...defaults.handlers],
19
+ mutableDefaults: defaults.mutableDefaults,
20
+ };
21
+ Object.defineProperty(defaults, 'mutableDefaults', {
22
+ enumerable: true,
23
+ configurable: false,
24
+ writable: false,
25
+ });
26
+ // Got interface
27
+ const got = ((url, options, defaultOptions = defaults.options) => {
28
+ const request = new Request(url, options, defaultOptions);
29
+ let promise;
30
+ const lastHandler = (normalized) => {
31
+ // Note: `options` is `undefined` when `new Options(...)` fails
32
+ request.options = normalized;
33
+ request._noPipe = !normalized?.isStream;
34
+ void request.flush();
35
+ if (normalized?.isStream) {
36
+ return request;
37
+ }
38
+ promise ||= asPromise(request);
39
+ return promise;
40
+ };
41
+ let iteration = 0;
42
+ const iterateHandlers = (newOptions) => {
43
+ const handler = defaults.handlers[iteration++] ?? lastHandler;
44
+ const result = handler(newOptions, iterateHandlers);
45
+ if (is.promise(result) && !request.options?.isStream) {
46
+ promise ||= asPromise(request);
47
+ if (result !== promise) {
48
+ const descriptors = Object.getOwnPropertyDescriptors(promise);
49
+ for (const key in descriptors) {
50
+ if (key in result) {
51
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
52
+ delete descriptors[key];
53
+ }
54
+ }
55
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
56
+ Object.defineProperties(result, descriptors);
57
+ result.cancel = promise.cancel;
58
+ }
59
+ }
60
+ return result;
61
+ };
62
+ return iterateHandlers(request.options);
63
+ });
64
+ got.extend = (...instancesOrOptions) => {
65
+ const options = new Options(undefined, undefined, defaults.options);
66
+ const handlers = [...defaults.handlers];
67
+ let mutableDefaults;
68
+ for (const value of instancesOrOptions) {
69
+ if (isGotInstance(value)) {
70
+ options.merge(value.defaults.options);
71
+ handlers.push(...value.defaults.handlers);
72
+ mutableDefaults = value.defaults.mutableDefaults;
73
+ }
74
+ else {
75
+ options.merge(value);
76
+ if (value.handlers) {
77
+ handlers.push(...value.handlers);
78
+ }
79
+ mutableDefaults = value.mutableDefaults;
80
+ }
81
+ }
82
+ return create({
83
+ options,
84
+ handlers,
85
+ mutableDefaults: Boolean(mutableDefaults),
86
+ });
87
+ };
88
+ // Pagination
89
+ const paginateEach = (async function* (url, options) {
90
+ let normalizedOptions = new Options(url, options, defaults.options);
91
+ normalizedOptions.resolveBodyOnly = false;
92
+ const { pagination } = normalizedOptions;
93
+ assert.function(pagination.transform);
94
+ assert.function(pagination.shouldContinue);
95
+ assert.function(pagination.filter);
96
+ assert.function(pagination.paginate);
97
+ assert.number(pagination.countLimit);
98
+ assert.number(pagination.requestLimit);
99
+ assert.number(pagination.backoff);
100
+ const allItems = [];
101
+ let { countLimit } = pagination;
102
+ let numberOfRequests = 0;
103
+ while (numberOfRequests < pagination.requestLimit) {
104
+ if (numberOfRequests !== 0) {
105
+ // eslint-disable-next-line no-await-in-loop
106
+ await delay(pagination.backoff);
107
+ }
108
+ // eslint-disable-next-line no-await-in-loop
109
+ const response = (await got(undefined, undefined, normalizedOptions));
110
+ // eslint-disable-next-line no-await-in-loop
111
+ const parsed = await pagination.transform(response);
112
+ const currentItems = [];
113
+ assert.array(parsed);
114
+ for (const item of parsed) {
115
+ if (pagination.filter({ item, currentItems, allItems })) {
116
+ if (!pagination.shouldContinue({ item, currentItems, allItems })) {
117
+ return;
118
+ }
119
+ yield item;
120
+ if (pagination.stackAllItems) {
121
+ allItems.push(item);
122
+ }
123
+ currentItems.push(item);
124
+ if (--countLimit <= 0) {
125
+ return;
126
+ }
127
+ }
128
+ }
129
+ const optionsToMerge = pagination.paginate({
130
+ response,
131
+ currentItems,
132
+ allItems,
133
+ });
134
+ if (optionsToMerge === false) {
135
+ return;
136
+ }
137
+ if (optionsToMerge === response.request.options) {
138
+ normalizedOptions = response.request.options;
139
+ }
140
+ else {
141
+ normalizedOptions.merge(optionsToMerge);
142
+ try {
143
+ assert.any([is.urlInstance, is.undefined], optionsToMerge.url);
144
+ }
145
+ catch (error) {
146
+ if (error instanceof Error) {
147
+ error.message = `Option 'pagination.paginate.url': ${error.message}`;
148
+ }
149
+ throw error;
150
+ }
151
+ if (optionsToMerge.url !== undefined) {
152
+ normalizedOptions.prefixUrl = '';
153
+ normalizedOptions.url = optionsToMerge.url;
154
+ }
155
+ }
156
+ numberOfRequests++;
157
+ }
158
+ });
159
+ got.paginate = paginateEach;
160
+ got.paginate.all = (async (url, options) => {
161
+ const results = [];
162
+ for await (const item of paginateEach(url, options)) {
163
+ results.push(item);
164
+ }
165
+ return results;
166
+ });
167
+ // For those who like very descriptive names
168
+ got.paginate.each = paginateEach;
169
+ // Stream API
170
+ got.stream = ((url, options) => got(url, { ...options, isStream: true }));
171
+ // Shortcuts
172
+ for (const method of aliases) {
173
+ got[method] = ((url, options) => got(url, { ...options, method }));
174
+ got.stream[method] = ((url, options) => got(url, { ...options, method, isStream: true }));
175
+ }
176
+ if (!defaults.mutableDefaults) {
177
+ Object.freeze(defaults.handlers);
178
+ defaults.options.freeze();
179
+ }
180
+ Object.defineProperty(got, 'defaults', {
181
+ value: defaults,
182
+ writable: false,
183
+ configurable: false,
184
+ enumerable: true,
185
+ });
186
+ return got;
187
+ };
188
+ export default create;
@@ -0,0 +1,16 @@
1
+ declare const got: import("./types.js").Got;
2
+ export default got;
3
+ export { got };
4
+ export { default as Options } from './core/options.js';
5
+ export * from './core/options.js';
6
+ export * from './core/response.js';
7
+ export type { default as Request } from './core/index.js';
8
+ export * from './core/index.js';
9
+ export * from './core/errors.js';
10
+ export * from './core/diagnostics-channel.js';
11
+ export type { Delays } from './core/timed-out.js';
12
+ export { default as calculateRetryDelay } from './core/calculate-retry-delay.js';
13
+ export * from './as-promise/types.js';
14
+ export * from './types.js';
15
+ export { default as create } from './create.js';
16
+ export { default as parseLinkHeader } from './core/parse-link-header.js';
@@ -0,0 +1,22 @@
1
+ import create from './create.js';
2
+ import Options from './core/options.js';
3
+ const defaults = {
4
+ options: new Options(),
5
+ handlers: [],
6
+ mutableDefaults: false,
7
+ };
8
+ const got = create(defaults);
9
+ export default got;
10
+ // TODO: Remove this in the next major version.
11
+ export { got };
12
+ export { default as Options } from './core/options.js';
13
+ export * from './core/options.js';
14
+ export * from './core/response.js';
15
+ export * from './core/index.js';
16
+ export * from './core/errors.js';
17
+ export * from './core/diagnostics-channel.js';
18
+ export { default as calculateRetryDelay } from './core/calculate-retry-delay.js';
19
+ export * from './as-promise/types.js';
20
+ export * from './types.js';
21
+ export { default as create } from './create.js';
22
+ export { default as parseLinkHeader } from './core/parse-link-header.js';