hanzio 1.2.0 → 2.0.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 (145) hide show
  1. package/README.md +786 -239
  2. package/dist/api-wrapper/builders.d.ts +4 -3
  3. package/dist/api-wrapper/create-client.d.ts +1 -1
  4. package/dist/api-wrapper/describe.d.ts +16 -0
  5. package/dist/api-wrapper/endpoint.d.ts +18 -0
  6. package/dist/api-wrapper/errors.d.ts +39 -2
  7. package/dist/api-wrapper/index.d.ts +5 -0
  8. package/dist/api-wrapper/otel.d.ts +44 -0
  9. package/dist/api-wrapper/paginate.d.ts +12 -0
  10. package/dist/api-wrapper/redaction.d.ts +2 -0
  11. package/dist/api-wrapper/shared.d.ts +16 -2
  12. package/dist/api-wrapper/testing.d.ts +23 -0
  13. package/dist/api-wrapper/transport.d.ts +4 -5
  14. package/dist/api-wrapper/types.d.ts +103 -18
  15. package/dist/array/index.d.ts +50 -4
  16. package/dist/cache/createCache.d.ts +31 -0
  17. package/dist/cache/index.d.ts +19 -2
  18. package/dist/color/contrast.d.ts +40 -0
  19. package/dist/color/index.d.ts +2 -0
  20. package/dist/{math → color}/metricsSeriesColors.d.ts +14 -7
  21. package/dist/cool-console-log/index.d.ts +34 -5
  22. package/dist/crypto/encoding.d.ts +18 -0
  23. package/dist/crypto/hash.d.ts +33 -0
  24. package/dist/crypto/index.d.ts +4 -0
  25. package/dist/crypto/sealer.d.ts +25 -0
  26. package/dist/crypto/webhook.d.ts +20 -0
  27. package/dist/date/index.d.ts +46 -2
  28. package/dist/emitter/index.d.ts +21 -0
  29. package/dist/error/index.d.ts +12 -0
  30. package/dist/format/index.d.ts +102 -0
  31. package/dist/function/index.d.ts +60 -0
  32. package/dist/guard/index.d.ts +20 -0
  33. package/dist/i18n/index.d.ts +37 -0
  34. package/dist/index-0zvtcbzy.js +224 -0
  35. package/dist/index-181e6vfw.js +29 -0
  36. package/dist/index-8r2vdzjg.js +87 -0
  37. package/dist/index-hy7kbb99.js +157 -0
  38. package/dist/{src/secrets/infisical.js → index-j1ybktbr.js} +500 -538
  39. package/dist/index-k9yx6bne.js +89 -0
  40. package/dist/index-kj1phgrx.js +169 -0
  41. package/dist/index-mnkcfyx8.js +78 -0
  42. package/dist/{p-queue/index.js → index-pwt0dz63.js} +7 -11
  43. package/dist/index-rp5pqghz.js +157 -0
  44. package/dist/index-srt06xd2.js +15 -0
  45. package/dist/index-wjyb9bsd.js +263 -0
  46. package/dist/index.d.ts +7 -7
  47. package/dist/jwt/index.d.ts +50 -2
  48. package/dist/math/index.d.ts +2 -2
  49. package/dist/math/linearRegressionTrend.d.ts +14 -1
  50. package/dist/math/scale.d.ts +8 -0
  51. package/dist/object/index.d.ts +19 -0
  52. package/dist/p-queue/index.d.ts +1 -1
  53. package/dist/promise/index.d.ts +97 -2
  54. package/dist/sitemap/index.d.ts +48 -6
  55. package/dist/src/api-wrapper/index.js +60 -1130
  56. package/dist/src/api-wrapper/testing.js +20 -0
  57. package/dist/{cool-console-log → src/cool-console-log}/index.js +80 -33
  58. package/dist/src/crypto/index.js +195 -0
  59. package/dist/src/format/index.js +211 -0
  60. package/dist/src/i18n/index.js +36 -0
  61. package/dist/src/index.js +739 -3145
  62. package/dist/src/jwt/index.js +138 -92
  63. package/dist/src/p-queue/index.js +9 -437
  64. package/dist/src/secrets/index.js +44 -1428
  65. package/dist/src/secrets/vite.js +6 -39
  66. package/dist/src/secrets/worker.js +10 -273
  67. package/dist/src/sitemap/index.js +183 -511
  68. package/dist/src/storage/index.js +119 -0
  69. package/dist/src/zod/index.js +340 -167
  70. package/dist/state/index.d.ts +21 -0
  71. package/dist/storage/index.d.ts +58 -0
  72. package/dist/string/index.d.ts +75 -2
  73. package/dist/typedswitch/index.d.ts +31 -24
  74. package/dist/types/index.d.ts +11 -0
  75. package/dist/url/index.d.ts +50 -1
  76. package/dist/zod/index.d.ts +32 -3
  77. package/dist/zod/introspect.d.ts +19 -0
  78. package/dist/zod/jsonToZodSchemaMapper.d.ts +3 -1
  79. package/dist/zod/zodMinMaxFilter.d.ts +22 -3
  80. package/dist/zod/zodToTypeString.d.ts +8 -3
  81. package/package.json +78 -7
  82. package/src/api-wrapper/actions-impl.ts +11 -72
  83. package/src/api-wrapper/builders.ts +32 -25
  84. package/src/api-wrapper/create-client.ts +171 -41
  85. package/src/api-wrapper/describe.ts +157 -0
  86. package/src/api-wrapper/endpoint.ts +26 -0
  87. package/src/api-wrapper/error-reporting.ts +7 -1
  88. package/src/api-wrapper/errors.ts +107 -2
  89. package/src/api-wrapper/headers.ts +11 -6
  90. package/src/api-wrapper/index.ts +5 -0
  91. package/src/api-wrapper/otel.ts +139 -0
  92. package/src/api-wrapper/paginate.ts +28 -0
  93. package/src/api-wrapper/redaction.ts +42 -0
  94. package/src/api-wrapper/shared.ts +21 -2
  95. package/src/api-wrapper/testing.ts +48 -0
  96. package/src/api-wrapper/transport.ts +41 -43
  97. package/src/api-wrapper/types.ts +185 -18
  98. package/src/array/index.ts +195 -42
  99. package/src/cache/createCache.ts +157 -0
  100. package/src/cache/index.ts +132 -147
  101. package/src/color/contrast.ts +163 -0
  102. package/src/color/index.ts +22 -0
  103. package/src/{math → color}/metricsSeriesColors.ts +47 -49
  104. package/src/cool-console-log/index.ts +128 -41
  105. package/src/crypto/encoding.ts +83 -0
  106. package/src/crypto/hash.ts +170 -0
  107. package/src/crypto/index.ts +26 -0
  108. package/src/crypto/sealer.ts +168 -0
  109. package/src/crypto/webhook.ts +86 -0
  110. package/src/date/index.ts +109 -34
  111. package/src/emitter/index.ts +82 -0
  112. package/src/error/index.ts +63 -0
  113. package/src/format/index.ts +389 -0
  114. package/src/function/index.ts +201 -0
  115. package/src/guard/index.ts +80 -0
  116. package/src/i18n/index.ts +125 -0
  117. package/src/index.ts +11 -7
  118. package/src/jwt/index.ts +199 -125
  119. package/src/math/index.ts +5 -10
  120. package/src/math/linearRegressionTrend.ts +33 -8
  121. package/src/math/scale.ts +17 -0
  122. package/src/object/index.ts +99 -0
  123. package/src/p-queue/index.ts +2 -0
  124. package/src/promise/index.ts +304 -9
  125. package/src/sitemap/index.ts +293 -130
  126. package/src/state/index.ts +133 -81
  127. package/src/storage/index.ts +187 -0
  128. package/src/string/index.ts +261 -23
  129. package/src/typedswitch/index.ts +58 -38
  130. package/src/types/index.ts +14 -0
  131. package/src/url/index.ts +146 -1
  132. package/src/zod/index.ts +105 -9
  133. package/src/zod/introspect.ts +103 -0
  134. package/src/zod/jsonToZodSchemaMapper.ts +44 -21
  135. package/src/zod/zodMinMaxFilter.ts +37 -13
  136. package/src/zod/zodToTypeString.ts +184 -181
  137. package/dist/api-wrapper/index.js +0 -250
  138. package/dist/gzip/index.d.ts +0 -2
  139. package/dist/gzip/index.js +0 -16
  140. package/dist/index.js +0 -1823
  141. package/dist/jwt/index.js +0 -19
  142. package/dist/sitemap/index.js +0 -552
  143. package/dist/src/gzip/index.js +0 -16
  144. package/dist/src/secrets/loaders.js +0 -1529
  145. package/dist/zod/index.js +0 -210
package/dist/jwt/index.js DELETED
@@ -1,19 +0,0 @@
1
- // src/jwt/index.ts
2
- import * as jose from "jose";
3
- async function jwtSign(payload, secret) {
4
- const secretKey = new TextEncoder().encode(secret);
5
- return await new jose.SignJWT(payload).setProtectedHeader({ alg: "HS256" }).setIssuedAt().sign(secretKey);
6
- }
7
- async function jwtVerify2(token, secret) {
8
- try {
9
- const secretKey = new TextEncoder().encode(secret);
10
- const { payload } = await jose.jwtVerify(token, secretKey);
11
- return payload;
12
- } catch (_error) {
13
- return null;
14
- }
15
- }
16
- export {
17
- jwtVerify2 as jwtVerify,
18
- jwtSign
19
- };
@@ -1,552 +0,0 @@
1
- // src/p-queue/index.ts
2
- class TimeoutError extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = "TimeoutError";
6
- }
7
- }
8
-
9
- class PriorityQueue {
10
- #queue = [];
11
- enqueue(run, options = {}) {
12
- const element = {
13
- priority: options.priority ?? 0,
14
- id: options.id,
15
- run
16
- };
17
- const index = this.#queue.findIndex((item) => item.priority < element.priority);
18
- if (index === -1) {
19
- this.#queue.push(element);
20
- return;
21
- }
22
- this.#queue.splice(index, 0, element);
23
- }
24
- dequeue() {
25
- return this.#queue.shift()?.run;
26
- }
27
- filter(options) {
28
- return this.#queue.filter((item) => Object.entries(options).every(([key, value]) => item[key] === value)).map((item) => item.run);
29
- }
30
- setPriority(id, priority) {
31
- const index = this.#queue.findIndex((item2) => item2.id === id);
32
- if (index === -1) {
33
- throw new ReferenceError(`No promise function with the id "${id}" exists in the queue.`);
34
- }
35
- const [item] = this.#queue.splice(index, 1);
36
- this.enqueue(item.run, { ...item, priority });
37
- }
38
- remove(id) {
39
- const index = this.#queue.findIndex((item) => item.id === id);
40
- if (index !== -1) {
41
- this.#queue.splice(index, 1);
42
- }
43
- }
44
- get size() {
45
- return this.#queue.length;
46
- }
47
- }
48
-
49
- class PQueue {
50
- #listeners = new Map;
51
- #queue;
52
- #queueClass;
53
- #pending = 0;
54
- #concurrency;
55
- #isPaused;
56
- #intervalCap;
57
- #interval;
58
- #carryoverIntervalCount;
59
- #strict;
60
- #intervalCount = 0;
61
- #intervalEnd = 0;
62
- #intervalTimer;
63
- #strictTimestamps = [];
64
- #rateLimited = false;
65
- #idCounter = 1n;
66
- #runningTasks = new Map;
67
- timeout;
68
- constructor(options = {}) {
69
- const {
70
- concurrency = Number.POSITIVE_INFINITY,
71
- autoStart = true,
72
- queueClass = PriorityQueue,
73
- intervalCap = Number.POSITIVE_INFINITY,
74
- interval = 0,
75
- carryoverIntervalCount,
76
- carryoverConcurrencyCount,
77
- strict = false,
78
- timeout
79
- } = options;
80
- if (!(typeof concurrency === "number" && concurrency >= 1)) {
81
- throw new TypeError("Expected `concurrency` to be a number from 1 and up");
82
- }
83
- if (!(typeof intervalCap === "number" && intervalCap >= 1)) {
84
- throw new TypeError("Expected `intervalCap` to be a number from 1 and up");
85
- }
86
- if (!(typeof interval === "number" && Number.isFinite(interval) && interval >= 0)) {
87
- throw new TypeError("Expected `interval` to be a finite number >= 0");
88
- }
89
- if (strict && interval === 0) {
90
- throw new TypeError("The `strict` option requires a non-zero `interval`");
91
- }
92
- if (strict && intervalCap === Number.POSITIVE_INFINITY) {
93
- throw new TypeError("The `strict` option requires a finite `intervalCap`");
94
- }
95
- if (timeout !== undefined && !(Number.isFinite(timeout) && timeout > 0)) {
96
- throw new TypeError("Expected `timeout` to be a positive finite number");
97
- }
98
- this.#queueClass = queueClass;
99
- this.#queue = new queueClass;
100
- this.#concurrency = concurrency;
101
- this.#isPaused = !autoStart;
102
- this.#intervalCap = intervalCap;
103
- this.#interval = interval;
104
- this.#carryoverIntervalCount = carryoverIntervalCount ?? carryoverConcurrencyCount ?? false;
105
- this.#strict = strict;
106
- this.timeout = timeout;
107
- }
108
- on(event, listener) {
109
- const listeners = this.#listeners.get(event) ?? new Set;
110
- listeners.add(listener);
111
- this.#listeners.set(event, listeners);
112
- return this;
113
- }
114
- off(event, listener) {
115
- this.#listeners.get(event)?.delete(listener);
116
- return this;
117
- }
118
- emit(event, ...arguments_) {
119
- const listeners = this.#listeners.get(event);
120
- if (!listeners || listeners.size === 0) {
121
- return false;
122
- }
123
- for (const listener of [...listeners]) {
124
- listener(...arguments_);
125
- }
126
- return true;
127
- }
128
- get concurrency() {
129
- return this.#concurrency;
130
- }
131
- set concurrency(newConcurrency) {
132
- if (!(typeof newConcurrency === "number" && newConcurrency >= 1)) {
133
- throw new TypeError("Expected `concurrency` to be a number from 1 and up");
134
- }
135
- this.#concurrency = newConcurrency;
136
- this.#processQueue();
137
- }
138
- get size() {
139
- return this.#queue.size;
140
- }
141
- sizeBy(options) {
142
- return this.#queue.filter(options).length;
143
- }
144
- get pending() {
145
- return this.#pending;
146
- }
147
- get isPaused() {
148
- return this.#isPaused;
149
- }
150
- get isRateLimited() {
151
- this.#updateRateLimitState();
152
- return this.#rateLimited;
153
- }
154
- get isSaturated() {
155
- return this.#pending >= this.#concurrency && this.#queue.size > 0 || this.isRateLimited && this.#queue.size > 0;
156
- }
157
- get runningTasks() {
158
- return [...this.#runningTasks.values()].map((task) => ({ ...task }));
159
- }
160
- setPriority(id, priority) {
161
- if (typeof priority !== "number" || !Number.isFinite(priority)) {
162
- throw new TypeError("Expected `priority` to be a finite number");
163
- }
164
- this.#queue.setPriority(id, priority);
165
- }
166
- async add(function_, options = {}) {
167
- const taskOptions = {
168
- timeout: this.timeout,
169
- ...options,
170
- id: options.id ?? (this.#idCounter++).toString()
171
- };
172
- return new Promise((resolve, reject) => {
173
- const taskSymbol = Symbol(taskOptions.id);
174
- let didRun = false;
175
- let queuedAbortHandler;
176
- let runningAbortHandler;
177
- const cleanupQueuedAbort = () => {
178
- if (queuedAbortHandler) {
179
- taskOptions.signal?.removeEventListener("abort", queuedAbortHandler);
180
- queuedAbortHandler = undefined;
181
- }
182
- };
183
- const run = async () => {
184
- didRun = true;
185
- cleanupQueuedAbort();
186
- this.#pending++;
187
- this.#runningTasks.set(taskSymbol, {
188
- id: taskOptions.id,
189
- priority: taskOptions.priority ?? 0,
190
- startTime: Date.now(),
191
- timeout: taskOptions.timeout
192
- });
193
- try {
194
- taskOptions.signal?.throwIfAborted();
195
- const operation = Promise.resolve(function_({ signal: taskOptions.signal }));
196
- const result = await this.#withTimeoutAndAbort(operation, taskOptions, (listener) => {
197
- runningAbortHandler = listener;
198
- });
199
- resolve(result);
200
- this.emit("completed", result);
201
- } catch (error) {
202
- reject(error);
203
- this.emit("error", error);
204
- } finally {
205
- if (runningAbortHandler) {
206
- taskOptions.signal?.removeEventListener("abort", runningAbortHandler);
207
- }
208
- this.#runningTasks.delete(taskSymbol);
209
- queueMicrotask(() => {
210
- this.#next();
211
- });
212
- }
213
- };
214
- if (taskOptions.signal?.aborted) {
215
- reject(taskOptions.signal.reason);
216
- return;
217
- }
218
- if (taskOptions.signal) {
219
- queuedAbortHandler = () => {
220
- if (didRun) {
221
- return;
222
- }
223
- this.#queue.remove?.(taskOptions.id);
224
- reject(taskOptions.signal?.reason);
225
- this.emit("next");
226
- this.#tryToStartAnother();
227
- };
228
- taskOptions.signal.addEventListener("abort", queuedAbortHandler, {
229
- once: true
230
- });
231
- }
232
- this.#queue.enqueue(run, taskOptions);
233
- this.emit("add");
234
- this.#processQueue();
235
- });
236
- }
237
- async addAll(functions, options) {
238
- return Promise.all(functions.map(async (function_) => this.add(function_, options)));
239
- }
240
- start() {
241
- if (!this.#isPaused) {
242
- return this;
243
- }
244
- this.#isPaused = false;
245
- this.#processQueue();
246
- return this;
247
- }
248
- pause() {
249
- this.#isPaused = true;
250
- }
251
- clear() {
252
- this.#queue = new this.#queueClass;
253
- this.#clearIntervalTimer();
254
- this.#updateRateLimitState();
255
- this.emit("empty");
256
- if (this.#pending === 0) {
257
- this.emit("idle");
258
- }
259
- this.emit("next");
260
- }
261
- async onEmpty() {
262
- if (this.#queue.size === 0) {
263
- return;
264
- }
265
- await this.#onEvent("empty");
266
- }
267
- async onIdle() {
268
- if (this.#queue.size === 0 && this.#pending === 0) {
269
- return;
270
- }
271
- await this.#onEvent("idle");
272
- }
273
- async onPendingZero() {
274
- if (this.#pending === 0) {
275
- return;
276
- }
277
- await this.#onEvent("pendingZero");
278
- }
279
- async onRateLimit() {
280
- if (this.isRateLimited) {
281
- return;
282
- }
283
- await this.#onEvent("rateLimit");
284
- }
285
- async onRateLimitCleared() {
286
- if (!this.isRateLimited) {
287
- return;
288
- }
289
- await this.#onEvent("rateLimitCleared");
290
- }
291
- onError() {
292
- return new Promise((_resolve, reject) => {
293
- const listener = (error) => {
294
- this.off("error", listener);
295
- reject(error);
296
- };
297
- this.on("error", listener);
298
- });
299
- }
300
- async onSizeLessThan(limit) {
301
- if (this.#queue.size < limit) {
302
- return;
303
- }
304
- await this.#onEvent("next", () => this.#queue.size < limit);
305
- }
306
- async#onEvent(event, filter) {
307
- return new Promise((resolve) => {
308
- const listener = () => {
309
- if (filter && !filter()) {
310
- return;
311
- }
312
- this.off(event, listener);
313
- resolve();
314
- };
315
- this.on(event, listener);
316
- });
317
- }
318
- async#withTimeoutAndAbort(operation, options, setAbortListener) {
319
- const races = [operation];
320
- let timeoutId;
321
- if (options.timeout) {
322
- races.push(new Promise((_resolve, reject) => {
323
- timeoutId = setTimeout(() => {
324
- reject(new TimeoutError(`Task timed out after ${options.timeout}ms`));
325
- }, options.timeout);
326
- }));
327
- }
328
- if (options.signal) {
329
- races.push(new Promise((_resolve, reject) => {
330
- const listener = () => {
331
- reject(options.signal?.reason);
332
- };
333
- setAbortListener(listener);
334
- options.signal?.addEventListener("abort", listener, { once: true });
335
- }));
336
- }
337
- try {
338
- return await Promise.race(races);
339
- } finally {
340
- if (timeoutId) {
341
- clearTimeout(timeoutId);
342
- }
343
- }
344
- }
345
- #next() {
346
- this.#pending--;
347
- if (this.#pending === 0) {
348
- this.emit("pendingZero");
349
- }
350
- this.#processQueue();
351
- this.emit("next");
352
- }
353
- #processQueue() {
354
- while (this.#tryToStartAnother()) {}
355
- this.#updateRateLimitState();
356
- }
357
- #tryToStartAnother() {
358
- if (this.#queue.size === 0) {
359
- this.#clearIntervalTimer();
360
- this.emit("empty");
361
- if (this.#pending === 0) {
362
- this.emit("idle");
363
- }
364
- return false;
365
- }
366
- if (this.#isPaused || this.#pending >= this.#concurrency || !this.#doesIntervalAllowAnother()) {
367
- return false;
368
- }
369
- const job = this.#queue.dequeue();
370
- if (!job) {
371
- return false;
372
- }
373
- this.#consumeIntervalSlot();
374
- this.emit("active");
375
- job();
376
- return true;
377
- }
378
- #doesIntervalAllowAnother() {
379
- if (this.#intervalCap === Number.POSITIVE_INFINITY || this.#interval === 0) {
380
- return true;
381
- }
382
- const now = Date.now();
383
- if (this.#strict) {
384
- this.#strictTimestamps = this.#strictTimestamps.filter((timestamp) => now - timestamp < this.#interval);
385
- if (this.#strictTimestamps.length < this.#intervalCap) {
386
- return true;
387
- }
388
- this.#scheduleIntervalResume(this.#interval - (now - this.#strictTimestamps[0]));
389
- return false;
390
- }
391
- if (this.#intervalEnd === 0 || now >= this.#intervalEnd) {
392
- this.#intervalCount = this.#carryoverIntervalCount ? this.#pending : 0;
393
- this.#intervalEnd = now + this.#interval;
394
- }
395
- if (this.#intervalCount < this.#intervalCap) {
396
- return true;
397
- }
398
- this.#scheduleIntervalResume(this.#intervalEnd - now);
399
- return false;
400
- }
401
- #consumeIntervalSlot() {
402
- if (this.#intervalCap === Number.POSITIVE_INFINITY || this.#interval === 0) {
403
- return;
404
- }
405
- if (this.#strict) {
406
- this.#strictTimestamps.push(Date.now());
407
- return;
408
- }
409
- this.#intervalCount++;
410
- }
411
- #scheduleIntervalResume(delay) {
412
- if (this.#intervalTimer) {
413
- return;
414
- }
415
- this.#intervalTimer = setTimeout(() => {
416
- this.#intervalTimer = undefined;
417
- this.#processQueue();
418
- }, Math.max(0, delay));
419
- }
420
- #clearIntervalTimer() {
421
- if (this.#intervalTimer) {
422
- clearTimeout(this.#intervalTimer);
423
- this.#intervalTimer = undefined;
424
- }
425
- }
426
- #updateRateLimitState() {
427
- const previous = this.#rateLimited;
428
- const isRateLimited = this.#queue.size > 0 && this.#intervalCap !== Number.POSITIVE_INFINITY && this.#interval > 0 && !this.#doesIntervalAllowAnother();
429
- this.#rateLimited = isRateLimited;
430
- if (previous !== isRateLimited) {
431
- this.emit(isRateLimited ? "rateLimit" : "rateLimitCleared");
432
- }
433
- }
434
- }
435
-
436
- // src/sitemap/index.ts
437
- var createTimeoutController = (timeout) => {
438
- const controller = new AbortController;
439
- setTimeout(() => controller.abort(), timeout);
440
- return controller;
441
- };
442
- var discoverSitemaps = async (domain) => {
443
- const normalizedDomain = domain.replace(/\/$/, "");
444
- const commonLocations = [
445
- "/sitemap.xml",
446
- "/sitemap_index.xml",
447
- "/sitemap/",
448
- "/sitemaps.xml",
449
- "/sitemap/sitemap.xml"
450
- ];
451
- const sitemaps = new Set;
452
- const requestOptions = {
453
- headers: {
454
- "User-Agent": "SitemapCrawler/1.0"
455
- },
456
- signal: createTimeoutController(5000).signal
457
- };
458
- try {
459
- const robotsTxt = await fetch(`${normalizedDomain}/robots.txt`, {
460
- ...requestOptions
461
- });
462
- if (robotsTxt.ok) {
463
- const text = await robotsTxt.text();
464
- const sitemapMatches = text.match(/Sitemap: (.*)/gi);
465
- if (sitemapMatches) {
466
- sitemapMatches.forEach((match) => {
467
- const url = match.replace("Sitemap:", "").trim();
468
- sitemaps.add(url);
469
- });
470
- }
471
- if (sitemaps.size > 0) {
472
- return [...sitemaps];
473
- }
474
- }
475
- } catch (error) {
476
- console.warn("Could not fetch robots.txt:", error instanceof Error ? error.message : "Unknown error");
477
- }
478
- for (const location of commonLocations) {
479
- try {
480
- const response = await fetch(`${normalizedDomain}${location}`, {
481
- ...requestOptions,
482
- method: "HEAD"
483
- });
484
- if (response.ok) {
485
- return [`${normalizedDomain}${location}`];
486
- }
487
- } catch (_error) {}
488
- }
489
- return [];
490
- };
491
- var getDomainSitemap = async (domain, options = {}) => {
492
- const {
493
- filterIndexes,
494
- concurrency = 10,
495
- maxDepth = 5,
496
- timeout = 1e4
497
- } = options;
498
- let normalizedDomain = domain.replace(/\/$/, "");
499
- if (!normalizedDomain.startsWith("http")) {
500
- normalizedDomain = `https://${normalizedDomain}`;
501
- }
502
- const sitemapUrls = await discoverSitemaps(normalizedDomain);
503
- if (sitemapUrls.length === 0) {
504
- throw new Error("No sitemaps found for the domain");
505
- }
506
- const queue = new PQueue({ concurrency });
507
- const result = {
508
- links: new Set,
509
- visited: new Set
510
- };
511
- const locRegex = /<loc>([^<]+)<\/loc>/g;
512
- const isXmlSitemap = (url) => url.endsWith(".xml") || url.toLowerCase().includes("sitemap");
513
- const processSitemap = async (sitemapUrl, depth = 0) => {
514
- if (depth > maxDepth || result.visited.has(sitemapUrl)) {
515
- return;
516
- }
517
- result.visited.add(sitemapUrl);
518
- try {
519
- const controller = createTimeoutController(timeout);
520
- const response = await fetch(sitemapUrl, {
521
- headers: {
522
- "User-Agent": "SitemapCrawler/1.0"
523
- },
524
- signal: controller.signal
525
- });
526
- if (!response.ok)
527
- throw new Error(`HTTP error! status: ${response.status}`);
528
- const data = await response.text();
529
- const matches = [...data.matchAll(locRegex)].map((match) => match[1].trim()).filter((link) => {
530
- if (filterIndexes && isXmlSitemap(link)) {
531
- return link.includes(filterIndexes);
532
- }
533
- return true;
534
- });
535
- for (const link of matches) {
536
- if (isXmlSitemap(link)) {
537
- queue.add(() => processSitemap(link, depth + 1));
538
- } else {
539
- result.links.add(link);
540
- }
541
- }
542
- } catch (error) {
543
- console.warn(`Failed to process sitemap ${sitemapUrl}:`, error instanceof Error ? error.message : "Unknown error");
544
- }
545
- };
546
- await Promise.all(sitemapUrls.map((sitemapUrl) => queue.add(() => processSitemap(sitemapUrl))));
547
- await queue.onIdle();
548
- return [...result.links];
549
- };
550
- export {
551
- getDomainSitemap
552
- };
@@ -1,16 +0,0 @@
1
- // src/gzip/index.ts
2
- import pako from "pako";
3
- function compressString(input) {
4
- const uint8Array = new TextEncoder().encode(input);
5
- const compressed = pako.deflate(uint8Array);
6
- return btoa(String.fromCharCode.apply(null, compressed));
7
- }
8
- function decompressString(compressedString) {
9
- const compressedData = new Uint8Array(atob(compressedString).split("").map((char) => char.charCodeAt(0)));
10
- const decompressed = pako.inflate(compressedData);
11
- return new TextDecoder().decode(decompressed);
12
- }
13
- export {
14
- decompressString,
15
- compressString
16
- };