From 8cb405db7d4a4d56d4b5f0fd30a44440e1e8b9b9 Mon Sep 17 00:00:00 2001 From: Lucas <lucasnrgaard@gmail.com> Date: Sun, 16 Mar 2025 06:42:05 +0100 Subject: [PATCH 1/2] feat: add emoji data handling and export route - Introduced a new script to fetch and copy emoji data from a remote source. - Updated `wrangler.jsonc` to include a build command for the emoji data. - Added a new export route to serve emoji data based on version. - Updated `.gitignore` to exclude the emoji data directory. - Enhanced `package.json` with new dependencies and build scripts. --- .gitignore | 1 + package.json | 3 + pnpm-lock.yaml | 204 +++++++++++++++++++++++++++++++++++++ scripts/copy-emoji-data.ts | 50 +++++++++ src/index.ts | 2 + src/routes/export.ts | 27 +++++ wrangler.jsonc | 11 ++ 7 files changed, 298 insertions(+) create mode 100644 scripts/copy-emoji-data.ts create mode 100644 src/routes/export.ts diff --git a/.gitignore b/.gitignore index 12f99e3..0d5641c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules .wrangler dist .dev.vars +.emoji-data diff --git a/package.json b/package.json index 0e725ac..dee4267 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "wrangler dev", "build": "wrangler deploy --dry-run --outdir=dist", "build:openapi": "tsx ./scripts/build-openapi", + "build:emoji-data": "tsx ./scripts/copy-emoji-data", "deploy": "wrangler deploy", "test": "pnpm vitest --run", "test:watch": "pnpm vitest", @@ -26,8 +27,10 @@ "@cloudflare/vitest-pool-workers": "^0.8.0", "@luxass/eslint-config": "^4.16.0", "@stoplight/spectral-cli": "^6.14.3", + "@types/tar": "^6.1.13", "eslint": "^9.22.0", "eslint-plugin-format": "^1.0.1", + "tar": "^7.4.3", "tsx": "^4.19.3", "typescript": "^5.8.2", "vitest": "^3.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e86d3e..37d0b92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,12 +33,18 @@ importers: '@stoplight/spectral-cli': specifier: ^6.14.3 version: 6.14.3 + '@types/tar': + specifier: ^6.1.13 + version: 6.1.13 eslint: specifier: ^9.22.0 version: 9.22.0 eslint-plugin-format: specifier: ^1.0.1 version: 1.0.1(eslint@9.22.0) + tar: + specifier: ^7.4.3 + version: 7.4.3 tsx: specifier: ^4.19.3 version: 4.19.3 @@ -755,6 +761,14 @@ packages: '@internationalized/number@3.6.0': resolution: {integrity: sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -862,6 +876,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1218,6 +1236,9 @@ packages: '@types/sarif@2.1.7': resolution: {integrity: sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==} + '@types/tar@6.1.13': + resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -1481,10 +1502,18 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} @@ -1611,6 +1640,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + ci-info@4.1.0: resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==} engines: {node: '>=8'} @@ -1782,12 +1815,18 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + electron-to-chromium@1.5.111: resolution: {integrity: sha512-vJyJlO95wQRAw6K2ZGF/8nol7AcbCOnp8S6H91mwOOBbXoS9seDBYxCTPYAFsvXLxl3lc0jLXXe9GLxC4nXVog==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} @@ -2128,6 +2167,10 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -2198,6 +2241,10 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -2503,6 +2550,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2793,6 +2843,23 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} @@ -2884,6 +2951,9 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.11: resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} @@ -2928,6 +2998,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} @@ -3110,6 +3184,10 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + rollup@2.79.2: resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} engines: {node: '>=10.0.0'} @@ -3194,6 +3272,10 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + simple-eval@1.0.1: resolution: {integrity: sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==} engines: {node: '>=12'} @@ -3257,6 +3339,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string.prototype.trim@1.2.10: resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} engines: {node: '>= 0.4'} @@ -3280,6 +3366,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-indent@4.0.0: resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} engines: {node: '>=12'} @@ -3320,6 +3410,10 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -3673,6 +3767,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -3696,6 +3794,10 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml-eslint-parser@1.3.0: resolution: {integrity: sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==} engines: {node: ^14.17.0 || >=16.0.0} @@ -4328,6 +4430,19 @@ snapshots: dependencies: '@swc/helpers': 0.5.15 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.0': {} @@ -4459,6 +4574,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@pkgjs/parseargs@0.11.0': + optional: true + '@pkgr/core@0.1.1': {} '@popperjs/core@2.11.8': {} @@ -5135,6 +5253,11 @@ snapshots: '@types/sarif@2.1.7': {} + '@types/tar@6.1.13': + dependencies: + '@types/node': 22.13.9 + minipass: 4.2.8 + '@types/unist@3.0.3': {} '@types/urijs@1.19.25': {} @@ -5441,10 +5564,14 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.1.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.1: {} + are-docs-informative@0.0.2: {} argparse@2.0.1: {} @@ -5566,6 +5693,8 @@ snapshots: check-error@2.1.1: {} + chownr@3.0.0: {} + ci-info@4.1.0: {} cjs-module-lexer@1.4.3: {} @@ -5727,10 +5856,14 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + electron-to-chromium@1.5.111: {} emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 @@ -6261,6 +6394,11 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -6342,6 +6480,15 @@ snapshots: glob-to-regexp@0.4.1: {} + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -6700,6 +6847,12 @@ snapshots: isexe@2.0.0: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -7157,6 +7310,17 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minipass@4.2.8: {} + + minipass@7.1.2: {} + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + mkdirp@3.0.1: {} + mlly@1.7.4: dependencies: acorn: 8.14.0 @@ -7253,6 +7417,8 @@ snapshots: dependencies: p-limit: 3.1.0 + package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.11: dependencies: quansync: 0.2.8 @@ -7290,6 +7456,11 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + path-to-regexp@6.3.0: {} pathe@2.0.3: {} @@ -7512,6 +7683,10 @@ snapshots: reusify@1.1.0: {} + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + rollup@2.79.2: optionalDependencies: fsevents: 2.3.3 @@ -7661,6 +7836,8 @@ snapshots: siginfo@2.0.0: {} + signal-exit@4.1.0: {} + simple-eval@1.0.1: dependencies: jsep: 1.4.0 @@ -7720,6 +7897,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 @@ -7758,6 +7941,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-indent@4.0.0: dependencies: min-indent: 1.0.1 @@ -7789,6 +7976,15 @@ snapshots: tapable@2.2.1: {} + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + text-table@0.2.0: {} tinybench@2.9.0: {} @@ -8197,6 +8393,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} ws@8.18.0: {} @@ -8205,6 +8407,8 @@ snapshots: y18n@5.0.8: {} + yallist@5.0.0: {} + yaml-eslint-parser@1.3.0: dependencies: eslint-visitor-keys: 3.4.3 diff --git a/scripts/copy-emoji-data.ts b/scripts/copy-emoji-data.ts new file mode 100644 index 0000000..012a7b4 --- /dev/null +++ b/scripts/copy-emoji-data.ts @@ -0,0 +1,50 @@ +import type { TarOptionsWithAliases } from "tar"; +import { existsSync } from "node:fs"; +import { mkdir, writeFile } from "node:fs/promises"; +import path from "node:path"; +import process from "node:process"; +import { extract } from "tar"; + +const root = path.resolve(import.meta.dirname, "../"); + +async function run() { + if (!existsSync(path.join(root.toString(), "./node_modules/.emoji-data"))) { + await mkdir(path.join(root.toString(), "./node_modules/.emoji-data"), { recursive: true }); + } + + if (!existsSync(path.join(root.toString(), "./.emoji-data"))) { + await mkdir(path.join(root.toString(), "./.emoji-data"), { recursive: true }); + } + + const res = await fetch("https://github.com/mojisdev/emoji-data/archive/refs/heads/main.tar.gz"); + + if (!res.ok) { + throw new Error(`Failed to fetch emoji-data: ${res.statusText}`); + } + + const blob = await res.blob(); + + // eslint-disable-next-line node/prefer-global/buffer + const buffer = Buffer.from(await blob.arrayBuffer()); + await writeFile(path.join(root.toString(), "./node_modules/.emoji-data/emoji-data.tar.gz"), buffer); + + await extract(<TarOptionsWithAliases>{ + file: path.join(root.toString(), "./node_modules/.emoji-data/emoji-data.tar.gz"), + cwd: path.join(root.toString(), "./.emoji-data"), + onentry(entry) { + entry.path = entry.path.split("/").splice(1).join("/"); + if (entry.path.startsWith(`data/`)) { + // Rewrite path + entry.path = entry.path.slice("data".length); + } else { + // Skip + entry.path = ""; + } + }, + }); +} + +run().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/src/index.ts b/src/index.ts index f3866b6..c919c8a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import { apiReference } from "@scalar/hono-api-reference"; import { env } from "hono/adapter"; import { HTTPException } from "hono/http-exception"; import { buildOpenApiConfig } from "./openapi"; +import { EXPORT_ROUTER } from "./routes/export"; import { GATEWAY_GITHUB_ROUTER } from "./routes/gateway_github"; import { RANDOM_EMOJI_ROUTER } from "./routes/random-emoji"; import { V1_CATEGORIES_ROUTER } from "./routes/v1_categories"; @@ -15,6 +16,7 @@ app.route("/", V1_VERSIONS_ROUTER); app.route("/", V1_CATEGORIES_ROUTER); app.route("/", GATEWAY_GITHUB_ROUTER); app.route("/", RANDOM_EMOJI_ROUTER); +app.route("/export", EXPORT_ROUTER); app.get( "/scalar", diff --git a/src/routes/export.ts b/src/routes/export.ts new file mode 100644 index 0000000..c88189b --- /dev/null +++ b/src/routes/export.ts @@ -0,0 +1,27 @@ +import { Hono } from "hono"; + +export const EXPORT_ROUTER = new Hono(); + +EXPORT_ROUTER.get("/:version", async (c) => { + const version = c.req.param("version"); + + async function findCorrectVersion(version: string) { + if (version === "16.0") { + return await import(`../../.emoji-data/v16.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "17.0") { + return await import(`../../.emoji-data/v17.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + throw new Error(`Unsupported version: ${version}`); + } + + const mod = await findCorrectVersion(version); + + return c.json(mod); +}); diff --git a/wrangler.jsonc b/wrangler.jsonc index 7425edb..e1cad37 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -9,6 +9,17 @@ }, "enabled": true }, + "build": { + "command": "pnpm run build:emoji-data" + }, + "rules": [ + { + "type": "ESModule", + "globs": [ + ".emoji-data/**" + ] + } + ], "vars": { "GITHUB_TOKEN": "", "API_VERSION": "x.y.z" From f19ae14c63930fac4d8719c892dd29244df00290 Mon Sep 17 00:00:00 2001 From: Lucas <lucasnrgaard@gmail.com> Date: Sun, 16 Mar 2025 06:46:30 +0100 Subject: [PATCH 2/2] does this work? --- src/routes/export.ts | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/routes/export.ts b/src/routes/export.ts index c88189b..8f33385 100644 --- a/src/routes/export.ts +++ b/src/routes/export.ts @@ -6,6 +6,84 @@ EXPORT_ROUTER.get("/:version", async (c) => { const version = c.req.param("version"); async function findCorrectVersion(version: string) { + if (version === "1.0") { + return await import(`../../.emoji-data/v1.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "2.0") { + return await import(`../../.emoji-data/v2.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "3.0") { + return await import(`../../.emoji-data/v3.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "4.0") { + return await import(`../../.emoji-data/v4.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "5.0") { + return await import(`../../.emoji-data/v5.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "11.0") { + return await import(`../../.emoji-data/v11.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "12.0") { + return await import(`../../.emoji-data/v12.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "12.1") { + return await import(`../../.emoji-data/v12.1/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "13.0") { + return await import(`../../.emoji-data/v13.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "13.1") { + return await import(`../../.emoji-data/v13.1/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "14.0") { + return await import(`../../.emoji-data/v14.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "15.0") { + return await import(`../../.emoji-data/v15.0/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + + if (version === "15.1") { + return await import(`../../.emoji-data/v15.1/groups.json`, { + with: { type: "json" }, + }).then((mod) => mod.default); + } + if (version === "16.0") { return await import(`../../.emoji-data/v16.0/groups.json`, { with: { type: "json" },