@utilix-tech/sdk 0.46.0 → 0.48.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,14 @@
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.48.0
6
+ - Add `resolveYamlAnchors` (yaml-anchor-resolver): expand YAML anchors, aliases, and merge keys inline, and list which anchors were referenced vs. left unused.
7
+ - Add `splitSitemap` (sitemap-index-splitter): split a URL list exceeding the sitemaps.org 50,000-URL cap into multiple sitemap.xml files plus a sitemap index file.
8
+
9
+ ## 0.47.0
10
+ - Add `buildContentDisposition`, `parseContentDisposition` (content-disposition-builder): build a `Content-Disposition` response header from a disposition type and filename, with an RFC 5987 `filename*` extended parameter for non-ASCII filenames, or parse an existing header into its type, filename, and raw parameters.
11
+ - Add `inspectGifFrames` (gif-frame-inspector): walk a GIF87a/89a file's block structure to report frame count, total animation duration, and loop count, without decoding any LZW-compressed pixel data.
12
+
5
13
  ## 0.46.0
6
14
  - Add `calculateDepreciationSchedule` (depreciation-schedule-calculator): build a year-by-year fixed-asset depreciation schedule from cost, salvage value, and useful life, using straight-line, double-declining-balance, or sum-of-years-digits.
7
15
  - Add `analyzeKeywordDensity` (keyword-density-analyzer): count keyword/phrase frequency and density (occurrences per 100 words) across a block of text, with single-word or 2/3-word phrase modes.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @utilix-tech/sdk
2
2
 
3
- **632 developer utility functions for Node.js: runs locally, no API key required.**
3
+ **634 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)
@@ -201,7 +201,7 @@ analyzeKeywordDensity("machine learning models power machine learning systems");
201
201
  ### `/data`: CSV / YAML / TOML / XML / INI / NDJSON / .env diff / subtitles / Markdown front matter & TOC
202
202
 
203
203
  ```ts
204
- import { parseCsv, csvToJson, validateYaml, tomlToJson, jsonToToml,
204
+ import { parseCsv, csvToJson, validateYaml, resolveYamlAnchors, tomlToJson, jsonToToml,
205
205
  formatXml, xmlToJson, jsonToXml, parseIni,
206
206
  validateNdjson, formatNdjson, ndjsonToJsonArray, diffEnvExample,
207
207
  parseSubtitles, convertSubtitles, shiftSubtitles, parseFrontMatter,
@@ -213,6 +213,8 @@ csvToJson("name,age\nalice,30"); // [{ name: "alice", age: "30" }]
213
213
 
214
214
  // YAML
215
215
  validateYaml("key: value\nlist:\n - a\n - b");
216
+ resolveYamlAnchors("defaults: &defaults\n timeout: 30\nprod:\n <<: *defaults\n timeout: 60\n");
217
+ // { resolvedYaml: "defaults:\n timeout: 30\nprod:\n timeout: 60\n", anchors: [...], unusedAnchors: [], aliasCount: 1 }
216
218
 
217
219
  // TOML
218
220
  tomlToJson('[server]\nhost = "localhost"\nport = 8080');
@@ -447,10 +449,11 @@ calculateDepreciationSchedule(10000, 1000, 5, "straight-line");
447
449
  ```ts
448
450
  import { getStatusCode, isValidIp, isValidIpv4, isValidIpv6,
449
451
  searchStatusCodes, buildGeoUrl, countryCodeToFlag,
450
- parseHar, validateSitemap, validateRobotsTxt,
452
+ parseHar, validateSitemap, splitSitemap, validateRobotsTxt,
451
453
  parseUserAgent, buildCacheControl, buildReferrerPolicy, parseIpv6Address, buildLinkHeader, checkSetCookieHeader, analyzeEmailHeaders,
452
454
  buildRangeHeader, parseContentRangeHeader, buildVaryHeader, parseVaryHeader, validateManifest,
453
- buildPermissionsPolicy, parsePermissionsPolicy, buildClientHints, parseClientHintHeaders } from "@utilix-tech/sdk/network";
455
+ buildPermissionsPolicy, parsePermissionsPolicy, buildClientHints, parseClientHintHeaders,
456
+ buildContentDisposition, parseContentDisposition } from "@utilix-tech/sdk/network";
454
457
 
455
458
  getStatusCode(404);
456
459
  // { code: 404, text: "Not Found", description: "...", category: "Client Error" }
@@ -477,6 +480,10 @@ parseHar(har);
477
480
  validateSitemap('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>https://example.com/</loc></url></urlset>');
478
481
  // { type: "urlset", urlCount: 1, entries: [...], issues: [...], valid: true }
479
482
 
483
+ // Split a URL list exceeding the 50,000-URL sitemap cap into multiple sitemap.xml files + a sitemap index
484
+ splitSitemap("https://example.com/a\nhttps://example.com/b\nhttps://example.com/c", { baseUrl: "https://example.com", urlsPerFile: 2 });
485
+ // { files: [{ filename: "sitemap-1.xml", urlCount: 2, xml: "..." }, { filename: "sitemap-2.xml", urlCount: 1, xml: "..." }], indexXml: "...", totalUrls: 3 }
486
+
480
487
  // Validate a robots.txt file: User-agent groups, rules, and syntax mistakes
481
488
  validateRobotsTxt("User-agent: *\nDisallow: /admin\nSitemap: https://example.com/sitemap.xml");
482
489
  // { groups: [...], sitemaps: [...], issues: [...], valid: true }
@@ -541,6 +548,16 @@ buildClientHints(["Sec-CH-UA-Platform", "Sec-CH-DPR"]);
541
548
  // Decode raw Client Hints request-header text into structured values
542
549
  parseClientHintHeaders("Sec-CH-UA-Mobile: ?0");
543
550
  // { hints: [{ name: "Sec-CH-UA-Mobile", value: false, ... }], unrecognized: [] }
551
+
552
+ // Build a Content-Disposition header for a file download or inline display;
553
+ // non-ASCII filenames get an RFC 5987 filename* parameter alongside an
554
+ // ASCII-sanitized fallback
555
+ buildContentDisposition({ type: "attachment", filename: "résumé.pdf" });
556
+ // { header: 'attachment; filename="r_sum_.pdf"; filename*=UTF-8\'\'r%C3%A9sum%C3%A9.pdf', type: "attachment", filename: "résumé.pdf", filenameEncoded: true }
557
+
558
+ // Parse an existing Content-Disposition header, decoding filename* in preference to filename
559
+ parseContentDisposition('attachment; filename="report.pdf"');
560
+ // { type: "attachment", filename: "report.pdf", filenameIsExtended: false, params: { filename: "report.pdf" } }
544
561
  ```
545
562
 
546
563
  ---
@@ -700,10 +717,10 @@ analyzeString("café"); // { length: 4, codePoints: [...], ... }
700
717
 
701
718
  ---
702
719
 
703
- ### `/media`: Image Header Parsing, EXIF, PDF Metadata & Page Dimensions, WAV, ID3, ICO, FLAC & Video Metadata
720
+ ### `/media`: Image Header Parsing, EXIF, PDF Metadata & Page Dimensions, WAV, ID3, ICO, FLAC, Video & GIF Metadata
704
721
 
705
722
  ```ts
706
- import { readImageInfo, readExifData, readPdfMetadata, readPdfPageDimensions, readWavInfo, readId3Tags, readIcoInfo, readFlacInfo, readVideoInfo } from "@utilix-tech/sdk/media";
723
+ import { readImageInfo, readExifData, readPdfMetadata, readPdfPageDimensions, readWavInfo, readId3Tags, readIcoInfo, readFlacInfo, readVideoInfo, inspectGifFrames } from "@utilix-tech/sdk/media";
707
724
 
708
725
  // Reads format, dimensions, bit depth, and alpha channel straight from
709
726
  // file bytes: no decoding, no canvas, no image library.
@@ -761,9 +778,17 @@ readFlacInfo(new Uint8Array(flacBytes));
761
778
  const videoBytes = await fs.promises.readFile("clip.mp4");
762
779
  readVideoInfo(new Uint8Array(videoBytes));
763
780
  // { format: "mp4", durationSeconds: 12.5, width: 1920, height: 1080, videoCodec: "avc1", audioCodec: "mp4a", ... }
781
+
782
+ // Walks a GIF87a/89a file's block structure (image descriptors, graphic
783
+ // control extensions, the NETSCAPE2.0 application extension) to report
784
+ // frame count, total animation duration, and loop count, without decoding
785
+ // any LZW-compressed pixel data.
786
+ const gifBytes = await fs.promises.readFile("animation.gif");
787
+ inspectGifFrames(new Uint8Array(gifBytes));
788
+ // { version: "89a", width: 480, height: 270, frameCount: 24, animated: true, loopCount: 0, totalDurationMs: 2400, ... }
764
789
  ```
765
790
 
766
- `readImageInfo` supports PNG, JPEG, GIF, WebP, and BMP. `readExifData` supports JPEG only. `readWavInfo` supports the canonical RIFF/WAVE container only. `readId3Tags` decodes ID3v2.3/2.4 and ID3v1/1.1 only (ID3v2.2 is detected but not decoded). `readIcoInfo` reads .ico icon files only and rejects .cur cursor files. `readFlacInfo` reads the native FLAC container only, not FLAC-in-Ogg. `readVideoInfo` supports MP4 (ISO BMFF) and WebM (EBML/Matroska) containers only.
791
+ `readImageInfo` supports PNG, JPEG, GIF, WebP, and BMP. `readExifData` supports JPEG only. `readWavInfo` supports the canonical RIFF/WAVE container only. `readId3Tags` decodes ID3v2.3/2.4 and ID3v1/1.1 only (ID3v2.2 is detected but not decoded). `readIcoInfo` reads .ico icon files only and rejects .cur cursor files. `readFlacInfo` reads the native FLAC container only, not FLAC-in-Ogg. `readVideoInfo` supports MP4 (ISO BMFF) and WebM (EBML/Matroska) containers only. `inspectGifFrames` reads the GIF87a/89a block structure only; it never decodes pixel data.
767
792
 
768
793
  ---
769
794
 
@@ -775,18 +800,18 @@ readVideoInfo(new Uint8Array(videoBytes));
775
800
  | `@utilix-tech/sdk/encoding` | Base64, URL, HTML entities, Base32/Base58/Base62 encode/decode |
776
801
  | `@utilix-tech/sdk/hashing` | MD5, SHA-1/256/512, bcrypt, HMAC, .htpasswd, SRI hashes, content-hash ETag generation |
777
802
  | `@utilix-tech/sdk/text` | Case convert, slugify, word count, lorem ipsum, line ops, HTML→Markdown, Levenshtein/Damerau string distance, readability scoring, sentence length distribution, emoji lookup |
778
- | `@utilix-tech/sdk/data` | CSV, YAML, TOML, XML, INI, NDJSON parse and convert, SRT/WebVTT subtitles, Markdown front matter parser |
803
+ | `@utilix-tech/sdk/data` | CSV, YAML, TOML, XML, INI, NDJSON parse and convert, SRT/WebVTT subtitles, Markdown front matter parser, YAML anchor/alias resolver |
779
804
  | `@utilix-tech/sdk/generators` | UUID v4/v7, ULID, passwords, strength check, entropy estimator, fake data |
780
805
  | `@utilix-tech/sdk/time` | Date diff, timezone convert, cron parse, relative time |
781
806
  | `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN validation, loan calculator, EMI calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator, break-even point calculator, Rule of 72 calculator, savings goal calculator, ROI calculator, cash denomination/till calculator, payback period calculator, CD maturity calculator |
782
- | `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing, IPv6 address compress/expand, Permissions-Policy header builder, Client Hints header builder/parser |
807
+ | `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing, IPv6 address compress/expand, Permissions-Policy header builder, Client Hints header builder/parser, Content-Disposition header builder/parser, sitemap.xml validator, sitemap index splitter |
783
808
  | `@utilix-tech/sdk/api` | cURL build/parse, JWT decode/sign, JWKS parse, CORS headers, CSP header |
784
809
  | `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup, GitHub URL parsing, regex ReDoS detector, Conventional Commits linter |
785
810
  | `@utilix-tech/sdk/color` | Hex/RGB/HSL/HSV/CMYK convert, palette generation, contrast check |
786
811
  | `@utilix-tech/sdk/css` | CSS gradient, box-shadow, border-radius, keyframe animation generators |
787
812
  | `@utilix-tech/sdk/misc` | SVG optimize/sanitize, file size format, Unicode inspector |
788
813
  | `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect, vector similarity, few-shot prompt formatter, tool-definition schema linter |
789
- | `@utilix-tech/sdk/media` | Image format & dimension reading from raw bytes (PNG, JPEG, GIF, WebP, BMP); PDF metadata reading; PDF page dimension/orientation listing; WAV audio info; ID3 tags; ICO favicon inspection; FLAC metadata reading; MP4/WebM video info |
814
+ | `@utilix-tech/sdk/media` | Image format & dimension reading from raw bytes (PNG, JPEG, GIF, WebP, BMP); PDF metadata reading; PDF page dimension/orientation listing; WAV audio info; ID3 tags; ICO favicon inspection; FLAC metadata reading; MP4/WebM video info; GIF frame/loop inspection |
790
815
 
791
816
  ---
792
817
 
@@ -3,6 +3,7 @@ import { __export } from './chunk-MLKGABMK.js';
3
3
  // src/tools/media.ts
4
4
  var media_exports = {};
5
5
  __export(media_exports, {
6
+ inspectGifFrames: () => inspectGifFrames,
6
7
  readExifData: () => readExifData,
7
8
  readFlacInfo: () => readFlacInfo,
8
9
  readIcoInfo: () => readIcoInfo,
@@ -1220,5 +1221,90 @@ function parseWebm(bytes) {
1220
1221
  }
1221
1222
  return result;
1222
1223
  }
1224
+ function skipGifSubBlocks(bytes, offset) {
1225
+ while (offset < bytes.length) {
1226
+ const len = bytes[offset];
1227
+ offset += 1;
1228
+ if (len === 0) break;
1229
+ offset += len;
1230
+ }
1231
+ return offset;
1232
+ }
1233
+ function inspectGifFrames(bytes) {
1234
+ if (bytes.length < 13) return { error: "File too small to be a valid GIF file" };
1235
+ const signature = Buffer.from(bytes.subarray(0, 6)).toString("ascii");
1236
+ if (signature !== "GIF87a" && signature !== "GIF89a") return { error: "Not a valid GIF file (missing GIF87a/GIF89a signature)" };
1237
+ const version = signature.slice(3);
1238
+ const width = readU16LE(bytes, 6);
1239
+ const height = readU16LE(bytes, 8);
1240
+ const packed = bytes[10];
1241
+ const hasGlobalColorTable = (packed & 128) !== 0;
1242
+ const globalColorTableSize = hasGlobalColorTable ? 2 << (packed & 7) : 0;
1243
+ let offset = 13;
1244
+ if (hasGlobalColorTable) offset += globalColorTableSize * 3;
1245
+ let frameCount = 0;
1246
+ let loopCount = null;
1247
+ let totalDurationMs = 0;
1248
+ let hasTransparency = false;
1249
+ let pendingDelay = 0;
1250
+ while (offset < bytes.length) {
1251
+ const blockType = bytes[offset];
1252
+ if (blockType === 59) break;
1253
+ if (blockType === 33) {
1254
+ const label = bytes[offset + 1];
1255
+ offset += 2;
1256
+ if (label === 249) {
1257
+ const subLen = bytes[offset] ?? 0;
1258
+ if (subLen >= 4) {
1259
+ const flags = bytes[offset + 1];
1260
+ pendingDelay = readU16LE(bytes, offset + 2);
1261
+ if (flags & 1) hasTransparency = true;
1262
+ }
1263
+ offset += 1 + subLen;
1264
+ offset = skipGifSubBlocks(bytes, offset);
1265
+ } else if (label === 255) {
1266
+ const blockSize = bytes[offset] ?? 0;
1267
+ const appId = Buffer.from(bytes.subarray(offset + 1, offset + 1 + Math.min(blockSize, 11))).toString("ascii");
1268
+ offset += 1 + blockSize;
1269
+ if (appId === "NETSCAPE2.0") {
1270
+ const subLen = bytes[offset] ?? 0;
1271
+ if (subLen >= 3 && bytes[offset + 1] === 1) {
1272
+ loopCount = readU16LE(bytes, offset + 2);
1273
+ }
1274
+ }
1275
+ offset = skipGifSubBlocks(bytes, offset);
1276
+ } else {
1277
+ offset = skipGifSubBlocks(bytes, offset);
1278
+ }
1279
+ } else if (blockType === 44) {
1280
+ if (offset + 10 > bytes.length) return { error: "Truncated image descriptor" };
1281
+ frameCount++;
1282
+ totalDurationMs += pendingDelay * 10;
1283
+ pendingDelay = 0;
1284
+ const packedImg = bytes[offset + 9];
1285
+ const hasLocalColorTable = (packedImg & 128) !== 0;
1286
+ const localColorTableSize = hasLocalColorTable ? 2 << (packedImg & 7) : 0;
1287
+ offset += 10;
1288
+ if (hasLocalColorTable) offset += localColorTableSize * 3;
1289
+ offset += 1;
1290
+ offset = skipGifSubBlocks(bytes, offset);
1291
+ } else {
1292
+ break;
1293
+ }
1294
+ }
1295
+ if (frameCount === 0) return { error: "No image data blocks found in this GIF file" };
1296
+ return {
1297
+ version,
1298
+ width,
1299
+ height,
1300
+ frameCount,
1301
+ animated: frameCount > 1,
1302
+ loopCount,
1303
+ totalDurationMs,
1304
+ hasGlobalColorTable,
1305
+ globalColorTableSize,
1306
+ hasTransparency
1307
+ };
1308
+ }
1223
1309
 
1224
- export { media_exports, readExifData, readFlacInfo, readIcoInfo, readId3Tags, readImageInfo, readPdfMetadata, readPdfPageDimensions, readVideoInfo, readWavInfo };
1310
+ export { inspectGifFrames, media_exports, readExifData, readFlacInfo, readIcoInfo, readId3Tags, readImageInfo, readPdfMetadata, readPdfPageDimensions, readVideoInfo, readWavInfo };
@@ -40,6 +40,7 @@ __export(data_exports, {
40
40
  parseSubtitleTimestamp: () => parseSubtitleTimestamp,
41
41
  parseSubtitles: () => parseSubtitles,
42
42
  parseXmlToObject: () => parseXmlToObject,
43
+ resolveYamlAnchors: () => resolveYamlAnchors,
43
44
  serializeSubtitles: () => serializeSubtitles,
44
45
  shiftSubtitles: () => shiftSubtitles,
45
46
  stringifyIni: () => stringifyIni,
@@ -1560,5 +1561,67 @@ function findCsvDuplicateRows(input, options) {
1560
1561
  uniqueRowCount: parsed.rows.length - duplicateRowCount + duplicateGroups.length
1561
1562
  };
1562
1563
  }
1564
+ var _YAML_ANCHOR_RE = /(?:^|\s)&([A-Za-z0-9_.-]+)/g;
1565
+ var _YAML_ALIAS_RE = /(?:^|\s)\*([A-Za-z0-9_.-]+)/g;
1566
+ function _stripYamlLineComment(line) {
1567
+ let inSingle = false;
1568
+ let inDouble = false;
1569
+ for (let i = 0; i < line.length; i++) {
1570
+ const ch = line[i];
1571
+ if (ch === "'" && !inDouble) {
1572
+ inSingle = !inSingle;
1573
+ } else if (ch === '"' && !inSingle) {
1574
+ inDouble = !inDouble;
1575
+ } else if (ch === "#" && !inSingle && !inDouble && (i === 0 || /\s/.test(line[i - 1]))) {
1576
+ return line.slice(0, i);
1577
+ }
1578
+ }
1579
+ return line;
1580
+ }
1581
+ function resolveYamlAnchors(yamlText) {
1582
+ if (!yamlText || !yamlText.trim()) return { error: "Input is empty" };
1583
+ const anchorDefs = [];
1584
+ const referencedNames = /* @__PURE__ */ new Set();
1585
+ let aliasCount = 0;
1586
+ const lines = yamlText.split("\n");
1587
+ for (let i = 0; i < lines.length; i++) {
1588
+ const line = _stripYamlLineComment(lines[i]);
1589
+ const lineNum = i + 1;
1590
+ _YAML_ANCHOR_RE.lastIndex = 0;
1591
+ let m;
1592
+ while ((m = _YAML_ANCHOR_RE.exec(line)) !== null) {
1593
+ anchorDefs.push({ name: m[1], line: lineNum });
1594
+ }
1595
+ _YAML_ALIAS_RE.lastIndex = 0;
1596
+ while ((m = _YAML_ALIAS_RE.exec(line)) !== null) {
1597
+ referencedNames.add(m[1]);
1598
+ aliasCount++;
1599
+ }
1600
+ }
1601
+ let parsed;
1602
+ try {
1603
+ parsed = yaml.load(yamlText);
1604
+ } catch (e) {
1605
+ const err = e;
1606
+ return { error: err.reason ?? err.message };
1607
+ }
1608
+ let resolvedYaml;
1609
+ try {
1610
+ resolvedYaml = yaml.dump(parsed, { noRefs: true, lineWidth: -1 });
1611
+ } catch (e) {
1612
+ return { error: e instanceof Error ? e.message : String(e) };
1613
+ }
1614
+ const anchors = anchorDefs.map((a) => ({
1615
+ name: a.name,
1616
+ line: a.line,
1617
+ referenced: referencedNames.has(a.name)
1618
+ }));
1619
+ const seenAnchorNames = [];
1620
+ for (const a of anchorDefs) {
1621
+ if (!seenAnchorNames.includes(a.name)) seenAnchorNames.push(a.name);
1622
+ }
1623
+ const unusedAnchors = seenAnchorNames.filter((name) => !referencedNames.has(name));
1624
+ return { resolvedYaml, anchors, unusedAnchors, aliasCount };
1625
+ }
1563
1626
 
1564
- export { convertSubtitles, csvToJson, csvToSqlInsert, data_exports, detectDelimiter, detectSubtitleFormat, diffEnvExample, envToExport, envToJson, findCsvDuplicateRows, formatNdjson, formatSubtitleTimestamp, formatToml, formatXml, generateMarkdownToc, getSection, getSectionNames, getTomlStats, getXmlStats, getYamlStats, iniToJson, jsonArrayToNdjson, jsonToIni, jsonToToml, jsonToXml, minifyNdjson, minifyToml, minifyXml, ndjsonToJsonArray, parseCsv, parseEnv, parseFrontMatter, parseIni, parseSubtitleTimestamp, parseSubtitles, parseXmlToObject, serializeSubtitles, shiftSubtitles, stringifyIni, toCsvString, tomlToJson, validateEnvKey, validateIni, validateNdjson, validateToml, validateXml, validateYaml, xmlToJson };
1627
+ export { convertSubtitles, csvToJson, csvToSqlInsert, data_exports, detectDelimiter, detectSubtitleFormat, diffEnvExample, envToExport, envToJson, findCsvDuplicateRows, formatNdjson, formatSubtitleTimestamp, formatToml, formatXml, generateMarkdownToc, getSection, getSectionNames, getTomlStats, getXmlStats, getYamlStats, iniToJson, jsonArrayToNdjson, jsonToIni, jsonToToml, jsonToXml, minifyNdjson, minifyToml, minifyXml, ndjsonToJsonArray, parseCsv, parseEnv, parseFrontMatter, parseIni, parseSubtitleTimestamp, parseSubtitles, parseXmlToObject, resolveYamlAnchors, serializeSubtitles, shiftSubtitles, stringifyIni, toCsvString, tomlToJson, validateEnvKey, validateIni, validateNdjson, validateToml, validateXml, validateYaml, xmlToJson };
@@ -13,6 +13,7 @@ __export(network_exports, {
13
13
  analyzeEmailHeaders: () => analyzeEmailHeaders,
14
14
  buildCacheControl: () => buildCacheControl,
15
15
  buildClientHints: () => buildClientHints,
16
+ buildContentDisposition: () => buildContentDisposition,
16
17
  buildDnsQueryUrl: () => buildDnsQueryUrl,
17
18
  buildGeoUrl: () => buildGeoUrl,
18
19
  buildLinkHeader: () => buildLinkHeader,
@@ -37,6 +38,7 @@ __export(network_exports, {
37
38
  isValidIpv4: () => isValidIpv4,
38
39
  isValidIpv6: () => isValidIpv6,
39
40
  parseClientHintHeaders: () => parseClientHintHeaders,
41
+ parseContentDisposition: () => parseContentDisposition,
40
42
  parseContentRangeHeader: () => parseContentRangeHeader,
41
43
  parseDnsResponse: () => parseDnsResponse,
42
44
  parseGeoResponse: () => parseGeoResponse,
@@ -47,6 +49,7 @@ __export(network_exports, {
47
49
  parseVaryHeader: () => parseVaryHeader,
48
50
  searchHeaders: () => searchHeaders,
49
51
  searchStatusCodes: () => searchStatusCodes,
52
+ splitSitemap: () => splitSitemap,
50
53
  statusCodeToText: () => statusCodeToText,
51
54
  typeNumberToLabel: () => typeNumberToLabel,
52
55
  validateDomain: () => validateDomain,
@@ -1552,6 +1555,53 @@ function validateSitemap(xml) {
1552
1555
  const valid = !issues.some((i) => i.severity === "error");
1553
1556
  return { type, urlCount: entries.length, entries, issues, valid };
1554
1557
  }
1558
+ var SITEMAP_SPLITTER_MAX_URLS_PER_FILE = 5e4;
1559
+ function escapeXmlUrl(url) {
1560
+ return url.replace(/&(?!amp;|lt;|gt;|apos;|quot;|#\d+;)/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1561
+ }
1562
+ function splitSitemap(urlsText, options) {
1563
+ const urls = (urlsText ?? "").split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
1564
+ if (urls.length === 0) return { error: "No URLs provided" };
1565
+ for (let i = 0; i < urls.length; i++) {
1566
+ if (!/^https?:\/\//i.test(urls[i])) {
1567
+ return { error: `Line ${i + 1}: "${urls[i]}" is not an absolute URL starting with http:// or https://` };
1568
+ }
1569
+ }
1570
+ if (!options || !/^https?:\/\//i.test(options.baseUrl ?? "")) {
1571
+ return { error: "baseUrl must be an absolute URL starting with http:// or https://" };
1572
+ }
1573
+ const baseUrl = options.baseUrl.replace(/\/+$/, "") + "/";
1574
+ let urlsPerFile = options.urlsPerFile ?? SITEMAP_SPLITTER_MAX_URLS_PER_FILE;
1575
+ if (urlsPerFile <= 0) urlsPerFile = SITEMAP_SPLITTER_MAX_URLS_PER_FILE;
1576
+ if (urlsPerFile > SITEMAP_SPLITTER_MAX_URLS_PER_FILE) urlsPerFile = SITEMAP_SPLITTER_MAX_URLS_PER_FILE;
1577
+ const filePrefix = (options.filePrefix || "sitemap").replace(/[^A-Za-z0-9_-]/g, "");
1578
+ const files = [];
1579
+ for (let i = 0; i < urls.length; i += urlsPerFile) {
1580
+ const chunk = urls.slice(i, i + urlsPerFile);
1581
+ const fileIndex = files.length + 1;
1582
+ const filename = `${filePrefix}-${fileIndex}.xml`;
1583
+ const urlLines = chunk.map((url) => ` <url>
1584
+ <loc>${escapeXmlUrl(url)}</loc>
1585
+ </url>`).join("\n");
1586
+ const xml = `<?xml version="1.0" encoding="UTF-8"?>
1587
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
1588
+ ${urlLines}
1589
+ </urlset>
1590
+ `;
1591
+ files.push({ filename, urlCount: chunk.length, xml });
1592
+ }
1593
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1594
+ const indexEntries = files.map((f) => ` <sitemap>
1595
+ <loc>${escapeXmlUrl(baseUrl + f.filename)}</loc>
1596
+ <lastmod>${today}</lastmod>
1597
+ </sitemap>`).join("\n");
1598
+ const indexXml = `<?xml version="1.0" encoding="UTF-8"?>
1599
+ <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
1600
+ ${indexEntries}
1601
+ </sitemapindex>
1602
+ `;
1603
+ return { files, indexXml, totalUrls: urls.length };
1604
+ }
1555
1605
  var KNOWN_ROBOTS_DIRECTIVES = /* @__PURE__ */ new Set(["user-agent", "disallow", "allow", "sitemap", "crawl-delay", "host"]);
1556
1606
  function validateRobotsTxt(text) {
1557
1607
  if (!text || !text.trim()) return { error: "Input is empty" };
@@ -2678,5 +2728,52 @@ function parseClientHintHeaders(rawHeaders) {
2678
2728
  }
2679
2729
  return { hints, unrecognized };
2680
2730
  }
2731
+ function encodeRFC5987ValueChars(value) {
2732
+ return encodeURIComponent(value).replace(/[!'()*]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());
2733
+ }
2734
+ function buildContentDisposition(options = {}) {
2735
+ const type = options.type ?? "attachment";
2736
+ if (type !== "inline" && type !== "attachment") return { error: 'type must be "inline" or "attachment"' };
2737
+ if (!options.filename) return { header: type, type, filenameEncoded: false };
2738
+ const filename = options.filename;
2739
+ if (filename.includes("/") || filename.includes("\\")) return { error: "filename must not contain path separators" };
2740
+ const isAscii = /^[\x20-\x7e]*$/.test(filename);
2741
+ const asciiFallback = filename.replace(/[^\x20-\x7e]/g, "_").replace(/(["\\])/g, "\\$1");
2742
+ let header = `${type}; filename="${asciiFallback}"`;
2743
+ let filenameEncoded = false;
2744
+ if (!isAscii) {
2745
+ header += `; filename*=UTF-8''${encodeRFC5987ValueChars(filename)}`;
2746
+ filenameEncoded = true;
2747
+ }
2748
+ return { header, type, filename, filenameEncoded };
2749
+ }
2750
+ function parseContentDisposition(header) {
2751
+ if (typeof header !== "string" || header.trim() === "") return { error: "header is required" };
2752
+ const parts = header.split(";").map((p) => p.trim()).filter(Boolean);
2753
+ const type = parts[0]?.toLowerCase();
2754
+ if (!type) return { error: "Could not parse a disposition type from the header" };
2755
+ const params = {};
2756
+ for (let i = 1; i < parts.length; i++) {
2757
+ const eq = parts[i].indexOf("=");
2758
+ if (eq === -1) continue;
2759
+ const key = parts[i].slice(0, eq).trim().toLowerCase();
2760
+ let value = parts[i].slice(eq + 1).trim();
2761
+ if (value.startsWith('"') && value.endsWith('"')) value = value.slice(1, -1).replace(/\\(.)/g, "$1");
2762
+ params[key] = value;
2763
+ }
2764
+ let filename = params.filename;
2765
+ let filenameIsExtended = false;
2766
+ if (params["filename*"]) {
2767
+ const match = params["filename*"].match(/^([^']*)'([^']*)'(.*)$/);
2768
+ if (match) {
2769
+ try {
2770
+ filename = decodeURIComponent(match[3]);
2771
+ filenameIsExtended = true;
2772
+ } catch {
2773
+ }
2774
+ }
2775
+ }
2776
+ return { type, filename, filenameIsExtended, params };
2777
+ }
2681
2778
 
2682
- export { CLIENT_HINTS, DNS_RECORD_TYPES, HTTP_HEADERS, LINK_REL_VALUES, PERMISSIONS_POLICY_FEATURES, REFERRER_POLICY_VALUES, STATUS_CODES, analyzeEmailHeaders, buildCacheControl, buildClientHints, buildDnsQueryUrl, buildGeoUrl, buildLinkHeader, buildMapUrl, buildPermissionsPolicy, buildRangeHeader, buildReferrerPolicy, buildVaryHeader, checkSetCookieHeader, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseClientHintHeaders, parseContentRangeHeader, parseDnsResponse, parseGeoResponse, parseHar, parseIpv6Address, parsePermissionsPolicy, parseUserAgent, parseVaryHeader, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateManifest, validateRobotsTxt, validateSitemap };
2779
+ export { CLIENT_HINTS, DNS_RECORD_TYPES, HTTP_HEADERS, LINK_REL_VALUES, PERMISSIONS_POLICY_FEATURES, REFERRER_POLICY_VALUES, STATUS_CODES, analyzeEmailHeaders, buildCacheControl, buildClientHints, buildContentDisposition, buildDnsQueryUrl, buildGeoUrl, buildLinkHeader, buildMapUrl, buildPermissionsPolicy, buildRangeHeader, buildReferrerPolicy, buildVaryHeader, checkSetCookieHeader, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseClientHintHeaders, parseContentDisposition, parseContentRangeHeader, parseDnsResponse, parseGeoResponse, parseHar, parseIpv6Address, parsePermissionsPolicy, parseUserAgent, parseVaryHeader, searchHeaders, searchStatusCodes, splitSitemap, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateManifest, validateRobotsTxt, validateSitemap };
@@ -17,6 +17,7 @@
17
17
  * - markdown-toc-generator: generateMarkdownToc
18
18
  * - csv-to-sql-insert-generator: csvToSqlInsert
19
19
  * - csv-duplicate-row-finder: findCsvDuplicateRows
20
+ * - yaml-anchor-resolver: resolveYamlAnchors
20
21
  */
21
22
  interface ValidationResult {
22
23
  valid: boolean;
@@ -372,6 +373,29 @@ interface CsvDuplicateResult {
372
373
  declare function findCsvDuplicateRows(input: string, options?: CsvDuplicateOptions): CsvDuplicateResult | {
373
374
  error: string;
374
375
  };
376
+ interface YamlAnchorInfo {
377
+ name: string;
378
+ line: number;
379
+ referenced: boolean;
380
+ }
381
+ interface YamlAnchorResolveResult {
382
+ resolvedYaml: string;
383
+ anchors: YamlAnchorInfo[];
384
+ unusedAnchors: string[];
385
+ aliasCount: number;
386
+ }
387
+ interface YamlAnchorResolveError {
388
+ error: string;
389
+ }
390
+ /**
391
+ * Expand every YAML anchor, alias, and merge key in the input inline, and
392
+ * report which anchors were referenced vs. left unused. Unlike
393
+ * `validateYaml`, which only checks syntax, this fully resolves the
394
+ * document via js-yaml (which already implements anchor/alias/merge-key
395
+ * resolution per the YAML spec) and re-serializes it with no `&`/`*`
396
+ * syntax remaining.
397
+ */
398
+ declare function resolveYamlAnchors(yamlText: string): YamlAnchorResolveResult | YamlAnchorResolveError;
375
399
 
376
400
  type data_ConvertedSubtitles = ConvertedSubtitles;
377
401
  type data_CsvDuplicateGroup = CsvDuplicateGroup;
@@ -401,6 +425,9 @@ type data_TomlFormatResult = TomlFormatResult;
401
425
  type data_ValidationResult = ValidationResult;
402
426
  type data_XmlFormatResult = XmlFormatResult;
403
427
  type data_XmlToJsonOptions = XmlToJsonOptions;
428
+ type data_YamlAnchorInfo = YamlAnchorInfo;
429
+ type data_YamlAnchorResolveError = YamlAnchorResolveError;
430
+ type data_YamlAnchorResolveResult = YamlAnchorResolveResult;
404
431
  declare const data_convertSubtitles: typeof convertSubtitles;
405
432
  declare const data_csvToJson: typeof csvToJson;
406
433
  declare const data_csvToSqlInsert: typeof csvToSqlInsert;
@@ -436,6 +463,7 @@ declare const data_parseIni: typeof parseIni;
436
463
  declare const data_parseSubtitleTimestamp: typeof parseSubtitleTimestamp;
437
464
  declare const data_parseSubtitles: typeof parseSubtitles;
438
465
  declare const data_parseXmlToObject: typeof parseXmlToObject;
466
+ declare const data_resolveYamlAnchors: typeof resolveYamlAnchors;
439
467
  declare const data_serializeSubtitles: typeof serializeSubtitles;
440
468
  declare const data_shiftSubtitles: typeof shiftSubtitles;
441
469
  declare const data_stringifyIni: typeof stringifyIni;
@@ -449,7 +477,7 @@ declare const data_validateXml: typeof validateXml;
449
477
  declare const data_validateYaml: typeof validateYaml;
450
478
  declare const data_xmlToJson: typeof xmlToJson;
451
479
  declare namespace data {
452
- export { type data_ConvertedSubtitles as ConvertedSubtitles, type data_CsvDuplicateGroup as CsvDuplicateGroup, type data_CsvDuplicateOptions as CsvDuplicateOptions, type data_CsvDuplicateResult as CsvDuplicateResult, type data_CsvParseResult as CsvParseResult, type data_CsvToSqlOptions as CsvToSqlOptions, type data_CsvToSqlResult as CsvToSqlResult, type data_EnvDiffError as EnvDiffError, type data_EnvDiffResult as EnvDiffResult, type data_EnvEntry as EnvEntry, type data_EnvParseResult as EnvParseResult, type data_FrontMatterError as FrontMatterError, type data_FrontMatterResult as FrontMatterResult, type data_IniSection as IniSection, type data_MarkdownTocEntry as MarkdownTocEntry, type data_MarkdownTocOptions as MarkdownTocOptions, type data_MarkdownTocResult as MarkdownTocResult, type data_NdjsonLineResult as NdjsonLineResult, type data_NdjsonValidateResult as NdjsonValidateResult, type data_ParseOptions as ParseOptions, type data_ParsedIni as ParsedIni, type data_ParsedSubtitles as ParsedSubtitles, type data_SubtitleCue as SubtitleCue, type data_SubtitleFormat as SubtitleFormat, type data_TomlFormatResult as TomlFormatResult, type data_ValidationResult as ValidationResult, type data_XmlFormatResult as XmlFormatResult, type data_XmlToJsonOptions as XmlToJsonOptions, data_convertSubtitles as convertSubtitles, data_csvToJson as csvToJson, data_csvToSqlInsert as csvToSqlInsert, data_detectDelimiter as detectDelimiter, data_detectSubtitleFormat as detectSubtitleFormat, data_diffEnvExample as diffEnvExample, data_envToExport as envToExport, data_envToJson as envToJson, data_findCsvDuplicateRows as findCsvDuplicateRows, data_formatNdjson as formatNdjson, data_formatSubtitleTimestamp as formatSubtitleTimestamp, data_formatToml as formatToml, data_formatXml as formatXml, data_generateMarkdownToc as generateMarkdownToc, data_getSection as getSection, data_getSectionNames as getSectionNames, data_getTomlStats as getTomlStats, data_getXmlStats as getXmlStats, data_getYamlStats as getYamlStats, data_iniToJson as iniToJson, data_jsonArrayToNdjson as jsonArrayToNdjson, data_jsonToIni as jsonToIni, data_jsonToToml as jsonToToml, data_jsonToXml as jsonToXml, data_minifyNdjson as minifyNdjson, data_minifyToml as minifyToml, data_minifyXml as minifyXml, data_ndjsonToJsonArray as ndjsonToJsonArray, data_parseCsv as parseCsv, data_parseEnv as parseEnv, data_parseFrontMatter as parseFrontMatter, data_parseIni as parseIni, data_parseSubtitleTimestamp as parseSubtitleTimestamp, data_parseSubtitles as parseSubtitles, data_parseXmlToObject as parseXmlToObject, data_serializeSubtitles as serializeSubtitles, data_shiftSubtitles as shiftSubtitles, data_stringifyIni as stringifyIni, data_toCsvString as toCsvString, data_tomlToJson as tomlToJson, data_validateEnvKey as validateEnvKey, data_validateIni as validateIni, data_validateNdjson as validateNdjson, data_validateToml as validateToml, data_validateXml as validateXml, data_validateYaml as validateYaml, data_xmlToJson as xmlToJson };
480
+ export { type data_ConvertedSubtitles as ConvertedSubtitles, type data_CsvDuplicateGroup as CsvDuplicateGroup, type data_CsvDuplicateOptions as CsvDuplicateOptions, type data_CsvDuplicateResult as CsvDuplicateResult, type data_CsvParseResult as CsvParseResult, type data_CsvToSqlOptions as CsvToSqlOptions, type data_CsvToSqlResult as CsvToSqlResult, type data_EnvDiffError as EnvDiffError, type data_EnvDiffResult as EnvDiffResult, type data_EnvEntry as EnvEntry, type data_EnvParseResult as EnvParseResult, type data_FrontMatterError as FrontMatterError, type data_FrontMatterResult as FrontMatterResult, type data_IniSection as IniSection, type data_MarkdownTocEntry as MarkdownTocEntry, type data_MarkdownTocOptions as MarkdownTocOptions, type data_MarkdownTocResult as MarkdownTocResult, type data_NdjsonLineResult as NdjsonLineResult, type data_NdjsonValidateResult as NdjsonValidateResult, type data_ParseOptions as ParseOptions, type data_ParsedIni as ParsedIni, type data_ParsedSubtitles as ParsedSubtitles, type data_SubtitleCue as SubtitleCue, type data_SubtitleFormat as SubtitleFormat, type data_TomlFormatResult as TomlFormatResult, type data_ValidationResult as ValidationResult, type data_XmlFormatResult as XmlFormatResult, type data_XmlToJsonOptions as XmlToJsonOptions, type data_YamlAnchorInfo as YamlAnchorInfo, type data_YamlAnchorResolveError as YamlAnchorResolveError, type data_YamlAnchorResolveResult as YamlAnchorResolveResult, data_convertSubtitles as convertSubtitles, data_csvToJson as csvToJson, data_csvToSqlInsert as csvToSqlInsert, data_detectDelimiter as detectDelimiter, data_detectSubtitleFormat as detectSubtitleFormat, data_diffEnvExample as diffEnvExample, data_envToExport as envToExport, data_envToJson as envToJson, data_findCsvDuplicateRows as findCsvDuplicateRows, data_formatNdjson as formatNdjson, data_formatSubtitleTimestamp as formatSubtitleTimestamp, data_formatToml as formatToml, data_formatXml as formatXml, data_generateMarkdownToc as generateMarkdownToc, data_getSection as getSection, data_getSectionNames as getSectionNames, data_getTomlStats as getTomlStats, data_getXmlStats as getXmlStats, data_getYamlStats as getYamlStats, data_iniToJson as iniToJson, data_jsonArrayToNdjson as jsonArrayToNdjson, data_jsonToIni as jsonToIni, data_jsonToToml as jsonToToml, data_jsonToXml as jsonToXml, data_minifyNdjson as minifyNdjson, data_minifyToml as minifyToml, data_minifyXml as minifyXml, data_ndjsonToJsonArray as ndjsonToJsonArray, data_parseCsv as parseCsv, data_parseEnv as parseEnv, data_parseFrontMatter as parseFrontMatter, data_parseIni as parseIni, data_parseSubtitleTimestamp as parseSubtitleTimestamp, data_parseSubtitles as parseSubtitles, data_parseXmlToObject as parseXmlToObject, data_resolveYamlAnchors as resolveYamlAnchors, data_serializeSubtitles as serializeSubtitles, data_shiftSubtitles as shiftSubtitles, data_stringifyIni as stringifyIni, data_toCsvString as toCsvString, data_tomlToJson as tomlToJson, data_validateEnvKey as validateEnvKey, data_validateIni as validateIni, data_validateNdjson as validateNdjson, data_validateToml as validateToml, data_validateXml as validateXml, data_validateYaml as validateYaml, data_xmlToJson as xmlToJson };
453
481
  }
454
482
 
455
- export { minifyNdjson as $, findCsvDuplicateRows as A, formatNdjson as B, type ConvertedSubtitles as C, formatSubtitleTimestamp as D, type EnvDiffError as E, type FrontMatterError as F, formatToml as G, formatXml as H, type IniSection as I, generateMarkdownToc as J, getSection as K, getSectionNames as L, type MarkdownTocEntry as M, type NdjsonLineResult as N, getTomlStats as O, type ParseOptions as P, getXmlStats as Q, getYamlStats as R, type SubtitleCue as S, type TomlFormatResult as T, iniToJson as U, type ValidationResult as V, jsonArrayToNdjson as W, type XmlFormatResult as X, jsonToIni as Y, jsonToToml as Z, jsonToXml as _, type CsvDuplicateGroup as a, minifyToml as a0, minifyXml as a1, ndjsonToJsonArray as a2, parseCsv as a3, parseEnv as a4, parseFrontMatter as a5, parseIni as a6, parseSubtitleTimestamp as a7, parseSubtitles as a8, parseXmlToObject as a9, serializeSubtitles as aa, shiftSubtitles as ab, stringifyIni as ac, toCsvString as ad, tomlToJson as ae, validateEnvKey as af, validateIni as ag, validateNdjson as ah, validateToml as ai, validateXml as aj, validateYaml as ak, xmlToJson as al, type CsvDuplicateOptions as b, type CsvDuplicateResult as c, data as d, type CsvParseResult as e, type CsvToSqlOptions as f, type CsvToSqlResult as g, type EnvDiffResult as h, type EnvEntry as i, type EnvParseResult as j, type FrontMatterResult as k, type MarkdownTocOptions as l, type MarkdownTocResult as m, type NdjsonValidateResult as n, type ParsedIni as o, type ParsedSubtitles as p, type SubtitleFormat as q, type XmlToJsonOptions as r, convertSubtitles as s, csvToJson as t, csvToSqlInsert as u, detectDelimiter as v, detectSubtitleFormat as w, diffEnvExample as x, envToExport as y, envToJson as z };
483
+ export { jsonToIni as $, envToExport as A, envToJson as B, type ConvertedSubtitles as C, findCsvDuplicateRows as D, type EnvDiffError as E, type FrontMatterError as F, formatNdjson as G, formatSubtitleTimestamp as H, type IniSection as I, formatToml as J, formatXml as K, generateMarkdownToc as L, type MarkdownTocEntry as M, type NdjsonLineResult as N, getSection as O, type ParseOptions as P, getSectionNames as Q, getTomlStats as R, type SubtitleCue as S, type TomlFormatResult as T, getXmlStats as U, type ValidationResult as V, getYamlStats as W, type XmlFormatResult as X, type YamlAnchorInfo as Y, iniToJson as Z, jsonArrayToNdjson as _, type CsvDuplicateGroup as a, jsonToToml as a0, jsonToXml as a1, minifyNdjson as a2, minifyToml as a3, minifyXml as a4, ndjsonToJsonArray as a5, parseCsv as a6, parseEnv as a7, parseFrontMatter as a8, parseIni as a9, parseSubtitleTimestamp as aa, parseSubtitles as ab, parseXmlToObject as ac, resolveYamlAnchors as ad, serializeSubtitles as ae, shiftSubtitles as af, stringifyIni as ag, toCsvString as ah, tomlToJson as ai, validateEnvKey as aj, validateIni as ak, validateNdjson as al, validateToml as am, validateXml as an, validateYaml as ao, xmlToJson as ap, type CsvDuplicateOptions as b, type CsvDuplicateResult as c, data as d, type CsvParseResult as e, type CsvToSqlOptions as f, type CsvToSqlResult as g, type EnvDiffResult as h, type EnvEntry as i, type EnvParseResult as j, type FrontMatterResult as k, type MarkdownTocOptions as l, type MarkdownTocResult as m, type NdjsonValidateResult as n, type ParsedIni as o, type ParsedSubtitles as p, type SubtitleFormat as q, type XmlToJsonOptions as r, type YamlAnchorResolveError as s, type YamlAnchorResolveResult as t, convertSubtitles as u, csvToJson as v, csvToSqlInsert as w, detectDelimiter as x, detectSubtitleFormat as y, diffEnvExample as z };
@@ -17,6 +17,7 @@
17
17
  * - markdown-toc-generator: generateMarkdownToc
18
18
  * - csv-to-sql-insert-generator: csvToSqlInsert
19
19
  * - csv-duplicate-row-finder: findCsvDuplicateRows
20
+ * - yaml-anchor-resolver: resolveYamlAnchors
20
21
  */
21
22
  interface ValidationResult {
22
23
  valid: boolean;
@@ -372,6 +373,29 @@ interface CsvDuplicateResult {
372
373
  declare function findCsvDuplicateRows(input: string, options?: CsvDuplicateOptions): CsvDuplicateResult | {
373
374
  error: string;
374
375
  };
376
+ interface YamlAnchorInfo {
377
+ name: string;
378
+ line: number;
379
+ referenced: boolean;
380
+ }
381
+ interface YamlAnchorResolveResult {
382
+ resolvedYaml: string;
383
+ anchors: YamlAnchorInfo[];
384
+ unusedAnchors: string[];
385
+ aliasCount: number;
386
+ }
387
+ interface YamlAnchorResolveError {
388
+ error: string;
389
+ }
390
+ /**
391
+ * Expand every YAML anchor, alias, and merge key in the input inline, and
392
+ * report which anchors were referenced vs. left unused. Unlike
393
+ * `validateYaml`, which only checks syntax, this fully resolves the
394
+ * document via js-yaml (which already implements anchor/alias/merge-key
395
+ * resolution per the YAML spec) and re-serializes it with no `&`/`*`
396
+ * syntax remaining.
397
+ */
398
+ declare function resolveYamlAnchors(yamlText: string): YamlAnchorResolveResult | YamlAnchorResolveError;
375
399
 
376
400
  type data_ConvertedSubtitles = ConvertedSubtitles;
377
401
  type data_CsvDuplicateGroup = CsvDuplicateGroup;
@@ -401,6 +425,9 @@ type data_TomlFormatResult = TomlFormatResult;
401
425
  type data_ValidationResult = ValidationResult;
402
426
  type data_XmlFormatResult = XmlFormatResult;
403
427
  type data_XmlToJsonOptions = XmlToJsonOptions;
428
+ type data_YamlAnchorInfo = YamlAnchorInfo;
429
+ type data_YamlAnchorResolveError = YamlAnchorResolveError;
430
+ type data_YamlAnchorResolveResult = YamlAnchorResolveResult;
404
431
  declare const data_convertSubtitles: typeof convertSubtitles;
405
432
  declare const data_csvToJson: typeof csvToJson;
406
433
  declare const data_csvToSqlInsert: typeof csvToSqlInsert;
@@ -436,6 +463,7 @@ declare const data_parseIni: typeof parseIni;
436
463
  declare const data_parseSubtitleTimestamp: typeof parseSubtitleTimestamp;
437
464
  declare const data_parseSubtitles: typeof parseSubtitles;
438
465
  declare const data_parseXmlToObject: typeof parseXmlToObject;
466
+ declare const data_resolveYamlAnchors: typeof resolveYamlAnchors;
439
467
  declare const data_serializeSubtitles: typeof serializeSubtitles;
440
468
  declare const data_shiftSubtitles: typeof shiftSubtitles;
441
469
  declare const data_stringifyIni: typeof stringifyIni;
@@ -449,7 +477,7 @@ declare const data_validateXml: typeof validateXml;
449
477
  declare const data_validateYaml: typeof validateYaml;
450
478
  declare const data_xmlToJson: typeof xmlToJson;
451
479
  declare namespace data {
452
- export { type data_ConvertedSubtitles as ConvertedSubtitles, type data_CsvDuplicateGroup as CsvDuplicateGroup, type data_CsvDuplicateOptions as CsvDuplicateOptions, type data_CsvDuplicateResult as CsvDuplicateResult, type data_CsvParseResult as CsvParseResult, type data_CsvToSqlOptions as CsvToSqlOptions, type data_CsvToSqlResult as CsvToSqlResult, type data_EnvDiffError as EnvDiffError, type data_EnvDiffResult as EnvDiffResult, type data_EnvEntry as EnvEntry, type data_EnvParseResult as EnvParseResult, type data_FrontMatterError as FrontMatterError, type data_FrontMatterResult as FrontMatterResult, type data_IniSection as IniSection, type data_MarkdownTocEntry as MarkdownTocEntry, type data_MarkdownTocOptions as MarkdownTocOptions, type data_MarkdownTocResult as MarkdownTocResult, type data_NdjsonLineResult as NdjsonLineResult, type data_NdjsonValidateResult as NdjsonValidateResult, type data_ParseOptions as ParseOptions, type data_ParsedIni as ParsedIni, type data_ParsedSubtitles as ParsedSubtitles, type data_SubtitleCue as SubtitleCue, type data_SubtitleFormat as SubtitleFormat, type data_TomlFormatResult as TomlFormatResult, type data_ValidationResult as ValidationResult, type data_XmlFormatResult as XmlFormatResult, type data_XmlToJsonOptions as XmlToJsonOptions, data_convertSubtitles as convertSubtitles, data_csvToJson as csvToJson, data_csvToSqlInsert as csvToSqlInsert, data_detectDelimiter as detectDelimiter, data_detectSubtitleFormat as detectSubtitleFormat, data_diffEnvExample as diffEnvExample, data_envToExport as envToExport, data_envToJson as envToJson, data_findCsvDuplicateRows as findCsvDuplicateRows, data_formatNdjson as formatNdjson, data_formatSubtitleTimestamp as formatSubtitleTimestamp, data_formatToml as formatToml, data_formatXml as formatXml, data_generateMarkdownToc as generateMarkdownToc, data_getSection as getSection, data_getSectionNames as getSectionNames, data_getTomlStats as getTomlStats, data_getXmlStats as getXmlStats, data_getYamlStats as getYamlStats, data_iniToJson as iniToJson, data_jsonArrayToNdjson as jsonArrayToNdjson, data_jsonToIni as jsonToIni, data_jsonToToml as jsonToToml, data_jsonToXml as jsonToXml, data_minifyNdjson as minifyNdjson, data_minifyToml as minifyToml, data_minifyXml as minifyXml, data_ndjsonToJsonArray as ndjsonToJsonArray, data_parseCsv as parseCsv, data_parseEnv as parseEnv, data_parseFrontMatter as parseFrontMatter, data_parseIni as parseIni, data_parseSubtitleTimestamp as parseSubtitleTimestamp, data_parseSubtitles as parseSubtitles, data_parseXmlToObject as parseXmlToObject, data_serializeSubtitles as serializeSubtitles, data_shiftSubtitles as shiftSubtitles, data_stringifyIni as stringifyIni, data_toCsvString as toCsvString, data_tomlToJson as tomlToJson, data_validateEnvKey as validateEnvKey, data_validateIni as validateIni, data_validateNdjson as validateNdjson, data_validateToml as validateToml, data_validateXml as validateXml, data_validateYaml as validateYaml, data_xmlToJson as xmlToJson };
480
+ export { type data_ConvertedSubtitles as ConvertedSubtitles, type data_CsvDuplicateGroup as CsvDuplicateGroup, type data_CsvDuplicateOptions as CsvDuplicateOptions, type data_CsvDuplicateResult as CsvDuplicateResult, type data_CsvParseResult as CsvParseResult, type data_CsvToSqlOptions as CsvToSqlOptions, type data_CsvToSqlResult as CsvToSqlResult, type data_EnvDiffError as EnvDiffError, type data_EnvDiffResult as EnvDiffResult, type data_EnvEntry as EnvEntry, type data_EnvParseResult as EnvParseResult, type data_FrontMatterError as FrontMatterError, type data_FrontMatterResult as FrontMatterResult, type data_IniSection as IniSection, type data_MarkdownTocEntry as MarkdownTocEntry, type data_MarkdownTocOptions as MarkdownTocOptions, type data_MarkdownTocResult as MarkdownTocResult, type data_NdjsonLineResult as NdjsonLineResult, type data_NdjsonValidateResult as NdjsonValidateResult, type data_ParseOptions as ParseOptions, type data_ParsedIni as ParsedIni, type data_ParsedSubtitles as ParsedSubtitles, type data_SubtitleCue as SubtitleCue, type data_SubtitleFormat as SubtitleFormat, type data_TomlFormatResult as TomlFormatResult, type data_ValidationResult as ValidationResult, type data_XmlFormatResult as XmlFormatResult, type data_XmlToJsonOptions as XmlToJsonOptions, type data_YamlAnchorInfo as YamlAnchorInfo, type data_YamlAnchorResolveError as YamlAnchorResolveError, type data_YamlAnchorResolveResult as YamlAnchorResolveResult, data_convertSubtitles as convertSubtitles, data_csvToJson as csvToJson, data_csvToSqlInsert as csvToSqlInsert, data_detectDelimiter as detectDelimiter, data_detectSubtitleFormat as detectSubtitleFormat, data_diffEnvExample as diffEnvExample, data_envToExport as envToExport, data_envToJson as envToJson, data_findCsvDuplicateRows as findCsvDuplicateRows, data_formatNdjson as formatNdjson, data_formatSubtitleTimestamp as formatSubtitleTimestamp, data_formatToml as formatToml, data_formatXml as formatXml, data_generateMarkdownToc as generateMarkdownToc, data_getSection as getSection, data_getSectionNames as getSectionNames, data_getTomlStats as getTomlStats, data_getXmlStats as getXmlStats, data_getYamlStats as getYamlStats, data_iniToJson as iniToJson, data_jsonArrayToNdjson as jsonArrayToNdjson, data_jsonToIni as jsonToIni, data_jsonToToml as jsonToToml, data_jsonToXml as jsonToXml, data_minifyNdjson as minifyNdjson, data_minifyToml as minifyToml, data_minifyXml as minifyXml, data_ndjsonToJsonArray as ndjsonToJsonArray, data_parseCsv as parseCsv, data_parseEnv as parseEnv, data_parseFrontMatter as parseFrontMatter, data_parseIni as parseIni, data_parseSubtitleTimestamp as parseSubtitleTimestamp, data_parseSubtitles as parseSubtitles, data_parseXmlToObject as parseXmlToObject, data_resolveYamlAnchors as resolveYamlAnchors, data_serializeSubtitles as serializeSubtitles, data_shiftSubtitles as shiftSubtitles, data_stringifyIni as stringifyIni, data_toCsvString as toCsvString, data_tomlToJson as tomlToJson, data_validateEnvKey as validateEnvKey, data_validateIni as validateIni, data_validateNdjson as validateNdjson, data_validateToml as validateToml, data_validateXml as validateXml, data_validateYaml as validateYaml, data_xmlToJson as xmlToJson };
453
481
  }
454
482
 
455
- export { minifyNdjson as $, findCsvDuplicateRows as A, formatNdjson as B, type ConvertedSubtitles as C, formatSubtitleTimestamp as D, type EnvDiffError as E, type FrontMatterError as F, formatToml as G, formatXml as H, type IniSection as I, generateMarkdownToc as J, getSection as K, getSectionNames as L, type MarkdownTocEntry as M, type NdjsonLineResult as N, getTomlStats as O, type ParseOptions as P, getXmlStats as Q, getYamlStats as R, type SubtitleCue as S, type TomlFormatResult as T, iniToJson as U, type ValidationResult as V, jsonArrayToNdjson as W, type XmlFormatResult as X, jsonToIni as Y, jsonToToml as Z, jsonToXml as _, type CsvDuplicateGroup as a, minifyToml as a0, minifyXml as a1, ndjsonToJsonArray as a2, parseCsv as a3, parseEnv as a4, parseFrontMatter as a5, parseIni as a6, parseSubtitleTimestamp as a7, parseSubtitles as a8, parseXmlToObject as a9, serializeSubtitles as aa, shiftSubtitles as ab, stringifyIni as ac, toCsvString as ad, tomlToJson as ae, validateEnvKey as af, validateIni as ag, validateNdjson as ah, validateToml as ai, validateXml as aj, validateYaml as ak, xmlToJson as al, type CsvDuplicateOptions as b, type CsvDuplicateResult as c, data as d, type CsvParseResult as e, type CsvToSqlOptions as f, type CsvToSqlResult as g, type EnvDiffResult as h, type EnvEntry as i, type EnvParseResult as j, type FrontMatterResult as k, type MarkdownTocOptions as l, type MarkdownTocResult as m, type NdjsonValidateResult as n, type ParsedIni as o, type ParsedSubtitles as p, type SubtitleFormat as q, type XmlToJsonOptions as r, convertSubtitles as s, csvToJson as t, csvToSqlInsert as u, detectDelimiter as v, detectSubtitleFormat as w, diffEnvExample as x, envToExport as y, envToJson as z };
483
+ export { jsonToIni as $, envToExport as A, envToJson as B, type ConvertedSubtitles as C, findCsvDuplicateRows as D, type EnvDiffError as E, type FrontMatterError as F, formatNdjson as G, formatSubtitleTimestamp as H, type IniSection as I, formatToml as J, formatXml as K, generateMarkdownToc as L, type MarkdownTocEntry as M, type NdjsonLineResult as N, getSection as O, type ParseOptions as P, getSectionNames as Q, getTomlStats as R, type SubtitleCue as S, type TomlFormatResult as T, getXmlStats as U, type ValidationResult as V, getYamlStats as W, type XmlFormatResult as X, type YamlAnchorInfo as Y, iniToJson as Z, jsonArrayToNdjson as _, type CsvDuplicateGroup as a, jsonToToml as a0, jsonToXml as a1, minifyNdjson as a2, minifyToml as a3, minifyXml as a4, ndjsonToJsonArray as a5, parseCsv as a6, parseEnv as a7, parseFrontMatter as a8, parseIni as a9, parseSubtitleTimestamp as aa, parseSubtitles as ab, parseXmlToObject as ac, resolveYamlAnchors as ad, serializeSubtitles as ae, shiftSubtitles as af, stringifyIni as ag, toCsvString as ah, tomlToJson as ai, validateEnvKey as aj, validateIni as ak, validateNdjson as al, validateToml as am, validateXml as an, validateYaml as ao, xmlToJson as ap, type CsvDuplicateOptions as b, type CsvDuplicateResult as c, data as d, type CsvParseResult as e, type CsvToSqlOptions as f, type CsvToSqlResult as g, type EnvDiffResult as h, type EnvEntry as i, type EnvParseResult as j, type FrontMatterResult as k, type MarkdownTocOptions as l, type MarkdownTocResult as m, type NdjsonValidateResult as n, type ParsedIni as o, type ParsedSubtitles as p, type SubtitleFormat as q, type XmlToJsonOptions as r, type YamlAnchorResolveError as s, type YamlAnchorResolveResult as t, convertSubtitles as u, csvToJson as v, csvToSqlInsert as w, detectDelimiter as x, detectSubtitleFormat as y, diffEnvExample as z };