@foundatiofx/fetchclient 0.47.0

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 (106) hide show
  1. package/esm/mod.js +5 -0
  2. package/esm/package.json +3 -0
  3. package/esm/src/Counter.js +36 -0
  4. package/esm/src/DefaultHelpers.js +132 -0
  5. package/esm/src/FetchClient.js +543 -0
  6. package/esm/src/FetchClientCache.js +88 -0
  7. package/esm/src/FetchClientContext.js +1 -0
  8. package/esm/src/FetchClientMiddleware.js +1 -0
  9. package/esm/src/FetchClientOptions.js +1 -0
  10. package/esm/src/FetchClientProvider.js +200 -0
  11. package/esm/src/FetchClientResponse.js +1 -0
  12. package/esm/src/LinkHeader.js +70 -0
  13. package/esm/src/ObjectEvent.js +15 -0
  14. package/esm/src/ProblemDetails.js +47 -0
  15. package/esm/src/RateLimitMiddleware.js +115 -0
  16. package/esm/src/RateLimiter.js +347 -0
  17. package/esm/src/RequestOptions.js +1 -0
  18. package/license +20 -0
  19. package/package.json +50 -0
  20. package/readme.md +303 -0
  21. package/script/mod.js +27 -0
  22. package/script/package.json +3 -0
  23. package/script/src/Counter.js +40 -0
  24. package/script/src/DefaultHelpers.js +149 -0
  25. package/script/src/FetchClient.js +547 -0
  26. package/script/src/FetchClientCache.js +92 -0
  27. package/script/src/FetchClientContext.js +2 -0
  28. package/script/src/FetchClientMiddleware.js +2 -0
  29. package/script/src/FetchClientOptions.js +2 -0
  30. package/script/src/FetchClientProvider.js +204 -0
  31. package/script/src/FetchClientResponse.js +2 -0
  32. package/script/src/LinkHeader.js +72 -0
  33. package/script/src/ObjectEvent.js +19 -0
  34. package/script/src/ProblemDetails.js +51 -0
  35. package/script/src/RateLimitMiddleware.js +120 -0
  36. package/script/src/RateLimiter.js +356 -0
  37. package/script/src/RequestOptions.js +2 -0
  38. package/types/_dnt.test_shims.d.ts.map +1 -0
  39. package/types/deps/jsr.io/@std/assert/1.0.14/almost_equals.d.ts.map +1 -0
  40. package/types/deps/jsr.io/@std/assert/1.0.14/array_includes.d.ts.map +1 -0
  41. package/types/deps/jsr.io/@std/assert/1.0.14/assert.d.ts.map +1 -0
  42. package/types/deps/jsr.io/@std/assert/1.0.14/assertion_error.d.ts.map +1 -0
  43. package/types/deps/jsr.io/@std/assert/1.0.14/equal.d.ts.map +1 -0
  44. package/types/deps/jsr.io/@std/assert/1.0.14/equals.d.ts.map +1 -0
  45. package/types/deps/jsr.io/@std/assert/1.0.14/exists.d.ts.map +1 -0
  46. package/types/deps/jsr.io/@std/assert/1.0.14/fail.d.ts.map +1 -0
  47. package/types/deps/jsr.io/@std/assert/1.0.14/false.d.ts.map +1 -0
  48. package/types/deps/jsr.io/@std/assert/1.0.14/greater.d.ts.map +1 -0
  49. package/types/deps/jsr.io/@std/assert/1.0.14/greater_or_equal.d.ts.map +1 -0
  50. package/types/deps/jsr.io/@std/assert/1.0.14/instance_of.d.ts.map +1 -0
  51. package/types/deps/jsr.io/@std/assert/1.0.14/is_error.d.ts.map +1 -0
  52. package/types/deps/jsr.io/@std/assert/1.0.14/less.d.ts.map +1 -0
  53. package/types/deps/jsr.io/@std/assert/1.0.14/less_or_equal.d.ts.map +1 -0
  54. package/types/deps/jsr.io/@std/assert/1.0.14/match.d.ts.map +1 -0
  55. package/types/deps/jsr.io/@std/assert/1.0.14/mod.d.ts.map +1 -0
  56. package/types/deps/jsr.io/@std/assert/1.0.14/not_equals.d.ts.map +1 -0
  57. package/types/deps/jsr.io/@std/assert/1.0.14/not_instance_of.d.ts.map +1 -0
  58. package/types/deps/jsr.io/@std/assert/1.0.14/not_match.d.ts.map +1 -0
  59. package/types/deps/jsr.io/@std/assert/1.0.14/not_strict_equals.d.ts.map +1 -0
  60. package/types/deps/jsr.io/@std/assert/1.0.14/object_match.d.ts.map +1 -0
  61. package/types/deps/jsr.io/@std/assert/1.0.14/rejects.d.ts.map +1 -0
  62. package/types/deps/jsr.io/@std/assert/1.0.14/strict_equals.d.ts.map +1 -0
  63. package/types/deps/jsr.io/@std/assert/1.0.14/string_includes.d.ts.map +1 -0
  64. package/types/deps/jsr.io/@std/assert/1.0.14/throws.d.ts.map +1 -0
  65. package/types/deps/jsr.io/@std/assert/1.0.14/unimplemented.d.ts.map +1 -0
  66. package/types/deps/jsr.io/@std/assert/1.0.14/unreachable.d.ts.map +1 -0
  67. package/types/deps/jsr.io/@std/internal/1.0.10/build_message.d.ts.map +1 -0
  68. package/types/deps/jsr.io/@std/internal/1.0.10/diff.d.ts.map +1 -0
  69. package/types/deps/jsr.io/@std/internal/1.0.10/diff_str.d.ts.map +1 -0
  70. package/types/deps/jsr.io/@std/internal/1.0.10/format.d.ts.map +1 -0
  71. package/types/deps/jsr.io/@std/internal/1.0.10/styles.d.ts.map +1 -0
  72. package/types/deps/jsr.io/@std/internal/1.0.10/types.d.ts.map +1 -0
  73. package/types/mod.d.ts +11 -0
  74. package/types/mod.d.ts.map +1 -0
  75. package/types/src/Counter.d.ts +27 -0
  76. package/types/src/Counter.d.ts.map +1 -0
  77. package/types/src/DefaultHelpers.d.ts +106 -0
  78. package/types/src/DefaultHelpers.d.ts.map +1 -0
  79. package/types/src/FetchClient.d.ts +156 -0
  80. package/types/src/FetchClient.d.ts.map +1 -0
  81. package/types/src/FetchClient.test.d.ts.map +1 -0
  82. package/types/src/FetchClientCache.d.ts +62 -0
  83. package/types/src/FetchClientCache.d.ts.map +1 -0
  84. package/types/src/FetchClientContext.d.ts +8 -0
  85. package/types/src/FetchClientContext.d.ts.map +1 -0
  86. package/types/src/FetchClientMiddleware.d.ts +9 -0
  87. package/types/src/FetchClientMiddleware.d.ts.map +1 -0
  88. package/types/src/FetchClientOptions.d.ts +53 -0
  89. package/types/src/FetchClientOptions.d.ts.map +1 -0
  90. package/types/src/FetchClientProvider.d.ts +109 -0
  91. package/types/src/FetchClientProvider.d.ts.map +1 -0
  92. package/types/src/FetchClientResponse.d.ts +29 -0
  93. package/types/src/FetchClientResponse.d.ts.map +1 -0
  94. package/types/src/LinkHeader.d.ts +15 -0
  95. package/types/src/LinkHeader.d.ts.map +1 -0
  96. package/types/src/ObjectEvent.d.ts +20 -0
  97. package/types/src/ObjectEvent.d.ts.map +1 -0
  98. package/types/src/ProblemDetails.d.ts +43 -0
  99. package/types/src/ProblemDetails.d.ts.map +1 -0
  100. package/types/src/RateLimit.test.d.ts.map +1 -0
  101. package/types/src/RateLimitMiddleware.d.ts +50 -0
  102. package/types/src/RateLimitMiddleware.d.ts.map +1 -0
  103. package/types/src/RateLimiter.d.ts +179 -0
  104. package/types/src/RateLimiter.d.ts.map +1 -0
  105. package/types/src/RequestOptions.d.ts +64 -0
  106. package/types/src/RequestOptions.d.ts.map +1 -0
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultInstance = exports.FetchClientProvider = void 0;
4
+ const FetchClient_js_1 = require("./FetchClient.js");
5
+ const Counter_js_1 = require("./Counter.js");
6
+ const FetchClientCache_js_1 = require("./FetchClientCache.js");
7
+ const ObjectEvent_js_1 = require("./ObjectEvent.js");
8
+ const RateLimitMiddleware_js_1 = require("./RateLimitMiddleware.js");
9
+ const RateLimiter_js_1 = require("./RateLimiter.js");
10
+ /**
11
+ * Represents a provider for creating instances of the FetchClient class with shared default options and cache.
12
+ */
13
+ class FetchClientProvider {
14
+ #options = {};
15
+ #fetch;
16
+ #cache;
17
+ #rateLimitMiddleware;
18
+ #counter = new Counter_js_1.Counter();
19
+ #onLoading = new ObjectEvent_js_1.ObjectEvent();
20
+ /**
21
+ * Creates a new instance of FetchClientProvider.
22
+ * @param fetch - The fetch function to use. If not provided, the global fetch function will be used.
23
+ */
24
+ constructor(fetch) {
25
+ this.#cache = new FetchClientCache_js_1.FetchClientCache();
26
+ if (fetch) {
27
+ this.#fetch = fetch;
28
+ }
29
+ this.#options = {
30
+ cache: this.#cache,
31
+ providerCounter: this.#counter,
32
+ fetch: this.#fetch,
33
+ };
34
+ this.#counter.changed.on((e) => {
35
+ if (!e) {
36
+ throw new Error("Event data is required.");
37
+ }
38
+ if (e.value > 0 && e.previous == 0) {
39
+ this.#onLoading.trigger(true);
40
+ }
41
+ else if (e.value == 0 && e.previous > 0) {
42
+ this.#onLoading.trigger(false);
43
+ }
44
+ });
45
+ }
46
+ /**
47
+ * Gets the fetch function used for making requests.
48
+ */
49
+ get fetch() {
50
+ return this.#fetch;
51
+ }
52
+ /**
53
+ * Sets the fetch function used for making requests.
54
+ */
55
+ set fetch(value) {
56
+ this.#fetch = value;
57
+ }
58
+ /**
59
+ * Gets a value indicating whether there are ongoing requests.
60
+ */
61
+ get isLoading() {
62
+ return this.#counter.count > 0;
63
+ }
64
+ /**
65
+ * Gets an event that is triggered when the loading state changes.
66
+ */
67
+ get loading() {
68
+ return this.#onLoading.expose();
69
+ }
70
+ /**
71
+ * Gets the number of ongoing requests.
72
+ */
73
+ get requestCount() {
74
+ return this.#counter.count;
75
+ }
76
+ /**
77
+ * Gets the counter used for tracking ongoing requests.
78
+ */
79
+ get counter() {
80
+ return this.#counter;
81
+ }
82
+ /**
83
+ * Gets the options used for FetchClient instances.
84
+ */
85
+ get options() {
86
+ return this.#options;
87
+ }
88
+ /**
89
+ * Sets the options used for FetchClient instances.
90
+ */
91
+ set options(value) {
92
+ this.#options = value;
93
+ }
94
+ /**
95
+ * Gets the cache used for storing HTTP responses.
96
+ */
97
+ get cache() {
98
+ return this.#cache;
99
+ }
100
+ /**
101
+ * Creates a new instance of FetchClient using the current provider.
102
+ * @param options - The options to use for the FetchClient instance.
103
+ * @returns A new instance of FetchClient.
104
+ */
105
+ getFetchClient(options) {
106
+ if (options) {
107
+ options = {
108
+ ...this.#options,
109
+ ...options,
110
+ };
111
+ options.provider = this;
112
+ return new FetchClient_js_1.FetchClient(options);
113
+ }
114
+ return new FetchClient_js_1.FetchClient(this);
115
+ }
116
+ /**
117
+ * Applies the specified options by merging with the current options.
118
+ */
119
+ applyOptions(options) {
120
+ this.#options = {
121
+ ...this.#options,
122
+ ...options,
123
+ };
124
+ }
125
+ /**
126
+ * Sets the function used for retrieving the access token.
127
+ * @param accessTokenFunc - The function that retrieves the access token.
128
+ */
129
+ setAccessTokenFunc(accessTokenFunc) {
130
+ this.#options = {
131
+ ...this.#options,
132
+ accessTokenFunc: accessTokenFunc,
133
+ };
134
+ }
135
+ /**
136
+ * Sets the default model validator function for all FetchClient instances created by this provider.
137
+ * @param validate - The function that validates the model.
138
+ */
139
+ setModelValidator(validate) {
140
+ this.#options = {
141
+ ...this.#options,
142
+ modelValidator: validate,
143
+ };
144
+ }
145
+ /**
146
+ * Sets the default base URL for all FetchClient instances created by this provider.
147
+ * @param url - The URL to set as the default base URL.
148
+ */
149
+ setBaseUrl(url) {
150
+ this.#options = {
151
+ ...this.#options,
152
+ baseUrl: url,
153
+ };
154
+ }
155
+ /**
156
+ * Adds a middleware to all FetchClient instances created by this provider.
157
+ * @param middleware - The middleware function to be added.
158
+ */
159
+ useMiddleware(middleware) {
160
+ this.#options = {
161
+ ...this.#options,
162
+ middleware: [
163
+ ...(this.#options.middleware ?? []),
164
+ middleware,
165
+ ],
166
+ };
167
+ }
168
+ /**
169
+ * Enables rate limiting for all FetchClient instances created by this provider.
170
+ * @param options - The rate limiting configuration options.
171
+ */
172
+ useRateLimit(options) {
173
+ this.#rateLimitMiddleware = new RateLimitMiddleware_js_1.RateLimitMiddleware(options);
174
+ this.useMiddleware(this.#rateLimitMiddleware.middleware());
175
+ }
176
+ /**
177
+ * Enables rate limiting for all FetchClient instances created by this provider.
178
+ * @param options - The rate limiting configuration options.
179
+ */
180
+ usePerDomainRateLimit(options) {
181
+ this.#rateLimitMiddleware = new RateLimitMiddleware_js_1.RateLimitMiddleware({
182
+ ...options,
183
+ getGroupFunc: RateLimiter_js_1.groupByDomain,
184
+ });
185
+ this.useMiddleware(this.#rateLimitMiddleware.middleware());
186
+ }
187
+ /**
188
+ * Gets the rate limiter instance used for rate limiting.
189
+ * @returns The rate limiter instance, or undefined if rate limiting is not enabled.
190
+ */
191
+ get rateLimiter() {
192
+ return this.#rateLimitMiddleware?.rateLimiter;
193
+ }
194
+ /**
195
+ * Removes the rate limiting middleware from all FetchClient instances created by this provider.
196
+ */
197
+ removeRateLimit() {
198
+ this.#rateLimitMiddleware = undefined;
199
+ this.#options.middleware = this.#options.middleware?.filter((m) => !(m instanceof RateLimitMiddleware_js_1.RateLimitMiddleware));
200
+ }
201
+ }
202
+ exports.FetchClientProvider = FetchClientProvider;
203
+ const provider = new FetchClientProvider();
204
+ exports.defaultInstance = provider;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseLinkHeader = parseLinkHeader;
4
+ const MAX_HEADER_LENGTH = 2000;
5
+ const THROW_ON_MAX_HEADER_LENGTH_EXCEEDED = false;
6
+ function hasRel(x) {
7
+ return x && x.rel;
8
+ }
9
+ function intoRels(acc, x) {
10
+ function splitRel(rel) {
11
+ acc[rel] = Object.assign({}, x, { rel: rel });
12
+ }
13
+ x.rel.split(/\s+/).forEach(splitRel);
14
+ return acc;
15
+ }
16
+ // deno-lint-ignore no-explicit-any
17
+ function createObjects(acc, p) {
18
+ // rel="next" => 1: rel 2: next
19
+ const m = p.match(/\s*(.+)\s*=\s*"?([^"]+)"?/);
20
+ if (m)
21
+ acc[m[1]] = m[2];
22
+ return acc;
23
+ }
24
+ function parseLink(link) {
25
+ try {
26
+ const m = link.match(/<?([^>]*)>(.*)/);
27
+ if (!m)
28
+ return null;
29
+ const linkUrl = m[1];
30
+ const parts = m[2].split(";");
31
+ const qry = {};
32
+ // The origin is unused but it's required to parse relative URLs
33
+ const url = new URL(linkUrl, "https://example.com");
34
+ for (const [key, value] of url.searchParams) {
35
+ qry[key] = value;
36
+ }
37
+ parts.shift();
38
+ let info = parts.reduce(createObjects, {});
39
+ info = Object.assign({}, qry, info);
40
+ info.url = linkUrl;
41
+ return info;
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ function checkHeader(linkHeader, options) {
48
+ if (!linkHeader)
49
+ return false;
50
+ options = options || {};
51
+ const maxHeaderLength = options.maxHeaderLength || MAX_HEADER_LENGTH;
52
+ const throwOnMaxHeaderLengthExceeded = options.throwOnMaxHeaderLengthExceeded ||
53
+ THROW_ON_MAX_HEADER_LENGTH_EXCEEDED;
54
+ if (linkHeader.length > maxHeaderLength) {
55
+ if (throwOnMaxHeaderLengthExceeded) {
56
+ throw new Error("Input string too long, it should be under " + maxHeaderLength +
57
+ " characters.");
58
+ }
59
+ else {
60
+ return false;
61
+ }
62
+ }
63
+ return true;
64
+ }
65
+ function parseLinkHeader(linkHeader, options) {
66
+ if (!checkHeader(linkHeader, options))
67
+ return null;
68
+ return linkHeader.split(/,\s*</)
69
+ .map(parseLink)
70
+ .filter(hasRel)
71
+ .reduce(intoRels, {});
72
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectEvent = void 0;
4
+ class ObjectEvent {
5
+ handlers = [];
6
+ on(handler) {
7
+ this.handlers.push(handler);
8
+ }
9
+ off(handler) {
10
+ this.handlers = this.handlers.filter((h) => h !== handler);
11
+ }
12
+ trigger(data) {
13
+ this.handlers.slice(0).forEach((h) => h(data));
14
+ }
15
+ expose() {
16
+ return this;
17
+ }
18
+ }
19
+ exports.ObjectEvent = ObjectEvent;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProblemDetails = void 0;
4
+ /**
5
+ * Represents a problem details object.
6
+ */
7
+ class ProblemDetails {
8
+ /**
9
+ * The type of the problem details.
10
+ */
11
+ type;
12
+ /**
13
+ * The title of the problem details.
14
+ */
15
+ title;
16
+ /**
17
+ * The HTTP status code of the problem details.
18
+ */
19
+ status;
20
+ /**
21
+ * Additional details about the problem.
22
+ */
23
+ detail;
24
+ /**
25
+ * The URI of the specific occurrence of the problem.
26
+ */
27
+ instance;
28
+ /**
29
+ * Represents the errors associated with a problem details response.
30
+ */
31
+ errors = {};
32
+ /**
33
+ * Clears the error with the specified name.
34
+ * @param name - The name of the error to clear.
35
+ * @returns The updated ProblemDetails instance.
36
+ */
37
+ clear(name) {
38
+ delete this.errors[name];
39
+ return this;
40
+ }
41
+ /**
42
+ * Sets the error message for the general error.
43
+ * @param message - The error message to set.
44
+ * @returns The updated ProblemDetails instance.
45
+ */
46
+ setErrorMessage(message) {
47
+ this.errors.general = [message];
48
+ return this;
49
+ }
50
+ }
51
+ exports.ProblemDetails = ProblemDetails;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimitMiddleware = exports.RateLimitError = void 0;
4
+ const ProblemDetails_js_1 = require("./ProblemDetails.js");
5
+ const RateLimiter_js_1 = require("./RateLimiter.js");
6
+ /**
7
+ * Rate limiting error thrown when requests exceed the rate limit.
8
+ */
9
+ class RateLimitError extends Error {
10
+ resetTime;
11
+ remainingRequests;
12
+ constructor(resetTime, remainingRequests, message) {
13
+ super(message ||
14
+ `Rate limit exceeded. Try again after ${new Date(resetTime).toISOString()}`);
15
+ this.name = "RateLimitError";
16
+ this.resetTime = resetTime;
17
+ this.remainingRequests = remainingRequests;
18
+ }
19
+ }
20
+ exports.RateLimitError = RateLimitError;
21
+ /**
22
+ * Rate limiting middleware instance that can be shared across requests.
23
+ */
24
+ class RateLimitMiddleware {
25
+ #rateLimiter;
26
+ throwOnRateLimit;
27
+ errorMessage;
28
+ autoUpdateFromHeaders;
29
+ constructor(options) {
30
+ this.#rateLimiter = new RateLimiter_js_1.RateLimiter(options);
31
+ this.throwOnRateLimit = options.throwOnRateLimit ?? true;
32
+ this.errorMessage = options.errorMessage;
33
+ this.autoUpdateFromHeaders = options.autoUpdateFromHeaders ?? true;
34
+ }
35
+ /**
36
+ * Gets the underlying rate limiter instance.
37
+ */
38
+ get rateLimiter() {
39
+ return this.#rateLimiter;
40
+ }
41
+ /**
42
+ * Creates the middleware function.
43
+ * @returns The middleware function
44
+ */
45
+ middleware() {
46
+ return async (context, next) => {
47
+ const url = context.request.url;
48
+ // Check if request is allowed
49
+ if (!this.rateLimiter.isAllowed(url)) {
50
+ const group = this.rateLimiter.getGroup(url);
51
+ const resetTime = this.rateLimiter.getResetTime(url) ?? Date.now();
52
+ const remainingRequests = this.rateLimiter.getRemainingRequests(url);
53
+ if (this.throwOnRateLimit) {
54
+ throw new RateLimitError(resetTime, remainingRequests, this.errorMessage);
55
+ }
56
+ // Create a 429 Too Many Requests response
57
+ const groupOptions = this.rateLimiter.getGroupOptions(group);
58
+ const maxRequests = groupOptions.maxRequests;
59
+ const windowSeconds = groupOptions.windowSeconds;
60
+ // Create IETF standard rate limit headers
61
+ const resetSeconds = Math.ceil((resetTime - Date.now()) / 1000);
62
+ const rateLimitHeader = (0, RateLimiter_js_1.buildRateLimitHeader)({
63
+ policy: group,
64
+ remaining: remainingRequests,
65
+ resetSeconds: resetSeconds,
66
+ });
67
+ const rateLimitPolicyHeader = (0, RateLimiter_js_1.buildRateLimitPolicyHeader)({
68
+ policy: group,
69
+ limit: maxRequests,
70
+ windowSeconds: Math.floor(windowSeconds),
71
+ });
72
+ const headers = new Headers({
73
+ "Content-Type": "application/problem+json",
74
+ "RateLimit": rateLimitHeader,
75
+ "RateLimit-Policy": rateLimitPolicyHeader,
76
+ // Legacy headers for backward compatibility
77
+ "RateLimit-Limit": maxRequests.toString(),
78
+ "RateLimit-Remaining": remainingRequests.toString(),
79
+ "RateLimit-Reset": Math.ceil(resetTime / 1000).toString(),
80
+ "Retry-After": resetSeconds.toString(),
81
+ });
82
+ const problem = new ProblemDetails_js_1.ProblemDetails();
83
+ problem.status = 429;
84
+ problem.title = "Too Many Requests";
85
+ problem.detail = this.errorMessage ||
86
+ `Rate limit exceeded. Try again after ${new Date(resetTime).toISOString()}`;
87
+ context.response = {
88
+ url: context.request.url,
89
+ status: 429,
90
+ statusText: "Too Many Requests",
91
+ body: null,
92
+ bodyUsed: true,
93
+ ok: false,
94
+ headers: headers,
95
+ redirected: false,
96
+ type: "basic",
97
+ problem: problem,
98
+ data: null,
99
+ meta: { links: {} },
100
+ json: () => Promise.resolve(problem),
101
+ text: () => Promise.resolve(JSON.stringify(problem)),
102
+ arrayBuffer: () => Promise.resolve(new ArrayBuffer(0)),
103
+ // @ts-ignore: New in Deno 1.44
104
+ bytes: () => Promise.resolve(new Uint8Array()),
105
+ blob: () => Promise.resolve(new Blob()),
106
+ formData: () => Promise.resolve(new FormData()),
107
+ clone: () => {
108
+ throw new Error("Not implemented");
109
+ },
110
+ };
111
+ return;
112
+ }
113
+ await next();
114
+ if (this.autoUpdateFromHeaders && context.response) {
115
+ this.rateLimiter.updateFromHeadersForRequest(url, context.response.headers);
116
+ }
117
+ };
118
+ }
119
+ }
120
+ exports.RateLimitMiddleware = RateLimitMiddleware;