@utilix-tech/sdk 0.16.0 → 0.17.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
4
4
 
5
+ ## 0.17.0
6
+ - Added User-Agent Parser (`parseUserAgent`) and GitHub URL Parser (`parseGithubUrl`).
7
+
5
8
  ## 0.16.0
6
9
  - Added Simple Interest Calculator (`calculateSimpleInterest`) and Base58 / Base62 Encoder (`base58Encode`, `base58Decode`, `base62Encode`, `base62Decode`).
7
10
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @utilix-tech/sdk
2
2
 
3
- **548 developer utility functions for Node.js: runs locally, no API key required.**
3
+ **550 developer utility functions for Node.js: runs locally, no API key required.**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@utilix-tech/sdk?style=flat-square&color=cb3837)](https://www.npmjs.com/package/@utilix-tech/sdk)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@utilix-tech/sdk?style=flat-square)](https://www.npmjs.com/package/@utilix-tech/sdk)
@@ -310,7 +310,8 @@ calculateSimpleInterest(1000, 5, 2);
310
310
  ```ts
311
311
  import { getStatusCode, isValidIp, isValidIpv4, isValidIpv6,
312
312
  searchStatusCodes, buildGeoUrl, countryCodeToFlag,
313
- parseHar, validateSitemap, validateRobotsTxt } from "@utilix-tech/sdk/network";
313
+ parseHar, validateSitemap, validateRobotsTxt,
314
+ parseUserAgent } from "@utilix-tech/sdk/network";
314
315
 
315
316
  getStatusCode(404);
316
317
  // { code: 404, text: "Not Found", description: "...", category: "Client Error" }
@@ -323,6 +324,11 @@ isValidIp("256.0.0.1"); // false
323
324
 
324
325
  countryCodeToFlag("US"); // "🇺🇸"
325
326
 
327
+ // User-Agent parsing
328
+ parseUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
329
+ // { browser: { name: "Chrome", version: "120.0.0.0" }, engine: { name: "Blink", version: "120.0.0.0" },
330
+ // os: { name: "Windows", version: "10" }, device: { type: "desktop" }, raw: "..." }
331
+
326
332
  // Parse a DevTools .har network export into entries + summary stats
327
333
  const har = await fs.promises.readFile("network.har", "utf-8");
328
334
  parseHar(har);
@@ -379,7 +385,7 @@ generateCspHeader({ "default-src": ["'self'"], "script-src": ["'self'", "cdn.exa
379
385
 
380
386
  ```ts
381
387
  import { formatSql, minifySql, testRegex, formatHtml, formatGql,
382
- detectDialect, splitStatements, lookupMime } from "@utilix-tech/sdk/code";
388
+ detectDialect, splitStatements, lookupMime, parseGithubUrl } from "@utilix-tech/sdk/code";
383
389
 
384
390
  // SQL
385
391
  formatSql("SELECT id,name FROM users WHERE active=1 ORDER BY name");
@@ -407,6 +413,10 @@ formatGql("query { user(id: 1) { name email } }");
407
413
  // MIME type lookup, either direction
408
414
  lookupMime("json"); // { kind: "extension", matches: [{ extension: "json", mimeType: "application/json" }] }
409
415
  lookupMime("image/jpeg"); // { kind: "mime", matches: [{ extension: "jpg", ... }, { extension: "jpeg", ... }] }
416
+
417
+ // GitHub URL parsing
418
+ parseGithubUrl("https://github.com/facebook/react/pull/1234");
419
+ // { owner: "facebook", repo: "react", type: "pull", number: 1234 }
410
420
  ```
411
421
 
412
422
  ---
@@ -536,9 +546,9 @@ readIcoInfo(new Uint8Array(icoBytes));
536
546
  | `@utilix-tech/sdk/generators` | UUID v4/v7, ULID, passwords, strength check, fake data |
537
547
  | `@utilix-tech/sdk/time` | Date diff, timezone convert, cron parse, relative time |
538
548
  | `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN validation, loan calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator |
539
- | `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing |
549
+ | `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing |
540
550
  | `@utilix-tech/sdk/api` | cURL build/parse, JWT decode/sign, JWKS parse, CORS headers, CSP header |
541
- | `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup |
551
+ | `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup, GitHub URL parsing |
542
552
  | `@utilix-tech/sdk/color` | Hex/RGB/HSL/HSV/CMYK convert, palette generation, contrast check |
543
553
  | `@utilix-tech/sdk/css` | CSS gradient, box-shadow, border-radius, keyframe animation generators |
544
554
  | `@utilix-tech/sdk/misc` | SVG optimize/sanitize, file size format, Unicode inspector |
@@ -26,6 +26,7 @@ __export(network_exports, {
26
26
  parseDnsResponse: () => parseDnsResponse,
27
27
  parseGeoResponse: () => parseGeoResponse,
28
28
  parseHar: () => parseHar,
29
+ parseUserAgent: () => parseUserAgent,
29
30
  searchHeaders: () => searchHeaders,
30
31
  searchStatusCodes: () => searchStatusCodes,
31
32
  statusCodeToText: () => statusCodeToText,
@@ -1615,5 +1616,110 @@ function validateRobotsTxt(text) {
1615
1616
  const valid = !issues.some((i) => i.severity === "error");
1616
1617
  return { groups, sitemaps, issues, valid };
1617
1618
  }
1619
+ var UA_BOT_PATTERNS = [
1620
+ [/googlebot/i, "Googlebot"],
1621
+ [/bingbot/i, "Bingbot"],
1622
+ [/slurp/i, "Slurp"],
1623
+ [/duckduckbot/i, "DuckDuckBot"],
1624
+ [/baiduspider/i, "Baiduspider"],
1625
+ [/yandexbot/i, "YandexBot"],
1626
+ [/facebookexternalhit/i, "Facebot"],
1627
+ [/twitterbot/i, "Twitterbot"],
1628
+ [/applebot/i, "Applebot"],
1629
+ [/discordbot/i, "Discordbot"],
1630
+ [/slackbot/i, "Slackbot"],
1631
+ [/telegrambot/i, "TelegramBot"],
1632
+ [/whatsapp/i, "WhatsApp"],
1633
+ [/ahrefsbot/i, "AhrefsBot"],
1634
+ [/semrushbot/i, "SemrushBot"],
1635
+ [/crawler|spider|\bbot\b/i, "Bot"]
1636
+ ];
1637
+ function _detectUaBrowser(s) {
1638
+ let m;
1639
+ if (m = s.match(/Edg(?:A|iOS)?\/([\d.]+)/)) return { name: "Edge", version: m[1] };
1640
+ if (m = s.match(/Edge\/([\d.]+)/)) return { name: "Edge (Legacy)", version: m[1] };
1641
+ if (m = s.match(/OPR\/([\d.]+)/)) return { name: "Opera", version: m[1] };
1642
+ if (m = s.match(/Opera\/([\d.]+)/)) return { name: "Opera", version: m[1] };
1643
+ if (m = s.match(/SamsungBrowser\/([\d.]+)/)) return { name: "Samsung Internet", version: m[1] };
1644
+ if (m = s.match(/FxiOS\/([\d.]+)/)) return { name: "Firefox", version: m[1] };
1645
+ if (m = s.match(/Firefox\/([\d.]+)/)) return { name: "Firefox", version: m[1] };
1646
+ if (m = s.match(/CriOS\/([\d.]+)/)) return { name: "Chrome", version: m[1] };
1647
+ if (m = s.match(/Chrome\/([\d.]+)/)) return { name: "Chrome", version: m[1] };
1648
+ if (m = s.match(/Version\/([\d.]+).*Safari\//)) return { name: "Safari", version: m[1] };
1649
+ if (/Safari\//.test(s)) return { name: "Safari", version: "" };
1650
+ if (m = s.match(/MSIE ([\d.]+)/)) return { name: "Internet Explorer", version: m[1] };
1651
+ if (m = s.match(/Trident\/.*rv:([\d.]+)/)) return { name: "Internet Explorer", version: m[1] };
1652
+ return { name: "Unknown", version: "" };
1653
+ }
1654
+ function _detectUaEngine(s, browserName) {
1655
+ let m;
1656
+ if (/Chrome\/|CriOS\/|Edg\/|OPR\/|SamsungBrowser\//.test(s)) {
1657
+ m = s.match(/Chrome\/([\d.]+)/) || s.match(/CriOS\/([\d.]+)/);
1658
+ return { name: "Blink", version: m ? m[1] : "" };
1659
+ }
1660
+ if (/Firefox\/|FxiOS\//.test(s)) {
1661
+ m = s.match(/rv:([\d.]+)/);
1662
+ return { name: "Gecko", version: m ? m[1] : "" };
1663
+ }
1664
+ if (m = s.match(/AppleWebKit\/([\d.]+)/)) return { name: "WebKit", version: m[1] };
1665
+ if (m = s.match(/Trident\/([\d.]+)/)) return { name: "Trident", version: m[1] };
1666
+ if (browserName === "Edge (Legacy)") return { name: "EdgeHTML", version: "" };
1667
+ return { name: "Unknown", version: "" };
1668
+ }
1669
+ var UA_WINDOWS_VERSIONS = {
1670
+ "10.0": "10",
1671
+ "6.3": "8.1",
1672
+ "6.2": "8",
1673
+ "6.1": "7",
1674
+ "6.0": "Vista",
1675
+ "5.1": "XP"
1676
+ };
1677
+ function _detectUaOs(s) {
1678
+ if (/Windows NT/.test(s)) return "Windows";
1679
+ if (/CrOS/.test(s)) return "ChromeOS";
1680
+ if (/Android/.test(s)) return "Android";
1681
+ if (/iPhone|iPad|iPod/.test(s)) return "iOS";
1682
+ if (/Mac OS X/.test(s)) return "macOS";
1683
+ if (/Linux/.test(s)) return "Linux";
1684
+ return "Unknown";
1685
+ }
1686
+ function _detectUaOsVersion(s) {
1687
+ let m;
1688
+ if (m = s.match(/Windows NT ([\d.]+)/)) return UA_WINDOWS_VERSIONS[m[1]] ?? m[1];
1689
+ if (/CrOS/.test(s) && (m = s.match(/CrOS \S+ ([\d.]+)/))) return m[1];
1690
+ if (m = s.match(/Android ([\d.]+)/)) return m[1];
1691
+ if (m = s.match(/(?:iPhone|CPU) OS ([\d_]+)/)) return m[1].replace(/_/g, ".");
1692
+ if (m = s.match(/Mac OS X ([\d_]+)/)) return m[1].replace(/_/g, ".");
1693
+ return "";
1694
+ }
1695
+ function _detectUaDeviceType(s) {
1696
+ if (/iPad/.test(s)) return "tablet";
1697
+ if (/Android/.test(s) && !/Mobile/.test(s)) return "tablet";
1698
+ if (/Mobile|iPhone|iPod|Android/.test(s)) return "mobile";
1699
+ return "desktop";
1700
+ }
1701
+ function parseUserAgent(ua) {
1702
+ if (!ua || typeof ua !== "string" || ua.trim() === "") {
1703
+ return { error: "Empty user-agent string" };
1704
+ }
1705
+ const s = ua.trim();
1706
+ for (const [re, name] of UA_BOT_PATTERNS) {
1707
+ if (re.test(s)) {
1708
+ const versionMatch = s.match(new RegExp(`${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\/([\\d.]+)`, "i"));
1709
+ return {
1710
+ browser: { name, version: versionMatch ? versionMatch[1] : "" },
1711
+ engine: { name: "Unknown", version: "" },
1712
+ os: { name: _detectUaOs(s), version: _detectUaOsVersion(s) },
1713
+ device: { type: "bot" },
1714
+ raw: s
1715
+ };
1716
+ }
1717
+ }
1718
+ const browser = _detectUaBrowser(s);
1719
+ const engine = _detectUaEngine(s, browser.name);
1720
+ const os = { name: _detectUaOs(s), version: _detectUaOsVersion(s) };
1721
+ const device = { type: _detectUaDeviceType(s) };
1722
+ return { browser, engine, os, device, raw: s };
1723
+ }
1618
1724
 
1619
- export { DNS_RECORD_TYPES, HTTP_HEADERS, STATUS_CODES, buildDnsQueryUrl, buildGeoUrl, buildMapUrl, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseDnsResponse, parseGeoResponse, parseHar, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap };
1725
+ export { DNS_RECORD_TYPES, HTTP_HEADERS, STATUS_CODES, buildDnsQueryUrl, buildGeoUrl, buildMapUrl, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseDnsResponse, parseGeoResponse, parseHar, parseUserAgent, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap };
@@ -39,6 +39,7 @@ __export(code_exports, {
39
39
  parseDockerImage: () => parseDockerImage,
40
40
  parseEnv: () => parseEnv,
41
41
  parseGitCommand: () => parseGitCommand,
42
+ parseGithubUrl: () => parseGithubUrl,
42
43
  parseSpec: () => parseSpec,
43
44
  removeConsoleCalls: () => removeConsoleCalls,
44
45
  removeEmptyAttributes: () => removeEmptyAttributes,
@@ -2412,5 +2413,67 @@ function lookupMime(query) {
2412
2413
  if (matches.length === 0) return { error: `No known MIME type for extension ".${ext}"` };
2413
2414
  return { query: trimmed, kind: "extension", matches };
2414
2415
  }
2416
+ function _parseGithubLineRange(hash) {
2417
+ const m = hash.match(/^#?L(\d+)(?:-L?(\d+))?$/i);
2418
+ if (!m) return {};
2419
+ const startLine = parseInt(m[1], 10);
2420
+ const endLine = m[2] ? parseInt(m[2], 10) : void 0;
2421
+ return endLine !== void 0 ? { startLine, endLine } : { startLine };
2422
+ }
2423
+ function parseGithubUrl(input) {
2424
+ if (!input || typeof input !== "string" || input.trim() === "") {
2425
+ return { error: "Empty URL" };
2426
+ }
2427
+ const trimmed = input.trim();
2428
+ const normalized = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
2429
+ let url;
2430
+ try {
2431
+ url = new URL(normalized);
2432
+ } catch {
2433
+ return { error: "Invalid URL" };
2434
+ }
2435
+ if (!/^(www\.)?github\.com$/i.test(url.hostname)) {
2436
+ return { error: `Not a github.com URL (got host "${url.hostname}")` };
2437
+ }
2438
+ const segments = url.pathname.split("/").filter(Boolean);
2439
+ if (segments.length < 2) {
2440
+ return { error: "URL must include an owner and a repository" };
2441
+ }
2442
+ const [owner, repo, ...rest] = segments;
2443
+ if (rest.length === 0) {
2444
+ return { owner, repo, type: "repo" };
2445
+ }
2446
+ const kind = rest[0];
2447
+ if (kind === "pull" || kind === "issues") {
2448
+ const number = parseInt(rest[1], 10);
2449
+ if (!rest[1] || Number.isNaN(number)) {
2450
+ return { error: `Missing ${kind === "pull" ? "pull request" : "issue"} number` };
2451
+ }
2452
+ return { owner, repo, type: kind === "pull" ? "pull" : "issue", number };
2453
+ }
2454
+ if (kind === "commit") {
2455
+ if (!rest[1]) return { error: "Missing commit SHA" };
2456
+ return { owner, repo, type: "commit", ref: rest[1] };
2457
+ }
2458
+ if (kind === "blob") {
2459
+ const ref = rest[1];
2460
+ const path = rest.slice(2).join("/");
2461
+ if (!ref || !path) return { error: "File URL must include a ref and a file path (/blob/<ref>/<path>)" };
2462
+ return { owner, repo, type: "file", ref, path, ..._parseGithubLineRange(url.hash) };
2463
+ }
2464
+ if (kind === "tree") {
2465
+ const ref = rest[1];
2466
+ if (!ref) return { error: "Missing branch or tag ref (/tree/<ref>)" };
2467
+ const path = rest.slice(2).join("/");
2468
+ return { owner, repo, type: "tree", ref, ...path ? { path } : {} };
2469
+ }
2470
+ if (kind === "releases") {
2471
+ if (rest[1] !== "tag" || !rest[2]) {
2472
+ return { error: "Unsupported releases URL (expected /releases/tag/<name>)" };
2473
+ }
2474
+ return { owner, repo, type: "release", ref: rest[2] };
2475
+ }
2476
+ return { error: `Unsupported GitHub URL path: /${rest.join("/")}` };
2477
+ }
2415
2478
 
2416
- export { ALL_FLAGS, CHEATSHEET, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey };
2479
+ export { ALL_FLAGS, CHEATSHEET, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseGithubUrl, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey };
@@ -18,6 +18,7 @@
18
18
  * - env-parser (parseEnv, envToJson, envToExport, validateEnvKey)
19
19
  * - css-minifier (minifyCss, formatCss, countRules, countProperties)
20
20
  * - mime-lookup (lookupMime, MIME_TABLE)
21
+ * - github-url-parser (parseGithubUrl)
21
22
  */
22
23
  type RegexFlag = 'g' | 'i' | 'm' | 's' | 'u';
23
24
  declare const ALL_FLAGS: RegexFlag[];
@@ -285,6 +286,27 @@ declare const MIME_TABLE: MimeEntry[];
285
286
  declare function lookupMime(query: string): MimeLookupResult | {
286
287
  error: string;
287
288
  };
289
+ type GithubUrlType = 'repo' | 'pull' | 'issue' | 'commit' | 'file' | 'tree' | 'release';
290
+ interface GithubUrlInfo {
291
+ owner: string;
292
+ repo: string;
293
+ type: GithubUrlType;
294
+ number?: number;
295
+ ref?: string;
296
+ path?: string;
297
+ startLine?: number;
298
+ endLine?: number;
299
+ }
300
+ /**
301
+ * Parses a github.com URL (repo, pull request, issue, commit, or a
302
+ * file/tree with an optional line range) into structured components via
303
+ * the path segments GitHub's own routing uses. Only covers github.com URLs
304
+ * over HTTP(S): SSH remotes (git@github.com:owner/repo.git) and other Git
305
+ * hosts are out of scope.
306
+ */
307
+ declare function parseGithubUrl(input: string): GithubUrlInfo | {
308
+ error: string;
309
+ };
288
310
 
289
311
  declare const code_ALL_FLAGS: typeof ALL_FLAGS;
290
312
  type code_ApiEndpoint = ApiEndpoint;
@@ -298,6 +320,8 @@ type code_EnvParseResult = EnvParseResult;
298
320
  type code_GitCommandConfig = GitCommandConfig;
299
321
  type code_GitCommandResult = GitCommandResult;
300
322
  type code_GitOperation = GitOperation;
323
+ type code_GithubUrlInfo = GithubUrlInfo;
324
+ type code_GithubUrlType = GithubUrlType;
301
325
  type code_GqlFormatResult = GqlFormatResult;
302
326
  type code_HtmlFormatResult = HtmlFormatResult;
303
327
  type code_HtmlMinifyOptions = HtmlMinifyOptions;
@@ -351,6 +375,7 @@ declare const code_normalizeRef: typeof normalizeRef;
351
375
  declare const code_parseDockerImage: typeof parseDockerImage;
352
376
  declare const code_parseEnv: typeof parseEnv;
353
377
  declare const code_parseGitCommand: typeof parseGitCommand;
378
+ declare const code_parseGithubUrl: typeof parseGithubUrl;
354
379
  declare const code_parseSpec: typeof parseSpec;
355
380
  declare const code_removeConsoleCalls: typeof removeConsoleCalls;
356
381
  declare const code_removeEmptyAttributes: typeof removeEmptyAttributes;
@@ -364,7 +389,7 @@ declare const code_testPattern: typeof testPattern;
364
389
  declare const code_testRegex: typeof testRegex;
365
390
  declare const code_validateEnvKey: typeof validateEnvKey;
366
391
  declare namespace code {
367
- export { code_ALL_FLAGS as ALL_FLAGS, type code_ApiEndpoint as ApiEndpoint, type code_ApiInfo as ApiInfo, code_CHEATSHEET as CHEATSHEET, type code_CheatsheetEntry as CheatsheetEntry, type code_CssResult as CssResult, type code_DockerImageRef as DockerImageRef, type code_EnvEntry as EnvEntry, type code_EnvParseResult as EnvParseResult, type code_GitCommandConfig as GitCommandConfig, type code_GitCommandResult as GitCommandResult, type code_GitOperation as GitOperation, type code_GqlFormatResult as GqlFormatResult, type code_HtmlFormatResult as HtmlFormatResult, type code_HtmlMinifyOptions as HtmlMinifyOptions, type code_HtmlMinifyResult as HtmlMinifyResult, type code_JsMinifyOptions as JsMinifyOptions, type code_JsMinifyResult as JsMinifyResult, code_MIME_TABLE as MIME_TABLE, type code_MatchResult as MatchResult, type code_MimeEntry as MimeEntry, type code_MimeLookupResult as MimeLookupResult, code_OPERATIONS as OPERATIONS, type code_ParsedSpec as ParsedSpec, type code_RegexError as RegexError, type code_RegexFlag as RegexFlag, type code_RegexMatch as RegexMatch, type code_RegexResult as RegexResult, type code_RegexSuccess as RegexSuccess, code_SQL_DEFAULT_OPTIONS as SQL_DEFAULT_OPTIONS, type code_Segment as Segment, type code_SpecVersion as SpecVersion, type code_SqlDialect as SqlDialect, type code_SqlFormatOptions as SqlFormatOptions, type code_TestPatternResult as TestPatternResult, code_buildDockerPull as buildDockerPull, code_buildDockerRun as buildDockerRun, code_buildGitCommand as buildGitCommand, code_collapseHtmlWhitespace as collapseHtmlWhitespace, code_collapseJsWhitespace as collapseJsWhitespace, code_countProperties as countProperties, code_countRules as countRules, code_detectDialect as detectDialect, code_detectOperationType as detectOperationType, code_envToExport as envToExport, code_envToJson as envToJson, code_formatCss as formatCss, code_formatGql as formatGql, code_formatHtml as formatHtml, code_formatSql as formatSql, code_getEndpointsByTag as getEndpointsByTag, code_getHtmlStats as getHtmlStats, code_getJsStats as getJsStats, code_getMethodColor as getMethodColor, code_isValidTag as isValidTag, code_lookupMime as lookupMime, code_minifyCss as minifyCss, code_minifyGql as minifyGql, code_minifyHtml as minifyHtml, code_minifyJs as minifyJs, code_minifySql as minifySql, code_normalizeRef as normalizeRef, code_parseDockerImage as parseDockerImage, code_parseEnv as parseEnv, code_parseGitCommand as parseGitCommand, code_parseSpec as parseSpec, code_removeConsoleCalls as removeConsoleCalls, code_removeEmptyAttributes as removeEmptyAttributes, code_removeHtmlComments as removeHtmlComments, code_removeJsComments as removeJsComments, code_removeRedundantAttributes as removeRedundantAttributes, code_searchCheatsheet as searchCheatsheet, code_searchEndpoints as searchEndpoints, code_splitStatements as splitStatements, code_testPattern as testPattern, code_testRegex as testRegex, code_validateEnvKey as validateEnvKey };
392
+ export { code_ALL_FLAGS as ALL_FLAGS, type code_ApiEndpoint as ApiEndpoint, type code_ApiInfo as ApiInfo, code_CHEATSHEET as CHEATSHEET, type code_CheatsheetEntry as CheatsheetEntry, type code_CssResult as CssResult, type code_DockerImageRef as DockerImageRef, type code_EnvEntry as EnvEntry, type code_EnvParseResult as EnvParseResult, type code_GitCommandConfig as GitCommandConfig, type code_GitCommandResult as GitCommandResult, type code_GitOperation as GitOperation, type code_GithubUrlInfo as GithubUrlInfo, type code_GithubUrlType as GithubUrlType, type code_GqlFormatResult as GqlFormatResult, type code_HtmlFormatResult as HtmlFormatResult, type code_HtmlMinifyOptions as HtmlMinifyOptions, type code_HtmlMinifyResult as HtmlMinifyResult, type code_JsMinifyOptions as JsMinifyOptions, type code_JsMinifyResult as JsMinifyResult, code_MIME_TABLE as MIME_TABLE, type code_MatchResult as MatchResult, type code_MimeEntry as MimeEntry, type code_MimeLookupResult as MimeLookupResult, code_OPERATIONS as OPERATIONS, type code_ParsedSpec as ParsedSpec, type code_RegexError as RegexError, type code_RegexFlag as RegexFlag, type code_RegexMatch as RegexMatch, type code_RegexResult as RegexResult, type code_RegexSuccess as RegexSuccess, code_SQL_DEFAULT_OPTIONS as SQL_DEFAULT_OPTIONS, type code_Segment as Segment, type code_SpecVersion as SpecVersion, type code_SqlDialect as SqlDialect, type code_SqlFormatOptions as SqlFormatOptions, type code_TestPatternResult as TestPatternResult, code_buildDockerPull as buildDockerPull, code_buildDockerRun as buildDockerRun, code_buildGitCommand as buildGitCommand, code_collapseHtmlWhitespace as collapseHtmlWhitespace, code_collapseJsWhitespace as collapseJsWhitespace, code_countProperties as countProperties, code_countRules as countRules, code_detectDialect as detectDialect, code_detectOperationType as detectOperationType, code_envToExport as envToExport, code_envToJson as envToJson, code_formatCss as formatCss, code_formatGql as formatGql, code_formatHtml as formatHtml, code_formatSql as formatSql, code_getEndpointsByTag as getEndpointsByTag, code_getHtmlStats as getHtmlStats, code_getJsStats as getJsStats, code_getMethodColor as getMethodColor, code_isValidTag as isValidTag, code_lookupMime as lookupMime, code_minifyCss as minifyCss, code_minifyGql as minifyGql, code_minifyHtml as minifyHtml, code_minifyJs as minifyJs, code_minifySql as minifySql, code_normalizeRef as normalizeRef, code_parseDockerImage as parseDockerImage, code_parseEnv as parseEnv, code_parseGitCommand as parseGitCommand, code_parseGithubUrl as parseGithubUrl, code_parseSpec as parseSpec, code_removeConsoleCalls as removeConsoleCalls, code_removeEmptyAttributes as removeEmptyAttributes, code_removeHtmlComments as removeHtmlComments, code_removeJsComments as removeJsComments, code_removeRedundantAttributes as removeRedundantAttributes, code_searchCheatsheet as searchCheatsheet, code_searchEndpoints as searchEndpoints, code_splitStatements as splitStatements, code_testPattern as testPattern, code_testRegex as testRegex, code_validateEnvKey as validateEnvKey };
368
393
  }
369
394
 
370
- export { getJsStats as $, ALL_FLAGS as A, collapseHtmlWhitespace as B, CHEATSHEET as C, type DockerImageRef as D, type EnvEntry as E, collapseJsWhitespace as F, type GitCommandConfig as G, type HtmlFormatResult as H, countProperties as I, type JsMinifyOptions as J, countRules as K, detectDialect as L, MIME_TABLE as M, detectOperationType as N, OPERATIONS as O, type ParsedSpec as P, envToExport as Q, type RegexError as R, SQL_DEFAULT_OPTIONS as S, type TestPatternResult as T, envToJson as U, formatCss as V, formatGql as W, formatHtml as X, formatSql as Y, getEndpointsByTag as Z, getHtmlStats as _, type ApiEndpoint as a, getMethodColor as a0, isValidTag as a1, lookupMime as a2, minifyCss as a3, minifyGql as a4, minifyHtml as a5, minifyJs as a6, minifySql as a7, normalizeRef as a8, parseDockerImage as a9, parseEnv as aa, parseGitCommand as ab, parseSpec as ac, removeConsoleCalls as ad, removeEmptyAttributes as ae, removeHtmlComments as af, removeJsComments as ag, removeRedundantAttributes as ah, searchCheatsheet as ai, searchEndpoints as aj, splitStatements as ak, testPattern as al, testRegex as am, validateEnvKey as an, type ApiInfo as b, code as c, type CheatsheetEntry as d, type CssResult as e, type EnvParseResult as f, type GitCommandResult as g, type GitOperation as h, type GqlFormatResult as i, type HtmlMinifyOptions as j, type HtmlMinifyResult as k, type JsMinifyResult as l, type MatchResult as m, type MimeEntry as n, type MimeLookupResult as o, type RegexFlag as p, type RegexMatch as q, type RegexResult as r, type RegexSuccess as s, type Segment as t, type SpecVersion as u, type SqlDialect as v, type SqlFormatOptions as w, buildDockerPull as x, buildDockerRun as y, buildGitCommand as z };
395
+ export { getEndpointsByTag as $, ALL_FLAGS as A, buildDockerRun as B, CHEATSHEET as C, type DockerImageRef as D, type EnvEntry as E, buildGitCommand as F, type GitCommandConfig as G, type HtmlFormatResult as H, collapseHtmlWhitespace as I, type JsMinifyOptions as J, collapseJsWhitespace as K, countProperties as L, MIME_TABLE as M, countRules as N, OPERATIONS as O, type ParsedSpec as P, detectDialect as Q, type RegexError as R, SQL_DEFAULT_OPTIONS as S, type TestPatternResult as T, detectOperationType as U, envToExport as V, envToJson as W, formatCss as X, formatGql as Y, formatHtml as Z, formatSql as _, type ApiEndpoint as a, getHtmlStats as a0, getJsStats as a1, getMethodColor as a2, isValidTag as a3, lookupMime as a4, minifyCss as a5, minifyGql as a6, minifyHtml as a7, minifyJs as a8, minifySql as a9, normalizeRef as aa, parseDockerImage as ab, parseEnv as ac, parseGitCommand as ad, parseGithubUrl as ae, parseSpec as af, removeConsoleCalls as ag, removeEmptyAttributes as ah, removeHtmlComments as ai, removeJsComments as aj, removeRedundantAttributes as ak, searchCheatsheet as al, searchEndpoints as am, splitStatements as an, testPattern as ao, testRegex as ap, validateEnvKey as aq, type ApiInfo as b, code as c, type CheatsheetEntry as d, type CssResult as e, type EnvParseResult as f, type GitCommandResult as g, type GitOperation as h, type GithubUrlInfo as i, type GithubUrlType as j, type GqlFormatResult as k, type HtmlMinifyOptions as l, type HtmlMinifyResult as m, type JsMinifyResult as n, type MatchResult as o, type MimeEntry as p, type MimeLookupResult as q, type RegexFlag as r, type RegexMatch as s, type RegexResult as t, type RegexSuccess as u, type Segment as v, type SpecVersion as w, type SqlDialect as x, type SqlFormatOptions as y, buildDockerPull as z };
@@ -18,6 +18,7 @@
18
18
  * - env-parser (parseEnv, envToJson, envToExport, validateEnvKey)
19
19
  * - css-minifier (minifyCss, formatCss, countRules, countProperties)
20
20
  * - mime-lookup (lookupMime, MIME_TABLE)
21
+ * - github-url-parser (parseGithubUrl)
21
22
  */
22
23
  type RegexFlag = 'g' | 'i' | 'm' | 's' | 'u';
23
24
  declare const ALL_FLAGS: RegexFlag[];
@@ -285,6 +286,27 @@ declare const MIME_TABLE: MimeEntry[];
285
286
  declare function lookupMime(query: string): MimeLookupResult | {
286
287
  error: string;
287
288
  };
289
+ type GithubUrlType = 'repo' | 'pull' | 'issue' | 'commit' | 'file' | 'tree' | 'release';
290
+ interface GithubUrlInfo {
291
+ owner: string;
292
+ repo: string;
293
+ type: GithubUrlType;
294
+ number?: number;
295
+ ref?: string;
296
+ path?: string;
297
+ startLine?: number;
298
+ endLine?: number;
299
+ }
300
+ /**
301
+ * Parses a github.com URL (repo, pull request, issue, commit, or a
302
+ * file/tree with an optional line range) into structured components via
303
+ * the path segments GitHub's own routing uses. Only covers github.com URLs
304
+ * over HTTP(S): SSH remotes (git@github.com:owner/repo.git) and other Git
305
+ * hosts are out of scope.
306
+ */
307
+ declare function parseGithubUrl(input: string): GithubUrlInfo | {
308
+ error: string;
309
+ };
288
310
 
289
311
  declare const code_ALL_FLAGS: typeof ALL_FLAGS;
290
312
  type code_ApiEndpoint = ApiEndpoint;
@@ -298,6 +320,8 @@ type code_EnvParseResult = EnvParseResult;
298
320
  type code_GitCommandConfig = GitCommandConfig;
299
321
  type code_GitCommandResult = GitCommandResult;
300
322
  type code_GitOperation = GitOperation;
323
+ type code_GithubUrlInfo = GithubUrlInfo;
324
+ type code_GithubUrlType = GithubUrlType;
301
325
  type code_GqlFormatResult = GqlFormatResult;
302
326
  type code_HtmlFormatResult = HtmlFormatResult;
303
327
  type code_HtmlMinifyOptions = HtmlMinifyOptions;
@@ -351,6 +375,7 @@ declare const code_normalizeRef: typeof normalizeRef;
351
375
  declare const code_parseDockerImage: typeof parseDockerImage;
352
376
  declare const code_parseEnv: typeof parseEnv;
353
377
  declare const code_parseGitCommand: typeof parseGitCommand;
378
+ declare const code_parseGithubUrl: typeof parseGithubUrl;
354
379
  declare const code_parseSpec: typeof parseSpec;
355
380
  declare const code_removeConsoleCalls: typeof removeConsoleCalls;
356
381
  declare const code_removeEmptyAttributes: typeof removeEmptyAttributes;
@@ -364,7 +389,7 @@ declare const code_testPattern: typeof testPattern;
364
389
  declare const code_testRegex: typeof testRegex;
365
390
  declare const code_validateEnvKey: typeof validateEnvKey;
366
391
  declare namespace code {
367
- export { code_ALL_FLAGS as ALL_FLAGS, type code_ApiEndpoint as ApiEndpoint, type code_ApiInfo as ApiInfo, code_CHEATSHEET as CHEATSHEET, type code_CheatsheetEntry as CheatsheetEntry, type code_CssResult as CssResult, type code_DockerImageRef as DockerImageRef, type code_EnvEntry as EnvEntry, type code_EnvParseResult as EnvParseResult, type code_GitCommandConfig as GitCommandConfig, type code_GitCommandResult as GitCommandResult, type code_GitOperation as GitOperation, type code_GqlFormatResult as GqlFormatResult, type code_HtmlFormatResult as HtmlFormatResult, type code_HtmlMinifyOptions as HtmlMinifyOptions, type code_HtmlMinifyResult as HtmlMinifyResult, type code_JsMinifyOptions as JsMinifyOptions, type code_JsMinifyResult as JsMinifyResult, code_MIME_TABLE as MIME_TABLE, type code_MatchResult as MatchResult, type code_MimeEntry as MimeEntry, type code_MimeLookupResult as MimeLookupResult, code_OPERATIONS as OPERATIONS, type code_ParsedSpec as ParsedSpec, type code_RegexError as RegexError, type code_RegexFlag as RegexFlag, type code_RegexMatch as RegexMatch, type code_RegexResult as RegexResult, type code_RegexSuccess as RegexSuccess, code_SQL_DEFAULT_OPTIONS as SQL_DEFAULT_OPTIONS, type code_Segment as Segment, type code_SpecVersion as SpecVersion, type code_SqlDialect as SqlDialect, type code_SqlFormatOptions as SqlFormatOptions, type code_TestPatternResult as TestPatternResult, code_buildDockerPull as buildDockerPull, code_buildDockerRun as buildDockerRun, code_buildGitCommand as buildGitCommand, code_collapseHtmlWhitespace as collapseHtmlWhitespace, code_collapseJsWhitespace as collapseJsWhitespace, code_countProperties as countProperties, code_countRules as countRules, code_detectDialect as detectDialect, code_detectOperationType as detectOperationType, code_envToExport as envToExport, code_envToJson as envToJson, code_formatCss as formatCss, code_formatGql as formatGql, code_formatHtml as formatHtml, code_formatSql as formatSql, code_getEndpointsByTag as getEndpointsByTag, code_getHtmlStats as getHtmlStats, code_getJsStats as getJsStats, code_getMethodColor as getMethodColor, code_isValidTag as isValidTag, code_lookupMime as lookupMime, code_minifyCss as minifyCss, code_minifyGql as minifyGql, code_minifyHtml as minifyHtml, code_minifyJs as minifyJs, code_minifySql as minifySql, code_normalizeRef as normalizeRef, code_parseDockerImage as parseDockerImage, code_parseEnv as parseEnv, code_parseGitCommand as parseGitCommand, code_parseSpec as parseSpec, code_removeConsoleCalls as removeConsoleCalls, code_removeEmptyAttributes as removeEmptyAttributes, code_removeHtmlComments as removeHtmlComments, code_removeJsComments as removeJsComments, code_removeRedundantAttributes as removeRedundantAttributes, code_searchCheatsheet as searchCheatsheet, code_searchEndpoints as searchEndpoints, code_splitStatements as splitStatements, code_testPattern as testPattern, code_testRegex as testRegex, code_validateEnvKey as validateEnvKey };
392
+ export { code_ALL_FLAGS as ALL_FLAGS, type code_ApiEndpoint as ApiEndpoint, type code_ApiInfo as ApiInfo, code_CHEATSHEET as CHEATSHEET, type code_CheatsheetEntry as CheatsheetEntry, type code_CssResult as CssResult, type code_DockerImageRef as DockerImageRef, type code_EnvEntry as EnvEntry, type code_EnvParseResult as EnvParseResult, type code_GitCommandConfig as GitCommandConfig, type code_GitCommandResult as GitCommandResult, type code_GitOperation as GitOperation, type code_GithubUrlInfo as GithubUrlInfo, type code_GithubUrlType as GithubUrlType, type code_GqlFormatResult as GqlFormatResult, type code_HtmlFormatResult as HtmlFormatResult, type code_HtmlMinifyOptions as HtmlMinifyOptions, type code_HtmlMinifyResult as HtmlMinifyResult, type code_JsMinifyOptions as JsMinifyOptions, type code_JsMinifyResult as JsMinifyResult, code_MIME_TABLE as MIME_TABLE, type code_MatchResult as MatchResult, type code_MimeEntry as MimeEntry, type code_MimeLookupResult as MimeLookupResult, code_OPERATIONS as OPERATIONS, type code_ParsedSpec as ParsedSpec, type code_RegexError as RegexError, type code_RegexFlag as RegexFlag, type code_RegexMatch as RegexMatch, type code_RegexResult as RegexResult, type code_RegexSuccess as RegexSuccess, code_SQL_DEFAULT_OPTIONS as SQL_DEFAULT_OPTIONS, type code_Segment as Segment, type code_SpecVersion as SpecVersion, type code_SqlDialect as SqlDialect, type code_SqlFormatOptions as SqlFormatOptions, type code_TestPatternResult as TestPatternResult, code_buildDockerPull as buildDockerPull, code_buildDockerRun as buildDockerRun, code_buildGitCommand as buildGitCommand, code_collapseHtmlWhitespace as collapseHtmlWhitespace, code_collapseJsWhitespace as collapseJsWhitespace, code_countProperties as countProperties, code_countRules as countRules, code_detectDialect as detectDialect, code_detectOperationType as detectOperationType, code_envToExport as envToExport, code_envToJson as envToJson, code_formatCss as formatCss, code_formatGql as formatGql, code_formatHtml as formatHtml, code_formatSql as formatSql, code_getEndpointsByTag as getEndpointsByTag, code_getHtmlStats as getHtmlStats, code_getJsStats as getJsStats, code_getMethodColor as getMethodColor, code_isValidTag as isValidTag, code_lookupMime as lookupMime, code_minifyCss as minifyCss, code_minifyGql as minifyGql, code_minifyHtml as minifyHtml, code_minifyJs as minifyJs, code_minifySql as minifySql, code_normalizeRef as normalizeRef, code_parseDockerImage as parseDockerImage, code_parseEnv as parseEnv, code_parseGitCommand as parseGitCommand, code_parseGithubUrl as parseGithubUrl, code_parseSpec as parseSpec, code_removeConsoleCalls as removeConsoleCalls, code_removeEmptyAttributes as removeEmptyAttributes, code_removeHtmlComments as removeHtmlComments, code_removeJsComments as removeJsComments, code_removeRedundantAttributes as removeRedundantAttributes, code_searchCheatsheet as searchCheatsheet, code_searchEndpoints as searchEndpoints, code_splitStatements as splitStatements, code_testPattern as testPattern, code_testRegex as testRegex, code_validateEnvKey as validateEnvKey };
368
393
  }
369
394
 
370
- export { getJsStats as $, ALL_FLAGS as A, collapseHtmlWhitespace as B, CHEATSHEET as C, type DockerImageRef as D, type EnvEntry as E, collapseJsWhitespace as F, type GitCommandConfig as G, type HtmlFormatResult as H, countProperties as I, type JsMinifyOptions as J, countRules as K, detectDialect as L, MIME_TABLE as M, detectOperationType as N, OPERATIONS as O, type ParsedSpec as P, envToExport as Q, type RegexError as R, SQL_DEFAULT_OPTIONS as S, type TestPatternResult as T, envToJson as U, formatCss as V, formatGql as W, formatHtml as X, formatSql as Y, getEndpointsByTag as Z, getHtmlStats as _, type ApiEndpoint as a, getMethodColor as a0, isValidTag as a1, lookupMime as a2, minifyCss as a3, minifyGql as a4, minifyHtml as a5, minifyJs as a6, minifySql as a7, normalizeRef as a8, parseDockerImage as a9, parseEnv as aa, parseGitCommand as ab, parseSpec as ac, removeConsoleCalls as ad, removeEmptyAttributes as ae, removeHtmlComments as af, removeJsComments as ag, removeRedundantAttributes as ah, searchCheatsheet as ai, searchEndpoints as aj, splitStatements as ak, testPattern as al, testRegex as am, validateEnvKey as an, type ApiInfo as b, code as c, type CheatsheetEntry as d, type CssResult as e, type EnvParseResult as f, type GitCommandResult as g, type GitOperation as h, type GqlFormatResult as i, type HtmlMinifyOptions as j, type HtmlMinifyResult as k, type JsMinifyResult as l, type MatchResult as m, type MimeEntry as n, type MimeLookupResult as o, type RegexFlag as p, type RegexMatch as q, type RegexResult as r, type RegexSuccess as s, type Segment as t, type SpecVersion as u, type SqlDialect as v, type SqlFormatOptions as w, buildDockerPull as x, buildDockerRun as y, buildGitCommand as z };
395
+ export { getEndpointsByTag as $, ALL_FLAGS as A, buildDockerRun as B, CHEATSHEET as C, type DockerImageRef as D, type EnvEntry as E, buildGitCommand as F, type GitCommandConfig as G, type HtmlFormatResult as H, collapseHtmlWhitespace as I, type JsMinifyOptions as J, collapseJsWhitespace as K, countProperties as L, MIME_TABLE as M, countRules as N, OPERATIONS as O, type ParsedSpec as P, detectDialect as Q, type RegexError as R, SQL_DEFAULT_OPTIONS as S, type TestPatternResult as T, detectOperationType as U, envToExport as V, envToJson as W, formatCss as X, formatGql as Y, formatHtml as Z, formatSql as _, type ApiEndpoint as a, getHtmlStats as a0, getJsStats as a1, getMethodColor as a2, isValidTag as a3, lookupMime as a4, minifyCss as a5, minifyGql as a6, minifyHtml as a7, minifyJs as a8, minifySql as a9, normalizeRef as aa, parseDockerImage as ab, parseEnv as ac, parseGitCommand as ad, parseGithubUrl as ae, parseSpec as af, removeConsoleCalls as ag, removeEmptyAttributes as ah, removeHtmlComments as ai, removeJsComments as aj, removeRedundantAttributes as ak, searchCheatsheet as al, searchEndpoints as am, splitStatements as an, testPattern as ao, testRegex as ap, validateEnvKey as aq, type ApiInfo as b, code as c, type CheatsheetEntry as d, type CssResult as e, type EnvParseResult as f, type GitCommandResult as g, type GitOperation as h, type GithubUrlInfo as i, type GithubUrlType as j, type GqlFormatResult as k, type HtmlMinifyOptions as l, type HtmlMinifyResult as m, type JsMinifyResult as n, type MatchResult as o, type MimeEntry as p, type MimeLookupResult as q, type RegexFlag as r, type RegexMatch as s, type RegexResult as t, type RegexSuccess as u, type Segment as v, type SpecVersion as w, type SqlDialect as x, type SqlFormatOptions as y, buildDockerPull as z };
package/dist/index.cjs CHANGED
@@ -7989,6 +7989,7 @@ __export(network_exports, {
7989
7989
  parseDnsResponse: () => parseDnsResponse,
7990
7990
  parseGeoResponse: () => parseGeoResponse,
7991
7991
  parseHar: () => parseHar,
7992
+ parseUserAgent: () => parseUserAgent,
7992
7993
  searchHeaders: () => searchHeaders,
7993
7994
  searchStatusCodes: () => searchStatusCodes,
7994
7995
  statusCodeToText: () => statusCodeToText,
@@ -9578,6 +9579,111 @@ function validateRobotsTxt(text) {
9578
9579
  const valid = !issues.some((i) => i.severity === "error");
9579
9580
  return { groups, sitemaps, issues, valid };
9580
9581
  }
9582
+ var UA_BOT_PATTERNS = [
9583
+ [/googlebot/i, "Googlebot"],
9584
+ [/bingbot/i, "Bingbot"],
9585
+ [/slurp/i, "Slurp"],
9586
+ [/duckduckbot/i, "DuckDuckBot"],
9587
+ [/baiduspider/i, "Baiduspider"],
9588
+ [/yandexbot/i, "YandexBot"],
9589
+ [/facebookexternalhit/i, "Facebot"],
9590
+ [/twitterbot/i, "Twitterbot"],
9591
+ [/applebot/i, "Applebot"],
9592
+ [/discordbot/i, "Discordbot"],
9593
+ [/slackbot/i, "Slackbot"],
9594
+ [/telegrambot/i, "TelegramBot"],
9595
+ [/whatsapp/i, "WhatsApp"],
9596
+ [/ahrefsbot/i, "AhrefsBot"],
9597
+ [/semrushbot/i, "SemrushBot"],
9598
+ [/crawler|spider|\bbot\b/i, "Bot"]
9599
+ ];
9600
+ function _detectUaBrowser(s) {
9601
+ let m;
9602
+ if (m = s.match(/Edg(?:A|iOS)?\/([\d.]+)/)) return { name: "Edge", version: m[1] };
9603
+ if (m = s.match(/Edge\/([\d.]+)/)) return { name: "Edge (Legacy)", version: m[1] };
9604
+ if (m = s.match(/OPR\/([\d.]+)/)) return { name: "Opera", version: m[1] };
9605
+ if (m = s.match(/Opera\/([\d.]+)/)) return { name: "Opera", version: m[1] };
9606
+ if (m = s.match(/SamsungBrowser\/([\d.]+)/)) return { name: "Samsung Internet", version: m[1] };
9607
+ if (m = s.match(/FxiOS\/([\d.]+)/)) return { name: "Firefox", version: m[1] };
9608
+ if (m = s.match(/Firefox\/([\d.]+)/)) return { name: "Firefox", version: m[1] };
9609
+ if (m = s.match(/CriOS\/([\d.]+)/)) return { name: "Chrome", version: m[1] };
9610
+ if (m = s.match(/Chrome\/([\d.]+)/)) return { name: "Chrome", version: m[1] };
9611
+ if (m = s.match(/Version\/([\d.]+).*Safari\//)) return { name: "Safari", version: m[1] };
9612
+ if (/Safari\//.test(s)) return { name: "Safari", version: "" };
9613
+ if (m = s.match(/MSIE ([\d.]+)/)) return { name: "Internet Explorer", version: m[1] };
9614
+ if (m = s.match(/Trident\/.*rv:([\d.]+)/)) return { name: "Internet Explorer", version: m[1] };
9615
+ return { name: "Unknown", version: "" };
9616
+ }
9617
+ function _detectUaEngine(s, browserName) {
9618
+ let m;
9619
+ if (/Chrome\/|CriOS\/|Edg\/|OPR\/|SamsungBrowser\//.test(s)) {
9620
+ m = s.match(/Chrome\/([\d.]+)/) || s.match(/CriOS\/([\d.]+)/);
9621
+ return { name: "Blink", version: m ? m[1] : "" };
9622
+ }
9623
+ if (/Firefox\/|FxiOS\//.test(s)) {
9624
+ m = s.match(/rv:([\d.]+)/);
9625
+ return { name: "Gecko", version: m ? m[1] : "" };
9626
+ }
9627
+ if (m = s.match(/AppleWebKit\/([\d.]+)/)) return { name: "WebKit", version: m[1] };
9628
+ if (m = s.match(/Trident\/([\d.]+)/)) return { name: "Trident", version: m[1] };
9629
+ if (browserName === "Edge (Legacy)") return { name: "EdgeHTML", version: "" };
9630
+ return { name: "Unknown", version: "" };
9631
+ }
9632
+ var UA_WINDOWS_VERSIONS = {
9633
+ "10.0": "10",
9634
+ "6.3": "8.1",
9635
+ "6.2": "8",
9636
+ "6.1": "7",
9637
+ "6.0": "Vista",
9638
+ "5.1": "XP"
9639
+ };
9640
+ function _detectUaOs(s) {
9641
+ if (/Windows NT/.test(s)) return "Windows";
9642
+ if (/CrOS/.test(s)) return "ChromeOS";
9643
+ if (/Android/.test(s)) return "Android";
9644
+ if (/iPhone|iPad|iPod/.test(s)) return "iOS";
9645
+ if (/Mac OS X/.test(s)) return "macOS";
9646
+ if (/Linux/.test(s)) return "Linux";
9647
+ return "Unknown";
9648
+ }
9649
+ function _detectUaOsVersion(s) {
9650
+ let m;
9651
+ if (m = s.match(/Windows NT ([\d.]+)/)) return UA_WINDOWS_VERSIONS[m[1]] ?? m[1];
9652
+ if (/CrOS/.test(s) && (m = s.match(/CrOS \S+ ([\d.]+)/))) return m[1];
9653
+ if (m = s.match(/Android ([\d.]+)/)) return m[1];
9654
+ if (m = s.match(/(?:iPhone|CPU) OS ([\d_]+)/)) return m[1].replace(/_/g, ".");
9655
+ if (m = s.match(/Mac OS X ([\d_]+)/)) return m[1].replace(/_/g, ".");
9656
+ return "";
9657
+ }
9658
+ function _detectUaDeviceType(s) {
9659
+ if (/iPad/.test(s)) return "tablet";
9660
+ if (/Android/.test(s) && !/Mobile/.test(s)) return "tablet";
9661
+ if (/Mobile|iPhone|iPod|Android/.test(s)) return "mobile";
9662
+ return "desktop";
9663
+ }
9664
+ function parseUserAgent(ua) {
9665
+ if (!ua || typeof ua !== "string" || ua.trim() === "") {
9666
+ return { error: "Empty user-agent string" };
9667
+ }
9668
+ const s = ua.trim();
9669
+ for (const [re, name] of UA_BOT_PATTERNS) {
9670
+ if (re.test(s)) {
9671
+ const versionMatch = s.match(new RegExp(`${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\/([\\d.]+)`, "i"));
9672
+ return {
9673
+ browser: { name, version: versionMatch ? versionMatch[1] : "" },
9674
+ engine: { name: "Unknown", version: "" },
9675
+ os: { name: _detectUaOs(s), version: _detectUaOsVersion(s) },
9676
+ device: { type: "bot" },
9677
+ raw: s
9678
+ };
9679
+ }
9680
+ }
9681
+ const browser = _detectUaBrowser(s);
9682
+ const engine = _detectUaEngine(s, browser.name);
9683
+ const os = { name: _detectUaOs(s), version: _detectUaOsVersion(s) };
9684
+ const device = { type: _detectUaDeviceType(s) };
9685
+ return { browser, engine, os, device, raw: s };
9686
+ }
9581
9687
 
9582
9688
  // src/tools/api.ts
9583
9689
  var api_exports = {};
@@ -10882,6 +10988,7 @@ __export(code_exports, {
10882
10988
  parseDockerImage: () => parseDockerImage,
10883
10989
  parseEnv: () => parseEnv2,
10884
10990
  parseGitCommand: () => parseGitCommand,
10991
+ parseGithubUrl: () => parseGithubUrl,
10885
10992
  parseSpec: () => parseSpec,
10886
10993
  removeConsoleCalls: () => removeConsoleCalls,
10887
10994
  removeEmptyAttributes: () => removeEmptyAttributes,
@@ -13255,6 +13362,68 @@ function lookupMime(query) {
13255
13362
  if (matches.length === 0) return { error: `No known MIME type for extension ".${ext}"` };
13256
13363
  return { query: trimmed, kind: "extension", matches };
13257
13364
  }
13365
+ function _parseGithubLineRange(hash) {
13366
+ const m = hash.match(/^#?L(\d+)(?:-L?(\d+))?$/i);
13367
+ if (!m) return {};
13368
+ const startLine = parseInt(m[1], 10);
13369
+ const endLine = m[2] ? parseInt(m[2], 10) : void 0;
13370
+ return endLine !== void 0 ? { startLine, endLine } : { startLine };
13371
+ }
13372
+ function parseGithubUrl(input) {
13373
+ if (!input || typeof input !== "string" || input.trim() === "") {
13374
+ return { error: "Empty URL" };
13375
+ }
13376
+ const trimmed = input.trim();
13377
+ const normalized = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
13378
+ let url;
13379
+ try {
13380
+ url = new URL(normalized);
13381
+ } catch {
13382
+ return { error: "Invalid URL" };
13383
+ }
13384
+ if (!/^(www\.)?github\.com$/i.test(url.hostname)) {
13385
+ return { error: `Not a github.com URL (got host "${url.hostname}")` };
13386
+ }
13387
+ const segments = url.pathname.split("/").filter(Boolean);
13388
+ if (segments.length < 2) {
13389
+ return { error: "URL must include an owner and a repository" };
13390
+ }
13391
+ const [owner, repo, ...rest] = segments;
13392
+ if (rest.length === 0) {
13393
+ return { owner, repo, type: "repo" };
13394
+ }
13395
+ const kind = rest[0];
13396
+ if (kind === "pull" || kind === "issues") {
13397
+ const number = parseInt(rest[1], 10);
13398
+ if (!rest[1] || Number.isNaN(number)) {
13399
+ return { error: `Missing ${kind === "pull" ? "pull request" : "issue"} number` };
13400
+ }
13401
+ return { owner, repo, type: kind === "pull" ? "pull" : "issue", number };
13402
+ }
13403
+ if (kind === "commit") {
13404
+ if (!rest[1]) return { error: "Missing commit SHA" };
13405
+ return { owner, repo, type: "commit", ref: rest[1] };
13406
+ }
13407
+ if (kind === "blob") {
13408
+ const ref = rest[1];
13409
+ const path = rest.slice(2).join("/");
13410
+ if (!ref || !path) return { error: "File URL must include a ref and a file path (/blob/<ref>/<path>)" };
13411
+ return { owner, repo, type: "file", ref, path, ..._parseGithubLineRange(url.hash) };
13412
+ }
13413
+ if (kind === "tree") {
13414
+ const ref = rest[1];
13415
+ if (!ref) return { error: "Missing branch or tag ref (/tree/<ref>)" };
13416
+ const path = rest.slice(2).join("/");
13417
+ return { owner, repo, type: "tree", ref, ...path ? { path } : {} };
13418
+ }
13419
+ if (kind === "releases") {
13420
+ if (rest[1] !== "tag" || !rest[2]) {
13421
+ return { error: "Unsupported releases URL (expected /releases/tag/<name>)" };
13422
+ }
13423
+ return { owner, repo, type: "release", ref: rest[2] };
13424
+ }
13425
+ return { error: `Unsupported GitHub URL path: /${rest.join("/")}` };
13426
+ }
13258
13427
 
13259
13428
  // src/tools/color.ts
13260
13429
  var color_exports = {};
package/dist/index.d.cts CHANGED
@@ -6,9 +6,9 @@ export { d as data } from './data-D8XTI7Du.cjs';
6
6
  export { g as generators } from './generators-BGtRGpJZ.cjs';
7
7
  export { t as time } from './time-DbT8fjaF.cjs';
8
8
  export { u as units } from './units-CkV4kAIs.cjs';
9
- export { n as network } from './network-DaNoZ5ER.cjs';
9
+ export { n as network } from './network-DZugNyAQ.cjs';
10
10
  export { a as api } from './api-Xl7OzIgq.cjs';
11
- export { c as code } from './code-C4skwg3l.cjs';
11
+ export { c as code } from './code-Cn9uOIAh.cjs';
12
12
  export { c as color } from './color-tPwZCr9H.cjs';
13
13
  export { c as css } from './css-Cf7AMGM-.cjs';
14
14
  export { m as misc } from './misc-CA3N198T.cjs';
package/dist/index.d.ts CHANGED
@@ -6,9 +6,9 @@ export { d as data } from './data-D8XTI7Du.js';
6
6
  export { g as generators } from './generators-BGtRGpJZ.js';
7
7
  export { t as time } from './time-DbT8fjaF.js';
8
8
  export { u as units } from './units-CkV4kAIs.js';
9
- export { n as network } from './network-DaNoZ5ER.js';
9
+ export { n as network } from './network-DZugNyAQ.js';
10
10
  export { a as api } from './api-Xl7OzIgq.js';
11
- export { c as code } from './code-C4skwg3l.js';
11
+ export { c as code } from './code-Cn9uOIAh.js';
12
12
  export { c as color } from './color-tPwZCr9H.js';
13
13
  export { c as css } from './css-Cf7AMGM-.js';
14
14
  export { m as misc } from './misc-CA3N198T.js';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  export { media_exports as media } from './chunk-XMKJYVKB.js';
2
2
  export { units_exports as units } from './chunk-M4MMO6C6.js';
3
- export { network_exports as network } from './chunk-OB56VNKJ.js';
3
+ export { network_exports as network } from './chunk-3QMUUTBH.js';
4
4
  export { api_exports as api } from './chunk-Q3B3YWOA.js';
5
- export { code_exports as code } from './chunk-Y5X34JAC.js';
5
+ export { code_exports as code } from './chunk-L53LAVAD.js';
6
6
  export { color_exports as color } from './chunk-BPVAB4P2.js';
7
7
  export { css_exports as css } from './chunk-6YPV2AB5.js';
8
8
  export { misc_exports as misc } from './chunk-GX7H6TAX.js';
@@ -10,6 +10,7 @@
10
10
  * - har-viewer : parseHar
11
11
  * - sitemap-validator: validateSitemap
12
12
  * - robots-txt-validator: validateRobotsTxt
13
+ * - user-agent-parser: parseUserAgent
13
14
  */
14
15
  declare const DNS_RECORD_TYPES: readonly ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
15
16
  type DnsRecordType = typeof DNS_RECORD_TYPES[number];
@@ -222,6 +223,35 @@ interface RobotsValidationResult {
222
223
  declare function validateRobotsTxt(text: string): RobotsValidationResult | {
223
224
  error: string;
224
225
  };
226
+ type UaDeviceType = 'desktop' | 'mobile' | 'tablet' | 'bot';
227
+ interface UserAgentInfo {
228
+ browser: {
229
+ name: string;
230
+ version: string;
231
+ };
232
+ engine: {
233
+ name: string;
234
+ version: string;
235
+ };
236
+ os: {
237
+ name: string;
238
+ version: string;
239
+ };
240
+ device: {
241
+ type: UaDeviceType;
242
+ };
243
+ raw: string;
244
+ }
245
+ /**
246
+ * Parses a browser User-Agent string into browser, engine, OS, and device
247
+ * type via pattern matching against well-known UA token formats. Covers the
248
+ * major desktop/mobile browsers and common search-engine/social crawlers;
249
+ * it is not an exhaustive UA database and falls back to 'Unknown' fields
250
+ * for obscure or custom UA strings.
251
+ */
252
+ declare function parseUserAgent(ua: string): UserAgentInfo | {
253
+ error: string;
254
+ };
225
255
 
226
256
  declare const network_DNS_RECORD_TYPES: typeof DNS_RECORD_TYPES;
227
257
  type network_DnsRecord = DnsRecord;
@@ -246,6 +276,8 @@ type network_SitemapIssue = SitemapIssue;
246
276
  type network_SitemapUrlEntry = SitemapUrlEntry;
247
277
  type network_SitemapValidationResult = SitemapValidationResult;
248
278
  type network_StatusCode = StatusCode;
279
+ type network_UaDeviceType = UaDeviceType;
280
+ type network_UserAgentInfo = UserAgentInfo;
249
281
  declare const network_buildDnsQueryUrl: typeof buildDnsQueryUrl;
250
282
  declare const network_buildGeoUrl: typeof buildGeoUrl;
251
283
  declare const network_buildMapUrl: typeof buildMapUrl;
@@ -266,6 +298,7 @@ declare const network_isValidIpv6: typeof isValidIpv6;
266
298
  declare const network_parseDnsResponse: typeof parseDnsResponse;
267
299
  declare const network_parseGeoResponse: typeof parseGeoResponse;
268
300
  declare const network_parseHar: typeof parseHar;
301
+ declare const network_parseUserAgent: typeof parseUserAgent;
269
302
  declare const network_searchHeaders: typeof searchHeaders;
270
303
  declare const network_searchStatusCodes: typeof searchStatusCodes;
271
304
  declare const network_statusCodeToText: typeof statusCodeToText;
@@ -276,7 +309,7 @@ declare const network_validateHeaderValue: typeof validateHeaderValue;
276
309
  declare const network_validateRobotsTxt: typeof validateRobotsTxt;
277
310
  declare const network_validateSitemap: typeof validateSitemap;
278
311
  declare namespace network {
279
- export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, type network_RobotsGroup as RobotsGroup, type network_RobotsIssue as RobotsIssue, type network_RobotsRule as RobotsRule, type network_RobotsValidationResult as RobotsValidationResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateRobotsTxt as validateRobotsTxt, network_validateSitemap as validateSitemap };
312
+ export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, type network_RobotsGroup as RobotsGroup, type network_RobotsIssue as RobotsIssue, type network_RobotsRule as RobotsRule, type network_RobotsValidationResult as RobotsValidationResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, type network_UaDeviceType as UaDeviceType, type network_UserAgentInfo as UserAgentInfo, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_parseUserAgent as parseUserAgent, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateRobotsTxt as validateRobotsTxt, network_validateSitemap as validateSitemap };
280
313
  }
281
314
 
282
- export { getHeadersByCategory as A, getStatusByCategory as B, getStatusCode as C, DNS_RECORD_TYPES as D, isClientError as E, isServerError as F, type GeoResult as G, HTTP_HEADERS as H, isSuccess as I, isValidIp as J, isValidIpv4 as K, isValidIpv6 as L, parseDnsResponse as M, parseGeoResponse as N, parseHar as O, type ParsedDnsResult as P, searchHeaders as Q, type RobotsGroup as R, STATUS_CODES as S, searchStatusCodes as T, statusCodeToText as U, typeNumberToLabel as V, validateDomain as W, validateHeaderName as X, validateHeaderValue as Y, validateRobotsTxt as Z, validateSitemap as _, type DnsRecord as a, type DnsRecordType as b, type DnsResponse as c, type HarEntry as d, type HarParseResult as e, type HarSummary as f, type HeaderCategory as g, type HttpHeader as h, type ParsedGeoResult as i, type RobotsIssue as j, type RobotsRule as k, type RobotsValidationResult as l, type SitemapIndexEntry as m, network as n, type SitemapIssue as o, type SitemapUrlEntry as p, type SitemapValidationResult as q, type StatusCode as r, buildDnsQueryUrl as s, buildGeoUrl as t, buildMapUrl as u, countryCodeToFlag as v, formatCoordinates as w, formatTtl as x, getByCategory as y, getHeader as z };
315
+ export { validateHeaderValue as $, getHeader as A, getHeadersByCategory as B, getStatusByCategory as C, DNS_RECORD_TYPES as D, getStatusCode as E, isClientError as F, type GeoResult as G, HTTP_HEADERS as H, isServerError as I, isSuccess as J, isValidIp as K, isValidIpv4 as L, isValidIpv6 as M, parseDnsResponse as N, parseGeoResponse as O, type ParsedDnsResult as P, parseHar as Q, type RobotsGroup as R, STATUS_CODES as S, parseUserAgent as T, type UaDeviceType as U, searchHeaders as V, searchStatusCodes as W, statusCodeToText as X, typeNumberToLabel as Y, validateDomain as Z, validateHeaderName as _, type DnsRecord as a, validateRobotsTxt as a0, validateSitemap as a1, type DnsRecordType as b, type DnsResponse as c, type HarEntry as d, type HarParseResult as e, type HarSummary as f, type HeaderCategory as g, type HttpHeader as h, type ParsedGeoResult as i, type RobotsIssue as j, type RobotsRule as k, type RobotsValidationResult as l, type SitemapIndexEntry as m, network as n, type SitemapIssue as o, type SitemapUrlEntry as p, type SitemapValidationResult as q, type StatusCode as r, type UserAgentInfo as s, buildDnsQueryUrl as t, buildGeoUrl as u, buildMapUrl as v, countryCodeToFlag as w, formatCoordinates as x, formatTtl as y, getByCategory as z };
@@ -10,6 +10,7 @@
10
10
  * - har-viewer : parseHar
11
11
  * - sitemap-validator: validateSitemap
12
12
  * - robots-txt-validator: validateRobotsTxt
13
+ * - user-agent-parser: parseUserAgent
13
14
  */
14
15
  declare const DNS_RECORD_TYPES: readonly ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
15
16
  type DnsRecordType = typeof DNS_RECORD_TYPES[number];
@@ -222,6 +223,35 @@ interface RobotsValidationResult {
222
223
  declare function validateRobotsTxt(text: string): RobotsValidationResult | {
223
224
  error: string;
224
225
  };
226
+ type UaDeviceType = 'desktop' | 'mobile' | 'tablet' | 'bot';
227
+ interface UserAgentInfo {
228
+ browser: {
229
+ name: string;
230
+ version: string;
231
+ };
232
+ engine: {
233
+ name: string;
234
+ version: string;
235
+ };
236
+ os: {
237
+ name: string;
238
+ version: string;
239
+ };
240
+ device: {
241
+ type: UaDeviceType;
242
+ };
243
+ raw: string;
244
+ }
245
+ /**
246
+ * Parses a browser User-Agent string into browser, engine, OS, and device
247
+ * type via pattern matching against well-known UA token formats. Covers the
248
+ * major desktop/mobile browsers and common search-engine/social crawlers;
249
+ * it is not an exhaustive UA database and falls back to 'Unknown' fields
250
+ * for obscure or custom UA strings.
251
+ */
252
+ declare function parseUserAgent(ua: string): UserAgentInfo | {
253
+ error: string;
254
+ };
225
255
 
226
256
  declare const network_DNS_RECORD_TYPES: typeof DNS_RECORD_TYPES;
227
257
  type network_DnsRecord = DnsRecord;
@@ -246,6 +276,8 @@ type network_SitemapIssue = SitemapIssue;
246
276
  type network_SitemapUrlEntry = SitemapUrlEntry;
247
277
  type network_SitemapValidationResult = SitemapValidationResult;
248
278
  type network_StatusCode = StatusCode;
279
+ type network_UaDeviceType = UaDeviceType;
280
+ type network_UserAgentInfo = UserAgentInfo;
249
281
  declare const network_buildDnsQueryUrl: typeof buildDnsQueryUrl;
250
282
  declare const network_buildGeoUrl: typeof buildGeoUrl;
251
283
  declare const network_buildMapUrl: typeof buildMapUrl;
@@ -266,6 +298,7 @@ declare const network_isValidIpv6: typeof isValidIpv6;
266
298
  declare const network_parseDnsResponse: typeof parseDnsResponse;
267
299
  declare const network_parseGeoResponse: typeof parseGeoResponse;
268
300
  declare const network_parseHar: typeof parseHar;
301
+ declare const network_parseUserAgent: typeof parseUserAgent;
269
302
  declare const network_searchHeaders: typeof searchHeaders;
270
303
  declare const network_searchStatusCodes: typeof searchStatusCodes;
271
304
  declare const network_statusCodeToText: typeof statusCodeToText;
@@ -276,7 +309,7 @@ declare const network_validateHeaderValue: typeof validateHeaderValue;
276
309
  declare const network_validateRobotsTxt: typeof validateRobotsTxt;
277
310
  declare const network_validateSitemap: typeof validateSitemap;
278
311
  declare namespace network {
279
- export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, type network_RobotsGroup as RobotsGroup, type network_RobotsIssue as RobotsIssue, type network_RobotsRule as RobotsRule, type network_RobotsValidationResult as RobotsValidationResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateRobotsTxt as validateRobotsTxt, network_validateSitemap as validateSitemap };
312
+ export { network_DNS_RECORD_TYPES as DNS_RECORD_TYPES, type network_DnsRecord as DnsRecord, type network_DnsRecordType as DnsRecordType, type network_DnsResponse as DnsResponse, type network_GeoResult as GeoResult, network_HTTP_HEADERS as HTTP_HEADERS, type network_HarEntry as HarEntry, type network_HarParseResult as HarParseResult, type network_HarSummary as HarSummary, type network_HeaderCategory as HeaderCategory, type network_HttpHeader as HttpHeader, type network_ParsedDnsResult as ParsedDnsResult, type network_ParsedGeoResult as ParsedGeoResult, type network_RobotsGroup as RobotsGroup, type network_RobotsIssue as RobotsIssue, type network_RobotsRule as RobotsRule, type network_RobotsValidationResult as RobotsValidationResult, network_STATUS_CODES as STATUS_CODES, type network_SitemapIndexEntry as SitemapIndexEntry, type network_SitemapIssue as SitemapIssue, type network_SitemapUrlEntry as SitemapUrlEntry, type network_SitemapValidationResult as SitemapValidationResult, type network_StatusCode as StatusCode, type network_UaDeviceType as UaDeviceType, type network_UserAgentInfo as UserAgentInfo, network_buildDnsQueryUrl as buildDnsQueryUrl, network_buildGeoUrl as buildGeoUrl, network_buildMapUrl as buildMapUrl, network_countryCodeToFlag as countryCodeToFlag, network_formatCoordinates as formatCoordinates, network_formatTtl as formatTtl, network_getByCategory as getByCategory, network_getHeader as getHeader, network_getHeadersByCategory as getHeadersByCategory, network_getStatusByCategory as getStatusByCategory, network_getStatusCode as getStatusCode, network_isClientError as isClientError, network_isServerError as isServerError, network_isSuccess as isSuccess, network_isValidIp as isValidIp, network_isValidIpv4 as isValidIpv4, network_isValidIpv6 as isValidIpv6, network_parseDnsResponse as parseDnsResponse, network_parseGeoResponse as parseGeoResponse, network_parseHar as parseHar, network_parseUserAgent as parseUserAgent, network_searchHeaders as searchHeaders, network_searchStatusCodes as searchStatusCodes, network_statusCodeToText as statusCodeToText, network_typeNumberToLabel as typeNumberToLabel, network_validateDomain as validateDomain, network_validateHeaderName as validateHeaderName, network_validateHeaderValue as validateHeaderValue, network_validateRobotsTxt as validateRobotsTxt, network_validateSitemap as validateSitemap };
280
313
  }
281
314
 
282
- export { getHeadersByCategory as A, getStatusByCategory as B, getStatusCode as C, DNS_RECORD_TYPES as D, isClientError as E, isServerError as F, type GeoResult as G, HTTP_HEADERS as H, isSuccess as I, isValidIp as J, isValidIpv4 as K, isValidIpv6 as L, parseDnsResponse as M, parseGeoResponse as N, parseHar as O, type ParsedDnsResult as P, searchHeaders as Q, type RobotsGroup as R, STATUS_CODES as S, searchStatusCodes as T, statusCodeToText as U, typeNumberToLabel as V, validateDomain as W, validateHeaderName as X, validateHeaderValue as Y, validateRobotsTxt as Z, validateSitemap as _, type DnsRecord as a, type DnsRecordType as b, type DnsResponse as c, type HarEntry as d, type HarParseResult as e, type HarSummary as f, type HeaderCategory as g, type HttpHeader as h, type ParsedGeoResult as i, type RobotsIssue as j, type RobotsRule as k, type RobotsValidationResult as l, type SitemapIndexEntry as m, network as n, type SitemapIssue as o, type SitemapUrlEntry as p, type SitemapValidationResult as q, type StatusCode as r, buildDnsQueryUrl as s, buildGeoUrl as t, buildMapUrl as u, countryCodeToFlag as v, formatCoordinates as w, formatTtl as x, getByCategory as y, getHeader as z };
315
+ export { validateHeaderValue as $, getHeader as A, getHeadersByCategory as B, getStatusByCategory as C, DNS_RECORD_TYPES as D, getStatusCode as E, isClientError as F, type GeoResult as G, HTTP_HEADERS as H, isServerError as I, isSuccess as J, isValidIp as K, isValidIpv4 as L, isValidIpv6 as M, parseDnsResponse as N, parseGeoResponse as O, type ParsedDnsResult as P, parseHar as Q, type RobotsGroup as R, STATUS_CODES as S, parseUserAgent as T, type UaDeviceType as U, searchHeaders as V, searchStatusCodes as W, statusCodeToText as X, typeNumberToLabel as Y, validateDomain as Z, validateHeaderName as _, type DnsRecord as a, validateRobotsTxt as a0, validateSitemap as a1, type DnsRecordType as b, type DnsResponse as c, type HarEntry as d, type HarParseResult as e, type HarSummary as f, type HeaderCategory as g, type HttpHeader as h, type ParsedGeoResult as i, type RobotsIssue as j, type RobotsRule as k, type RobotsValidationResult as l, type SitemapIndexEntry as m, network as n, type SitemapIssue as o, type SitemapUrlEntry as p, type SitemapValidationResult as q, type StatusCode as r, type UserAgentInfo as s, buildDnsQueryUrl as t, buildGeoUrl as u, buildMapUrl as v, countryCodeToFlag as w, formatCoordinates as x, formatTtl as y, getByCategory as z };
@@ -2363,6 +2363,68 @@ function lookupMime(query) {
2363
2363
  if (matches.length === 0) return { error: `No known MIME type for extension ".${ext}"` };
2364
2364
  return { query: trimmed, kind: "extension", matches };
2365
2365
  }
2366
+ function _parseGithubLineRange(hash) {
2367
+ const m = hash.match(/^#?L(\d+)(?:-L?(\d+))?$/i);
2368
+ if (!m) return {};
2369
+ const startLine = parseInt(m[1], 10);
2370
+ const endLine = m[2] ? parseInt(m[2], 10) : void 0;
2371
+ return endLine !== void 0 ? { startLine, endLine } : { startLine };
2372
+ }
2373
+ function parseGithubUrl(input) {
2374
+ if (!input || typeof input !== "string" || input.trim() === "") {
2375
+ return { error: "Empty URL" };
2376
+ }
2377
+ const trimmed = input.trim();
2378
+ const normalized = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
2379
+ let url;
2380
+ try {
2381
+ url = new URL(normalized);
2382
+ } catch {
2383
+ return { error: "Invalid URL" };
2384
+ }
2385
+ if (!/^(www\.)?github\.com$/i.test(url.hostname)) {
2386
+ return { error: `Not a github.com URL (got host "${url.hostname}")` };
2387
+ }
2388
+ const segments = url.pathname.split("/").filter(Boolean);
2389
+ if (segments.length < 2) {
2390
+ return { error: "URL must include an owner and a repository" };
2391
+ }
2392
+ const [owner, repo, ...rest] = segments;
2393
+ if (rest.length === 0) {
2394
+ return { owner, repo, type: "repo" };
2395
+ }
2396
+ const kind = rest[0];
2397
+ if (kind === "pull" || kind === "issues") {
2398
+ const number = parseInt(rest[1], 10);
2399
+ if (!rest[1] || Number.isNaN(number)) {
2400
+ return { error: `Missing ${kind === "pull" ? "pull request" : "issue"} number` };
2401
+ }
2402
+ return { owner, repo, type: kind === "pull" ? "pull" : "issue", number };
2403
+ }
2404
+ if (kind === "commit") {
2405
+ if (!rest[1]) return { error: "Missing commit SHA" };
2406
+ return { owner, repo, type: "commit", ref: rest[1] };
2407
+ }
2408
+ if (kind === "blob") {
2409
+ const ref = rest[1];
2410
+ const path = rest.slice(2).join("/");
2411
+ if (!ref || !path) return { error: "File URL must include a ref and a file path (/blob/<ref>/<path>)" };
2412
+ return { owner, repo, type: "file", ref, path, ..._parseGithubLineRange(url.hash) };
2413
+ }
2414
+ if (kind === "tree") {
2415
+ const ref = rest[1];
2416
+ if (!ref) return { error: "Missing branch or tag ref (/tree/<ref>)" };
2417
+ const path = rest.slice(2).join("/");
2418
+ return { owner, repo, type: "tree", ref, ...path ? { path } : {} };
2419
+ }
2420
+ if (kind === "releases") {
2421
+ if (rest[1] !== "tag" || !rest[2]) {
2422
+ return { error: "Unsupported releases URL (expected /releases/tag/<name>)" };
2423
+ }
2424
+ return { owner, repo, type: "release", ref: rest[2] };
2425
+ }
2426
+ return { error: `Unsupported GitHub URL path: /${rest.join("/")}` };
2427
+ }
2366
2428
 
2367
2429
  exports.ALL_FLAGS = ALL_FLAGS;
2368
2430
  exports.CHEATSHEET = CHEATSHEET;
@@ -2399,6 +2461,7 @@ exports.normalizeRef = normalizeRef;
2399
2461
  exports.parseDockerImage = parseDockerImage;
2400
2462
  exports.parseEnv = parseEnv;
2401
2463
  exports.parseGitCommand = parseGitCommand;
2464
+ exports.parseGithubUrl = parseGithubUrl;
2402
2465
  exports.parseSpec = parseSpec;
2403
2466
  exports.removeConsoleCalls = removeConsoleCalls;
2404
2467
  exports.removeEmptyAttributes = removeEmptyAttributes;
@@ -1 +1 @@
1
- export { A as ALL_FLAGS, a as ApiEndpoint, b as ApiInfo, C as CHEATSHEET, d as CheatsheetEntry, e as CssResult, D as DockerImageRef, E as EnvEntry, f as EnvParseResult, G as GitCommandConfig, g as GitCommandResult, h as GitOperation, i as GqlFormatResult, H as HtmlFormatResult, j as HtmlMinifyOptions, k as HtmlMinifyResult, J as JsMinifyOptions, l as JsMinifyResult, M as MIME_TABLE, m as MatchResult, n as MimeEntry, o as MimeLookupResult, O as OPERATIONS, P as ParsedSpec, R as RegexError, p as RegexFlag, q as RegexMatch, r as RegexResult, s as RegexSuccess, S as SQL_DEFAULT_OPTIONS, t as Segment, u as SpecVersion, v as SqlDialect, w as SqlFormatOptions, T as TestPatternResult, x as buildDockerPull, y as buildDockerRun, z as buildGitCommand, B as collapseHtmlWhitespace, F as collapseJsWhitespace, I as countProperties, K as countRules, L as detectDialect, N as detectOperationType, Q as envToExport, U as envToJson, V as formatCss, W as formatGql, X as formatHtml, Y as formatSql, Z as getEndpointsByTag, _ as getHtmlStats, $ as getJsStats, a0 as getMethodColor, a1 as isValidTag, a2 as lookupMime, a3 as minifyCss, a4 as minifyGql, a5 as minifyHtml, a6 as minifyJs, a7 as minifySql, a8 as normalizeRef, a9 as parseDockerImage, aa as parseEnv, ab as parseGitCommand, ac as parseSpec, ad as removeConsoleCalls, ae as removeEmptyAttributes, af as removeHtmlComments, ag as removeJsComments, ah as removeRedundantAttributes, ai as searchCheatsheet, aj as searchEndpoints, ak as splitStatements, al as testPattern, am as testRegex, an as validateEnvKey } from '../code-C4skwg3l.cjs';
1
+ export { A as ALL_FLAGS, a as ApiEndpoint, b as ApiInfo, C as CHEATSHEET, d as CheatsheetEntry, e as CssResult, D as DockerImageRef, E as EnvEntry, f as EnvParseResult, G as GitCommandConfig, g as GitCommandResult, h as GitOperation, i as GithubUrlInfo, j as GithubUrlType, k as GqlFormatResult, H as HtmlFormatResult, l as HtmlMinifyOptions, m as HtmlMinifyResult, J as JsMinifyOptions, n as JsMinifyResult, M as MIME_TABLE, o as MatchResult, p as MimeEntry, q as MimeLookupResult, O as OPERATIONS, P as ParsedSpec, R as RegexError, r as RegexFlag, s as RegexMatch, t as RegexResult, u as RegexSuccess, S as SQL_DEFAULT_OPTIONS, v as Segment, w as SpecVersion, x as SqlDialect, y as SqlFormatOptions, T as TestPatternResult, z as buildDockerPull, B as buildDockerRun, F as buildGitCommand, I as collapseHtmlWhitespace, K as collapseJsWhitespace, L as countProperties, N as countRules, Q as detectDialect, U as detectOperationType, V as envToExport, W as envToJson, X as formatCss, Y as formatGql, Z as formatHtml, _ as formatSql, $ as getEndpointsByTag, a0 as getHtmlStats, a1 as getJsStats, a2 as getMethodColor, a3 as isValidTag, a4 as lookupMime, a5 as minifyCss, a6 as minifyGql, a7 as minifyHtml, a8 as minifyJs, a9 as minifySql, aa as normalizeRef, ab as parseDockerImage, ac as parseEnv, ad as parseGitCommand, ae as parseGithubUrl, af as parseSpec, ag as removeConsoleCalls, ah as removeEmptyAttributes, ai as removeHtmlComments, aj as removeJsComments, ak as removeRedundantAttributes, al as searchCheatsheet, am as searchEndpoints, an as splitStatements, ao as testPattern, ap as testRegex, aq as validateEnvKey } from '../code-Cn9uOIAh.cjs';
@@ -1 +1 @@
1
- export { A as ALL_FLAGS, a as ApiEndpoint, b as ApiInfo, C as CHEATSHEET, d as CheatsheetEntry, e as CssResult, D as DockerImageRef, E as EnvEntry, f as EnvParseResult, G as GitCommandConfig, g as GitCommandResult, h as GitOperation, i as GqlFormatResult, H as HtmlFormatResult, j as HtmlMinifyOptions, k as HtmlMinifyResult, J as JsMinifyOptions, l as JsMinifyResult, M as MIME_TABLE, m as MatchResult, n as MimeEntry, o as MimeLookupResult, O as OPERATIONS, P as ParsedSpec, R as RegexError, p as RegexFlag, q as RegexMatch, r as RegexResult, s as RegexSuccess, S as SQL_DEFAULT_OPTIONS, t as Segment, u as SpecVersion, v as SqlDialect, w as SqlFormatOptions, T as TestPatternResult, x as buildDockerPull, y as buildDockerRun, z as buildGitCommand, B as collapseHtmlWhitespace, F as collapseJsWhitespace, I as countProperties, K as countRules, L as detectDialect, N as detectOperationType, Q as envToExport, U as envToJson, V as formatCss, W as formatGql, X as formatHtml, Y as formatSql, Z as getEndpointsByTag, _ as getHtmlStats, $ as getJsStats, a0 as getMethodColor, a1 as isValidTag, a2 as lookupMime, a3 as minifyCss, a4 as minifyGql, a5 as minifyHtml, a6 as minifyJs, a7 as minifySql, a8 as normalizeRef, a9 as parseDockerImage, aa as parseEnv, ab as parseGitCommand, ac as parseSpec, ad as removeConsoleCalls, ae as removeEmptyAttributes, af as removeHtmlComments, ag as removeJsComments, ah as removeRedundantAttributes, ai as searchCheatsheet, aj as searchEndpoints, ak as splitStatements, al as testPattern, am as testRegex, an as validateEnvKey } from '../code-C4skwg3l.js';
1
+ export { A as ALL_FLAGS, a as ApiEndpoint, b as ApiInfo, C as CHEATSHEET, d as CheatsheetEntry, e as CssResult, D as DockerImageRef, E as EnvEntry, f as EnvParseResult, G as GitCommandConfig, g as GitCommandResult, h as GitOperation, i as GithubUrlInfo, j as GithubUrlType, k as GqlFormatResult, H as HtmlFormatResult, l as HtmlMinifyOptions, m as HtmlMinifyResult, J as JsMinifyOptions, n as JsMinifyResult, M as MIME_TABLE, o as MatchResult, p as MimeEntry, q as MimeLookupResult, O as OPERATIONS, P as ParsedSpec, R as RegexError, r as RegexFlag, s as RegexMatch, t as RegexResult, u as RegexSuccess, S as SQL_DEFAULT_OPTIONS, v as Segment, w as SpecVersion, x as SqlDialect, y as SqlFormatOptions, T as TestPatternResult, z as buildDockerPull, B as buildDockerRun, F as buildGitCommand, I as collapseHtmlWhitespace, K as collapseJsWhitespace, L as countProperties, N as countRules, Q as detectDialect, U as detectOperationType, V as envToExport, W as envToJson, X as formatCss, Y as formatGql, Z as formatHtml, _ as formatSql, $ as getEndpointsByTag, a0 as getHtmlStats, a1 as getJsStats, a2 as getMethodColor, a3 as isValidTag, a4 as lookupMime, a5 as minifyCss, a6 as minifyGql, a7 as minifyHtml, a8 as minifyJs, a9 as minifySql, aa as normalizeRef, ab as parseDockerImage, ac as parseEnv, ad as parseGitCommand, ae as parseGithubUrl, af as parseSpec, ag as removeConsoleCalls, ah as removeEmptyAttributes, ai as removeHtmlComments, aj as removeJsComments, ak as removeRedundantAttributes, al as searchCheatsheet, am as searchEndpoints, an as splitStatements, ao as testPattern, ap as testRegex, aq as validateEnvKey } from '../code-Cn9uOIAh.js';
@@ -1,2 +1,2 @@
1
- export { ALL_FLAGS, CHEATSHEET, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey } from '../chunk-Y5X34JAC.js';
1
+ export { ALL_FLAGS, CHEATSHEET, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseGithubUrl, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey } from '../chunk-L53LAVAD.js';
2
2
  import '../chunk-MLKGABMK.js';
@@ -1580,6 +1580,111 @@ function validateRobotsTxt(text) {
1580
1580
  const valid = !issues.some((i) => i.severity === "error");
1581
1581
  return { groups, sitemaps, issues, valid };
1582
1582
  }
1583
+ var UA_BOT_PATTERNS = [
1584
+ [/googlebot/i, "Googlebot"],
1585
+ [/bingbot/i, "Bingbot"],
1586
+ [/slurp/i, "Slurp"],
1587
+ [/duckduckbot/i, "DuckDuckBot"],
1588
+ [/baiduspider/i, "Baiduspider"],
1589
+ [/yandexbot/i, "YandexBot"],
1590
+ [/facebookexternalhit/i, "Facebot"],
1591
+ [/twitterbot/i, "Twitterbot"],
1592
+ [/applebot/i, "Applebot"],
1593
+ [/discordbot/i, "Discordbot"],
1594
+ [/slackbot/i, "Slackbot"],
1595
+ [/telegrambot/i, "TelegramBot"],
1596
+ [/whatsapp/i, "WhatsApp"],
1597
+ [/ahrefsbot/i, "AhrefsBot"],
1598
+ [/semrushbot/i, "SemrushBot"],
1599
+ [/crawler|spider|\bbot\b/i, "Bot"]
1600
+ ];
1601
+ function _detectUaBrowser(s) {
1602
+ let m;
1603
+ if (m = s.match(/Edg(?:A|iOS)?\/([\d.]+)/)) return { name: "Edge", version: m[1] };
1604
+ if (m = s.match(/Edge\/([\d.]+)/)) return { name: "Edge (Legacy)", version: m[1] };
1605
+ if (m = s.match(/OPR\/([\d.]+)/)) return { name: "Opera", version: m[1] };
1606
+ if (m = s.match(/Opera\/([\d.]+)/)) return { name: "Opera", version: m[1] };
1607
+ if (m = s.match(/SamsungBrowser\/([\d.]+)/)) return { name: "Samsung Internet", version: m[1] };
1608
+ if (m = s.match(/FxiOS\/([\d.]+)/)) return { name: "Firefox", version: m[1] };
1609
+ if (m = s.match(/Firefox\/([\d.]+)/)) return { name: "Firefox", version: m[1] };
1610
+ if (m = s.match(/CriOS\/([\d.]+)/)) return { name: "Chrome", version: m[1] };
1611
+ if (m = s.match(/Chrome\/([\d.]+)/)) return { name: "Chrome", version: m[1] };
1612
+ if (m = s.match(/Version\/([\d.]+).*Safari\//)) return { name: "Safari", version: m[1] };
1613
+ if (/Safari\//.test(s)) return { name: "Safari", version: "" };
1614
+ if (m = s.match(/MSIE ([\d.]+)/)) return { name: "Internet Explorer", version: m[1] };
1615
+ if (m = s.match(/Trident\/.*rv:([\d.]+)/)) return { name: "Internet Explorer", version: m[1] };
1616
+ return { name: "Unknown", version: "" };
1617
+ }
1618
+ function _detectUaEngine(s, browserName) {
1619
+ let m;
1620
+ if (/Chrome\/|CriOS\/|Edg\/|OPR\/|SamsungBrowser\//.test(s)) {
1621
+ m = s.match(/Chrome\/([\d.]+)/) || s.match(/CriOS\/([\d.]+)/);
1622
+ return { name: "Blink", version: m ? m[1] : "" };
1623
+ }
1624
+ if (/Firefox\/|FxiOS\//.test(s)) {
1625
+ m = s.match(/rv:([\d.]+)/);
1626
+ return { name: "Gecko", version: m ? m[1] : "" };
1627
+ }
1628
+ if (m = s.match(/AppleWebKit\/([\d.]+)/)) return { name: "WebKit", version: m[1] };
1629
+ if (m = s.match(/Trident\/([\d.]+)/)) return { name: "Trident", version: m[1] };
1630
+ if (browserName === "Edge (Legacy)") return { name: "EdgeHTML", version: "" };
1631
+ return { name: "Unknown", version: "" };
1632
+ }
1633
+ var UA_WINDOWS_VERSIONS = {
1634
+ "10.0": "10",
1635
+ "6.3": "8.1",
1636
+ "6.2": "8",
1637
+ "6.1": "7",
1638
+ "6.0": "Vista",
1639
+ "5.1": "XP"
1640
+ };
1641
+ function _detectUaOs(s) {
1642
+ if (/Windows NT/.test(s)) return "Windows";
1643
+ if (/CrOS/.test(s)) return "ChromeOS";
1644
+ if (/Android/.test(s)) return "Android";
1645
+ if (/iPhone|iPad|iPod/.test(s)) return "iOS";
1646
+ if (/Mac OS X/.test(s)) return "macOS";
1647
+ if (/Linux/.test(s)) return "Linux";
1648
+ return "Unknown";
1649
+ }
1650
+ function _detectUaOsVersion(s) {
1651
+ let m;
1652
+ if (m = s.match(/Windows NT ([\d.]+)/)) return UA_WINDOWS_VERSIONS[m[1]] ?? m[1];
1653
+ if (/CrOS/.test(s) && (m = s.match(/CrOS \S+ ([\d.]+)/))) return m[1];
1654
+ if (m = s.match(/Android ([\d.]+)/)) return m[1];
1655
+ if (m = s.match(/(?:iPhone|CPU) OS ([\d_]+)/)) return m[1].replace(/_/g, ".");
1656
+ if (m = s.match(/Mac OS X ([\d_]+)/)) return m[1].replace(/_/g, ".");
1657
+ return "";
1658
+ }
1659
+ function _detectUaDeviceType(s) {
1660
+ if (/iPad/.test(s)) return "tablet";
1661
+ if (/Android/.test(s) && !/Mobile/.test(s)) return "tablet";
1662
+ if (/Mobile|iPhone|iPod|Android/.test(s)) return "mobile";
1663
+ return "desktop";
1664
+ }
1665
+ function parseUserAgent(ua) {
1666
+ if (!ua || typeof ua !== "string" || ua.trim() === "") {
1667
+ return { error: "Empty user-agent string" };
1668
+ }
1669
+ const s = ua.trim();
1670
+ for (const [re, name] of UA_BOT_PATTERNS) {
1671
+ if (re.test(s)) {
1672
+ const versionMatch = s.match(new RegExp(`${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\/([\\d.]+)`, "i"));
1673
+ return {
1674
+ browser: { name, version: versionMatch ? versionMatch[1] : "" },
1675
+ engine: { name: "Unknown", version: "" },
1676
+ os: { name: _detectUaOs(s), version: _detectUaOsVersion(s) },
1677
+ device: { type: "bot" },
1678
+ raw: s
1679
+ };
1680
+ }
1681
+ }
1682
+ const browser = _detectUaBrowser(s);
1683
+ const engine = _detectUaEngine(s, browser.name);
1684
+ const os = { name: _detectUaOs(s), version: _detectUaOsVersion(s) };
1685
+ const device = { type: _detectUaDeviceType(s) };
1686
+ return { browser, engine, os, device, raw: s };
1687
+ }
1583
1688
 
1584
1689
  exports.DNS_RECORD_TYPES = DNS_RECORD_TYPES;
1585
1690
  exports.HTTP_HEADERS = HTTP_HEADERS;
@@ -1604,6 +1709,7 @@ exports.isValidIpv6 = isValidIpv6;
1604
1709
  exports.parseDnsResponse = parseDnsResponse;
1605
1710
  exports.parseGeoResponse = parseGeoResponse;
1606
1711
  exports.parseHar = parseHar;
1712
+ exports.parseUserAgent = parseUserAgent;
1607
1713
  exports.searchHeaders = searchHeaders;
1608
1714
  exports.searchStatusCodes = searchStatusCodes;
1609
1715
  exports.statusCodeToText = statusCodeToText;
@@ -1 +1 @@
1
- export { D as DNS_RECORD_TYPES, a as DnsRecord, b as DnsRecordType, c as DnsResponse, G as GeoResult, H as HTTP_HEADERS, d as HarEntry, e as HarParseResult, f as HarSummary, g as HeaderCategory, h as HttpHeader, P as ParsedDnsResult, i as ParsedGeoResult, R as RobotsGroup, j as RobotsIssue, k as RobotsRule, l as RobotsValidationResult, S as STATUS_CODES, m as SitemapIndexEntry, o as SitemapIssue, p as SitemapUrlEntry, q as SitemapValidationResult, r as StatusCode, s as buildDnsQueryUrl, t as buildGeoUrl, u as buildMapUrl, v as countryCodeToFlag, w as formatCoordinates, x as formatTtl, y as getByCategory, z as getHeader, A as getHeadersByCategory, B as getStatusByCategory, C as getStatusCode, E as isClientError, F as isServerError, I as isSuccess, J as isValidIp, K as isValidIpv4, L as isValidIpv6, M as parseDnsResponse, N as parseGeoResponse, O as parseHar, Q as searchHeaders, T as searchStatusCodes, U as statusCodeToText, V as typeNumberToLabel, W as validateDomain, X as validateHeaderName, Y as validateHeaderValue, Z as validateRobotsTxt, _ as validateSitemap } from '../network-DaNoZ5ER.cjs';
1
+ export { D as DNS_RECORD_TYPES, a as DnsRecord, b as DnsRecordType, c as DnsResponse, G as GeoResult, H as HTTP_HEADERS, d as HarEntry, e as HarParseResult, f as HarSummary, g as HeaderCategory, h as HttpHeader, P as ParsedDnsResult, i as ParsedGeoResult, R as RobotsGroup, j as RobotsIssue, k as RobotsRule, l as RobotsValidationResult, S as STATUS_CODES, m as SitemapIndexEntry, o as SitemapIssue, p as SitemapUrlEntry, q as SitemapValidationResult, r as StatusCode, U as UaDeviceType, s as UserAgentInfo, t as buildDnsQueryUrl, u as buildGeoUrl, v as buildMapUrl, w as countryCodeToFlag, x as formatCoordinates, y as formatTtl, z as getByCategory, A as getHeader, B as getHeadersByCategory, C as getStatusByCategory, E as getStatusCode, F as isClientError, I as isServerError, J as isSuccess, K as isValidIp, L as isValidIpv4, M as isValidIpv6, N as parseDnsResponse, O as parseGeoResponse, Q as parseHar, T as parseUserAgent, V as searchHeaders, W as searchStatusCodes, X as statusCodeToText, Y as typeNumberToLabel, Z as validateDomain, _ as validateHeaderName, $ as validateHeaderValue, a0 as validateRobotsTxt, a1 as validateSitemap } from '../network-DZugNyAQ.cjs';
@@ -1 +1 @@
1
- export { D as DNS_RECORD_TYPES, a as DnsRecord, b as DnsRecordType, c as DnsResponse, G as GeoResult, H as HTTP_HEADERS, d as HarEntry, e as HarParseResult, f as HarSummary, g as HeaderCategory, h as HttpHeader, P as ParsedDnsResult, i as ParsedGeoResult, R as RobotsGroup, j as RobotsIssue, k as RobotsRule, l as RobotsValidationResult, S as STATUS_CODES, m as SitemapIndexEntry, o as SitemapIssue, p as SitemapUrlEntry, q as SitemapValidationResult, r as StatusCode, s as buildDnsQueryUrl, t as buildGeoUrl, u as buildMapUrl, v as countryCodeToFlag, w as formatCoordinates, x as formatTtl, y as getByCategory, z as getHeader, A as getHeadersByCategory, B as getStatusByCategory, C as getStatusCode, E as isClientError, F as isServerError, I as isSuccess, J as isValidIp, K as isValidIpv4, L as isValidIpv6, M as parseDnsResponse, N as parseGeoResponse, O as parseHar, Q as searchHeaders, T as searchStatusCodes, U as statusCodeToText, V as typeNumberToLabel, W as validateDomain, X as validateHeaderName, Y as validateHeaderValue, Z as validateRobotsTxt, _ as validateSitemap } from '../network-DaNoZ5ER.js';
1
+ export { D as DNS_RECORD_TYPES, a as DnsRecord, b as DnsRecordType, c as DnsResponse, G as GeoResult, H as HTTP_HEADERS, d as HarEntry, e as HarParseResult, f as HarSummary, g as HeaderCategory, h as HttpHeader, P as ParsedDnsResult, i as ParsedGeoResult, R as RobotsGroup, j as RobotsIssue, k as RobotsRule, l as RobotsValidationResult, S as STATUS_CODES, m as SitemapIndexEntry, o as SitemapIssue, p as SitemapUrlEntry, q as SitemapValidationResult, r as StatusCode, U as UaDeviceType, s as UserAgentInfo, t as buildDnsQueryUrl, u as buildGeoUrl, v as buildMapUrl, w as countryCodeToFlag, x as formatCoordinates, y as formatTtl, z as getByCategory, A as getHeader, B as getHeadersByCategory, C as getStatusByCategory, E as getStatusCode, F as isClientError, I as isServerError, J as isSuccess, K as isValidIp, L as isValidIpv4, M as isValidIpv6, N as parseDnsResponse, O as parseGeoResponse, Q as parseHar, T as parseUserAgent, V as searchHeaders, W as searchStatusCodes, X as statusCodeToText, Y as typeNumberToLabel, Z as validateDomain, _ as validateHeaderName, $ as validateHeaderValue, a0 as validateRobotsTxt, a1 as validateSitemap } from '../network-DZugNyAQ.js';
@@ -1,2 +1,2 @@
1
- export { DNS_RECORD_TYPES, HTTP_HEADERS, STATUS_CODES, buildDnsQueryUrl, buildGeoUrl, buildMapUrl, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, parseDnsResponse, parseGeoResponse, parseHar, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap } from '../chunk-OB56VNKJ.js';
1
+ export { DNS_RECORD_TYPES, HTTP_HEADERS, STATUS_CODES, buildDnsQueryUrl, buildGeoUrl, buildMapUrl, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, parseDnsResponse, parseGeoResponse, parseHar, parseUserAgent, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap } from '../chunk-3QMUUTBH.js';
2
2
  import '../chunk-MLKGABMK.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilix-tech/sdk",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "154+ developer utility tools for Node.js: JSON, encoding, hashing, color, CSS, network and more. Runs locally, no API key required.",
5
5
  "author": "Utilix <hello@utilix.tech>",
6
6
  "license": "MIT",