{"_id":"@1001-digital/resolve-metadata","_rev":"5-60c7ce608b77d69e7e802a26a9ebd901","name":"@1001-digital/resolve-metadata","dist-tags":{"latest":"1.0.3"},"versions":{"0.1.0":{"name":"@1001-digital/resolve-metadata","version":"0.1.0","license":"MIT","_id":"@1001-digital/resolve-metadata@0.1.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/resolve-metadata#readme","bugs":{"url":"https://github.com/1001-digital/resolve-metadata/issues"},"dist":{"shasum":"72c2fb39f9acbe3d2d1d926207aa56e24c8ffe24","tarball":"https://registry.npmjs.org/@1001-digital/resolve-metadata/-/resolve-metadata-0.1.0.tgz","fileCount":13,"integrity":"sha512-BbrRLEnt3uTSq8z5KgbPztcSJJBDRYHLY5JLq96ObSC+7gKDljg8x+goBez21jwCl6T5k31abNy/WjC1cvdnhA==","signatures":[{"sig":"MEUCIDV/956Rf+I5FSwnjEguoQavWq50XSBvZ7QgeYAci7d7AiEA3OolDaJi2NGJtqPtJmbG7oPPboMbA0cjg5eybafDcM8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27431},"main":"./dist/index.js","type":"module","_from":"file:1001-digital-resolve-metadata-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"vite build","format":"prettier --write .","changeset":"changeset","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check ."},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/ee03fc3bcd6485bb417211521776c053/1001-digital-resolve-metadata-0.1.0.tgz","_integrity":"sha512-BbrRLEnt3uTSq8z5KgbPztcSJJBDRYHLY5JLq96ObSC+7gKDljg8x+goBez21jwCl6T5k31abNy/WjC1cvdnhA==","repository":{"url":"git+https://github.com/1001-digital/resolve-metadata.git","type":"git"},"_npmVersion":"11.9.0","description":"Normalize NFT token and contract metadata into a strict typed schema.","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","vitest":"^3.0.0","prettier":"^3.5.3","typescript":"^5.7.0","@changesets/cli":"^2.30.0","vite-plugin-dts":"^4.0.0","@changesets/changelog-github":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/resolve-metadata_0.1.0_1774105145889_0.5108122613948431","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@1001-digital/resolve-metadata","version":"1.0.0","license":"MIT","_id":"@1001-digital/resolve-metadata@1.0.0","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/resolve-metadata#readme","bugs":{"url":"https://github.com/1001-digital/resolve-metadata/issues"},"dist":{"shasum":"b8ba82138d80182b63470b7d5041c0e9fda0915d","tarball":"https://registry.npmjs.org/@1001-digital/resolve-metadata/-/resolve-metadata-1.0.0.tgz","fileCount":14,"integrity":"sha512-SJqu+/iyvDJ6Zd9tJFOILLIMzNbmVAPOFnyqNAiV2u9WtAxNLXm21u0JiLKhlz6EyrUExqy6+XFxhm8JRg2aFA==","signatures":[{"sig":"MEQCIG4ucVzJ5fvuCkE7xgI6/t8+1EmzQEpBa4x4jGEEqY1vAiBKU1YVR6yYMgUtnMQUUjwX+926EIX4BmfgMOR2AhzlgQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26022},"main":"./dist/index.js","type":"module","_from":"file:1001-digital-resolve-metadata-1.0.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"vite build","format":"prettier --write .","changeset":"changeset","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check ."},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/5e118e0b3d1df79a1cc5ce14a46770fe/1001-digital-resolve-metadata-1.0.0.tgz","_integrity":"sha512-SJqu+/iyvDJ6Zd9tJFOILLIMzNbmVAPOFnyqNAiV2u9WtAxNLXm21u0JiLKhlz6EyrUExqy6+XFxhm8JRg2aFA==","repository":{"url":"git+https://github.com/1001-digital/resolve-metadata.git","type":"git"},"_npmVersion":"11.9.0","description":"Normalize NFT token and contract metadata into a strict typed schema.","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","vitest":"^3.0.0","prettier":"^3.5.3","typescript":"^5.7.0","@changesets/cli":"^2.30.0","vite-plugin-dts":"^4.0.0","@changesets/changelog-github":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/resolve-metadata_1.0.0_1774105504575_0.7822281693746533","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@1001-digital/resolve-metadata","version":"1.0.1","license":"MIT","_id":"@1001-digital/resolve-metadata@1.0.1","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/resolve-metadata#readme","bugs":{"url":"https://github.com/1001-digital/resolve-metadata/issues"},"dist":{"shasum":"fdb7361171b42ff597835a59bce5ce3e915f23e6","tarball":"https://registry.npmjs.org/@1001-digital/resolve-metadata/-/resolve-metadata-1.0.1.tgz","fileCount":14,"integrity":"sha512-IGnJ6dhqH03LyHZcSHBD8g7yLJndTK/4ONT5awdQJLElpZxCGkI4lYEZ8YnUp+cfm9y13DpVF5ri9TSmcauOAg==","signatures":[{"sig":"MEQCIAF505f4iAniQjKq13zB3sFfU+K00WLv76jLE9vJyy7wAiBeEsCaFQTW2W5qrbYHb4bHl8c8enR+kGrQRMIaHOPLNQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26280},"main":"./dist/index.js","type":"module","_from":"file:1001-digital-resolve-metadata-1.0.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"vite build","format":"prettier --write .","changeset":"changeset","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check ."},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/94611a15156244e83f153c01d44da9d3/1001-digital-resolve-metadata-1.0.1.tgz","_integrity":"sha512-IGnJ6dhqH03LyHZcSHBD8g7yLJndTK/4ONT5awdQJLElpZxCGkI4lYEZ8YnUp+cfm9y13DpVF5ri9TSmcauOAg==","repository":{"url":"git+https://github.com/1001-digital/resolve-metadata.git","type":"git"},"_npmVersion":"11.9.0","description":"Normalize NFT token and contract metadata into a strict typed schema.","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","vitest":"^3.0.0","prettier":"^3.5.3","typescript":"^5.7.0","@changesets/cli":"^2.30.0","vite-plugin-dts":"^4.0.0","@changesets/changelog-github":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/resolve-metadata_1.0.1_1774467233750_0.5374080105357506","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@1001-digital/resolve-metadata","version":"1.0.2","license":"MIT","_id":"@1001-digital/resolve-metadata@1.0.2","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"homepage":"https://github.com/1001-digital/resolve-metadata#readme","bugs":{"url":"https://github.com/1001-digital/resolve-metadata/issues"},"dist":{"shasum":"f58cebed70d655cb9d3dc24d7a10e0a5800ef463","tarball":"https://registry.npmjs.org/@1001-digital/resolve-metadata/-/resolve-metadata-1.0.2.tgz","fileCount":14,"integrity":"sha512-Yym8HfcbJO08WOoaBL2XHl9xZFzdEqWJaZA1JXYcMRIp6il1JttdGMdhcSk6apkntLKbgWCvrQCNDeCCTWYmqg==","signatures":[{"sig":"MEUCIFbEKanNnoy/dIohBJUicqu9BcJvxIRWXbzV9JINaQNjAiEAyTNTk7nM0O6HApZVJ4rWNHAY/jvv/Iqadnxb/VssoKY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27108},"main":"./dist/index.js","type":"module","_from":"file:1001-digital-resolve-metadata-1.0.2.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"vite build","format":"prettier --write .","changeset":"changeset","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"prettier --check ."},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"_resolved":"/tmp/b349550bd15d947c51e798450605d805/1001-digital-resolve-metadata-1.0.2.tgz","_integrity":"sha512-Yym8HfcbJO08WOoaBL2XHl9xZFzdEqWJaZA1JXYcMRIp6il1JttdGMdhcSk6apkntLKbgWCvrQCNDeCCTWYmqg==","repository":{"url":"git+https://github.com/1001-digital/resolve-metadata.git","type":"git"},"_npmVersion":"11.9.0","description":"Normalize NFT token and contract metadata into a strict typed schema.","directories":{},"_nodeVersion":"24.14.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.0","vitest":"^3.0.0","prettier":"^3.5.3","typescript":"^5.7.0","@changesets/cli":"^2.30.0","vite-plugin-dts":"^4.0.0","@changesets/changelog-github":"^0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/resolve-metadata_1.0.2_1774468788756_0.13883939682799373","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@1001-digital/resolve-metadata","version":"1.0.3","description":"Normalize NFT token and contract metadata into a strict typed schema.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/1001-digital/resolve-metadata.git"},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/index.d.ts","devDependencies":{"@changesets/changelog-github":"^0.6.0","@changesets/cli":"^2.30.0","prettier":"^3.5.3","typescript":"^5.7.0","vite":"^6.0.0","vite-plugin-dts":"^4.0.0","vitest":"^3.0.0"},"dependencies":{"@1001-digital/normalize-dweb-url":"^0.1.0"},"scripts":{"build":"vite build","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","changeset":"changeset","format":"prettier --write .","format:check":"prettier --check ."},"_id":"@1001-digital/resolve-metadata@1.0.3","bugs":{"url":"https://github.com/1001-digital/resolve-metadata/issues"},"homepage":"https://github.com/1001-digital/resolve-metadata#readme","_integrity":"sha512-lYdw0xNjSUS+2j4OCxkNm3Lizf7drq54I7uZBL0txSBoWebS8PWWbMK9Qb/zNzc+ayfGjVSV6LQaSRc/MRWMmQ==","_resolved":"/tmp/ed7f9eaf191160258eb0558b3feee614/1001-digital-resolve-metadata-1.0.3.tgz","_from":"file:1001-digital-resolve-metadata-1.0.3.tgz","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-lYdw0xNjSUS+2j4OCxkNm3Lizf7drq54I7uZBL0txSBoWebS8PWWbMK9Qb/zNzc+ayfGjVSV6LQaSRc/MRWMmQ==","shasum":"a7d2050e2493b9c1bd03ef0ee6edace4d6abd128","tarball":"https://registry.npmjs.org/@1001-digital/resolve-metadata/-/resolve-metadata-1.0.3.tgz","fileCount":13,"unpackedSize":23039,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDOX1AwcH8U9jX4VTTdrobq/ClAzqKuqh5uGdmmxZDl9QIhAN6fKcy6Gxaclxdl/SCUi1TOoMfr/DVJECWeXqfZGYMV"}]},"_npmUser":{"name":"jwahdatehagh","email":"jalil@1001.digital"},"directories":{},"maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/resolve-metadata_1.0.3_1776854010284_0.6349481199165301"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-21T14:59:05.807Z","modified":"2026-04-22T10:33:30.555Z","0.1.0":"2026-03-21T14:59:06.031Z","1.0.0":"2026-03-21T15:05:04.737Z","1.0.1":"2026-03-25T19:33:53.899Z","1.0.2":"2026-03-25T19:59:48.902Z","1.0.3":"2026-04-22T10:33:30.416Z"},"bugs":{"url":"https://github.com/1001-digital/resolve-metadata/issues"},"license":"MIT","homepage":"https://github.com/1001-digital/resolve-metadata#readme","repository":{"type":"git","url":"git+https://github.com/1001-digital/resolve-metadata.git"},"description":"Normalize NFT token and contract metadata into a strict typed schema.","maintainers":[{"name":"jwahdatehagh","email":"jalil@1001.digital"}],"readme":"# @1001-digital/resolve-metadata\n\nNormalize NFT metadata JSON (ERC-721, ERC-1155, contractURI) into a strict, typed schema. Pairs with [`@1001-digital/dweb-fetch`](https://github.com/1001-digital/dweb-fetch) — this package standardizes the JSON, dweb-fetch resolves the links.\n\n## Usage\n\n```ts\nimport { resolveTokenMetadata, resolveContractMetadata } from '@1001-digital/resolve-metadata'\n\n// Raw metadata from a tokenURI / uri response\nconst raw = {\n  name: 'Cool NFT #42',\n  description: 'A very cool NFT',\n  image: 'https://gateway.pinata.cloud/ipfs/QmImage...',\n  animation_url: 'https://arweave.net/txVideo...',\n  background_color: '#FF0000',\n  attributes: [\n    { trait_type: 'Color', value: 'Blue' },\n    { trait_type: 'Level', value: '7' },\n  ],\n}\n\nconst metadata = resolveTokenMetadata(raw)\n// {\n//   name: 'Cool NFT #42',\n//   description: 'A very cool NFT',\n//   image: 'ipfs://QmImage...',            ← gateway URL → protocol URI\n//   animation_url: 'ar://txVideo...',       ← gateway URL → protocol URI\n//   external_url: null,\n//   background_color: 'ff0000',             ← normalized hex, no #\n//   attributes: [\n//     { trait_type: 'Color', value: 'Blue' },\n//     { trait_type: 'Level', value: 7 },    ← numeric string → number\n//   ],\n//   decimals: null,\n//   properties: null,\n//   localization: null,\n//   extra: {},\n// }\n\n// Contract-level metadata from contractURI\nconst contract = resolveContractMetadata({\n  name: 'Cool Collection',\n  description: 'A collection of cool NFTs',\n  image: 'https://ipfs.io/ipfs/QmLogo...',\n  banner_image: 'https://arweave.net/txBanner...',\n  external_link: 'https://coolcollection.xyz',\n  collaborators: ['0xABC...', '0xDEF...'],\n  seller_fee_basis_points: 250,\n})\n// {\n//   name: 'Cool Collection',\n//   description: 'A collection of cool NFTs',\n//   image: 'ipfs://QmLogo...',\n//   banner_image: 'ar://txBanner...',\n//   featured_image: null,\n//   external_link: 'https://coolcollection.xyz',\n//   collaborators: ['0xABC...', '0xDEF...'],\n//   extra: { seller_fee_basis_points: 250 },\n// }\n```\n\n## URI Normalization\n\nGateway URLs are converted to protocol URIs. Links are not resolved — use `dweb-fetch` for that.\n\n```ts\nimport { normalizeUri } from '@1001-digital/resolve-metadata'\n\nnormalizeUri('https://gateway.pinata.cloud/ipfs/QmXxx')  // → 'ipfs://QmXxx'\nnormalizeUri('https://bafyABC.ipfs.nftstorage.link')     // → 'ipfs://bafyABC'\nnormalizeUri('https://ipfs.io/ipns/example.eth')          // → 'ipns://example.eth'\nnormalizeUri('https://arweave.net/txId123')               // → 'ar://txId123'\nnormalizeUri('QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz...')  // → 'ipfs://QmYwAPJzv5...'\nnormalizeUri('ipfs://QmXxx')                              // → 'ipfs://QmXxx' (passthrough)\nnormalizeUri('https://example.com/image.png')             // → 'https://example.com/image.png' (passthrough)\n```\n\nIPFS gateways are detected by path (`/ipfs/`, `/ipns/`) and subdomain (`.ipfs.`, `.ipns.`) patterns, so any gateway works without a hardcoded list. Arweave gateways are matched by known hostnames (`arweave.net`, `ar-io.dev`, `ar-io.net`, `arweave.dev`).\n\n## What Gets Normalized\n\n### Token Metadata (ERC-721 + ERC-1155)\n\n| What | How |\n|---|---|\n| URI fields (`image`, `animation_url`, `external_url`) | Gateway URLs → protocol URIs |\n| `background_color` | Strips `#`, expands 3-char to 6-char, lowercases |\n| Attributes `[{ trait_type, value }]` | Unified from multiple formats (see below) |\n| Numeric string attribute values (`\"42\"`) | Coerced to numbers |\n| Field aliases (`image_url`, `image_data`, `animation`, `external_link`) | Mapped to canonical names |\n| ERC-1155 fields (`decimals`, `properties`, `localization`) | Extracted when present |\n| Unknown fields | Preserved in `extra` |\n\n### Contract Metadata (ERC-7572 / contractURI)\n\n| What | How |\n|---|---|\n| URI fields (`image`, `banner_image`, `featured_image`) | Gateway URLs → protocol URIs |\n| `collaborators` | Validated as string array |\n| Field alias (`external_url`) | Mapped to `external_link` |\n| Unknown fields | Preserved in `extra` |\n\n### Attribute Format Handling\n\nAll of these are normalized to `{ trait_type: string, value: string | number }`:\n\n```ts\n// Standard (ERC-721)\n[{ trait_type: 'Color', value: 'Blue' }]\n\n// With display hints\n[{ trait_type: 'Level', value: 5, display_type: 'number', max_value: 10 }]\n\n// Rarible-style (name instead of trait_type)\n[{ name: 'Color', value: 'Blue' }]\n\n// Plain object\n{ Color: 'Blue', Rarity: 'Legendary' }\n```\n\n## API\n\n### `resolveTokenMetadata(input: unknown): TokenMetadata`\n\nNormalizes raw token metadata JSON. Accepts any value — returns typed output with `null` for missing fields, empty arrays for missing collections, and unknown fields in `extra`.\n\n### `resolveContractMetadata(input: unknown): ContractMetadata`\n\nNormalizes raw contract/collection metadata JSON. Same guarantees as above.\n\n### `normalizeUri(uri: string): string`\n\nConverts gateway URLs to protocol URIs. Returns the input unchanged if it is not a recognized gateway URL.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}