{"versions":{"2.0.1":{"name":"@peculiar/utils","version":"2.0.1","description":"Modern byte, encoding, converter registry, and PEM utilities for TypeScript projects.","type":"module","main":"./build/cjs/index.js","module":"./build/esm/index.js","types":"./build/types/index.d.ts","exports":{".":{"types":"./build/types/index.d.ts","import":"./build/esm/index.js","require":"./build/cjs/index.js"},"./bytes":{"types":"./build/types/bytes/index.d.ts","import":"./build/esm/bytes/index.js","require":"./build/cjs/bytes/index.js"},"./encoding":{"types":"./build/types/encoding/index.d.ts","import":"./build/esm/encoding/index.js","require":"./build/cjs/encoding/index.js"},"./encoding/*":{"types":"./build/types/encoding/*.d.ts","import":"./build/esm/encoding/*.js","require":"./build/cjs/encoding/*.js"},"./converters":{"types":"./build/types/converters/index.d.ts","import":"./build/esm/converters/index.js","require":"./build/cjs/converters/index.js"},"./pem":{"types":"./build/types/pem/index.d.ts","import":"./build/esm/pem/index.js","require":"./build/cjs/pem/index.js"},"./legacy":{"types":"./build/types/legacy/index.d.ts","import":"./build/esm/legacy/index.js","require":"./build/cjs/legacy/index.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"scripts":{"test":"vitest run","coverage":"vitest run --coverage","clear":"rimraf build","rebuild":"npm run clear && npm run build","build":"node scripts/prune-legacy-build-outputs.mjs && tsc -p tsconfig.build.types.json && tsc -p tsconfig.build.esm.json && tsc -p tsconfig.build.cjs.json && node scripts/write-cjs-package-json.mjs","prepack":"npm run build","publish:manual":"npm run check && npm run build && npm publish --ignore-scripts","lint:check":"eslint . --fix-dry-run","check":"npm run lint:check && tsc --noEmit && npm test","lint":"eslint .","lint:fix":"eslint . --fix"},"keywords":["typescript","utils","buffer","bytes","convert","encoding","base64","base64url","hex","utf8","utf16","pem","pki","peculiar"],"author":{"name":"PeculiarVentures"},"contributors":[{"name":"Miroshin Stepan","email":"microshine@mail.ru"}],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/PeculiarVentures/pvtsutils.git"},"bugs":{"url":"https://github.com/PeculiarVentures/pvtsutils/issues"},"homepage":"https://github.com/PeculiarVentures/pvtsutils#readme","dependencies":{"tslib":"^2.8.1"},"devDependencies":{"@peculiar/eslint-config-base":"^0.2.9","@types/node":"^25.6.0","@vitest/coverage-v8":"^4.1.5","rimraf":"^6.1.3","typescript":"^6.0.3","vitest":"^4.1.5"},"gitHead":"e986ed8cf253d945ff1c8bbf5b8cfffb45dc92c7","_id":"@peculiar/utils@2.0.1","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-7f/uHXQ+YAKs3NtY0Yg8CwPdBqRWV9eu5C/tYU7hITzPHtYTksj4jbr3pmu2wzBitPIeLMCQuoHX2zv+9TARWQ==","shasum":"d2b09ed8700913b633c2d9d0b02c154b0a56ceb8","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@peculiar/utils/-/utils-2.0.1.tgz","fileCount":82,"unpackedSize":145467,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@peculiar%2futils@2.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDPQftdGmW5fr02OuzeS394ADQE5TG4h8egeXwz2In3AwIgaGfm5Uhh7/tTpaRHncj4+6G34irJ22BRCdPBqkbQ8XI="}],"size":25479},"_npmUser":{"name":"anonymous","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:603fb165-d7dd-4f47-8a2c-aabe09a30237"}},"directories":{},"maintainers":[{"name":"anonymous","email":"ryan_hurst@hotmail.com"},{"name":"anonymous","email":"microshine@mail.ru"},{"name":"anonymous","email":"yury@strozhevsky.com"},{"name":"anonymous","email":"info@peculiarventures.com"},{"name":"anonymous","email":"apilguk@gmail.com"},{"name":"anonymous","email":"donskovdmitriyv@gmail.com"},{"name":"anonymous","email":"mihailzachepilo@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/utils_2.0.1_1777462603918_0.29019453056711764"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-04-29T11:36:44.042Z","publish_time":1777462604042,"_source_registry_name":"default"},"2.0.0":{"name":"@peculiar/utils","version":"2.0.0","keywords":["typescript","utils","buffer","bytes","convert","encoding","base64","base64url","hex","utf8","utf16","pem","pki","peculiar"],"author":{"name":"PeculiarVentures"},"license":"MIT","_id":"@peculiar/utils@2.0.0","maintainers":[{"name":"anonymous","email":"ryan_hurst@hotmail.com"},{"name":"anonymous","email":"microshine@mail.ru"},{"name":"anonymous","email":"yury@strozhevsky.com"},{"name":"anonymous","email":"info@peculiarventures.com"},{"name":"anonymous","email":"apilguk@gmail.com"},{"name":"anonymous","email":"donskovdmitriyv@gmail.com"},{"name":"anonymous","email":"mihailzachepilo@gmail.com"}],"contributors":[{"name":"Miroshin Stepan","email":"microshine@mail.ru"}],"homepage":"https://github.com/PeculiarVentures/pvtsutils#readme","bugs":{"url":"https://github.com/PeculiarVentures/pvtsutils/issues"},"dist":{"shasum":"b6676d99ea71d25cd547387c4ffa3dc71a3a4673","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@peculiar/utils/-/utils-2.0.0.tgz","fileCount":82,"integrity":"sha512-6Dd/pXfKu4pD3WrM6MX2u6LAWmo2AMrDQBhmS8+IafXeWBAUgseI22a8qkBJknJ+cc0cSfkEX9Pt5Ju+kmjJLg==","signatures":[{"sig":"MEUCIQCcPBg6g4HaLZvEZzW0o9ncr19g8pF7AaxN7lrUp/6UMwIgHp+j8xrB2CMoiQ4TXtsZVXT9xMtxQBTngrX+lJdHTtA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":144833,"size":25290},"main":"./build/cjs/index.js","type":"module","types":"./build/types/index.d.ts","module":"./build/esm/index.js","exports":{".":{"types":"./build/types/index.d.ts","import":"./build/esm/index.js","require":"./build/cjs/index.js"},"./pem":{"types":"./build/types/pem/index.d.ts","import":"./build/esm/pem/index.js","require":"./build/cjs/pem/index.js"},"./bytes":{"types":"./build/types/bytes/index.d.ts","import":"./build/esm/bytes/index.js","require":"./build/cjs/bytes/index.js"},"./legacy":{"types":"./build/types/legacy/index.d.ts","import":"./build/esm/legacy/index.js","require":"./build/cjs/legacy/index.js"},"./encoding":{"types":"./build/types/encoding/index.d.ts","import":"./build/esm/encoding/index.js","require":"./build/cjs/encoding/index.js"},"./converters":{"types":"./build/types/converters/index.d.ts","import":"./build/esm/converters/index.js","require":"./build/cjs/converters/index.js"},"./encoding/*":{"types":"./build/types/encoding/*.d.ts","import":"./build/esm/encoding/*.js","require":"./build/cjs/encoding/*.js"},"./package.json":"./package.json"},"gitHead":"76b8d6eafc98d3e6a0b94917a2ef8bf81ac901a0","scripts":{"lint":"eslint .","test":"vitest run","build":"node scripts/prune-legacy-build-outputs.mjs && tsc -p tsconfig.build.types.json && tsc -p tsconfig.build.esm.json && tsc -p tsconfig.build.cjs.json && node scripts/write-cjs-package-json.mjs","check":"npm run lint:check && tsc --noEmit && npm test","clear":"rimraf build","prepack":"npm run build","rebuild":"npm run clear && npm run build","coverage":"vitest run --coverage","lint:fix":"eslint . --fix","lint:check":"eslint . --fix-dry-run","publish:manual":"npm run check && npm run build && npm publish --ignore-scripts"},"_npmUser":{"name":"anonymous","email":"microshine@mail.ru"},"repository":{"url":"git+https://github.com/PeculiarVentures/pvtsutils.git","type":"git"},"_npmVersion":"11.7.0","description":"Modern byte, encoding, converter registry, and PEM utilities for TypeScript projects.","directories":{},"_nodeVersion":"24.10.0","dependencies":{"tslib":"^2.8.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.3","vitest":"^4.1.5","typescript":"^6.0.3","@types/node":"^25.6.0","@vitest/coverage-v8":"^4.1.5","@peculiar/eslint-config-base":"^0.2.9"},"_npmOperationalInternal":{"tmp":"tmp/utils_2.0.0_1777462060637_0.300768155454914","host":"s3://npm-registry-packages-npm-production"},"_cnpmcore_publish_time":"2026-04-29T11:27:40.787Z","publish_time":1777462060787,"_source_registry_name":"default"},"2.0.2":{"name":"@peculiar/utils","version":"2.0.2","description":"Modern byte, encoding, converter registry, and PEM utilities for TypeScript projects.","type":"module","main":"./build/cjs/index.js","module":"./build/esm/index.js","types":"./build/types/index.d.ts","exports":{".":{"types":"./build/types/index.d.ts","import":"./build/esm/index.js","require":"./build/cjs/index.js"},"./bytes":{"types":"./build/types/bytes/index.d.ts","import":"./build/esm/bytes/index.js","require":"./build/cjs/bytes/index.js"},"./encoding":{"types":"./build/types/encoding/index.d.ts","import":"./build/esm/encoding/index.js","require":"./build/cjs/encoding/index.js"},"./encoding/*":{"types":"./build/types/encoding/*.d.ts","import":"./build/esm/encoding/*.js","require":"./build/cjs/encoding/*.js"},"./converters":{"types":"./build/types/converters/index.d.ts","import":"./build/esm/converters/index.js","require":"./build/cjs/converters/index.js"},"./pem":{"types":"./build/types/pem/index.d.ts","import":"./build/esm/pem/index.js","require":"./build/cjs/pem/index.js"},"./legacy":{"types":"./build/types/legacy/index.d.ts","import":"./build/esm/legacy/index.js","require":"./build/cjs/legacy/index.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"scripts":{"test":"vitest run","coverage":"vitest run --coverage","clear":"rimraf build","rebuild":"npm run clear && npm run build","build":"node scripts/prune-legacy-build-outputs.mjs && tsc -p tsconfig.build.types.json && tsc -p tsconfig.build.esm.json && tsc -p tsconfig.build.cjs.json && node scripts/write-cjs-package-json.mjs","prepack":"npm run build","publish:manual":"npm run check && npm run build && npm publish --ignore-scripts","lint:check":"eslint . --fix-dry-run","check":"npm run lint:check && tsc --noEmit && npm test","lint":"eslint .","lint:fix":"eslint . --fix"},"keywords":["typescript","utils","buffer","bytes","convert","encoding","base64","base64url","hex","utf8","utf16","pem","pki","peculiar"],"author":{"name":"PeculiarVentures"},"contributors":[{"name":"Miroshin Stepan","email":"microshine@mail.ru"}],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/PeculiarVentures/pvtsutils.git"},"bugs":{"url":"https://github.com/PeculiarVentures/pvtsutils/issues"},"homepage":"https://github.com/PeculiarVentures/pvtsutils#readme","dependencies":{"tslib":"^2.8.1"},"devDependencies":{"@peculiar/eslint-config-base":"^0.2.9","@types/node":"^25.6.0","@vitest/coverage-v8":"^4.1.5","rimraf":"^6.1.3","typescript":"^6.0.3","vitest":"^4.1.5"},"gitHead":"68ae4e0ba239980d93166b6e59ae1d7adc9e898a","_id":"@peculiar/utils@2.0.2","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-lHhrK/1QAXGn0GUYkme7t4zo0mQ5QIp+/8YED6pzu8AQFdjA9bAXeNURAHk4sw7n9i89MMNQVom0LkuuLUZMog==","shasum":"284eec30b0375ff9ef48e5a0b98f1eb29d837af5","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@peculiar/utils/-/utils-2.0.2.tgz","fileCount":82,"unpackedSize":146282,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@peculiar%2futils@2.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBieu8kFZmF0qtYFQD1kEToMIASeUoQuHdKC4lI18ZOnAiEA8VT/AXH1u9tCX6XfU9Qd0bgPY/g7dydMEOemQBIR8dE="}],"size":25579},"_npmUser":{"name":"anonymous","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:603fb165-d7dd-4f47-8a2c-aabe09a30237"}},"directories":{},"maintainers":[{"name":"anonymous","email":"ryan_hurst@hotmail.com"},{"name":"anonymous","email":"microshine@mail.ru"},{"name":"anonymous","email":"yury@strozhevsky.com"},{"name":"anonymous","email":"info@peculiarventures.com"},{"name":"anonymous","email":"apilguk@gmail.com"},{"name":"anonymous","email":"donskovdmitriyv@gmail.com"},{"name":"anonymous","email":"mihailzachepilo@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/utils_2.0.2_1777561925105_0.43180363585179715"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-04-30T15:12:05.250Z","publish_time":1777561925250,"_source_registry_name":"default"},"2.0.3":{"name":"@peculiar/utils","version":"2.0.3","description":"Modern byte, encoding, converter registry, and PEM utilities for TypeScript projects.","type":"module","main":"./build/cjs/index.js","module":"./build/esm/index.js","types":"./build/types/index.d.ts","exports":{".":{"types":"./build/types/index.d.ts","import":"./build/esm/index.js","require":"./build/cjs/index.js"},"./bytes":{"types":"./build/types/bytes/index.d.ts","import":"./build/esm/bytes/index.js","require":"./build/cjs/bytes/index.js"},"./encoding":{"types":"./build/types/encoding/index.d.ts","import":"./build/esm/encoding/index.js","require":"./build/cjs/encoding/index.js"},"./encoding/*":{"types":"./build/types/encoding/*.d.ts","import":"./build/esm/encoding/*.js","require":"./build/cjs/encoding/*.js"},"./converters":{"types":"./build/types/converters/index.d.ts","import":"./build/esm/converters/index.js","require":"./build/cjs/converters/index.js"},"./pem":{"types":"./build/types/pem/index.d.ts","import":"./build/esm/pem/index.js","require":"./build/cjs/pem/index.js"},"./legacy":{"types":"./build/types/legacy/index.d.ts","import":"./build/esm/legacy/index.js","require":"./build/cjs/legacy/index.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"scripts":{"test":"vitest run","coverage":"vitest run --coverage","clear":"rimraf build","rebuild":"npm run clear && npm run build","build":"node scripts/prune-legacy-build-outputs.mjs && tsc -p tsconfig.build.types.json && tsc -p tsconfig.build.esm.json && tsc -p tsconfig.build.cjs.json && node scripts/write-cjs-package-json.mjs","prepack":"npm run build","publish:manual":"npm run check && npm run build && npm publish --ignore-scripts","lint:check":"eslint . --fix-dry-run","check":"npm run lint:check && tsc --noEmit && npm test","lint":"eslint .","lint:fix":"eslint . --fix"},"keywords":["typescript","utils","buffer","bytes","convert","encoding","base64","base64url","hex","utf8","utf16","pem","pki","peculiar"],"author":{"name":"PeculiarVentures"},"contributors":[{"name":"Miroshin Stepan","email":"microshine@mail.ru"}],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/PeculiarVentures/pvtsutils.git"},"bugs":{"url":"https://github.com/PeculiarVentures/pvtsutils/issues"},"homepage":"https://github.com/PeculiarVentures/pvtsutils#readme","dependencies":{"tslib":"^2.8.1"},"devDependencies":{"@peculiar/eslint-config-base":"^0.2.9","@types/node":"^25.6.0","@vitest/coverage-v8":"^4.1.5","rimraf":"^6.1.3","typescript":"^6.0.3","vitest":"^4.1.5"},"_id":"@peculiar/utils@2.0.3","_integrity":"sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==","_resolved":"/home/runner/work/pvtsutils/pvtsutils/release-package/peculiar-utils-2.0.3.tgz","_from":"file:release-package/peculiar-utils-2.0.3.tgz","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==","shasum":"a27ca4c4b73652e110f19a7d16d664f458a5528e","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@peculiar/utils/-/utils-2.0.3.tgz","fileCount":82,"unpackedSize":146759,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@peculiar%2futils@2.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEQUeHm6o8RS6+afL2J0+npt5KWVk6K35Pwu/U8YNP2yAiBW83+KH9u8dlnKRPrVMozNyDzjqaYrHdAAOQBQyEf1mg=="}],"size":25624},"_npmUser":{"name":"anonymous","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:603fb165-d7dd-4f47-8a2c-aabe09a30237"}},"directories":{},"maintainers":[{"name":"anonymous","email":"ryan_hurst@hotmail.com"},{"name":"anonymous","email":"microshine@mail.ru"},{"name":"anonymous","email":"yury@strozhevsky.com"},{"name":"anonymous","email":"info@peculiarventures.com"},{"name":"anonymous","email":"apilguk@gmail.com"},{"name":"anonymous","email":"donskovdmitriyv@gmail.com"},{"name":"anonymous","email":"mihailzachepilo@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/utils_2.0.3_1777662318868_0.33368571184422735"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-05-01T19:05:19.014Z","publish_time":1777662319014,"_source_registry_name":"default"}},"dist-tags":{"latest":"2.0.3"},"name":"@peculiar/utils","time":{"created":"2026-04-29T11:36:55.817Z","modified":"2026-05-01T19:05:53.131Z","2.0.1":"2026-04-29T11:36:44.042Z","2.0.0":"2026-04-29T11:27:40.787Z","2.0.2":"2026-04-30T15:12:05.250Z","2.0.3":"2026-05-01T19:05:19.014Z"},"readme":"# @peculiar/utils\n\n[![npm version](https://img.shields.io/npm/v/%40peculiar%2Futils.svg)](https://www.npmjs.com/package/@peculiar/utils)\n[![Test](https://github.com/PeculiarVentures/pvtsutils/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/PeculiarVentures/pvtsutils/actions/workflows/test.yml)\n[![Coverage Status](https://coveralls.io/repos/github/PeculiarVentures/pvtsutils/badge.svg?branch=master)](https://coveralls.io/github/PeculiarVentures/pvtsutils?branch=master)\n[![License: MIT](https://img.shields.io/github/license/PeculiarVentures/pvtsutils.svg)](https://github.com/PeculiarVentures/pvtsutils/blob/master/LICENSE)\n\nModern byte, text, converter registry, and PEM utilities for TypeScript projects.\n\nThe package is designed around a modular v2 API:\n\n- multi-entry exports for tree-shake-friendly imports;\n- `encode` and `decode` terminology;\n- an extensible runtime converter registry;\n- generic PEM helpers without PKI-specific parsing;\n- a legacy compatibility layer for historical `pvtsutils` consumers.\n\n## Install\n\n```bash\nnpm install @peculiar/utils\n```\n\n## Entry Points\n\n```ts\nimport { bytes } from \"@peculiar/utils\";\nimport { hex, base64, base64url } from \"@peculiar/utils/encoding\";\nimport { pem } from \"@peculiar/utils/pem\";\nimport { convert, createConverterRegistry, defaultConverters } from \"@peculiar/utils/converters\";\nimport { Convert } from \"@peculiar/utils/legacy\";\n```\n\n## Bytes Helpers\n\n`@peculiar/utils/bytes` stays focused on stateless byte sequence utilities. It does not include stateful readers, writers, ASN.1 parsing, PDF parsing, or other structured binary readers. For structured binary parsing, use a dedicated binary reader package.\n\n```ts\nimport { bytes } from \"@peculiar/utils\";\n\nconst offset = bytes.indexOf(new Uint8Array([0x25, 0x25, 0x45, 0x4f, 0x46]), \"%%EOF\", {\n encoding: \"ascii\",\n});\n\nconst suffix = bytes.endsWith(new Uint8Array([0x25, 0x25, 0x45, 0x4f, 0x46]), \"%%EOF\", {\n encoding: \"ascii\",\n});\n```\n\n### Find `startxref` In A PDF Tail\n\n```ts\nimport { lastIndexOf } from \"@peculiar/utils/bytes\";\n\nconst tailStart = Math.max(0, pdf.byteLength - 4096);\n\nconst offset = lastIndexOf(pdf, \"startxref\", {\n encoding: \"ascii\",\n start: pdf.byteLength,\n end: tailStart,\n});\n\nif (offset === -1) {\n throw new Error(\"PDF startxref marker not found\");\n}\n```\n\n### Find `startxref` Via `tail`\n\n```ts\nimport { lastIndexOf, tail } from \"@peculiar/utils/bytes\";\n\nconst pdfTail = tail(pdf, 4096);\n\nconst localOffset = lastIndexOf(pdfTail, \"startxref\", {\n encoding: \"ascii\",\n});\n\nconst offset =\n localOffset === -1\n    ? -1\n    : pdf.byteLength - pdfTail.byteLength + localOffset;\n```\n\n### Check Prefixes And Suffixes\n\n```ts\nimport { bytes } from \"@peculiar/utils\";\n\nbytes.startsWith(data, \"-----BEGIN\", { encoding: \"ascii\" });\nbytes.endsWith(data, \"%%EOF\", { encoding: \"ascii\" });\n```\n\n### Compare Byte Sequences\n\n```ts\nimport { bytes } from \"@peculiar/utils\";\n\nconst result = bytes.compare(a, b);\n\nif (result === 0) {\n console.log(\"equal\");\n}\n```\n\n## Convert API\n\nThe default `convert` facade is a convenience singleton backed by the built-in registry.\n\n```ts\nimport { convert } from \"@peculiar/utils/converters\";\n\nconst bytes = convert.decode(\"base64\", \"AQID\");\nconst text = convert.encode(\"hex\", bytes, { case: \"upper\" });\n```\n\nDeprecated `convert.to(...)` and `convert.from(...)` aliases are still available for temporary migration, but the primary v2 API is `encode` and `decode`.\n\n## Transcode\n\nDirect text-to-text transcoding goes through the registry without a manual intermediate step.\n\n```ts\nimport { convert } from \"@peculiar/utils/converters\";\nimport { hex } from \"@peculiar/utils/encoding\";\n\nconst pemText = convert.transcode(\"AQID\", {\n from: \"base64\",\n to: \"pem\",\n toOptions: {\n  label: \"CERTIFICATE\",\n },\n});\n\nconst hexText = convert.transcode(pemText, {\n from: \"pem\",\n fromOptions: { label: \"CERTIFICATE\" },\n to: \"hex\",\n toOptions: hex.formats.colonUpper,\n});\n```\n\nThere is intentionally no chain API.\n\n## Hex Formatting\n\nThe `hex` codec accepts common input styles and can format output explicitly.\n\n```ts\nimport { hex } from \"@peculiar/utils/encoding\";\n\nhex.decode(\"0102030405060708090a0b0c\");\nhex.decode(\"01020304 05060708 090a0b0c\");\nhex.decode(\"01:02:03:04:05:06:07:08:09:0A:0B:0C\");\nhex.decode(\"0x0102030405060708090a0b0c\");\n\nhex.encode(new Uint8Array([1, 2, 3, 4]), hex.formats.colonUpper);\nhex.encode(new Uint8Array([1, 2, 3, 4]), {\n prefix: \"0x\",\n group: {\n  size: 2,\n  separator: \" \",\n },\n});\n```\n\nAvailable presets:\n\n- `hex.formats.compact`\n- `hex.formats.upper`\n- `hex.formats.colon`\n- `hex.formats.colonUpper`\n- `hex.formats.groupsOf4`\n- `hex.formats.prefixed`\n\n## Preserve Formatting\n\nUse `parse` and `format` when you want to keep the original visual style of a hex string.\n\n```ts\nimport { hex } from \"@peculiar/utils/encoding\";\n\nconst parsed = hex.parse(\"01:02:03:04:05:06\");\n\nparsed.bytes;\nparsed.format;\nparsed.normalized;\n\nconst updated = hex.format(new Uint8Array([0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]), parsed.format);\n```\n\nThe same capabilities are available through the registry facade:\n\n```ts\nimport { convert } from \"@peculiar/utils/converters\";\n\nconst parsed = convert.parse(\"hex\", \"01:02:03:04\");\nconst formatted = convert.format(\"hex\", new Uint8Array([0xaa, 0xbb, 0xcc, 0xdd]), parsed.format);\n```\n\n## PEM Helpers\n\nPEM support stays generic. The package does not parse ASN.1, validate PKI semantics, or handle encrypted PEM containers.\n\n```ts\nimport { pem } from \"@peculiar/utils/pem\";\n\nconst text = pem.encode(\"CERTIFICATE\", new Uint8Array([1, 2, 3]));\nconst blocks = pem.decode(text);\nconst block = pem.find(text, \"CERTIFICATE\");\nconst matches = pem.findAll(text, \"CERTIFICATE\");\n\nconst bundle = pem.encodeMany([\n { label: \"CERTIFICATE\", data: new Uint8Array([1, 2, 3]) },\n { label: \"PRIVATE KEY\", data: new Uint8Array([4, 5, 6]) },\n]);\n```\n\n## Safe Decode And Detection\n\n```ts\nimport { convert } from \"@peculiar/utils/converters\";\n\nconst result = convert.tryDecode(\"hex\", \"01:02:03\");\n\nif (result.ok) {\n console.log(result.bytes);\n} else {\n console.error(result.error);\n}\n\nconst candidates = convert.detect(\"-----BEGIN DATA-----\\nAQID\\n-----END DATA-----\\n\", {\n formats: [\"pem\", \"base64\", \"hex\"],\n});\n```\n\n## Custom Registries\n\nApplications can create isolated registries instead of mutating global state.\n\n```ts\nimport { createConverterRegistry, defaultConverters } from \"@peculiar/utils/converters\";\n\nconst registry = createConverterRegistry(defaultConverters);\n\nregistry.register({\n name: \"base58btc\",\n aliases: [\"b58\"],\n encode(data) {\n  return base58btcEncode(data);\n },\n decode(text) {\n  return base58btcDecode(text);\n },\n});\n```\n\nName and alias conflicts throw by default. Use `{ override: true }` only when replacement is intentional.\n\n## Typed Converter Options\n\nBuilt-in converters expose typed options through the registry facade.\n\n```ts\nimport { convert } from \"@peculiar/utils/converters\";\n\nconvert.encode(\"hex\", new Uint8Array([1, 2, 3]), {\n case: \"upper\",\n});\n```\n\nWrong options are rejected by TypeScript:\n\n```ts\nconvert.encode(\"hex\", new Uint8Array([1, 2, 3]), {\n label: \"CERTIFICATE\",\n});\n```\n\nCustom converters can extend the options map via module augmentation:\n\n```ts\ndeclare module \"@peculiar/utils/converters\" {\n interface ConverterOptionsMap {\n  base58btc: {\n   encode: Base58EncodeOptions;\n   decode: Base58DecodeOptions;\n  };\n }\n}\n```\n\n## Legacy Compatibility\n\nThe old `pvtsutils`-style surface is preserved under the legacy entry point.\n\n```ts\nimport { BufferSourceConverter, Convert, assign, combine, isEqual } from \"@peculiar/utils/legacy\";\n```","users":{}}