build: update infra (#652)

pull/653/head
Ika 2023-07-22 19:19:36 +08:00 committed by GitHub
parent ef5ce591cb
commit 4896810dcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3158 additions and 6086 deletions

1
.gitattributes vendored
View File

@ -1 +0,0 @@
* text eol=lf

View File

@ -0,0 +1,13 @@
name: setup
description: setup
runs:
using: composite
steps:
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
with:
cache: pnpm
node-version: '18'
registry-url: 'https://registry.npmjs.org'
- run: pnpm install
shell: bash

View File

@ -1,24 +0,0 @@
name: Lint
on:
- push
- pull_request
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2-beta
with:
node-version: "16"
- name: Install Dependencies
run: yarn
- name: Lint
run: yarn lint

View File

@ -1,24 +1,27 @@
name: Test
on:
- push
- pull_request
push:
branches:
- master
pull_request:
branches:
- master
jobs:
test:
name: Test
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2-beta
with:
node-version: "16"
- name: Install Dependencies
run: yarn
- name: Test
run: yarn test --ci
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: pnpm run lint
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: pnpm run check
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: pnpm run test

View File

@ -2,28 +2,16 @@ name: Up to Date
on:
schedule:
- cron: "0 0 * * *"
- cron: '0 0 * * *'
jobs:
update:
name: Update
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v2-beta
with:
node-version: "16"
- name: Install Dependencies
run: yarn
- name: Generate Cheat Sheet
run: yarn generate
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: pnpm run generate
- name: Push New Cheat Sheet to Updated Branch
run: |

3
.gitignore vendored
View File

@ -1 +1,2 @@
node_modules/
/.vscode/
/node_modules/

2
.prettierignore 100644
View File

@ -0,0 +1,2 @@
/pnpm-lock.yaml
/README.md

3
.prettierrc.yml 100644
View File

@ -0,0 +1,3 @@
arrowParens: avoid
semi: false
singleQuote: true

View File

@ -1,5 +1,6 @@
{
"name": "emoji-cheat-sheet",
"type": "module",
"version": "0.0.0-dev",
"private": true,
"repository": "ikatyang/emoji-cheat-sheet",
@ -11,25 +12,21 @@
},
"license": "MIT",
"scripts": {
"lint": "tslint -p . --type-check",
"test": "jest",
"generate": "node ./scripts/generate.js > ./README.md"
},
"dependencies": {
"request": "^2.88.0"
"lint": "prettier --check .",
"check": "tsc --noEmit",
"test": "vitest",
"generate": "vite-node ./scripts/generate.ts -- run > ./README.md"
},
"devDependencies": {
"@types/jest": "24.0.18",
"@types/node": "12.7.4",
"@types/request": "2.48.2",
"jest": "24.9.0",
"jest-playback": "2.0.2",
"prettier": "1.17.0",
"tslint": "5.19.0",
"tslint-plugin-prettier": "2.0.1",
"typescript": "3.6.2"
"jest-playback": "4.0.0",
"prettier": "3.0.0",
"typescript": "5.1.6",
"vite": "4.4.6",
"vite-node": "0.33.0",
"vitest": "0.33.0"
},
"engines": {
"node": ">= 12"
}
"node": ">=18"
},
"packageManager": "pnpm@8.6.6"
}

762
pnpm-lock.yaml 100644
View File

@ -0,0 +1,762 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
devDependencies:
jest-playback:
specifier: 4.0.0
version: 4.0.0
prettier:
specifier: 3.0.0
version: 3.0.0
typescript:
specifier: 5.1.6
version: 5.1.6
vite:
specifier: 4.4.6
version: 4.4.6(@types/node@20.4.3)
vite-node:
specifier: 0.33.0
version: 0.33.0(@types/node@20.4.3)
vitest:
specifier: 0.33.0
version: 0.33.0
packages:
/@esbuild/android-arm64@0.18.15:
resolution: {integrity: sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm@0.18.15:
resolution: {integrity: sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-x64@0.18.15:
resolution: {integrity: sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-arm64@0.18.15:
resolution: {integrity: sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-x64@0.18.15:
resolution: {integrity: sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-arm64@0.18.15:
resolution: {integrity: sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-x64@0.18.15:
resolution: {integrity: sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm64@0.18.15:
resolution: {integrity: sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm@0.18.15:
resolution: {integrity: sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ia32@0.18.15:
resolution: {integrity: sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64@0.18.15:
resolution: {integrity: sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-mips64el@0.18.15:
resolution: {integrity: sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ppc64@0.18.15:
resolution: {integrity: sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-riscv64@0.18.15:
resolution: {integrity: sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-s390x@0.18.15:
resolution: {integrity: sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-x64@0.18.15:
resolution: {integrity: sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/netbsd-x64@0.18.15:
resolution: {integrity: sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/openbsd-x64@0.18.15:
resolution: {integrity: sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/sunos-x64@0.18.15:
resolution: {integrity: sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-arm64@0.18.15:
resolution: {integrity: sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-ia32@0.18.15:
resolution: {integrity: sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-x64@0.18.15:
resolution: {integrity: sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@jest/schemas@29.6.0:
resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@sinclair/typebox': 0.27.8
dev: true
/@jridgewell/sourcemap-codec@1.4.15:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
dev: true
/@mswjs/interceptors@0.23.0:
resolution: {integrity: sha512-JytvDa7pBbxXvCTXBYQs+0eE6MqxpqH/H4peRNY6zVAlvJ6d/hAWLHAef1D9lWN4zuIigN0VkakGOAUrX7FWLg==}
engines: {node: '>=18'}
dependencies:
'@open-draft/deferred-promise': 2.1.0
'@open-draft/logger': 0.3.0
'@open-draft/until': 2.1.0
headers-polyfill: 3.1.2
outvariant: 1.4.0
strict-event-emitter: 0.5.0
dev: true
/@open-draft/deferred-promise@2.1.0:
resolution: {integrity: sha512-Rzd5JrXZX8zErHzgcGyngh4fmEbSHqTETdGj9rXtejlqMIgXFlyKBA7Jn1Xp0Ls0M0Y22+xHcWiEzbmdWl0BOA==}
dev: true
/@open-draft/logger@0.3.0:
resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==}
dependencies:
is-node-process: 1.2.0
outvariant: 1.4.0
dev: true
/@open-draft/until@2.1.0:
resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
dev: true
/@sinclair/typebox@0.27.8:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true
/@types/chai-subset@1.3.3:
resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==}
dependencies:
'@types/chai': 4.3.5
dev: true
/@types/chai@4.3.5:
resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==}
dev: true
/@types/node@20.4.3:
resolution: {integrity: sha512-Yu3+r4Mn/iY6Mf0aihncZQ1qOjOUrCiodbHHY1hds5O+7BbKp9t+Li7zLO13zO8j9L2C6euz8xsYQP0rjGvVXw==}
dev: true
/@vitest/expect@0.33.0:
resolution: {integrity: sha512-sVNf+Gla3mhTCxNJx+wJLDPp/WcstOe0Ksqz4Vec51MmgMth/ia0MGFEkIZmVGeTL5HtjYR4Wl/ZxBxBXZJTzQ==}
dependencies:
'@vitest/spy': 0.33.0
'@vitest/utils': 0.33.0
chai: 4.3.7
dev: true
/@vitest/runner@0.33.0:
resolution: {integrity: sha512-UPfACnmCB6HKRHTlcgCoBh6ppl6fDn+J/xR8dTufWiKt/74Y9bHci5CKB8tESSV82zKYtkBJo9whU3mNvfaisg==}
dependencies:
'@vitest/utils': 0.33.0
p-limit: 4.0.0
pathe: 1.1.1
dev: true
/@vitest/snapshot@0.33.0:
resolution: {integrity: sha512-tJjrl//qAHbyHajpFvr8Wsk8DIOODEebTu7pgBrP07iOepR5jYkLFiqLq2Ltxv+r0uptUb4izv1J8XBOwKkVYA==}
dependencies:
magic-string: 0.30.1
pathe: 1.1.1
pretty-format: 29.6.1
dev: true
/@vitest/spy@0.33.0:
resolution: {integrity: sha512-Kv+yZ4hnH1WdiAkPUQTpRxW8kGtH8VRTnus7ZTGovFYM1ZezJpvGtb9nPIjPnptHbsyIAxYZsEpVPYgtpjGnrg==}
dependencies:
tinyspy: 2.1.1
dev: true
/@vitest/utils@0.33.0:
resolution: {integrity: sha512-pF1w22ic965sv+EN6uoePkAOTkAPWM03Ri/jXNyMIKBb/XHLDPfhLvf/Fa9g0YECevAIz56oVYXhodLvLQ/awA==}
dependencies:
diff-sequences: 29.4.3
loupe: 2.3.6
pretty-format: 29.6.1
dev: true
/acorn-walk@8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
dev: true
/acorn@8.10.0:
resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/ansi-styles@5.2.0:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
dev: true
/assertion-error@1.1.0:
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
dev: true
/cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
dev: true
/chai@4.3.7:
resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==}
engines: {node: '>=4'}
dependencies:
assertion-error: 1.1.0
check-error: 1.0.2
deep-eql: 4.1.3
get-func-name: 2.0.0
loupe: 2.3.6
pathval: 1.1.1
type-detect: 4.0.8
dev: true
/check-error@1.0.2:
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
dev: true
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
dev: true
/deep-eql@4.1.3:
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
engines: {node: '>=6'}
dependencies:
type-detect: 4.0.8
dev: true
/diff-sequences@29.4.3:
resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
/esbuild@0.18.15:
resolution: {integrity: sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@esbuild/android-arm': 0.18.15
'@esbuild/android-arm64': 0.18.15
'@esbuild/android-x64': 0.18.15
'@esbuild/darwin-arm64': 0.18.15
'@esbuild/darwin-x64': 0.18.15
'@esbuild/freebsd-arm64': 0.18.15
'@esbuild/freebsd-x64': 0.18.15
'@esbuild/linux-arm': 0.18.15
'@esbuild/linux-arm64': 0.18.15
'@esbuild/linux-ia32': 0.18.15
'@esbuild/linux-loong64': 0.18.15
'@esbuild/linux-mips64el': 0.18.15
'@esbuild/linux-ppc64': 0.18.15
'@esbuild/linux-riscv64': 0.18.15
'@esbuild/linux-s390x': 0.18.15
'@esbuild/linux-x64': 0.18.15
'@esbuild/netbsd-x64': 0.18.15
'@esbuild/openbsd-x64': 0.18.15
'@esbuild/sunos-x64': 0.18.15
'@esbuild/win32-arm64': 0.18.15
'@esbuild/win32-ia32': 0.18.15
'@esbuild/win32-x64': 0.18.15
dev: true
/fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
/get-func-name@2.0.0:
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
dev: true
/headers-polyfill@3.1.2:
resolution: {integrity: sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA==}
dev: true
/is-node-process@1.2.0:
resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
dev: true
/jest-playback@4.0.0:
resolution: {integrity: sha512-Nolhk72NYSo9JOBOrOb7GNlyaV/pVumX6sEFDSMuEn17jxCjimzsYmNTl7Je2ICRbLdA+u5SgB1v9L8M3SbBTw==}
engines: {node: '>=18'}
dependencies:
'@mswjs/interceptors': 0.23.0
jest-snapshot-serializer-raw: 2.0.0
mime-types: 2.1.35
dev: true
/jest-snapshot-serializer-raw@2.0.0:
resolution: {integrity: sha512-E/gWFBAltOPQVAvafH/zYkob3G/TqL/DFG3fHurinwLcFRkz6kASjuihyJJ6zoizlLUNaiOdS3v5ZflTvifpBA==}
engines: {node: '>=16'}
dev: true
/jsonc-parser@3.2.0:
resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
dev: true
/local-pkg@0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
dev: true
/loupe@2.3.6:
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
dependencies:
get-func-name: 2.0.0
dev: true
/magic-string@0.30.1:
resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
/mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
dev: true
/mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
dev: true
/mlly@1.4.0:
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
dependencies:
acorn: 8.10.0
pathe: 1.1.1
pkg-types: 1.0.3
ufo: 1.1.2
dev: true
/ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
/nanoid@3.3.6:
resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
dev: true
/outvariant@1.4.0:
resolution: {integrity: sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==}
dev: true
/p-limit@4.0.0:
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
yocto-queue: 1.0.0
dev: true
/pathe@1.1.1:
resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
dev: true
/pathval@1.1.1:
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
dev: true
/picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
/pkg-types@1.0.3:
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
dependencies:
jsonc-parser: 3.2.0
mlly: 1.4.0
pathe: 1.1.1
dev: true
/postcss@8.4.27:
resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.6
picocolors: 1.0.0
source-map-js: 1.0.2
dev: true
/prettier@3.0.0:
resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==}
engines: {node: '>=14'}
hasBin: true
dev: true
/pretty-format@29.6.1:
resolution: {integrity: sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/schemas': 29.6.0
ansi-styles: 5.2.0
react-is: 18.2.0
dev: true
/react-is@18.2.0:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
dev: true
/rollup@3.26.3:
resolution: {integrity: sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.2
dev: true
/siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
dev: true
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
dev: true
/stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
dev: true
/std-env@3.3.3:
resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==}
dev: true
/strict-event-emitter@0.5.0:
resolution: {integrity: sha512-sqnMpVJLSB3daNO6FcvsEk4Mq5IJeAwDeH80DP1S8+pgxrF6yZnE1+VeapesGled7nEcIkz1Ax87HzaIy+02kA==}
dev: true
/strip-literal@1.0.1:
resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==}
dependencies:
acorn: 8.10.0
dev: true
/tinybench@2.5.0:
resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==}
dev: true
/tinypool@0.6.0:
resolution: {integrity: sha512-FdswUUo5SxRizcBc6b1GSuLpLjisa8N8qMyYoP3rl+bym+QauhtJP5bvZY1ytt8krKGmMLYIRl36HBZfeAoqhQ==}
engines: {node: '>=14.0.0'}
dev: true
/tinyspy@2.1.1:
resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==}
engines: {node: '>=14.0.0'}
dev: true
/type-detect@4.0.8:
resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
engines: {node: '>=4'}
dev: true
/typescript@5.1.6:
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/ufo@1.1.2:
resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==}
dev: true
/vite-node@0.33.0(@types/node@20.4.3):
resolution: {integrity: sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==}
engines: {node: '>=v14.18.0'}
hasBin: true
dependencies:
cac: 6.7.14
debug: 4.3.4
mlly: 1.4.0
pathe: 1.1.1
picocolors: 1.0.0
vite: 4.4.6(@types/node@20.4.3)
transitivePeerDependencies:
- '@types/node'
- less
- lightningcss
- sass
- stylus
- sugarss
- supports-color
- terser
dev: true
/vite@4.4.6(@types/node@20.4.3):
resolution: {integrity: sha512-EY6Mm8vJ++S3D4tNAckaZfw3JwG3wa794Vt70M6cNJ6NxT87yhq7EC8Rcap3ahyHdo8AhCmV9PTk+vG1HiYn1A==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': '>= 14'
less: '*'
lightningcss: ^1.21.0
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
'@types/node': 20.4.3
esbuild: 0.18.15
postcss: 8.4.27
rollup: 3.26.3
optionalDependencies:
fsevents: 2.3.2
dev: true
/vitest@0.33.0:
resolution: {integrity: sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==}
engines: {node: '>=v14.18.0'}
hasBin: true
peerDependencies:
'@edge-runtime/vm': '*'
'@vitest/browser': '*'
'@vitest/ui': '*'
happy-dom: '*'
jsdom: '*'
playwright: '*'
safaridriver: '*'
webdriverio: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
'@vitest/browser':
optional: true
'@vitest/ui':
optional: true
happy-dom:
optional: true
jsdom:
optional: true
playwright:
optional: true
safaridriver:
optional: true
webdriverio:
optional: true
dependencies:
'@types/chai': 4.3.5
'@types/chai-subset': 1.3.3
'@types/node': 20.4.3
'@vitest/expect': 0.33.0
'@vitest/runner': 0.33.0
'@vitest/snapshot': 0.33.0
'@vitest/spy': 0.33.0
'@vitest/utils': 0.33.0
acorn: 8.10.0
acorn-walk: 8.2.0
cac: 6.7.14
chai: 4.3.7
debug: 4.3.4
local-pkg: 0.4.3
magic-string: 0.30.1
pathe: 1.1.1
picocolors: 1.0.0
std-env: 3.3.3
strip-literal: 1.0.1
tinybench: 2.5.0
tinypool: 0.6.0
vite: 4.4.6(@types/node@20.4.3)
vite-node: 0.33.0(@types/node@20.4.3)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
- lightningcss
- sass
- stylus
- sugarss
- supports-color
- terser
dev: true
/why-is-node-running@2.2.2:
resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
engines: {node: '>=8'}
hasBin: true
dependencies:
siginfo: 2.0.0
stackback: 0.0.2
dev: true
/yocto-queue@1.0.0:
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
engines: {node: '>=12.20'}
dev: true

File diff suppressed because one or more lines are too long

View File

@ -1,196 +0,0 @@
const request = require("request");
/**
* @typedef {string} EmojiLiteral
* @returns {Promise<{ [githubEmojiId: string]: EmojiLiteral | [string] }>}
*/
async function getGithubEmojiIdMap() {
return Object.fromEntries(
Object.entries(
/** @type {{ [id: string]: string }} */ (await fetchJson(
"https://api.github.com/emojis",
{
headers: {
"User-Agent": "https://github.com/ikatyang/emoji-cheat-sheet"
}
}
))
).map(([id, url]) => [
id,
url.includes("/unicode/")
? getLast(url.split("/"))
.split(".png")[0]
.split("-")
.map(codePointText =>
String.fromCodePoint(Number.parseInt(codePointText, 16))
)
.join("")
: [getLast(url.split("/")).split(".png")[0]] // github's custom emoji
])
);
}
async function getUnicodeEmojiCategoryIterator() {
return getUnicodeEmojiCategoryIteratorFromText(
await fetch("https://unicode.org/emoji/charts/full-emoji-list.txt")
);
}
/**
* @param {string} text
*/
function* getUnicodeEmojiCategoryIteratorFromText(text) {
const lines = text.split("\n");
for (const line of lines) {
if (line.startsWith("@@")) {
const value = line.substring(2);
yield { type: "category", value };
} else if (line.startsWith("@")) {
const value = line.substring(1);
yield { type: "subcategory", value };
} else if (line.length) {
const value = line
.split("\t")[0]
.split(" ")
.map(_ => String.fromCodePoint(parseInt(_, 16)))
.join("");
yield { type: "emoji", value };
}
}
}
async function getCategorizeGithubEmojiIds() {
const githubEmojiIdMap = await getGithubEmojiIdMap();
/** @type {{ [emojiLiteral: string]: string[] }} */
const emojiLiteralToGithubEmojiIdsMap = {};
/** @type {{ [githubSpecificEmojiUri: string]: string[] }} */
const githubSpecificEmojiUriToGithubEmojiIdsMap = {};
for (const [emojiId, emojiLiteral] of Object.entries(githubEmojiIdMap)) {
if (Array.isArray(emojiLiteral)) {
const [uri] = emojiLiteral;
if (!githubSpecificEmojiUriToGithubEmojiIdsMap[uri]) {
githubSpecificEmojiUriToGithubEmojiIdsMap[uri] = [];
}
githubSpecificEmojiUriToGithubEmojiIdsMap[uri].push(emojiId);
delete githubEmojiIdMap[emojiId];
continue;
}
if (!emojiLiteralToGithubEmojiIdsMap[emojiLiteral]) {
emojiLiteralToGithubEmojiIdsMap[emojiLiteral] = [];
}
emojiLiteralToGithubEmojiIdsMap[emojiLiteral].push(emojiId);
}
/** @type {{ [category: string]: { [subcategory: string]: Array<string[]> } }} */
const categorizedEmojiIds = {};
const categoryStack = [];
for (const { type, value } of await getUnicodeEmojiCategoryIterator()) {
switch (type) {
case "category": {
while (categoryStack.length) categoryStack.pop();
const title = toTitleCase(value);
categoryStack.push(title);
categorizedEmojiIds[title] = {};
break;
}
case "subcategory": {
if (categoryStack.length > 1) categoryStack.pop();
const title = toTitleCase(value);
categoryStack.push(title);
categorizedEmojiIds[categoryStack[0]][title] = [];
break;
}
case "emoji": {
const key = value.replace(/[\ufe00-\ufe0f\u200d]/g, "");
if (key in emojiLiteralToGithubEmojiIdsMap) {
const githubEmojiIds = emojiLiteralToGithubEmojiIdsMap[key];
const [category, subcategory] = categoryStack;
categorizedEmojiIds[category][subcategory].push(githubEmojiIds);
for (const githubEmojiId of githubEmojiIds) {
delete githubEmojiIdMap[githubEmojiId];
}
}
break;
}
default:
throw new Error(`Unexpected type ${JSON.stringify(type)}`);
}
}
if (Object.keys(githubEmojiIdMap).length) {
throw new Error(`Uncategorized emoji(s) found.`);
}
for (const category of Object.keys(categorizedEmojiIds)) {
const subCategorizedEmojiIds = categorizedEmojiIds[category];
const subcategories = Object.keys(subCategorizedEmojiIds);
for (const subcategory of subcategories) {
if (subCategorizedEmojiIds[subcategory].length === 0) {
delete subCategorizedEmojiIds[subcategory];
}
}
if (Object.keys(subCategorizedEmojiIds).length === 0) {
delete categorizedEmojiIds[category];
}
}
if (Object.keys(githubSpecificEmojiUriToGithubEmojiIdsMap).length) {
categorizedEmojiIds["GitHub Custom Emoji"] = {
"": Object.entries(githubSpecificEmojiUriToGithubEmojiIdsMap).map(
([, v]) => v
)
};
}
return categorizedEmojiIds;
}
/**
* @param {string} str
*/
function toTitleCase(str) {
return str
.replace(/-/g, " ")
.replace(/\s+/g, " ")
.replace(/[a-zA-Z]+/g, word => word[0].toUpperCase() + word.slice(1));
}
/**
* @template T
* @param {Array<T>} array
*/
function getLast(array) {
return array[array.length - 1];
}
/**
* @param {string} url
* @param {Partial<request.Options>} options
* @returns {Promise<any>}
*/
async function fetchJson(url, options = {}) {
return JSON.parse(await fetch(url, options));
}
/**
* @param {string} url
* @param {Partial<request.Options>} options
* @returns {Promise<string>}
*/
async function fetch(url, options = {}) {
return new Promise((resolve, reject) => {
request.get(
/** @type {request.Options} */ ({ url, ...options }),
(error, response, html) => {
if (!error && response.statusCode === 200) {
resolve(html);
} else {
reject(
error
? error
: `Unexpected response status code: ${response.statusCode}`
);
}
}
);
});
}
module.exports = {
getCategorizeGithubEmojiIds
};

160
scripts/fetch.ts 100644
View File

@ -0,0 +1,160 @@
type EmojiLiteral = string
async function getGithubEmojiIdMap(): Promise<{
[githubEmojiId: string]: EmojiLiteral | [string]
}> {
return Object.fromEntries(
Object.entries(
await fetchJson<{ [id: string]: string }>(
'https://api.github.com/emojis',
{
headers: {
'User-Agent': 'https://github.com/ikatyang/emoji-cheat-sheet',
},
},
),
).map(([id, url]) => [
id,
url.includes('/unicode/')
? getLast(url.split('/'))
.split('.png')[0]
.split('-')
.map(codePointText =>
String.fromCodePoint(Number.parseInt(codePointText, 16)),
)
.join('')
: [getLast(url.split('/')).split('.png')[0]], // github's custom emoji
]),
)
}
async function getUnicodeEmojiCategoryIterator() {
return getUnicodeEmojiCategoryIteratorFromText(
await fetchText('https://unicode.org/emoji/charts/full-emoji-list.txt'),
)
}
function* getUnicodeEmojiCategoryIteratorFromText(text: string) {
const lines = text.split('\n')
for (const line of lines) {
if (line.startsWith('@@')) {
const value = line.substring(2)
yield { type: 'category', value }
} else if (line.startsWith('@')) {
const value = line.substring(1)
yield { type: 'subcategory', value }
} else if (line.length) {
const value = line
.split('\t')[0]
.split(' ')
.map(_ => String.fromCodePoint(parseInt(_, 16)))
.join('')
yield { type: 'emoji', value }
}
}
}
export async function getCategorizeGithubEmojiIds() {
const githubEmojiIdMap = await getGithubEmojiIdMap()
const emojiLiteralToGithubEmojiIdsMap: {
[emojiLiteral: string]: string[]
} = {}
const githubSpecificEmojiUriToGithubEmojiIdsMap: {
[githubSpecificEmojiUri: string]: string[]
} = {}
for (const [emojiId, emojiLiteral] of Object.entries(githubEmojiIdMap)) {
if (Array.isArray(emojiLiteral)) {
const [uri] = emojiLiteral
if (!githubSpecificEmojiUriToGithubEmojiIdsMap[uri]) {
githubSpecificEmojiUriToGithubEmojiIdsMap[uri] = []
}
githubSpecificEmojiUriToGithubEmojiIdsMap[uri].push(emojiId)
delete githubEmojiIdMap[emojiId]
continue
}
if (!emojiLiteralToGithubEmojiIdsMap[emojiLiteral]) {
emojiLiteralToGithubEmojiIdsMap[emojiLiteral] = []
}
emojiLiteralToGithubEmojiIdsMap[emojiLiteral].push(emojiId)
}
const categorizedEmojiIds: {
[category: string]: { [subcategory: string]: Array<string[]> }
} = {}
const categoryStack = []
for (const { type, value } of await getUnicodeEmojiCategoryIterator()) {
switch (type) {
case 'category': {
while (categoryStack.length) categoryStack.pop()
const title = toTitleCase(value)
categoryStack.push(title)
categorizedEmojiIds[title] = {}
break
}
case 'subcategory': {
if (categoryStack.length > 1) categoryStack.pop()
const title = toTitleCase(value)
categoryStack.push(title)
categorizedEmojiIds[categoryStack[0]][title] = []
break
}
case 'emoji': {
const key = value.replace(/[\ufe00-\ufe0f\u200d]/g, '')
if (key in emojiLiteralToGithubEmojiIdsMap) {
const githubEmojiIds = emojiLiteralToGithubEmojiIdsMap[key]
const [category, subcategory] = categoryStack
categorizedEmojiIds[category][subcategory].push(githubEmojiIds)
for (const githubEmojiId of githubEmojiIds) {
delete githubEmojiIdMap[githubEmojiId]
}
}
break
}
default:
throw new Error(`Unexpected type ${JSON.stringify(type)}`)
}
}
if (Object.keys(githubEmojiIdMap).length) {
throw new Error(`Uncategorized emoji(s) found.`)
}
for (const category of Object.keys(categorizedEmojiIds)) {
const subCategorizedEmojiIds = categorizedEmojiIds[category]
const subcategories = Object.keys(subCategorizedEmojiIds)
for (const subcategory of subcategories) {
if (subCategorizedEmojiIds[subcategory].length === 0) {
delete subCategorizedEmojiIds[subcategory]
}
}
if (Object.keys(subCategorizedEmojiIds).length === 0) {
delete categorizedEmojiIds[category]
}
}
if (Object.keys(githubSpecificEmojiUriToGithubEmojiIdsMap).length) {
categorizedEmojiIds['GitHub Custom Emoji'] = {
'': Object.entries(githubSpecificEmojiUriToGithubEmojiIdsMap).map(
([, v]) => v,
),
}
}
return categorizedEmojiIds
}
function toTitleCase(text: string) {
return text
.replace(/-/g, ' ')
.replace(/\s+/g, ' ')
.replace(/[a-zA-Z]+/g, word => word[0].toUpperCase() + word.slice(1))
}
function getLast<T>(array: T[]) {
return array[array.length - 1]
}
async function fetchJson<T>(url: string, init?: RequestInit) {
const response = await fetch(url, init)
return (await response.json()) as T
}
async function fetchText(url: string, init?: RequestInit) {
const response = await fetch(url, init)
return await response.text()
}

View File

@ -1,12 +0,0 @@
const { getCategorizeGithubEmojiIds } = require("./fetch");
const { generateCheatSheet } = require("./markdown");
async function generate() {
return generateCheatSheet(await getCategorizeGithubEmojiIds());
}
if (require.main === /** @type {unknown} */ (module)) {
generate().then(cheatSheet => console.log(cheatSheet));
} else {
module.exports = generate;
}

View File

@ -1,8 +1,10 @@
require("jest-playback").setup(__dirname);
import { expect, test } from 'vitest'
import setupPlayback from 'jest-playback'
import { generate } from './generate.js'
const generate = require("./generate");
await setupPlayback()
test("emoji-cheat-sheet", async () => {
test('emoji-cheat-sheet', async () => {
expect(await generate()).toMatchInlineSnapshot(`
"# emoji-cheat-sheet
@ -1594,5 +1596,5 @@ test("emoji-cheat-sheet", async () => {
| [top](#github-custom-emoji) | :rage4: | \`:rage4:\` | :shipit: | \`:shipit:\` | [top](#table-of-contents) |
| [top](#github-custom-emoji) | :suspect: | \`:suspect:\` | :trollface: | \`:trollface:\` | [top](#table-of-contents) |
"
`);
});
`)
})

View File

@ -0,0 +1,10 @@
import { getCategorizeGithubEmojiIds } from './fetch.js'
import { generateCheatSheet } from './markdown.js'
export async function generate() {
return generateCheatSheet(await getCategorizeGithubEmojiIds())
}
if (process.argv[2] === 'run') {
console.log(await generate())
}

View File

@ -1,134 +0,0 @@
const { name: repoName, repository } = require("../package.json");
const resource1 = "[GitHub Emoji API](https://api.github.com/emojis)";
const resoruce2 =
"[Unicode Full Emoji List](https://unicode.org/emoji/charts/full-emoji-list.html)";
const columns = 2;
const tocName = "Table of Contents";
/**
* @typedef {Array<string[]>} GithubEmojiIds
*/
/**
* @param {{ [category: string]: { [subcategory: string]: GithubEmojiIds } }} categorizedGithubEmojiIds
*/
function generateCheatSheet(categorizedGithubEmojiIds) {
const lineTexts = [];
lineTexts.push(`# ${repoName}`);
lineTexts.push("");
lineTexts.push(
`[![Up to Date](https://github.com/${repository}/workflows/Up%20to%20Date/badge.svg)](https://github.com/${repository}/actions?query=workflow%3A%22Up+to+Date%22)`
);
lineTexts.push("");
lineTexts.push(
`This cheat sheet is automatically generated from ${resource1} and ${resoruce2}.`
);
lineTexts.push("");
const categories = Object.keys(categorizedGithubEmojiIds);
lineTexts.push(`## ${tocName}`);
lineTexts.push("");
lineTexts.push(...generateToc(categories));
lineTexts.push("");
for (const category of categories) {
lineTexts.push(`### ${category}`);
lineTexts.push("");
const subcategorizeGithubEmojiIds = categorizedGithubEmojiIds[category];
const subcategories = Object.keys(subcategorizeGithubEmojiIds);
if (subcategories.length > 1) {
lineTexts.push(...generateToc(subcategories));
lineTexts.push("");
}
for (const subcategory of subcategories) {
if (subcategory) {
lineTexts.push(`#### ${subcategory}`);
lineTexts.push("");
}
lineTexts.push(
...generateTable(
subcategorizeGithubEmojiIds[subcategory],
`[top](#${getHeaderId(category)})`,
`[top](#${getHeaderId(tocName)})`
)
);
lineTexts.push("");
}
}
return lineTexts.join("\n");
}
/**
* @param {string[]} headers
*/
function generateToc(headers) {
return headers.map(header => `- [${header}](#${getHeaderId(header)})`);
}
/**
* @param {string} header
*/
function getHeaderId(header) {
return header
.toLowerCase()
.replace(/ /g, "-")
.replace(/[^a-z0-9-]/g, "");
}
/**
* @param {GithubEmojiIds} githubEmojiIds
* @param {string} leftText
* @param {string} rightText
*/
function generateTable(githubEmojiIds, leftText, rightText) {
const lineTexts = [];
let header = "";
let delimieter = "";
header += "| ";
delimieter += "| - ";
for (let i = 0; i < columns && i < githubEmojiIds.length; i++) {
header += `| ico | shortcode `;
delimieter += "| :-: | - ";
}
header += "| |";
delimieter += "| - |";
lineTexts.push(header, delimieter);
for (let i = 0; i < githubEmojiIds.length; i += columns) {
let lineText = `| ${leftText} `;
for (let j = 0; j < columns; j++) {
if (i + j < githubEmojiIds.length) {
const emojiIds = githubEmojiIds[i + j];
const emojiId = emojiIds[0];
lineText += `| :${emojiId}: | \`:${emojiId}:\` `;
for (let k = 1; k < emojiIds.length; k++) {
lineText += `<br /> \`:${emojiIds[k]}:\` `;
}
} else if (githubEmojiIds.length > columns) {
lineText += "| | ";
}
}
lineText += `| ${rightText} |`;
lineTexts.push(lineText);
}
return lineTexts;
}
module.exports = {
generateCheatSheet
};

120
scripts/markdown.ts 100644
View File

@ -0,0 +1,120 @@
import { name as repoName, repository } from '../package.json'
const RESOURCE_1 = '[GitHub Emoji API](https://api.github.com/emojis)'
const RESOURCE_2 =
'[Unicode Full Emoji List](https://unicode.org/emoji/charts/full-emoji-list.html)'
const COLUMNS = 2
const TOC_NAME = 'Table of Contents'
type GithubEmojiIds = Array<string[]>
export function generateCheatSheet(categorizedGithubEmojiIds: {
[category: string]: { [subCategory: string]: GithubEmojiIds }
}) {
const lineTexts = []
lineTexts.push(`# ${repoName}`)
lineTexts.push('')
lineTexts.push(
`[![Up to Date](https://github.com/${repository}/workflows/Up%20to%20Date/badge.svg)](https://github.com/${repository}/actions?query=workflow%3A%22Up+to+Date%22)`,
)
lineTexts.push('')
lineTexts.push(
`This cheat sheet is automatically generated from ${RESOURCE_1} and ${RESOURCE_2}.`,
)
lineTexts.push('')
const categories = Object.keys(categorizedGithubEmojiIds)
lineTexts.push(`## ${TOC_NAME}`)
lineTexts.push('')
lineTexts.push(...generateToc(categories))
lineTexts.push('')
for (const category of categories) {
lineTexts.push(`### ${category}`)
lineTexts.push('')
const subCategorizedGithubEmojiIds = categorizedGithubEmojiIds[category]
const subCategories = Object.keys(subCategorizedGithubEmojiIds)
if (subCategories.length > 1) {
lineTexts.push(...generateToc(subCategories))
lineTexts.push('')
}
for (const subCategory of subCategories) {
if (subCategory) {
lineTexts.push(`#### ${subCategory}`)
lineTexts.push('')
}
lineTexts.push(
...generateTable(
subCategorizedGithubEmojiIds[subCategory],
`[top](#${getHeaderId(category)})`,
`[top](#${getHeaderId(TOC_NAME)})`,
),
)
lineTexts.push('')
}
}
return lineTexts.join('\n')
}
function generateToc(headers: string[]) {
return headers.map(header => `- [${header}](#${getHeaderId(header)})`)
}
function getHeaderId(header: string) {
return header
.toLowerCase()
.replace(/ /g, '-')
.replace(/[^a-z0-9-]/g, '')
}
function generateTable(
githubEmojiIds: GithubEmojiIds,
leftText: string,
rightText: string,
) {
const lineTexts = []
let header = ''
let delimiter = ''
header += '| '
delimiter += '| - '
for (let i = 0; i < COLUMNS && i < githubEmojiIds.length; i++) {
header += `| ico | shortcode `
delimiter += '| :-: | - '
}
header += '| |'
delimiter += '| - |'
lineTexts.push(header, delimiter)
for (let i = 0; i < githubEmojiIds.length; i += COLUMNS) {
let lineText = `| ${leftText} `
for (let j = 0; j < COLUMNS; j++) {
if (i + j < githubEmojiIds.length) {
const emojiIds = githubEmojiIds[i + j]
const emojiId = emojiIds[0]
lineText += `| :${emojiId}: | \`:${emojiId}:\` `
for (let k = 1; k < emojiIds.length; k++) {
lineText += `<br /> \`:${emojiIds[k]}:\` `
}
} else if (githubEmojiIds.length > COLUMNS) {
lineText += '| | '
}
}
lineText += `| ${rightText} |`
lineTexts.push(lineText)
}
return lineTexts
}

View File

@ -1,12 +1,12 @@
{
"include": ["scripts/**/*"],
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"moduleResolution": "node",
"noEmit": true,
"resolveJsonModule": true,
"strict": true,
"target": "esnext"
},
"include": ["scripts/**/*.js"]
"target": "ES2021",
"lib": ["ES2021", "DOM"],
"module": "Node16",
"moduleResolution": "Node16",
"skipLibCheck": true,
"resolveJsonModule": true
}
}

View File

@ -1,6 +0,0 @@
{
"extends": ["tslint-plugin-prettier"],
"jsRules": {
"prettier": true
}
}

3681
yarn.lock

File diff suppressed because it is too large Load Diff