@utilix-tech/sdk 0.7.0 → 0.9.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/dist/index.cjs CHANGED
@@ -4257,6 +4257,7 @@ var data_exports = {};
4257
4257
  __export(data_exports, {
4258
4258
  csvToJson: () => csvToJson2,
4259
4259
  detectDelimiter: () => detectDelimiter2,
4260
+ diffEnvExample: () => diffEnvExample,
4260
4261
  envToExport: () => envToExport,
4261
4262
  envToJson: () => envToJson,
4262
4263
  formatNdjson: () => formatNdjson,
@@ -5331,6 +5332,23 @@ function envToExport(input) {
5331
5332
  function validateEnvKey(key) {
5332
5333
  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
5333
5334
  }
5335
+ function diffEnvExample(envInput, exampleInput) {
5336
+ const envParsed = parseEnv(envInput);
5337
+ if (envParsed.errors.length > 0) {
5338
+ return { error: `.env: ${envParsed.errors.map((e) => `Line ${e.line}: ${e.message}`).join("; ")}` };
5339
+ }
5340
+ const exampleParsed = parseEnv(exampleInput);
5341
+ if (exampleParsed.errors.length > 0) {
5342
+ return { error: `.env.example: ${exampleParsed.errors.map((e) => `Line ${e.line}: ${e.message}`).join("; ")}` };
5343
+ }
5344
+ const envKeys = new Set(envParsed.entries.map((e) => e.key));
5345
+ const exampleValues = new Map(exampleParsed.entries.map((e) => [e.key, e.value]));
5346
+ const missingInExample = [...envKeys].filter((k) => !exampleValues.has(k)).sort();
5347
+ const missingInEnv = [...exampleValues.keys()].filter((k) => !envKeys.has(k)).sort();
5348
+ const emptyValueInExample = [...exampleValues.entries()].filter(([k, v]) => envKeys.has(k) && v === "").map(([k]) => k).sort();
5349
+ const keysInBoth = [...envKeys].filter((k) => exampleValues.has(k)).length;
5350
+ return { missingInExample, missingInEnv, emptyValueInExample, keysInBoth };
5351
+ }
5334
5352
  function validateNdjson(input) {
5335
5353
  const rawLines = input.split("\n");
5336
5354
  const lines = [];
@@ -7512,7 +7530,8 @@ __export(network_exports, {
7512
7530
  typeNumberToLabel: () => typeNumberToLabel,
7513
7531
  validateDomain: () => validateDomain,
7514
7532
  validateHeaderName: () => validateHeaderName,
7515
- validateHeaderValue: () => validateHeaderValue
7533
+ validateHeaderValue: () => validateHeaderValue,
7534
+ validateSitemap: () => validateSitemap
7516
7535
  });
7517
7536
  var DNS_RECORD_TYPES = ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
7518
7537
  function buildDnsQueryUrl(domain, type) {
@@ -8920,6 +8939,96 @@ function parseHar(input) {
8920
8939
  summary: { totalRequests, totalSize, totalTime, avgTime, failedRequests, methods, statusCodes }
8921
8940
  };
8922
8941
  }
8942
+ var VALID_CHANGEFREQ = /* @__PURE__ */ new Set(["always", "hourly", "daily", "weekly", "monthly", "yearly", "never"]);
8943
+ function sitemapLineNumber(xml, index) {
8944
+ let line = 1;
8945
+ for (let i = 0; i < index; i++) {
8946
+ if (xml[i] === "\n") line++;
8947
+ }
8948
+ return line;
8949
+ }
8950
+ function extractSitemapTag(block, tag) {
8951
+ const m = block.match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`, "i"));
8952
+ return m ? m[1].trim() : void 0;
8953
+ }
8954
+ function isValidW3CDatetime(s) {
8955
+ return /^\d{4}(-\d{2}(-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2}))?)?)?$/.test(s);
8956
+ }
8957
+ function isAbsoluteHttpUrl(s) {
8958
+ return /^https?:\/\//i.test(s);
8959
+ }
8960
+ function validateSitemap(xml) {
8961
+ if (!xml || !xml.trim()) return { error: "Input is empty" };
8962
+ const trimmed = xml.trim();
8963
+ const issues = [];
8964
+ if (!/^\s*<\?xml/i.test(trimmed)) {
8965
+ issues.push({ severity: "warning", line: 1, message: 'Missing XML declaration (<?xml version="1.0" encoding="UTF-8"?>)' });
8966
+ }
8967
+ const isUrlset = /<urlset[\s>]/i.test(trimmed);
8968
+ const isSitemapIndex = /<sitemapindex[\s>]/i.test(trimmed);
8969
+ if (!isUrlset && !isSitemapIndex) {
8970
+ return { error: "Not a valid sitemap: root element must be <urlset> or <sitemapindex>" };
8971
+ }
8972
+ if (isUrlset && isSitemapIndex) {
8973
+ return { error: "Ambiguous file: contains both <urlset> and <sitemapindex> root elements" };
8974
+ }
8975
+ const type = isUrlset ? "urlset" : "sitemapindex";
8976
+ if (isUrlset && !/xmlns\s*=\s*["']http:\/\/www\.sitemaps\.org\/schemas\/sitemap\/0\.9["']/i.test(trimmed)) {
8977
+ issues.push({ severity: "warning", line: 1, message: "Missing or non-standard xmlns namespace (expected http://www.sitemaps.org/schemas/sitemap/0.9)" });
8978
+ }
8979
+ const blockTag = isUrlset ? "url" : "sitemap";
8980
+ const blockRe = new RegExp(`<${blockTag}>([\\s\\S]*?)</${blockTag}>`, "gi");
8981
+ const seenLocs = /* @__PURE__ */ new Set();
8982
+ const entries = [];
8983
+ let match;
8984
+ while ((match = blockRe.exec(trimmed)) !== null) {
8985
+ const block = match[1];
8986
+ const line = sitemapLineNumber(trimmed, match.index);
8987
+ const loc = extractSitemapTag(block, "loc");
8988
+ if (!loc) {
8989
+ issues.push({ severity: "error", line, message: `<${blockTag}> entry is missing required <loc>` });
8990
+ continue;
8991
+ }
8992
+ if (!isAbsoluteHttpUrl(loc)) {
8993
+ issues.push({ severity: "error", line, message: `<loc>${loc}</loc> must be an absolute URL starting with http:// or https://` });
8994
+ }
8995
+ if (/&(?!amp;|lt;|gt;|apos;|quot;|#\d+;)/.test(loc)) {
8996
+ issues.push({ severity: "error", line, message: `<loc>${loc}</loc> contains an unescaped '&' (use &amp; instead)` });
8997
+ }
8998
+ if (seenLocs.has(loc)) {
8999
+ issues.push({ severity: "warning", line, message: `Duplicate <loc>${loc}</loc>` });
9000
+ }
9001
+ seenLocs.add(loc);
9002
+ const lastmod = extractSitemapTag(block, "lastmod");
9003
+ if (lastmod !== void 0 && !isValidW3CDatetime(lastmod)) {
9004
+ issues.push({ severity: "warning", line, message: `<lastmod>${lastmod}</lastmod> is not a valid W3C datetime` });
9005
+ }
9006
+ if (type === "urlset") {
9007
+ const changefreq = extractSitemapTag(block, "changefreq");
9008
+ if (changefreq !== void 0 && !VALID_CHANGEFREQ.has(changefreq.toLowerCase())) {
9009
+ issues.push({ severity: "error", line, message: `<changefreq>${changefreq}</changefreq> must be one of: ${[...VALID_CHANGEFREQ].join(", ")}` });
9010
+ }
9011
+ const priority = extractSitemapTag(block, "priority");
9012
+ if (priority !== void 0) {
9013
+ const p = Number(priority);
9014
+ if (Number.isNaN(p) || p < 0 || p > 1) {
9015
+ issues.push({ severity: "error", line, message: `<priority>${priority}</priority> must be a number between 0.0 and 1.0` });
9016
+ }
9017
+ }
9018
+ entries.push({ loc, lastmod, changefreq, priority, line });
9019
+ } else {
9020
+ entries.push({ loc, lastmod, line });
9021
+ }
9022
+ }
9023
+ if (entries.length === 0) {
9024
+ issues.push({ severity: "error", line: 1, message: `No <${blockTag}> entries found` });
9025
+ }
9026
+ if (type === "urlset" && entries.length > 5e4) {
9027
+ issues.push({ severity: "error", line: 1, message: `Sitemap contains ${entries.length} URLs, exceeding the 50,000 URL limit per the sitemaps.org spec` });
9028
+ }
9029
+ const valid = !issues.some((i) => i.severity === "error");
9030
+ return { type, urlCount: entries.length, entries, issues, valid };
9031
+ }
8923
9032
 
8924
9033
  // src/tools/api.ts
8925
9034
  var api_exports = {};
@@ -16997,6 +17106,7 @@ function summarizeForLlm(text, maxTokens = 200, strategy = "extractive") {
16997
17106
  var media_exports = {};
16998
17107
  __export(media_exports, {
16999
17108
  readExifData: () => readExifData,
17109
+ readId3Tags: () => readId3Tags,
17000
17110
  readImageInfo: () => readImageInfo,
17001
17111
  readPdfMetadata: () => readPdfMetadata,
17002
17112
  readWavInfo: () => readWavInfo
@@ -17513,6 +17623,215 @@ function readWavInfo(bytes) {
17513
17623
  fileSize
17514
17624
  };
17515
17625
  }
17626
+ var ID3V1_GENRES = [
17627
+ "Blues",
17628
+ "Classic Rock",
17629
+ "Country",
17630
+ "Dance",
17631
+ "Disco",
17632
+ "Funk",
17633
+ "Grunge",
17634
+ "Hip-Hop",
17635
+ "Jazz",
17636
+ "Metal",
17637
+ "New Age",
17638
+ "Oldies",
17639
+ "Other",
17640
+ "Pop",
17641
+ "R&B",
17642
+ "Rap",
17643
+ "Reggae",
17644
+ "Rock",
17645
+ "Techno",
17646
+ "Industrial",
17647
+ "Alternative",
17648
+ "Ska",
17649
+ "Death Metal",
17650
+ "Pranks",
17651
+ "Soundtrack",
17652
+ "Euro-Techno",
17653
+ "Ambient",
17654
+ "Trip-Hop",
17655
+ "Vocal",
17656
+ "Jazz+Funk",
17657
+ "Fusion",
17658
+ "Trance",
17659
+ "Classical",
17660
+ "Instrumental",
17661
+ "Acid",
17662
+ "House",
17663
+ "Game",
17664
+ "Sound Clip",
17665
+ "Gospel",
17666
+ "Noise",
17667
+ "AlternRock",
17668
+ "Bass",
17669
+ "Soul",
17670
+ "Punk",
17671
+ "Space",
17672
+ "Meditative",
17673
+ "Instrumental Pop",
17674
+ "Instrumental Rock",
17675
+ "Ethnic",
17676
+ "Gothic",
17677
+ "Darkwave",
17678
+ "Techno-Industrial",
17679
+ "Electronic",
17680
+ "Pop-Folk",
17681
+ "Eurodance",
17682
+ "Dream",
17683
+ "Southern Rock",
17684
+ "Comedy",
17685
+ "Cult",
17686
+ "Gangsta",
17687
+ "Top 40",
17688
+ "Christian Rap",
17689
+ "Pop/Funk",
17690
+ "Jungle",
17691
+ "Native American",
17692
+ "Cabaret",
17693
+ "New Wave",
17694
+ "Psychedelic",
17695
+ "Rave",
17696
+ "Showtunes",
17697
+ "Trailer",
17698
+ "Lo-Fi",
17699
+ "Tribal",
17700
+ "Acid Punk",
17701
+ "Acid Jazz",
17702
+ "Polka",
17703
+ "Retro",
17704
+ "Musical",
17705
+ "Rock & Roll",
17706
+ "Hard Rock"
17707
+ ];
17708
+ function readSynchsafeUInt32(bytes, offset) {
17709
+ return (bytes[offset] & 127) << 21 | (bytes[offset + 1] & 127) << 14 | (bytes[offset + 2] & 127) << 7 | bytes[offset + 3] & 127;
17710
+ }
17711
+ function readUInt32BE(bytes, offset) {
17712
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
17713
+ }
17714
+ function decodeId3Text(frameBytes) {
17715
+ if (frameBytes.length === 0) return "";
17716
+ const encodingByte = frameBytes[0];
17717
+ const content = frameBytes.subarray(1);
17718
+ let out = "";
17719
+ if (encodingByte === 3) {
17720
+ out = Buffer.from(content).toString("utf8");
17721
+ } else if (encodingByte === 1 || encodingByte === 2) {
17722
+ let little = encodingByte === 1;
17723
+ let start = 0;
17724
+ if (encodingByte === 1 && content.length >= 2) {
17725
+ if (content[0] === 255 && content[1] === 254) {
17726
+ little = true;
17727
+ start = 2;
17728
+ } else if (content[0] === 254 && content[1] === 255) {
17729
+ little = false;
17730
+ start = 2;
17731
+ }
17732
+ }
17733
+ for (let i = start; i + 1 < content.length; i += 2) {
17734
+ const code = little ? content[i] | content[i + 1] << 8 : content[i] << 8 | content[i + 1];
17735
+ if (code === 0) break;
17736
+ out += String.fromCharCode(code);
17737
+ }
17738
+ } else {
17739
+ for (const b of content) {
17740
+ if (b === 0) break;
17741
+ out += String.fromCharCode(b);
17742
+ }
17743
+ }
17744
+ return out.replace(/\0+$/, "").trim();
17745
+ }
17746
+ function readId3v2(bytes) {
17747
+ if (bytes.length < 10 || bytes[0] !== 73 || bytes[1] !== 68 || bytes[2] !== 51) return null;
17748
+ const majorVersion = bytes[3];
17749
+ const revision = bytes[4];
17750
+ const tagSize = readSynchsafeUInt32(bytes, 6);
17751
+ const version2 = `ID3v2.${majorVersion}.${revision}`;
17752
+ if (majorVersion !== 3 && majorVersion !== 4) {
17753
+ return { version: version2, frames: {}, frameCount: 0 };
17754
+ }
17755
+ const frames = {};
17756
+ let offset = 10;
17757
+ const end = Math.min(10 + tagSize, bytes.length);
17758
+ let frameCount = 0;
17759
+ while (offset + 10 <= end) {
17760
+ const frameId = String.fromCharCode(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]);
17761
+ if (frameId === "\0\0\0\0") break;
17762
+ const frameSize = majorVersion === 4 ? readSynchsafeUInt32(bytes, offset + 4) : readUInt32BE(bytes, offset + 4);
17763
+ const frameStart = offset + 10;
17764
+ if (frameSize <= 0 || frameStart + frameSize > bytes.length) break;
17765
+ const frameBytes = bytes.subarray(frameStart, frameStart + frameSize);
17766
+ if (frameId[0] === "T" && frameId !== "TXXX") {
17767
+ frames[frameId] = decodeId3Text(frameBytes);
17768
+ } else if (frameId === "COMM" && frameBytes.length > 4) {
17769
+ const rebuilt = new Uint8Array(frameBytes.length - 3);
17770
+ rebuilt[0] = frameBytes[0];
17771
+ rebuilt.set(frameBytes.subarray(4), 1);
17772
+ const decoded = decodeId3Text(rebuilt);
17773
+ const parts = decoded.split("\0");
17774
+ frames["COMM"] = (parts[parts.length - 1] || decoded).trim();
17775
+ }
17776
+ frameCount++;
17777
+ offset = frameStart + frameSize;
17778
+ }
17779
+ return { version: version2, frames, frameCount };
17780
+ }
17781
+ function readId3v1(bytes) {
17782
+ if (bytes.length < 128) return null;
17783
+ const start = bytes.length - 128;
17784
+ if (String.fromCharCode(bytes[start], bytes[start + 1], bytes[start + 2]) !== "TAG") return null;
17785
+ const readField = (offset, length) => {
17786
+ let s = "";
17787
+ for (let i = 0; i < length; i++) {
17788
+ const b = bytes[start + offset + i];
17789
+ if (b === 0) break;
17790
+ s += String.fromCharCode(b);
17791
+ }
17792
+ return s.trim();
17793
+ };
17794
+ const title = readField(3, 30);
17795
+ const artist = readField(33, 30);
17796
+ const album = readField(63, 30);
17797
+ const year = readField(93, 4);
17798
+ const isV11 = bytes[start + 125] === 0 && bytes[start + 126] !== 0;
17799
+ const comment = readField(97, isV11 ? 28 : 30);
17800
+ const genreIndex = bytes[start + 127];
17801
+ const genre = ID3V1_GENRES[genreIndex] ?? `Unknown (${genreIndex})`;
17802
+ const result = { genre };
17803
+ if (title) result.title = title;
17804
+ if (artist) result.artist = artist;
17805
+ if (album) result.album = album;
17806
+ if (year) result.year = year;
17807
+ if (comment) result.comment = comment;
17808
+ if (isV11) result.trackNumber = String(bytes[start + 126]);
17809
+ return result;
17810
+ }
17811
+ function readId3Tags(bytes) {
17812
+ const v2 = readId3v2(bytes);
17813
+ const v1 = readId3v1(bytes);
17814
+ if (v2 && Object.keys(v2.frames).length > 0) {
17815
+ const f = v2.frames;
17816
+ const result = { version: v2.version, frameCount: v2.frameCount };
17817
+ if (f["TIT2"]) result.title = f["TIT2"];
17818
+ if (f["TPE1"]) result.artist = f["TPE1"];
17819
+ if (f["TALB"]) result.album = f["TALB"];
17820
+ const year = f["TYER"] || f["TDRC"];
17821
+ if (year) result.year = year;
17822
+ if (f["TCON"]) result.genre = f["TCON"];
17823
+ if (f["COMM"]) result.comment = f["COMM"];
17824
+ if (f["TRCK"]) result.trackNumber = f["TRCK"];
17825
+ return result;
17826
+ }
17827
+ if (v1) {
17828
+ return { version: v1.trackNumber !== void 0 ? "ID3v1.1" : "ID3v1", ...v1 };
17829
+ }
17830
+ if (v2) {
17831
+ return { error: `Unsupported ID3 tag version: ${v2.version} (only ID3v2.3, ID3v2.4, and ID3v1/1.1 are supported)` };
17832
+ }
17833
+ return { error: "No ID3v1 or ID3v2.3/2.4 tags found in this file" };
17834
+ }
17516
17835
 
17517
17836
  // src/index.ts
17518
17837
  var version = "0.1.0";
package/dist/index.d.cts CHANGED
@@ -2,18 +2,18 @@ export { j as json } from './json-BjSoIS1h.cjs';
2
2
  export { e as encoding } from './encoding-7gmq-vkV.cjs';
3
3
  export { h as hashing } from './hashing-CnetQFD_.cjs';
4
4
  export { t as text } from './text-Bbx-tZ43.cjs';
5
- export { d as data } from './data-CakDxAcT.cjs';
5
+ 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-6lwDYBvX.cjs';
9
- export { n as network } from './network-DwyAjwJS.cjs';
9
+ export { n as network } from './network-Cy02-FIO.cjs';
10
10
  export { a as api } from './api-Xl7OzIgq.cjs';
11
11
  export { c as code } from './code-BUqyaofO.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';
15
15
  export { a as ai_agent } from './ai_agent-CcpkV2DR.cjs';
16
- export { m as media } from './media-D66WnthC.cjs';
16
+ export { m as media } from './media-C3ZvGyKc.cjs';
17
17
 
18
18
  declare const version = "0.1.0";
19
19
 
package/dist/index.d.ts CHANGED
@@ -2,18 +2,18 @@ export { j as json } from './json-BjSoIS1h.js';
2
2
  export { e as encoding } from './encoding-7gmq-vkV.js';
3
3
  export { h as hashing } from './hashing-CnetQFD_.js';
4
4
  export { t as text } from './text-Bbx-tZ43.js';
5
- export { d as data } from './data-CakDxAcT.js';
5
+ 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-6lwDYBvX.js';
9
- export { n as network } from './network-DwyAjwJS.js';
9
+ export { n as network } from './network-Cy02-FIO.js';
10
10
  export { a as api } from './api-Xl7OzIgq.js';
11
11
  export { c as code } from './code-BUqyaofO.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';
15
15
  export { a as ai_agent } from './ai_agent-CcpkV2DR.js';
16
- export { m as media } from './media-D66WnthC.js';
16
+ export { m as media } from './media-C3ZvGyKc.js';
17
17
 
18
18
  declare const version = "0.1.0";
19
19
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { media_exports as media } from './chunk-5CKOJXFU.js';
1
+ export { media_exports as media } from './chunk-GUUYEIU6.js';
2
2
  export { units_exports as units } from './chunk-QJE743LY.js';
3
- export { network_exports as network } from './chunk-V5JKVDBA.js';
3
+ export { network_exports as network } from './chunk-LI5AME5R.js';
4
4
  export { api_exports as api } from './chunk-Q3B3YWOA.js';
5
5
  export { code_exports as code } from './chunk-V5S6OJ4A.js';
6
6
  export { color_exports as color } from './chunk-BPVAB4P2.js';
@@ -11,7 +11,7 @@ export { json_exports as json } from './chunk-TSAGO3XP.js';
11
11
  export { encoding_exports as encoding } from './chunk-IPR7FSX4.js';
12
12
  export { hashing_exports as hashing } from './chunk-GEFVMGZR.js';
13
13
  export { text_exports as text } from './chunk-F57WMKZO.js';
14
- export { data_exports as data } from './chunk-DNCOIO5N.js';
14
+ export { data_exports as data } from './chunk-TINQFTLO.js';
15
15
  export { generators_exports as generators } from './chunk-2CJSLYWI.js';
16
16
  export { time_exports as time } from './chunk-ZPQZEIXP.js';
17
17
  import './chunk-MLKGABMK.js';
@@ -86,9 +86,33 @@ interface WavInfoError {
86
86
  * rarer RF64 variant used for files over 4GB).
87
87
  */
88
88
  declare function readWavInfo(bytes: Uint8Array): WavInfo | WavInfoError;
89
+ interface Id3Tags {
90
+ version: string;
91
+ title?: string;
92
+ artist?: string;
93
+ album?: string;
94
+ year?: string;
95
+ genre?: string;
96
+ comment?: string;
97
+ trackNumber?: string;
98
+ frameCount?: number;
99
+ }
100
+ interface Id3TagsError {
101
+ error: string;
102
+ }
103
+ /**
104
+ * Read ID3 tags (title, artist, album, year, genre, comment, track number)
105
+ * directly from an MP3 file's bytes, without any audio-decoding library.
106
+ * Prefers an ID3v2.3/2.4 header at the start of the file; falls back to a
107
+ * classic ID3v1/1.1 128-byte trailer if no ID3v2 text frames are found.
108
+ * ID3v2.2 tags are detected but their 3-character frame IDs are not decoded.
109
+ */
110
+ declare function readId3Tags(bytes: Uint8Array): Id3Tags | Id3TagsError;
89
111
 
90
112
  type media_ExifData = ExifData;
91
113
  type media_ExifError = ExifError;
114
+ type media_Id3Tags = Id3Tags;
115
+ type media_Id3TagsError = Id3TagsError;
92
116
  type media_ImageFormat = ImageFormat;
93
117
  type media_ImageInfo = ImageInfo;
94
118
  type media_ImageInfoError = ImageInfoError;
@@ -97,11 +121,12 @@ type media_PdfMetadataError = PdfMetadataError;
97
121
  type media_WavInfo = WavInfo;
98
122
  type media_WavInfoError = WavInfoError;
99
123
  declare const media_readExifData: typeof readExifData;
124
+ declare const media_readId3Tags: typeof readId3Tags;
100
125
  declare const media_readImageInfo: typeof readImageInfo;
101
126
  declare const media_readPdfMetadata: typeof readPdfMetadata;
102
127
  declare const media_readWavInfo: typeof readWavInfo;
103
128
  declare namespace media {
104
- export { type media_ExifData as ExifData, type media_ExifError as ExifError, type media_ImageFormat as ImageFormat, type media_ImageInfo as ImageInfo, type media_ImageInfoError as ImageInfoError, type media_PdfMetadata as PdfMetadata, type media_PdfMetadataError as PdfMetadataError, type media_WavInfo as WavInfo, type media_WavInfoError as WavInfoError, media_readExifData as readExifData, media_readImageInfo as readImageInfo, media_readPdfMetadata as readPdfMetadata, media_readWavInfo as readWavInfo };
129
+ export { type media_ExifData as ExifData, type media_ExifError as ExifError, type media_Id3Tags as Id3Tags, type media_Id3TagsError as Id3TagsError, type media_ImageFormat as ImageFormat, type media_ImageInfo as ImageInfo, type media_ImageInfoError as ImageInfoError, type media_PdfMetadata as PdfMetadata, type media_PdfMetadataError as PdfMetadataError, type media_WavInfo as WavInfo, type media_WavInfoError as WavInfoError, media_readExifData as readExifData, media_readId3Tags as readId3Tags, media_readImageInfo as readImageInfo, media_readPdfMetadata as readPdfMetadata, media_readWavInfo as readWavInfo };
105
130
  }
106
131
 
107
- export { type ExifData as E, type ImageFormat as I, type PdfMetadata as P, type WavInfo as W, type ExifError as a, type ImageInfo as b, type ImageInfoError as c, type PdfMetadataError as d, type WavInfoError as e, readImageInfo as f, readPdfMetadata as g, readWavInfo as h, media as m, readExifData as r };
132
+ export { type ExifData as E, type Id3Tags as I, type PdfMetadata as P, type WavInfo as W, type ExifError as a, type Id3TagsError as b, type ImageFormat as c, type ImageInfo as d, type ImageInfoError as e, type PdfMetadataError as f, type WavInfoError as g, readId3Tags as h, readImageInfo as i, readPdfMetadata as j, readWavInfo as k, media as m, readExifData as r };
@@ -86,9 +86,33 @@ interface WavInfoError {
86
86
  * rarer RF64 variant used for files over 4GB).
87
87
  */
88
88
  declare function readWavInfo(bytes: Uint8Array): WavInfo | WavInfoError;
89
+ interface Id3Tags {
90
+ version: string;
91
+ title?: string;
92
+ artist?: string;
93
+ album?: string;
94
+ year?: string;
95
+ genre?: string;
96
+ comment?: string;
97
+ trackNumber?: string;
98
+ frameCount?: number;
99
+ }
100
+ interface Id3TagsError {
101
+ error: string;
102
+ }
103
+ /**
104
+ * Read ID3 tags (title, artist, album, year, genre, comment, track number)
105
+ * directly from an MP3 file's bytes, without any audio-decoding library.
106
+ * Prefers an ID3v2.3/2.4 header at the start of the file; falls back to a
107
+ * classic ID3v1/1.1 128-byte trailer if no ID3v2 text frames are found.
108
+ * ID3v2.2 tags are detected but their 3-character frame IDs are not decoded.
109
+ */
110
+ declare function readId3Tags(bytes: Uint8Array): Id3Tags | Id3TagsError;
89
111
 
90
112
  type media_ExifData = ExifData;
91
113
  type media_ExifError = ExifError;
114
+ type media_Id3Tags = Id3Tags;
115
+ type media_Id3TagsError = Id3TagsError;
92
116
  type media_ImageFormat = ImageFormat;
93
117
  type media_ImageInfo = ImageInfo;
94
118
  type media_ImageInfoError = ImageInfoError;
@@ -97,11 +121,12 @@ type media_PdfMetadataError = PdfMetadataError;
97
121
  type media_WavInfo = WavInfo;
98
122
  type media_WavInfoError = WavInfoError;
99
123
  declare const media_readExifData: typeof readExifData;
124
+ declare const media_readId3Tags: typeof readId3Tags;
100
125
  declare const media_readImageInfo: typeof readImageInfo;
101
126
  declare const media_readPdfMetadata: typeof readPdfMetadata;
102
127
  declare const media_readWavInfo: typeof readWavInfo;
103
128
  declare namespace media {
104
- export { type media_ExifData as ExifData, type media_ExifError as ExifError, type media_ImageFormat as ImageFormat, type media_ImageInfo as ImageInfo, type media_ImageInfoError as ImageInfoError, type media_PdfMetadata as PdfMetadata, type media_PdfMetadataError as PdfMetadataError, type media_WavInfo as WavInfo, type media_WavInfoError as WavInfoError, media_readExifData as readExifData, media_readImageInfo as readImageInfo, media_readPdfMetadata as readPdfMetadata, media_readWavInfo as readWavInfo };
129
+ export { type media_ExifData as ExifData, type media_ExifError as ExifError, type media_Id3Tags as Id3Tags, type media_Id3TagsError as Id3TagsError, type media_ImageFormat as ImageFormat, type media_ImageInfo as ImageInfo, type media_ImageInfoError as ImageInfoError, type media_PdfMetadata as PdfMetadata, type media_PdfMetadataError as PdfMetadataError, type media_WavInfo as WavInfo, type media_WavInfoError as WavInfoError, media_readExifData as readExifData, media_readId3Tags as readId3Tags, media_readImageInfo as readImageInfo, media_readPdfMetadata as readPdfMetadata, media_readWavInfo as readWavInfo };
105
130
  }
106
131
 
107
- export { type ExifData as E, type ImageFormat as I, type PdfMetadata as P, type WavInfo as W, type ExifError as a, type ImageInfo as b, type ImageInfoError as c, type PdfMetadataError as d, type WavInfoError as e, readImageInfo as f, readPdfMetadata as g, readWavInfo as h, media as m, readExifData as r };
132
+ export { type ExifData as E, type Id3Tags as I, type PdfMetadata as P, type WavInfo as W, type ExifError as a, type Id3TagsError as b, type ImageFormat as c, type ImageInfo as d, type ImageInfoError as e, type PdfMetadataError as f, type WavInfoError as g, readId3Tags as h, readImageInfo as i, readPdfMetadata as j, readWavInfo as k, media as m, readExifData as r };
@@ -8,6 +8,7 @@
8
8
  * - http-status : HTTP status code lookup and search
9
9
  * - http-headers : HTTP header reference lookup and validation
10
10
  * - har-viewer : parseHar
11
+ * - sitemap-validator: validateSitemap
11
12
  */
12
13
  declare const DNS_RECORD_TYPES: readonly ["A", "AAAA", "CNAME", "MX", "TXT", "NS", "SOA", "PTR", "SRV", "CAA"];
13
14
  type DnsRecordType = typeof DNS_RECORD_TYPES[number];
@@ -157,6 +158,38 @@ interface HarParseResult {
157
158
  declare function parseHar(input: string): HarParseResult | {
158
159
  error: string;
159
160
  };
161
+ interface SitemapUrlEntry {
162
+ loc: string;
163
+ lastmod?: string;
164
+ changefreq?: string;
165
+ priority?: string;
166
+ line: number;
167
+ }
168
+ interface SitemapIndexEntry {
169
+ loc: string;
170
+ lastmod?: string;
171
+ line: number;
172
+ }
173
+ interface SitemapIssue {
174
+ severity: 'error' | 'warning';
175
+ line: number;
176
+ message: string;
177
+ }
178
+ interface SitemapValidationResult {
179
+ type: 'urlset' | 'sitemapindex';
180
+ urlCount: number;
181
+ entries: SitemapUrlEntry[] | SitemapIndexEntry[];
182
+ issues: SitemapIssue[];
183
+ valid: boolean;
184
+ }
185
+ /**
186
+ * Validate a sitemap.xml (urlset) or sitemap index (sitemapindex) against the
187
+ * sitemaps.org protocol: required <loc>, absolute URLs, valid <changefreq>/
188
+ * <priority>/<lastmod> values, the 50,000-URL limit, and duplicate entries.
189
+ */
190
+ declare function validateSitemap(xml: string): SitemapValidationResult | {
191
+ error: string;
192
+ };
160
193
 
161
194
  declare const network_DNS_RECORD_TYPES: typeof DNS_RECORD_TYPES;
162
195
  type network_DnsRecord = DnsRecord;
@@ -172,6 +205,10 @@ type network_HttpHeader = HttpHeader;
172
205
  type network_ParsedDnsResult = ParsedDnsResult;
173
206
  type network_ParsedGeoResult = ParsedGeoResult;
174
207
  declare const network_STATUS_CODES: typeof STATUS_CODES;
208
+ type network_SitemapIndexEntry = SitemapIndexEntry;
209
+ type network_SitemapIssue = SitemapIssue;
210
+ type network_SitemapUrlEntry = SitemapUrlEntry;
211
+ type network_SitemapValidationResult = SitemapValidationResult;
175
212
  type network_StatusCode = StatusCode;
176
213
  declare const network_buildDnsQueryUrl: typeof buildDnsQueryUrl;
177
214
  declare const network_buildGeoUrl: typeof buildGeoUrl;
@@ -200,8 +237,9 @@ declare const network_typeNumberToLabel: typeof typeNumberToLabel;
200
237
  declare const network_validateDomain: typeof validateDomain;
201
238
  declare const network_validateHeaderName: typeof validateHeaderName;
202
239
  declare const network_validateHeaderValue: typeof validateHeaderValue;
240
+ declare const network_validateSitemap: typeof validateSitemap;
203
241
  declare namespace network {
204
- 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, network_STATUS_CODES as STATUS_CODES, 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 };
242
+ 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, 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_validateSitemap as validateSitemap };
205
243
  }
206
244
 
207
- export { isValidIpv4 as A, isValidIpv6 as B, parseDnsResponse as C, DNS_RECORD_TYPES as D, parseGeoResponse as E, parseHar as F, type GeoResult as G, HTTP_HEADERS as H, searchHeaders as I, searchStatusCodes as J, statusCodeToText as K, typeNumberToLabel as L, validateDomain as M, validateHeaderName as N, validateHeaderValue as O, type ParsedDnsResult as P, STATUS_CODES as S, 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 StatusCode as j, buildDnsQueryUrl as k, buildGeoUrl as l, buildMapUrl as m, network as n, countryCodeToFlag as o, formatCoordinates as p, formatTtl as q, getByCategory as r, getHeader as s, getHeadersByCategory as t, getStatusByCategory as u, getStatusCode as v, isClientError as w, isServerError as x, isSuccess as y, isValidIp as z };
245
+ export { isClientError as A, isServerError as B, isSuccess as C, DNS_RECORD_TYPES as D, isValidIp as E, isValidIpv4 as F, type GeoResult as G, HTTP_HEADERS as H, isValidIpv6 as I, parseDnsResponse as J, parseGeoResponse as K, parseHar as L, searchHeaders as M, searchStatusCodes as N, statusCodeToText as O, type ParsedDnsResult as P, typeNumberToLabel as Q, validateDomain as R, STATUS_CODES as S, validateHeaderName as T, validateHeaderValue as U, validateSitemap as V, 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 SitemapIndexEntry as j, type SitemapIssue as k, type SitemapUrlEntry as l, type SitemapValidationResult as m, network as n, type StatusCode as o, buildDnsQueryUrl as p, buildGeoUrl as q, buildMapUrl as r, countryCodeToFlag as s, formatCoordinates as t, formatTtl as u, getByCategory as v, getHeader as w, getHeadersByCategory as x, getStatusByCategory as y, getStatusCode as z };