@utilix-tech/sdk 0.6.0 → 0.8.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
@@ -1845,6 +1845,7 @@ __export(text_exports, {
1845
1845
  readabilityScore: () => readabilityScore,
1846
1846
  renderMarkdown: () => renderMarkdown,
1847
1847
  romanToNumber: () => romanToNumber,
1848
+ scoreReadability: () => scoreReadability,
1848
1849
  sentenceCount: () => sentenceCount,
1849
1850
  slugify: () => slugify,
1850
1851
  slugifyAll: () => slugifyAll,
@@ -4183,12 +4184,80 @@ function detectPassiveVoice(text) {
4183
4184
  const passivePercent = totalSentences > 0 ? Math.round(passiveSentences / totalSentences * 1e3) / 10 : 0;
4184
4185
  return { sentences: analyzed, totalSentences, passiveSentences, passivePercent };
4185
4186
  }
4187
+ function countSyllables(word) {
4188
+ const w = word.toLowerCase().replace(/[^a-z]/g, "");
4189
+ if (w.length === 0) return 0;
4190
+ if (w.length <= 3) return 1;
4191
+ let count = 0;
4192
+ let prevWasVowel = false;
4193
+ for (const ch of w) {
4194
+ const isVowel = "aeiouy".includes(ch);
4195
+ if (isVowel && !prevWasVowel) count++;
4196
+ prevWasVowel = isVowel;
4197
+ }
4198
+ if (w.endsWith("e") && !w.endsWith("le") && count > 1) count--;
4199
+ if (w.endsWith("le") && w.length > 2 && !"aeiouy".includes(w[w.length - 3])) count++;
4200
+ return Math.max(count, 1);
4201
+ }
4202
+ function readabilityGradeLabel(fleschReadingEase) {
4203
+ if (fleschReadingEase >= 90) return "Very easy (5th grade)";
4204
+ if (fleschReadingEase >= 80) return "Easy (6th grade)";
4205
+ if (fleschReadingEase >= 70) return "Fairly easy (7th grade)";
4206
+ if (fleschReadingEase >= 60) return "Standard (8th-9th grade)";
4207
+ if (fleschReadingEase >= 50) return "Fairly difficult (10th-12th grade)";
4208
+ if (fleschReadingEase >= 30) return "Difficult (college)";
4209
+ return "Very difficult (college graduate)";
4210
+ }
4211
+ function round1(n) {
4212
+ return Math.round(n * 10) / 10;
4213
+ }
4214
+ function scoreReadability(text) {
4215
+ const sentences = splitIntoSentences(text);
4216
+ const words = text.match(/[a-zA-Z']+/g) ?? [];
4217
+ const sentenceCount2 = Math.max(sentences.length, 1);
4218
+ const wordCount = words.length;
4219
+ const syllableCounts = words.map(countSyllables);
4220
+ const syllableCount2 = syllableCounts.reduce((a, b) => a + b, 0);
4221
+ const complexWordCount = syllableCounts.filter((c) => c >= 3).length;
4222
+ if (wordCount === 0) {
4223
+ return {
4224
+ wordCount: 0,
4225
+ sentenceCount: 0,
4226
+ syllableCount: 0,
4227
+ complexWordCount: 0,
4228
+ avgWordsPerSentence: 0,
4229
+ avgSyllablesPerWord: 0,
4230
+ fleschReadingEase: 0,
4231
+ fleschKincaidGrade: 0,
4232
+ gunningFog: 0,
4233
+ readingLevel: "No text to score"
4234
+ };
4235
+ }
4236
+ const avgWordsPerSentence = wordCount / sentenceCount2;
4237
+ const avgSyllablesPerWord = syllableCount2 / wordCount;
4238
+ const fleschReadingEase = round1(206.835 - 1.015 * avgWordsPerSentence - 84.6 * avgSyllablesPerWord);
4239
+ const fleschKincaidGrade = round1(0.39 * avgWordsPerSentence + 11.8 * avgSyllablesPerWord - 15.59);
4240
+ const gunningFog = round1(0.4 * (avgWordsPerSentence + 100 * (complexWordCount / wordCount)));
4241
+ return {
4242
+ wordCount,
4243
+ sentenceCount: sentences.length,
4244
+ syllableCount: syllableCount2,
4245
+ complexWordCount,
4246
+ avgWordsPerSentence: round1(avgWordsPerSentence),
4247
+ avgSyllablesPerWord: round1(avgSyllablesPerWord),
4248
+ fleschReadingEase,
4249
+ fleschKincaidGrade,
4250
+ gunningFog,
4251
+ readingLevel: readabilityGradeLabel(fleschReadingEase)
4252
+ };
4253
+ }
4186
4254
 
4187
4255
  // src/tools/data.ts
4188
4256
  var data_exports = {};
4189
4257
  __export(data_exports, {
4190
4258
  csvToJson: () => csvToJson2,
4191
4259
  detectDelimiter: () => detectDelimiter2,
4260
+ diffEnvExample: () => diffEnvExample,
4192
4261
  envToExport: () => envToExport,
4193
4262
  envToJson: () => envToJson,
4194
4263
  formatNdjson: () => formatNdjson,
@@ -5263,6 +5332,23 @@ function envToExport(input) {
5263
5332
  function validateEnvKey(key) {
5264
5333
  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
5265
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
+ }
5266
5352
  function validateNdjson(input) {
5267
5353
  const rawLines = input.split("\n");
5268
5354
  const lines = [];
@@ -16929,8 +17015,10 @@ function summarizeForLlm(text, maxTokens = 200, strategy = "extractive") {
16929
17015
  var media_exports = {};
16930
17016
  __export(media_exports, {
16931
17017
  readExifData: () => readExifData,
17018
+ readId3Tags: () => readId3Tags,
16932
17019
  readImageInfo: () => readImageInfo,
16933
- readPdfMetadata: () => readPdfMetadata
17020
+ readPdfMetadata: () => readPdfMetadata,
17021
+ readWavInfo: () => readWavInfo
16934
17022
  });
16935
17023
  function readU32BE(bytes, offset) {
16936
17024
  return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
@@ -17388,6 +17476,271 @@ function readPdfMetadata(bytes) {
17388
17476
  encrypted
17389
17477
  };
17390
17478
  }
17479
+ var AUDIO_FORMAT_LABELS = {
17480
+ 1: "PCM",
17481
+ 3: "IEEE float",
17482
+ 6: "A-law",
17483
+ 7: "mu-law",
17484
+ 65534: "Extensible"
17485
+ };
17486
+ function readAscii4(bytes, offset) {
17487
+ return String.fromCharCode(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]);
17488
+ }
17489
+ function readWavInfo(bytes) {
17490
+ if (bytes.length < 12) return { error: "File is too small to be a valid WAV file" };
17491
+ if (readAscii4(bytes, 0) !== "RIFF") return { error: 'Not a RIFF file (missing "RIFF" header)' };
17492
+ if (readAscii4(bytes, 8) !== "WAVE") return { error: 'Not a WAVE file (missing "WAVE" format marker)' };
17493
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17494
+ const fileSize = view.getUint32(4, true) + 8;
17495
+ let offset = 12;
17496
+ let fmt = null;
17497
+ let dataSize = null;
17498
+ while (offset + 8 <= bytes.length) {
17499
+ const chunkId = readAscii4(bytes, offset);
17500
+ const chunkSize = view.getUint32(offset + 4, true);
17501
+ const dataOffset = offset + 8;
17502
+ if (chunkId === "fmt ") {
17503
+ if (dataOffset + 16 > bytes.length) return { error: 'Truncated "fmt " chunk' };
17504
+ fmt = {
17505
+ audioFormat: view.getUint16(dataOffset, true),
17506
+ channels: view.getUint16(dataOffset + 2, true),
17507
+ sampleRate: view.getUint32(dataOffset + 4, true),
17508
+ byteRate: view.getUint32(dataOffset + 8, true),
17509
+ blockAlign: view.getUint16(dataOffset + 12, true),
17510
+ bitsPerSample: view.getUint16(dataOffset + 14, true)
17511
+ };
17512
+ } else if (chunkId === "data") {
17513
+ dataSize = Math.min(chunkSize, bytes.length - dataOffset);
17514
+ }
17515
+ offset = dataOffset + chunkSize + chunkSize % 2;
17516
+ if (fmt && dataSize !== null) break;
17517
+ }
17518
+ if (!fmt) return { error: 'No "fmt " chunk found in this WAV file' };
17519
+ if (dataSize === null) return { error: 'No "data" chunk found in this WAV file' };
17520
+ if (fmt.byteRate <= 0) return { error: 'Invalid byte rate in "fmt " chunk' };
17521
+ const durationSeconds = Math.round(dataSize / fmt.byteRate * 1e3) / 1e3;
17522
+ return {
17523
+ audioFormat: fmt.audioFormat,
17524
+ audioFormatLabel: AUDIO_FORMAT_LABELS[fmt.audioFormat] ?? `Unknown (0x${fmt.audioFormat.toString(16)})`,
17525
+ channels: fmt.channels,
17526
+ sampleRate: fmt.sampleRate,
17527
+ byteRate: fmt.byteRate,
17528
+ blockAlign: fmt.blockAlign,
17529
+ bitsPerSample: fmt.bitsPerSample,
17530
+ dataSize,
17531
+ durationSeconds,
17532
+ fileSize
17533
+ };
17534
+ }
17535
+ var ID3V1_GENRES = [
17536
+ "Blues",
17537
+ "Classic Rock",
17538
+ "Country",
17539
+ "Dance",
17540
+ "Disco",
17541
+ "Funk",
17542
+ "Grunge",
17543
+ "Hip-Hop",
17544
+ "Jazz",
17545
+ "Metal",
17546
+ "New Age",
17547
+ "Oldies",
17548
+ "Other",
17549
+ "Pop",
17550
+ "R&B",
17551
+ "Rap",
17552
+ "Reggae",
17553
+ "Rock",
17554
+ "Techno",
17555
+ "Industrial",
17556
+ "Alternative",
17557
+ "Ska",
17558
+ "Death Metal",
17559
+ "Pranks",
17560
+ "Soundtrack",
17561
+ "Euro-Techno",
17562
+ "Ambient",
17563
+ "Trip-Hop",
17564
+ "Vocal",
17565
+ "Jazz+Funk",
17566
+ "Fusion",
17567
+ "Trance",
17568
+ "Classical",
17569
+ "Instrumental",
17570
+ "Acid",
17571
+ "House",
17572
+ "Game",
17573
+ "Sound Clip",
17574
+ "Gospel",
17575
+ "Noise",
17576
+ "AlternRock",
17577
+ "Bass",
17578
+ "Soul",
17579
+ "Punk",
17580
+ "Space",
17581
+ "Meditative",
17582
+ "Instrumental Pop",
17583
+ "Instrumental Rock",
17584
+ "Ethnic",
17585
+ "Gothic",
17586
+ "Darkwave",
17587
+ "Techno-Industrial",
17588
+ "Electronic",
17589
+ "Pop-Folk",
17590
+ "Eurodance",
17591
+ "Dream",
17592
+ "Southern Rock",
17593
+ "Comedy",
17594
+ "Cult",
17595
+ "Gangsta",
17596
+ "Top 40",
17597
+ "Christian Rap",
17598
+ "Pop/Funk",
17599
+ "Jungle",
17600
+ "Native American",
17601
+ "Cabaret",
17602
+ "New Wave",
17603
+ "Psychedelic",
17604
+ "Rave",
17605
+ "Showtunes",
17606
+ "Trailer",
17607
+ "Lo-Fi",
17608
+ "Tribal",
17609
+ "Acid Punk",
17610
+ "Acid Jazz",
17611
+ "Polka",
17612
+ "Retro",
17613
+ "Musical",
17614
+ "Rock & Roll",
17615
+ "Hard Rock"
17616
+ ];
17617
+ function readSynchsafeUInt32(bytes, offset) {
17618
+ return (bytes[offset] & 127) << 21 | (bytes[offset + 1] & 127) << 14 | (bytes[offset + 2] & 127) << 7 | bytes[offset + 3] & 127;
17619
+ }
17620
+ function readUInt32BE(bytes, offset) {
17621
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
17622
+ }
17623
+ function decodeId3Text(frameBytes) {
17624
+ if (frameBytes.length === 0) return "";
17625
+ const encodingByte = frameBytes[0];
17626
+ const content = frameBytes.subarray(1);
17627
+ let out = "";
17628
+ if (encodingByte === 3) {
17629
+ out = Buffer.from(content).toString("utf8");
17630
+ } else if (encodingByte === 1 || encodingByte === 2) {
17631
+ let little = encodingByte === 1;
17632
+ let start = 0;
17633
+ if (encodingByte === 1 && content.length >= 2) {
17634
+ if (content[0] === 255 && content[1] === 254) {
17635
+ little = true;
17636
+ start = 2;
17637
+ } else if (content[0] === 254 && content[1] === 255) {
17638
+ little = false;
17639
+ start = 2;
17640
+ }
17641
+ }
17642
+ for (let i = start; i + 1 < content.length; i += 2) {
17643
+ const code = little ? content[i] | content[i + 1] << 8 : content[i] << 8 | content[i + 1];
17644
+ if (code === 0) break;
17645
+ out += String.fromCharCode(code);
17646
+ }
17647
+ } else {
17648
+ for (const b of content) {
17649
+ if (b === 0) break;
17650
+ out += String.fromCharCode(b);
17651
+ }
17652
+ }
17653
+ return out.replace(/\0+$/, "").trim();
17654
+ }
17655
+ function readId3v2(bytes) {
17656
+ if (bytes.length < 10 || bytes[0] !== 73 || bytes[1] !== 68 || bytes[2] !== 51) return null;
17657
+ const majorVersion = bytes[3];
17658
+ const revision = bytes[4];
17659
+ const tagSize = readSynchsafeUInt32(bytes, 6);
17660
+ const version2 = `ID3v2.${majorVersion}.${revision}`;
17661
+ if (majorVersion !== 3 && majorVersion !== 4) {
17662
+ return { version: version2, frames: {}, frameCount: 0 };
17663
+ }
17664
+ const frames = {};
17665
+ let offset = 10;
17666
+ const end = Math.min(10 + tagSize, bytes.length);
17667
+ let frameCount = 0;
17668
+ while (offset + 10 <= end) {
17669
+ const frameId = String.fromCharCode(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]);
17670
+ if (frameId === "\0\0\0\0") break;
17671
+ const frameSize = majorVersion === 4 ? readSynchsafeUInt32(bytes, offset + 4) : readUInt32BE(bytes, offset + 4);
17672
+ const frameStart = offset + 10;
17673
+ if (frameSize <= 0 || frameStart + frameSize > bytes.length) break;
17674
+ const frameBytes = bytes.subarray(frameStart, frameStart + frameSize);
17675
+ if (frameId[0] === "T" && frameId !== "TXXX") {
17676
+ frames[frameId] = decodeId3Text(frameBytes);
17677
+ } else if (frameId === "COMM" && frameBytes.length > 4) {
17678
+ const rebuilt = new Uint8Array(frameBytes.length - 3);
17679
+ rebuilt[0] = frameBytes[0];
17680
+ rebuilt.set(frameBytes.subarray(4), 1);
17681
+ const decoded = decodeId3Text(rebuilt);
17682
+ const parts = decoded.split("\0");
17683
+ frames["COMM"] = (parts[parts.length - 1] || decoded).trim();
17684
+ }
17685
+ frameCount++;
17686
+ offset = frameStart + frameSize;
17687
+ }
17688
+ return { version: version2, frames, frameCount };
17689
+ }
17690
+ function readId3v1(bytes) {
17691
+ if (bytes.length < 128) return null;
17692
+ const start = bytes.length - 128;
17693
+ if (String.fromCharCode(bytes[start], bytes[start + 1], bytes[start + 2]) !== "TAG") return null;
17694
+ const readField = (offset, length) => {
17695
+ let s = "";
17696
+ for (let i = 0; i < length; i++) {
17697
+ const b = bytes[start + offset + i];
17698
+ if (b === 0) break;
17699
+ s += String.fromCharCode(b);
17700
+ }
17701
+ return s.trim();
17702
+ };
17703
+ const title = readField(3, 30);
17704
+ const artist = readField(33, 30);
17705
+ const album = readField(63, 30);
17706
+ const year = readField(93, 4);
17707
+ const isV11 = bytes[start + 125] === 0 && bytes[start + 126] !== 0;
17708
+ const comment = readField(97, isV11 ? 28 : 30);
17709
+ const genreIndex = bytes[start + 127];
17710
+ const genre = ID3V1_GENRES[genreIndex] ?? `Unknown (${genreIndex})`;
17711
+ const result = { genre };
17712
+ if (title) result.title = title;
17713
+ if (artist) result.artist = artist;
17714
+ if (album) result.album = album;
17715
+ if (year) result.year = year;
17716
+ if (comment) result.comment = comment;
17717
+ if (isV11) result.trackNumber = String(bytes[start + 126]);
17718
+ return result;
17719
+ }
17720
+ function readId3Tags(bytes) {
17721
+ const v2 = readId3v2(bytes);
17722
+ const v1 = readId3v1(bytes);
17723
+ if (v2 && Object.keys(v2.frames).length > 0) {
17724
+ const f = v2.frames;
17725
+ const result = { version: v2.version, frameCount: v2.frameCount };
17726
+ if (f["TIT2"]) result.title = f["TIT2"];
17727
+ if (f["TPE1"]) result.artist = f["TPE1"];
17728
+ if (f["TALB"]) result.album = f["TALB"];
17729
+ const year = f["TYER"] || f["TDRC"];
17730
+ if (year) result.year = year;
17731
+ if (f["TCON"]) result.genre = f["TCON"];
17732
+ if (f["COMM"]) result.comment = f["COMM"];
17733
+ if (f["TRCK"]) result.trackNumber = f["TRCK"];
17734
+ return result;
17735
+ }
17736
+ if (v1) {
17737
+ return { version: v1.trackNumber !== void 0 ? "ID3v1.1" : "ID3v1", ...v1 };
17738
+ }
17739
+ if (v2) {
17740
+ return { error: `Unsupported ID3 tag version: ${v2.version} (only ID3v2.3, ID3v2.4, and ID3v1/1.1 are supported)` };
17741
+ }
17742
+ return { error: "No ID3v1 or ID3v2.3/2.4 tags found in this file" };
17743
+ }
17391
17744
 
17392
17745
  // src/index.ts
17393
17746
  var version = "0.1.0";
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  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
- export { t as text } from './text-CI7JAl7F.cjs';
5
- export { d as data } from './data-CakDxAcT.cjs';
4
+ export { t as text } from './text-Bbx-tZ43.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';
@@ -13,7 +13,7 @@ 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-CHaBS1dI.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
@@ -1,8 +1,8 @@
1
1
  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
- export { t as text } from './text-CI7JAl7F.js';
5
- export { d as data } from './data-CakDxAcT.js';
4
+ export { t as text } from './text-Bbx-tZ43.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';
@@ -13,7 +13,7 @@ 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-CHaBS1dI.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,4 +1,4 @@
1
- export { media_exports as media } from './chunk-FXBB7O5A.js';
1
+ export { media_exports as media } from './chunk-GUUYEIU6.js';
2
2
  export { units_exports as units } from './chunk-QJE743LY.js';
3
3
  export { network_exports as network } from './chunk-V5JKVDBA.js';
4
4
  export { api_exports as api } from './chunk-Q3B3YWOA.js';
@@ -10,8 +10,8 @@ export { ai_agent_exports as ai_agent } from './chunk-M35VJETW.js';
10
10
  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
- export { text_exports as text } from './chunk-YBBYFAOV.js';
14
- export { data_exports as data } from './chunk-DNCOIO5N.js';
13
+ export { text_exports as text } from './chunk-F57WMKZO.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';
@@ -0,0 +1,132 @@
1
+ type ImageFormat = 'png' | 'jpeg' | 'gif' | 'webp' | 'bmp';
2
+ interface ImageInfo {
3
+ format: ImageFormat;
4
+ width: number;
5
+ height: number;
6
+ bitDepth?: number;
7
+ colorType?: string;
8
+ hasAlpha?: boolean;
9
+ }
10
+ interface ImageInfoError {
11
+ error: string;
12
+ }
13
+ /**
14
+ * Read image format, dimensions, and basic color info straight from file
15
+ * bytes — no decoding, no image library, no canvas. Supports PNG, JPEG,
16
+ * GIF, WebP, and BMP.
17
+ */
18
+ declare function readImageInfo(bytes: Uint8Array): ImageInfo | ImageInfoError;
19
+ interface ExifData {
20
+ make?: string;
21
+ model?: string;
22
+ software?: string;
23
+ orientation?: number;
24
+ orientationLabel?: string;
25
+ dateTime?: string;
26
+ dateTimeOriginal?: string;
27
+ exposureTime?: string;
28
+ fNumber?: number;
29
+ isoSpeed?: number;
30
+ focalLength?: number;
31
+ gpsLatitude?: number;
32
+ gpsLongitude?: number;
33
+ tagCount: number;
34
+ }
35
+ interface ExifError {
36
+ error: string;
37
+ }
38
+ /**
39
+ * Read common EXIF tags (make, model, orientation, timestamps, exposure
40
+ * settings, GPS coordinates) directly from a JPEG's APP1 segment. Only
41
+ * JPEG is supported: PNG, WebP, and other formats don't carry EXIF the
42
+ * same way and are rejected with an error.
43
+ */
44
+ declare function readExifData(bytes: Uint8Array): ExifData | ExifError;
45
+ interface PdfMetadata {
46
+ version: string | null;
47
+ pageCount: number | null;
48
+ title: string | null;
49
+ author: string | null;
50
+ subject: string | null;
51
+ keywords: string | null;
52
+ creator: string | null;
53
+ producer: string | null;
54
+ creationDate: string | null;
55
+ modDate: string | null;
56
+ encrypted: boolean;
57
+ }
58
+ interface PdfMetadataError {
59
+ error: string;
60
+ }
61
+ /**
62
+ * Read PDF metadata (title, author, dates, page count, encryption flag)
63
+ * straight from the file's trailer/Info dictionary and page tree — no
64
+ * pdf.js or other PDF rendering library required.
65
+ */
66
+ declare function readPdfMetadata(bytes: Uint8Array): PdfMetadata | PdfMetadataError;
67
+ interface WavInfo {
68
+ audioFormat: number;
69
+ audioFormatLabel: string;
70
+ channels: number;
71
+ sampleRate: number;
72
+ byteRate: number;
73
+ blockAlign: number;
74
+ bitsPerSample: number;
75
+ dataSize: number;
76
+ durationSeconds: number;
77
+ fileSize: number;
78
+ }
79
+ interface WavInfoError {
80
+ error: string;
81
+ }
82
+ /**
83
+ * Read a WAV file's RIFF/fmt/data chunk headers to report sample rate,
84
+ * channel count, bit depth, and duration, without decoding any audio
85
+ * samples. Only the canonical RIFF/WAVE container is supported (not the
86
+ * rarer RF64 variant used for files over 4GB).
87
+ */
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;
111
+
112
+ type media_ExifData = ExifData;
113
+ type media_ExifError = ExifError;
114
+ type media_Id3Tags = Id3Tags;
115
+ type media_Id3TagsError = Id3TagsError;
116
+ type media_ImageFormat = ImageFormat;
117
+ type media_ImageInfo = ImageInfo;
118
+ type media_ImageInfoError = ImageInfoError;
119
+ type media_PdfMetadata = PdfMetadata;
120
+ type media_PdfMetadataError = PdfMetadataError;
121
+ type media_WavInfo = WavInfo;
122
+ type media_WavInfoError = WavInfoError;
123
+ declare const media_readExifData: typeof readExifData;
124
+ declare const media_readId3Tags: typeof readId3Tags;
125
+ declare const media_readImageInfo: typeof readImageInfo;
126
+ declare const media_readPdfMetadata: typeof readPdfMetadata;
127
+ declare const media_readWavInfo: typeof readWavInfo;
128
+ declare namespace media {
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 };
130
+ }
131
+
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 };