{"_id":"@0xftm/fns-normalize","name":"@0xftm/fns-normalize","dist-tags":{"latest":"1.9.0"},"versions":{"1.9.0":{"name":"@0xftm/fns-normalize","version":"1.9.0","description":"Compact ES6 Fantom Name Service (FNS) Name Normalizer","keywords":["FNS","Fantom","UTS-46","UTS-51","IDNA","Normalize","NFC","NFD"],"type":"module","exports":{".":{"require":"./dist/index.cjs","import":"./dist/index.js","types":"./dist/index.d.ts"},"./xnf":{"require":"./dist/index-xnf.cjs","import":"./dist/index-xnf.js","types":"./dist/index.d.ts"}},"main":"./dist/index.js","repository":{"type":"git","url":"git+https://github.com/adraffy/ens-normalize.js.git"},"license":"MIT","bugs":{"url":"https://github.com/adraffy/ens-normalize.js/issues"},"homepage":"https://github.com/adraffy/ens-normalize.js#readme","author":{"name":"raffy.eth","email":"raffy@me.com","url":"http://raffy.antistupid.com"},"scripts":{"derive":"node derive/make.js","make":"node src/make.js","validate":"node validate/make.js","test":"node test/validate.js","build":"rollup -c","rebuild":"npm run derive && npm run make && npm run validate && npm run test && npm run build","order":"node validate/dump-group-order.js save && npm run rebuild"},"devDependencies":{"@rollup/plugin-node-resolve":"^13.3.0","rollup":"^2.77.1","rollup-plugin-terser":"^7.0.2"},"_id":"@0xftm/fns-normalize@1.9.0","gitHead":"de0ed40b8c65db2d9cae394054e949ad0dfcbf5f","types":"./dist/index.d.ts","_nodeVersion":"18.18.1","_npmVersion":"9.8.1","dist":{"integrity":"sha512-xIYXtbFpSiQPz82K0ePhuxnuqskzKVbYazJiXocQKitt+No5x9uTBBAgLFpVbdu7kdV1umQQ+aiT4G1Wzri4tQ==","shasum":"bf3ccf9cf5d83f97abbdc9a92d70db467fd2388d","tarball":"https://registry.npmjs.org/@0xftm/fns-normalize/-/fns-normalize-1.9.0.tgz","fileCount":13,"unpackedSize":424212,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAQ1ldHo9Z/0fTdBRz6erpEA5HqxhL2qyzq3EeNLKAFAIgWQgOv3VC3dPaS2zalKfGdz2RHeOqgqwpGdU4KicoZw0="}]},"_npmUser":{"name":"mr0xftm","email":"aiairdrop121@gmail.com"},"directories":{},"maintainers":[{"name":"mr0xftm","email":"aiairdrop121@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/fns-normalize_1.9.0_1699628635583_0.9371580255605256"},"_hasShrinkwrap":false}},"time":{"created":"2023-11-10T15:03:55.500Z","1.9.0":"2023-11-10T15:03:55.858Z","modified":"2023-11-10T15:03:56.164Z"},"maintainers":[{"name":"mr0xftm","email":"aiairdrop121@gmail.com"}],"description":"Compact ES6 Fantom Name Service (FNS) Name Normalizer","homepage":"https://github.com/adraffy/ens-normalize.js#readme","keywords":["FNS","Fantom","UTS-46","UTS-51","IDNA","Normalize","NFC","NFD"],"repository":{"type":"git","url":"git+https://github.com/adraffy/ens-normalize.js.git"},"author":{"name":"raffy.eth","email":"raffy@me.com","url":"http://raffy.antistupid.com"},"bugs":{"url":"https://github.com/adraffy/ens-normalize.js/issues"},"license":"MIT","readme":"# ens-normalize.js\n0-dependancy Compact ES6 [Ethereum Name Service](https://ens.domains/) (FNS) Name Normalizer that works in the browser.\n\n* Follows [FNS Name Normalization Standard](https://github.com/adraffy/ensip-norm/blob/main/draft.md)\n* [Passes **100%**](https://adraffy.github.io/ens-normalize.js/test/validate.html) Validation Tests\n* Custom [`NFC`](https://unicode.org/reports/tr15/) Implementation (or use native)\n\t* [Passes **100%**](https://adraffy.github.io/ens-normalize.js/test/report-nf.html) Unicode `15.0.0` [Normalization Tests](https://www.unicode.org/Public/15.0.0/ucd/NormalizationTest.txt)\n* Minified File Sizes: \n\t* [`27KB`](./dist/index-xnf.min.js) — native `NFC` via [nf-native.js](./src/nf-native.js) using `String.normalize()`\n\t* [`36KB` **Default** ](./dist/index.min.js) — custom `NFC` via [nf.js](./src/nf.js)\n\t* [`42KB`](./dist/all.min.js) *Everything!* — custom `NFC` + sub-libraries: [parts.js](./src/parts.js), [utils.js](./src/utils.js)\n* Included Apps:\n\t* [**Resolver Demo**](https://adraffy.github.io/ens-normalize.js/test/resolver.html)\n\t* [Character Viewer](https://adraffy.github.io/ens-normalize.js/test/chars.html)\n\t* [Supported Emoji](https://adraffy.github.io/ens-normalize.js/test/emoji.html)\n\t* [Confused Explainer](https://adraffy.github.io/ens-normalize.js/test/confused.html)\n* External Apps:\n\t* [Recent Registrations](https://raffy.antistupid.com/eth/ens-regs.html)\n\t* [Emoji Frequency Explorer](https://raffy.antistupid.com/eth/ens-emoji-freq.html)\n\t* [FNS+NFT Matcher](https://raffy.antistupid.com/eth/ens-nft-matcher.html)\n\t* [Batch Resolver](https://raffy.antistupid.com/eth/ens-batch-resolver.html)\n\t* [Punycode Coder](https://adraffy.github.io/punycode.js/test/demo.html)\n* [Breakdown Reports:](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/)\n\t* [Disallowed Characters](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/disallowed.html)\n\t* [Different Norm](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/diff.html)\n\t* [Illegal Mixtures](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/mixtures.html)\n\t* [Whole-script Confusables](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/wholes.html)\n\t* [Illegal Placement](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/placement.html)\n\t* [Non-spacing Marks](https://adraffy.github.io/ens-norm-tests/test-breakdown/output/nsm.html)\n\n```Javascript\nimport {ens_normalize} from '@adraffy/ens-normalize'; // or require()\n// npm i @adraffy/ens-normalize\n// browser: https://cdn.jsdelivr.net/npm/@adraffy/ens-normalize@latest/dist/index.min.js\n\n// *** ALL errors thrown by this library are safe to print ***\n// - characters are shown as {HEX} if should_escape()\n// - potentially different bidi directions inside \"quotes\"\n// - 200E is used near \"quotes\" to prevent spillover\n// - an \"error type\" can be extracted by slicing up to the first (:)\n\n// string -> string\n// throws on invalid names\n// output ready for namehash\nlet normalized = ens_normalize('RaFFY🚴‍♂️.eTh');\n// => \"raffy🚴‍♂.eth\"\n\n// note: does not enforce .eth TLD 3-character minimum\n```\n\nFormat names with fully-qualified emoji:\n```Javascript\n// works like ens_normalize()\n// output ready for display\nlet pretty = ens_beautify('1⃣2⃣.eth'); \n// => \"1️⃣2️⃣.eth\"\n\n// note: normalization is unchanged:\n// ens_normalize(ens_beautify(x)) == ens_normalize(x)\n```\n\nNormalize name fragments for [substring search](./test/fragment.js):\n```Javascript\n// these fragments fail ens_normalize() \n// but will normalize fine as fragments\nlet frag1 = ens_normalize_fragment('AB--');    // error: label ext\nlet frag2 = ens_normalize_fragment('\\u{303}'); // error: leading cm\nlet frag3 = ens_normalize_fragment('οо');      // error: mixture\n```\n\nInput-based tokenization:\n```Javascript\n// string -> Token[]\n// never throws\nlet tokens = ens_tokenize('_R💩\\u{FE0F}a\\u{FE0F}\\u{304}\\u{AD}./');\n// [\n//     { type: 'valid', cp: [ 95 ] }, // valid (as-is)\n//     {\n//         type: 'mapped', \n//         cp: 82,         // input\n//         cps: [ 114 ]    // output\n//     }, \n//     { \n//         type: 'emoji',\n//         input: Emoji(2) [ 128169, 65039 ],  // input \n//         emoji: [ 128169, 65039 ],           // fully-qualified\n//         cps: Emoji(1) [ 128169 ]            // output (normalized)\n//     },\n//     {\n//         type: 'nfc',\n//         input: [ 97, 772 ],  // input  (before nfc)\n//         tokens0: [           // tokens (before nfc)\n//             { type: 'valid', cps: [ 97 ] },\n//             { type: 'ignored', cp: 65039 },\n//             { type: 'valid', cps: [ 772 ] }\n//         ],\n//         cps: [ 257 ],        // output (after nfc)\n//         tokens: [            // tokens (after nfc)\n//             { type: 'valid', cps: [ 257 ] }\n//         ]\n//     },\n//     { type: 'ignored', cp: 173 },\n//     { type: 'stop', cp: 46 },\n//     { type: 'disallowed', cp: 47 }\n// ]\n\n// note: if name is normalizable, then:\n// ens_normalize(ens_tokenize(name).map(token => {\n//     ** convert valid/mapped/nfc/stop to string **\n// }).join('')) == ens_normalize(name)\n```\n\nOutput-based tokenization:\n```Javascript\n// string -> Label[]\n// never throws\nlet labels = ens_split('💩Raffy.eth_');\n// [\n//   {\n//     input: [ 128169, 82, 97, 102, 102, 121 ],  \n//     offset: 0, // index of codepoint, not substring index!\n//                // (corresponding length can be inferred from input)\n//     tokens: [\n//       Emoji(2) [ 128169, 65039 ],   // emoji\n//       [ 114, 97, 102, 102, 121 ]    // nfc-text\n//     ],\n//     output: [ 128169, 114, 97, 102, 102, 121 ],\n//     emoji: true,\n//     type: 'Latin'\n//   },\n//   {\n//     input: [ 101, 116, 104, 95 ],\n//     offset: 7,\n//     tokens: [ [ 101, 116, 104, 95 ] ],\n//     output: [ 101, 116, 104, 95 ],\n//     error: Error('underscore allowed only at start')\n//   }\n// ]\n```\n\nGenerate a sorted array of supported emoji codepoints:\n```Javascript\n// () -> number[][]\nconsole.log(ens_emoji());\n// [\n//     [ 2764 ],\n//     [ 128169, 65039 ],\n//     [ 128105, 127997, 8205, 9877, 65039 ],\n//     ...\n// ]\n```\n\nDetermine if a character shouldn't be printed directly:\n```Javascript\n// number -> bool\nconsole.log(should_escape(0x202E)); // eg. RIGHT-TO-LEFT OVERRIDE => true\n```\n\nDetermine if a character is a combining mark:\n```Javascript\n// number -> bool\nconsole.log(is_combining_mark(0x20E3)); // eg. COMBINING ENCLOSING KEYCAP => true\n```\n\n## Build\n\n* `git clone` this repo, then `npm install` \n* Follow instructions in [/derive/](./derive/) to generate data files\n\t* `npm run derive` \n\t\t* [spec.json](./derive/output/spec.json)\n\t\t* [nf.json](./derive/output/nf.json)\n\t\t* [nf-tests.json](./derive/output/nf-tests.json)\n* `npm run make` — compress data files from `/derive/output/`\n\t* [include-ens.js](./src/include-ens.js)\n\t* [include-nf.js](./src/include-nf.js)\n* Follow instructions in [/validate/](./validate/) to generate validation tests\n\t* `npm run validate`\n\t\t* [tests.json](./validate/tests.json)\n* `npm run test` — perform validation tests\n* `npm run build` — create `/dist/`\n* `npm run rebuild` — run all the commands above\n* `npm run order` — create optimal group ordering and rebuild again\n","readmeFilename":"README.md"}