├── .devcontainer └── devcontainer.json ├── .editorconfig ├── .git-hooks ├── pre-commit ├── pre-push └── prepare-commit-msg ├── .github ├── ISSUE_TEMPLATE │ ├── BUG_REPORT.yml │ ├── FEATURE_REQUEST.yml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── RELEASE_WORKFLOW.md ├── SECURITY.md ├── dependabot.yml ├── spec │ ├── label.yml │ └── setting.yml └── workflows │ ├── ci.yml │ ├── release.yml │ ├── spec-label.yml │ └── spec-setting-repo.yml ├── LICENSE ├── Makefile ├── README.md ├── deno.jsonc ├── deno.lock ├── deps.ts ├── dev ├── build.sh ├── setup.sh └── validate.sh ├── mod.test.ts ├── mod.ts └── util ├── build-dnt.ts └── build-mod.ts /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Deno", 3 | "image": "mcr.microsoft.com/devcontainers/base:bullseye", 4 | "features": { 5 | "ghcr.io/devcontainers-extra/features/deno:1": { 6 | "version": "latest" 7 | }, 8 | "ghcr.io/devcontainers/features/node:1": { 9 | "version": "latest" 10 | } 11 | }, 12 | "customizations": { 13 | "vscode": { 14 | "settings": { 15 | "files.hotExit": "onExitAndWindowClose", 16 | "files.insertFinalNewline": true, 17 | "files.trimFinalNewlines": true, 18 | "editor.formatOnSave": true, 19 | "editor.formatOnPaste": true, 20 | "[typescript]": { 21 | "editor.defaultFormatter": "denoland.vscode-deno", 22 | "editor.codeActionsOnSave": { 23 | "source.organizeImports": "always", 24 | "source.removeUnusedImports": "always", 25 | "source.sortImports": "always" 26 | } 27 | }, 28 | "[javascript]": { 29 | "editor.defaultFormatter": null 30 | }, 31 | "[json]": { 32 | "editor.defaultFormatter": "vscode.json-language-features" 33 | }, 34 | "[jsonc]": { 35 | "editor.defaultFormatter": "vscode.json-language-features" 36 | }, 37 | "deno.enable": true, 38 | "extensions.webWorker": true, 39 | "extensions.ignoreRecommendations": true 40 | }, 41 | "extensions": [ 42 | // Editor 43 | "editorconfig.editorconfig", 44 | // Language 45 | "justjavac.vscode-deno-extensionpack", 46 | // IntelliCode 47 | "VisualStudioExptTeam.vscodeintellicode", 48 | "VisualStudioExptTeam.vscodeintellicode-completions", 49 | "VisualStudioExptTeam.intellicode-api-usage-examples" 50 | ] 51 | } 52 | }, 53 | "remoteUser": "root" 54 | } 55 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | end_of_line = lf 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [Makefile] 13 | indent_style = tab 14 | indent_size = 4 15 | -------------------------------------------------------------------------------- /.git-hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Configure the hook with these options. 4 | HOOK_DEBUG=0 # Set to 1 to enable debug mode. This will print additional output. 5 | HOOK_DISABLE_NOTICE=0 # Set to 1 to disable the notice when the hook exits with an error code. 6 | 7 | # Import the git-hooked wrapper to prepare the env and execute the script below. 8 | . "$(dirname "$0")/_util/git-hooked.sh" 9 | 10 | # Your script begins here. 11 | make validate 12 | 13 | exit 0 # NO OP. This quietly passes to prevent spam during configuration. 14 | -------------------------------------------------------------------------------- /.git-hooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Configure the hook with these options. 4 | HOOK_DEBUG=0 # Set to 1 to enable debug mode. This will print additional output. 5 | HOOK_DISABLE_NOTICE=0 # Set to 1 to disable the notice when the hook exits with an error code. 6 | 7 | # Import the git-hooked wrapper to prepare the env and execute the script below. 8 | . "$(dirname "$0")/_util/git-hooked.sh" 9 | 10 | # Your script begins here. 11 | make validate 12 | 13 | exit 0 # NO OP. This quietly passes to prevent spam during configuration. 14 | -------------------------------------------------------------------------------- /.git-hooks/prepare-commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Configure the hook with these options. 4 | HOOK_DEBUG=0 # Set to 1 to enable debug mode. This will print additional output. 5 | HOOK_DISABLE_NOTICE=0 # Set to 1 to disable the notice when the hook exits with an error code. 6 | 7 | # Import the git-hooked wrapper to prepare the env and execute the script below. 8 | . "$(dirname "$0")/_util/git-hooked.sh" 9 | 10 | # Your script begins here. 11 | # The last command to run, or explicit "exit" commands, will determine the status code to Git. 12 | 13 | # From: https://dev.to/craicoverflow/enforcing-conventional-commits-using-git-hooks-1o5p 14 | # Build the Regular Expression Options. 15 | types="build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test" 16 | scope_minlen=1 17 | scope_maxlen=16 18 | scope_regexp="[a-z0-9_.-]{${scope_minlen},${scope_maxlen}}" 19 | subject_minlen=4 20 | subject_maxlen=120 21 | subject_regexp="[A-Za-z0-9_. -]{${subject_minlen},${subject_maxlen}}" 22 | 23 | # Build the Regular Expression String. 24 | regexp="^(revert: )?(${types})(\(${scope_regexp}\))?!?: ${subject_regexp}[^A-Z.,?]{1,}$" 25 | 26 | # Validate the commit message. 27 | if [[ ! "$(head -1 $1)" =~ ${regexp} ]]; then 28 | # Print the hook error message. 29 | echo 30 | echo "The commit message was not formatted correctly. Rejecting the commit request." 31 | echo " - https://www.conventionalcommits.org/en/v1.0.0/" 32 | echo " - https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional" 33 | echo 34 | echo " Having trouble with the format? Just not sure of how to commit correctly? https://commitlint.io/" 35 | echo " Something weird happening? Use https://regexr.com/ with the following expression to validate your commit." 36 | echo " - Expression: /${regexp}/" 37 | echo 38 | exit 1 39 | fi 40 | 41 | # Print the hook success message. 42 | echo "Validated 'prepare-commit-msg' hook." 43 | exit 0 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG_REPORT.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 'Bug Report' 4 | about: 'This template is used to report unintended behavior of our projects.' 5 | title: '[BUG] A brief overview of your concern.' 6 | ref: 'main' 7 | labels: 8 | - 'Type: Bug' 9 | - 'State: Conversation' 10 | 11 | --- 12 | 13 | **Describe the Bug**: A clear and concise description of what is problematic. 14 | 15 | **Information / Steps to Reproduce**: 16 | 17 | 1. Provide detailed steps on how to reproduce the issue. 18 | 2. Key aspects of how the environment was set up. 19 | 3. Code or repository that can be used to consistently reproduce the behavior. 20 | 4. Please include any and all errors that are generated. 21 | 22 | **Expected Behavior**: Please explain the behavior you expected the application 23 | to implement. 24 | 25 | **Current Environment**: Please detail the specs and operating system of the 26 | machine you are currently using. If possible, please replicate this issue across 27 | multiple different operating systems. Please include the version of our project 28 | that you are using. 29 | 30 | **Additional Context**: Please provide any additional information you feel 31 | should be shared, if applicable. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 'Enhancement Request' 4 | about: 'This template is used to request enhancements to be added in our projects.' 5 | title: '[FEAT] A brief overview of your request.' 6 | ref: 'main' 7 | labels: 8 | - 'Type: Enhancement' 9 | - 'State: Conversation' 10 | 11 | --- 12 | 13 | **Describe the Request**: A clear and concise description of what you are 14 | requesting. 15 | 16 | **Information**: 17 | 18 | 1. How would you like to see this implemented? 19 | 2. How do you feel this will benefit the project? 20 | 3. Is there any existing functionality that may need changed to support this? 21 | 4. Will this functionality replace or otherwise deprecate existing 22 | functionality? 23 | 24 | **Expected Behavior**: Please explain the behavior you are expecting the 25 | application to implement. 26 | 27 | **Additional Context**: Please provide any additional information you feel 28 | should be shared, if applicable. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: xCykrix Discord 4 | url: https://discord.gg/RHJQFPgbke 5 | about: Please feel free to reach out with questions and suggestions here. 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Describe Changes 2 | 3 | ... 4 | 5 | ## GitHub Issues Resolved 6 | 7 | Fixes #(issue) 8 | 9 | ## Commit Types 10 | 11 | - [ ] Bug Fixes / Small Adjustments - No New Features (fix, chore, docs) 12 | - [ ] New Features / Large Adjustments with Backwards Compatability (feat, refactor) 13 | - [ ] Breaking Change - Existing Functionlity Updated without Backwards Compatability (feat!, fix!) 14 | 15 | ## Testing Coverage 16 | 17 | - [ ] This pull request passes all existing automated tests. 18 | - [ ] I have added additional automated tests for code in this pull request. 19 | 20 | ## Documentation Coverage 21 | 22 | - [ ] This pull request has been fully documented in the applicable code, 23 | particularly dense sections. 24 | - [ ] This may require more/updated documentation on the Wiki. 25 | 26 | ## Acknowledgements 27 | 28 | - [ ] The code of this Pull Request complies with automated styling and existing 29 | code formatting. 30 | - [ ] I have performed a self-review of the code contained in this Pull Request 31 | for consistency and accuracy. 32 | - [ ] Changes to the code have produced no additional static analysis issues. 33 | 34 | With the submission of this Pull Request, I agree to the Contribution 35 | Guidelines, Code of Conduct, and Security Policy. 36 | -------------------------------------------------------------------------------- /.github/RELEASE_WORKFLOW.md: -------------------------------------------------------------------------------- 1 | # Internal Documentation 2 | 3 | Guideline to create a public release via automation. 4 | 5 | 1. Update `deno.jsonc` to the specified version. Include this in the commit. 6 | 2. Verify `make setup` and `make validate` run successfully. 7 | 3. `git tag vX.X.X` 8 | 4. `git push origin vX.X.X` 9 | 10 | This will trigger `.github/workflows/release.yml`. 11 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting 4 | 5 | If you believe you have discovered a vulnerability in this project, please 6 | report it through responsible disclosure. 7 | 8 | > [!CAUTION] 9 | > Please do NOT use a GitHub Issue, Discussion, Pull Request, or Public Forum. 10 | 11 | Reports are accepted via: 12 | 13 | - Report a Vulnerability via GitHub Private Disclosure. Please select the 14 | "Security" tab to begin this process. 15 | - Reach out via Discord to samuel.voeller@amethyst.live directly to report an issue. You can 16 | find our Discord Server Link via the "Issues" tab as well. 17 | 18 | ## A Good Disclosure 19 | 20 | When submitting a Vulnerability Report, please include as much relevant 21 | information as possible: 22 | 23 | - The type of issue (e.g., buffer overflow, SQL injection, or cross-site 24 | scripting). 25 | - Impacted version(s) of the project. 26 | - Impact of the issue, including how an attacker might exploit the issue. 27 | - The location of the affected source code (tag/branch/commit or direct URL). 28 | - Step-by-step instructions to reproduce the issue. 29 | - Any special configuration required to reproduce the issue (if applicable). 30 | - Any log files that are related to this issue (if possible). 31 | - Proof-of-concept or exploit code (if possible). 32 | 33 | You will never share too much information to us. 34 | 35 | ## After Submission 36 | 37 | Once reviewed, the clock begins for us. We will begin to validate the 38 | submission, assess the impact, and release a timeline of resolution and 39 | disclosure. Below is the general guidelines of this process: 40 | 41 | This is a passion project. Subject to availability. 42 | 43 | 1. Maintainers will acknowledge the submission and validate the claim. Process 44 | date starts at acknowledgement. 45 | 2. Maintainers will research the scope, impact, and severity of the claim. 46 | 3. Maintainers will begin work on analysis and possible mitigation of the 47 | reported issue. 48 | 4. Maintainers will release an update addressing the issue; if applicable. 49 | 5. Maintainers will release a statement and update the disclosure based on 50 | analysis, mitigation, and how/if it was addressed. 51 | 6. Maintainers will publish the disclosure to the public after mitigation 52 | is completed. 53 | 54 | - When a fix is deployed, a disclosure will be published within 5 business days days or 55 | 30 days of the initial submission process date; whichever is earliest. 56 | - If a vulnerability exists and it not yet patched, a disclosure will be 57 | published within 30 days of submission processing unless mutually agreed upon 58 | to extend the disclosure window for public interest. 59 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for more information: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | # https://containers.dev/guide/dependabot 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: "devcontainers" 10 | directory: "/" 11 | schedule: 12 | interval: weekly 13 | -------------------------------------------------------------------------------- /.github/spec/label.yml: -------------------------------------------------------------------------------- 1 | - color: '0E8A16' 2 | name: 'State: Help Wanted' 3 | - color: '000000' 4 | name: 'State: Blocked' 5 | - color: 'C5DEF5' 6 | name: 'State: Postponed' 7 | - color: '5319E7' 8 | name: 'State: Work in Progress' 9 | - color: '1D76DB' 10 | name: 'Type: Enhancement' 11 | - color: 'B60205' 12 | name: 'Type: Bug' 13 | - color: 'FBCA04' 14 | name: 'Type: Infrastructure' 15 | - color: 'D4C5F9' 16 | name: 'Type: Dependencies' 17 | - color: 'BFDADC' 18 | name: 'Meta: Question' 19 | - color: 'BFDADC' 20 | name: 'Meta: Duplicate' 21 | - color: '000000' 22 | name: 'Priority: 0 Critical' 23 | - color: F9D0C4 24 | name: 'Priority: 1 High' 25 | - color: FEF2C0 26 | name: 'Priority: 2 Medium' 27 | - color: 'D4C5F9' 28 | name: 'Priority: 3 Low' 29 | - color: '808080' 30 | name: 'Meta: Abandoned / No Fix' 31 | - color: '27828C' 32 | name: 'Meta: Conversation' 33 | -------------------------------------------------------------------------------- /.github/spec/setting.yml: -------------------------------------------------------------------------------- 1 | settings: 2 | private: false 3 | visibility: public 4 | security_and_analysis: 5 | secret_scanning: 6 | status: enabled 7 | secret_scanning_push_protection: 8 | status: enabled 9 | secret_scanning_ai_detection: 10 | status: enabled 11 | secret_scanning_non_provider_patterns: 12 | status: enabled 13 | has_issues: true 14 | has_projects: true 15 | has_wiki: true 16 | is_template: false 17 | default_branch: main 18 | allow_squash_merge: true 19 | allow_merge_commit: false 20 | allow_rebase_merge: true 21 | allow_auto_merge: false 22 | delete_branch_on_merge: false 23 | allow_update_branch: true 24 | squash_merge_commit_title: COMMIT_OR_PR_TITLE 25 | squash_merge_commit_message: COMMIT_MESSAGES 26 | allow_forking: true 27 | web_commit_signoff_required: true 28 | enable_automated_security_fixes: true 29 | enable_vulnerability_alerts: true 30 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build and Validate 2 | 3 | on: 4 | push: 5 | branches: [main, staging] 6 | pull_request: 7 | branches: [main, staging] 8 | 9 | jobs: 10 | validate: 11 | runs-on: ubuntu-latest 12 | name: Deno Validation Action 13 | steps: 14 | # Setup 15 | - uses: actions/checkout@v4 16 | # Languages 17 | - uses: devcontainers/ci@v0.3 18 | with: 19 | runCmd: deno test -A 20 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Automatic Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | 8 | jobs: 9 | candidate: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | # Languages 14 | - uses: denoland/setup-deno@v2 15 | with: 16 | deno-version: v2.x 17 | - uses: devcontainers/ci@v0.3 18 | with: 19 | runCmd: make validate 20 | # Publish 21 | - uses: softprops/action-gh-release@v2 22 | with: 23 | discussion_category_name: Announcements 24 | generate_release_notes: true 25 | files: | 26 | LICENSE 27 | README.md 28 | - name: 'Publish Package' 29 | run: deno publish 30 | -------------------------------------------------------------------------------- /.github/workflows/spec-label.yml: -------------------------------------------------------------------------------- 1 | name: Label Specification 2 | 3 | on: 4 | workflow_dispatch: 5 | label: 6 | types: [created, edited, deleted] 7 | 8 | jobs: 9 | label-spec: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | issues: write 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | sparse-checkout: .github/spec/label.yml 17 | - uses: EndBug/label-sync@v2 18 | with: 19 | config-file: .github/spec/label.yml 20 | delete-other-labels: true 21 | token: ${{ secrets.GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/spec-setting-repo.yml: -------------------------------------------------------------------------------- 1 | name: Setting Specification Repo 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | setting-spec: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | sparse-checkout: .github/spec/setting.yml 15 | - uses: actuarysailor/gha-repo-manager@v2 16 | with: 17 | action: apply 18 | settings_file: .github/spec/setting.yml 19 | token: ${{ secrets.GH_TOKEN }} 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Samuel Voeller 4 | Copyright (c) 2016-2020 Marek Kulik 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ################################ 2 | # Project Configuration Makefile 3 | ################################ 4 | 5 | setup: 6 | @echo "Task: 'setup'" 7 | @mkdir -p "dev" 8 | @touch ./dev/setup.sh 9 | @chmod +x ./dev/setup.sh 10 | ./dev/setup.sh 11 | 12 | build: 13 | @echo "Task: 'build'" 14 | @mkdir -p "dev" 15 | @touch ./dev/build.sh 16 | @chmod +x ./dev/build.sh 17 | ./dev/build.sh 18 | 19 | validate: 20 | @echo "Task: 'validate'" 21 | @mkdir -p "dev" 22 | @touch ./dev/validate.sh 23 | @chmod +x ./dev/validate.sh 24 | ./dev/build.sh 25 | ./dev/validate.sh 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # discord-emoji 2 | 3 | Library - Stable - A near exact emoji tables of Discord for string-based insertion of emotes without having to escape Unicode. 4 | 5 | Find more in-depth guidance and documentation can be found on the [GitHub Wiki](https://github.com/xCykrix/discord_emoji/wiki). 6 | 7 | ![GitHub License](https://img.shields.io/github/license/xCykrix/discord_emoji?style=for-the-badge&logo=github&cacheSeconds=86400) ![GitHub Issues](https://img.shields.io/github/issues/xCykrix/discord_emoji?style=for-the-badge&logo=github&cacheSeconds=3600) ![GitHub Pull Requests](https://img.shields.io/github/issues-pr/xCykrix/discord_emoji?style=for-the-badge&logo=github&cacheSeconds=3600) 8 | ![GitHub Discussions](https://img.shields.io/github/discussions/xCykrix/discord_emoji?style=for-the-badge&logo=github&cacheSeconds=3600) 9 | 10 | ## Install / Usage 11 | 12 | https://github.com/xCykrix/discord_emoji/wiki#installation 13 | 14 | ```ts 15 | // Deno 16 | import * as dismoji from 'jsr:@amethyst/discord-emoji'; 17 | 18 | // Node.js 19 | // $ npm install discord-emoji 20 | const dismoji = require('discord-emoji'); 21 | 22 | // Examples of Assertions. dismoji.category.identifier 23 | assertEquals(dismoji.people.grinning, '😀'); 24 | assertEquals(dismoji.nature.dog, '🐶'); 25 | assertEquals(dismoji.food.hamburger, '🍔'); 26 | assertEquals(dismoji.activity.basketball, '🏀'); 27 | assertEquals(dismoji.travel.airplane, '✈️'); 28 | assertEquals(dismoji.objects.watch, '⌚'); 29 | assertEquals(dismoji.symbols.eight_pointed_black_star, '✴️'); 30 | assertEquals(dismoji.flags.flag_us, '🇺🇸'); 31 | ``` 32 | 33 | ## Support 34 | 35 | For support, please open an issue or reach out via Discord. 36 | 37 | ## Contributing 38 | 39 | This project utilizes a Makefile to control the development, workflow, and distribution of the project. Dev Container support is required and VSCode is recommended. 40 | 41 | When creating a clone, please execute the following command(s): 42 | 43 | ```sh 44 | $ make setup 45 | $ make build 46 | ``` 47 | 48 | Application is built to `./dist/` when compiled by the `make build` task. 49 | 50 | ## Releases 51 | 52 | Tag-based releases to GitHub have been automated. Providence-backed Release Automation is configured for JSR.io on each update. Npm is subject to manual release by Maintainers due to being transformed to Node.js compatible format. 53 | 54 | GitHub Releases are created for informational purposes. 55 | 56 | ## Acknowledgements 57 | 58 | - Necktrox: Previous Author (Marek Kulik) 59 | -------------------------------------------------------------------------------- /deno.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@amethyst/discord-emoji", 3 | "version": "2.5.3", 4 | "exports": { 5 | ".": "./mod.ts" 6 | }, 7 | // Compiler Options 8 | "compilerOptions": { 9 | "lib": [ 10 | "deno.ns", 11 | "deno.worker", 12 | "deno.unstable", 13 | "dom.asynciterable" 14 | ], 15 | "allowUnreachableCode": false, 16 | "allowUnusedLabels": false, 17 | "exactOptionalPropertyTypes": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "noImplicitAny": true, 20 | "noImplicitOverride": true, 21 | "noImplicitReturns": true, 22 | "noImplicitThis": true, 23 | "noPropertyAccessFromIndexSignature": true, 24 | "noUncheckedIndexedAccess": true, 25 | "noUnusedLocals": true, 26 | "noUnusedParameters": true, 27 | "strict": true, 28 | "strictBindCallApply": true, 29 | "strictFunctionTypes": true, 30 | "strictNullChecks": true, 31 | "strictPropertyInitialization": true, 32 | "useUnknownInCatchVariables": true, 33 | "checkJs": false 34 | }, 35 | // Linting Options 36 | "lint": { 37 | "rules": { 38 | "tags": [ 39 | "recommended" 40 | ], 41 | "include": [ 42 | "ban-untagged-todo", 43 | "camelcase", 44 | "default-param-last", 45 | "eqeqeq", 46 | "explicit-function-return-type", 47 | "explicit-module-boundary-types", 48 | "guard-for-in", 49 | "no-console", 50 | "no-const-assign", 51 | "no-eval", 52 | "no-external-import", 53 | "no-self-compare", 54 | "no-sparse-arrays", 55 | "no-sync-fn-in-async-fn", 56 | "no-throw-literal", 57 | "no-undef", 58 | "prefer-ascii", 59 | "single-var-declarator", 60 | "triple-slash-reference", 61 | "verbatim-module-syntax" 62 | ] 63 | } 64 | }, 65 | // Formatting Options 66 | "fmt": { 67 | "useTabs": false, 68 | "lineWidth": 512, 69 | "indentWidth": 2, 70 | "semiColons": true, 71 | "singleQuote": true, 72 | "proseWrap": "always" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /deno.lock: -------------------------------------------------------------------------------- 1 | { 2 | "version": "4", 3 | "specifiers": { 4 | "jsr:@david/code-block-writer@^13.0.2": "13.0.3", 5 | "jsr:@deno/cache-dir@~0.10.3": "0.10.3", 6 | "jsr:@deno/dnt@*": "0.41.3", 7 | "jsr:@deno/dnt@0.41.3": "0.41.3", 8 | "jsr:@deno/graph@~0.73.1": "0.73.1", 9 | "jsr:@std/assert@0.223": "0.223.0", 10 | "jsr:@std/assert@0.226": "0.226.0", 11 | "jsr:@std/assert@1.0.11": "1.0.11", 12 | "jsr:@std/bytes@0.223": "0.223.0", 13 | "jsr:@std/fmt@0.223": "0.223.0", 14 | "jsr:@std/fmt@1": "1.0.5", 15 | "jsr:@std/fs@0.223": "0.223.0", 16 | "jsr:@std/fs@1": "1.0.13", 17 | "jsr:@std/fs@~0.229.3": "0.229.3", 18 | "jsr:@std/internal@^1.0.5": "1.0.5", 19 | "jsr:@std/io@0.223": "0.223.0", 20 | "jsr:@std/json@1": "1.0.1", 21 | "jsr:@std/jsonc@1.0.1": "1.0.1", 22 | "jsr:@std/path@0.223": "0.223.0", 23 | "jsr:@std/path@1": "1.0.8", 24 | "jsr:@std/path@1.0.0-rc.1": "1.0.0-rc.1", 25 | "jsr:@std/path@^1.0.8": "1.0.8", 26 | "jsr:@std/path@~0.225.2": "0.225.2", 27 | "jsr:@ts-morph/bootstrap@0.24": "0.24.0", 28 | "jsr:@ts-morph/common@0.24": "0.24.0", 29 | "npm:@types/node@*": "22.12.0" 30 | }, 31 | "jsr": { 32 | "@david/code-block-writer@13.0.3": { 33 | "integrity": "f98c77d320f5957899a61bfb7a9bead7c6d83ad1515daee92dbacc861e13bb7f" 34 | }, 35 | "@deno/cache-dir@0.10.3": { 36 | "integrity": "eb022f84ecc49c91d9d98131c6e6b118ff63a29e343624d058646b9d50404776", 37 | "dependencies": [ 38 | "jsr:@deno/graph", 39 | "jsr:@std/fmt@0.223", 40 | "jsr:@std/fs@0.223", 41 | "jsr:@std/io", 42 | "jsr:@std/path@0.223" 43 | ] 44 | }, 45 | "@deno/dnt@0.41.3": { 46 | "integrity": "b2ef2c8a5111eef86cb5bfcae103d6a2938e8e649e2461634a7befb7fc59d6d2", 47 | "dependencies": [ 48 | "jsr:@david/code-block-writer", 49 | "jsr:@deno/cache-dir", 50 | "jsr:@std/fmt@1", 51 | "jsr:@std/fs@1", 52 | "jsr:@std/path@1", 53 | "jsr:@ts-morph/bootstrap" 54 | ] 55 | }, 56 | "@deno/graph@0.73.1": { 57 | "integrity": "cd69639d2709d479037d5ce191a422eabe8d71bb68b0098344f6b07411c84d41" 58 | }, 59 | "@std/assert@0.223.0": { 60 | "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24" 61 | }, 62 | "@std/assert@0.226.0": { 63 | "integrity": "0dfb5f7c7723c18cec118e080fec76ce15b4c31154b15ad2bd74822603ef75b3" 64 | }, 65 | "@std/assert@1.0.11": { 66 | "integrity": "2461ef3c368fe88bc60e186e7744a93112f16fd110022e113a0849e94d1c83c1", 67 | "dependencies": [ 68 | "jsr:@std/internal" 69 | ] 70 | }, 71 | "@std/bytes@0.223.0": { 72 | "integrity": "84b75052cd8680942c397c2631318772b295019098f40aac5c36cead4cba51a8" 73 | }, 74 | "@std/fmt@0.223.0": { 75 | "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208" 76 | }, 77 | "@std/fmt@1.0.5": { 78 | "integrity": "0cfab43364bc36650d83c425cd6d99910fc20c4576631149f0f987eddede1a4d" 79 | }, 80 | "@std/fs@0.223.0": { 81 | "integrity": "3b4b0550b2c524cbaaa5a9170c90e96cbb7354e837ad1bdaf15fc9df1ae9c31c" 82 | }, 83 | "@std/fs@0.229.3": { 84 | "integrity": "783bca21f24da92e04c3893c9e79653227ab016c48e96b3078377ebd5222e6eb", 85 | "dependencies": [ 86 | "jsr:@std/path@1.0.0-rc.1" 87 | ] 88 | }, 89 | "@std/fs@1.0.13": { 90 | "integrity": "756d3ff0ade91c9e72b228e8012b6ff00c3d4a4ac9c642c4dac083536bf6c605", 91 | "dependencies": [ 92 | "jsr:@std/path@^1.0.8" 93 | ] 94 | }, 95 | "@std/internal@1.0.5": { 96 | "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" 97 | }, 98 | "@std/io@0.223.0": { 99 | "integrity": "2d8c3c2ab3a515619b90da2c6ff5ea7b75a94383259ef4d02116b228393f84f1", 100 | "dependencies": [ 101 | "jsr:@std/assert@0.223", 102 | "jsr:@std/bytes" 103 | ] 104 | }, 105 | "@std/json@1.0.1": { 106 | "integrity": "1f0f70737e8827f9acca086282e903677bc1bb0c8ffcd1f21bca60039563049f" 107 | }, 108 | "@std/jsonc@1.0.1": { 109 | "integrity": "6b36956e2a7cbb08ca5ad7fbec72e661e6217c202f348496ea88747636710dda", 110 | "dependencies": [ 111 | "jsr:@std/json" 112 | ] 113 | }, 114 | "@std/path@0.223.0": { 115 | "integrity": "593963402d7e6597f5a6e620931661053572c982fc014000459edc1f93cc3989", 116 | "dependencies": [ 117 | "jsr:@std/assert@0.223" 118 | ] 119 | }, 120 | "@std/path@0.225.2": { 121 | "integrity": "0f2db41d36b50ef048dcb0399aac720a5348638dd3cb5bf80685bf2a745aa506", 122 | "dependencies": [ 123 | "jsr:@std/assert@0.226" 124 | ] 125 | }, 126 | "@std/path@1.0.0-rc.1": { 127 | "integrity": "b8c00ae2f19106a6bb7cbf1ab9be52aa70de1605daeb2dbdc4f87a7cbaf10ff6" 128 | }, 129 | "@std/path@1.0.8": { 130 | "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" 131 | }, 132 | "@ts-morph/bootstrap@0.24.0": { 133 | "integrity": "a826a2ef7fa8a7c3f1042df2c034d20744d94da2ee32bf29275bcd4dffd3c060", 134 | "dependencies": [ 135 | "jsr:@ts-morph/common" 136 | ] 137 | }, 138 | "@ts-morph/common@0.24.0": { 139 | "integrity": "12b625b8e562446ba658cdbe9ad77774b4bd96b992ae8bd34c60dbf24d06c1f3", 140 | "dependencies": [ 141 | "jsr:@std/fs@~0.229.3", 142 | "jsr:@std/path@~0.225.2" 143 | ] 144 | } 145 | }, 146 | "npm": { 147 | "@types/node@22.12.0": { 148 | "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", 149 | "dependencies": [ 150 | "undici-types" 151 | ] 152 | }, 153 | "undici-types@6.20.0": { 154 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" 155 | } 156 | }, 157 | "redirects": { 158 | "https://esm.sh/@types/boolbase@~1.0.3/index.d.ts": "https://esm.sh/@types/boolbase@1.0.3/index.d.ts", 159 | "https://esm.sh/@types/safer-buffer@~2.1.3/index.d.ts": "https://esm.sh/@types/safer-buffer@2.1.3/index.d.ts", 160 | "https://esm.sh/boolbase@^1.0.0?target=denonext": "https://esm.sh/boolbase@1.0.0?target=denonext", 161 | "https://esm.sh/cheerio": "https://esm.sh/cheerio@1.0.0", 162 | "https://esm.sh/cheerio-select@^2.1.0?target=denonext": "https://esm.sh/cheerio-select@2.1.0?target=denonext", 163 | "https://esm.sh/css-select@^5.1.0?target=denonext": "https://esm.sh/css-select@5.1.0?target=denonext", 164 | "https://esm.sh/css-what@^6.1.0?target=denonext": "https://esm.sh/css-what@6.1.0?target=denonext", 165 | "https://esm.sh/dom-serializer@^2.0.0?target=denonext": "https://esm.sh/dom-serializer@2.0.0?target=denonext", 166 | "https://esm.sh/domelementtype@^2.3.0?target=denonext": "https://esm.sh/domelementtype@2.3.0?target=denonext", 167 | "https://esm.sh/domhandler@^5.0.3?target=denonext": "https://esm.sh/domhandler@5.0.3?target=denonext", 168 | "https://esm.sh/domutils@^3.0.1?target=denonext": "https://esm.sh/domutils@3.2.2?target=denonext", 169 | "https://esm.sh/domutils@^3.1.0?target=denonext": "https://esm.sh/domutils@3.2.2?target=denonext", 170 | "https://esm.sh/encoding-sniffer@^0.2.0?target=denonext": "https://esm.sh/encoding-sniffer@0.2.0?target=denonext", 171 | "https://esm.sh/entities@^4.2.0?target=denonext": "https://esm.sh/entities@4.5.0?target=denonext", 172 | "https://esm.sh/entities@^4.5.0/lib/decode?target=denonext": "https://esm.sh/entities@4.5.0/lib/decode?target=denonext", 173 | "https://esm.sh/entities@^4.5.0/lib/escape?target=denonext": "https://esm.sh/entities@4.5.0/lib/escape?target=denonext", 174 | "https://esm.sh/htmlparser2@^9.1.0?target=denonext": "https://esm.sh/htmlparser2@9.1.0?target=denonext", 175 | "https://esm.sh/iconv-lite@^0.6.3?target=denonext": "https://esm.sh/iconv-lite@0.6.3?target=denonext", 176 | "https://esm.sh/nth-check@^2.0.1?target=denonext": "https://esm.sh/nth-check@2.1.1?target=denonext", 177 | "https://esm.sh/parse5-htmlparser2-tree-adapter@^7.0.0?target=denonext": "https://esm.sh/parse5-htmlparser2-tree-adapter@7.1.0?target=denonext", 178 | "https://esm.sh/parse5-parser-stream@^7.1.2?target=denonext": "https://esm.sh/parse5-parser-stream@7.1.2?target=denonext", 179 | "https://esm.sh/parse5@^7.0.0?target=denonext": "https://esm.sh/parse5@7.2.1?target=denonext", 180 | "https://esm.sh/parse5@^7.1.2?target=denonext": "https://esm.sh/parse5@7.2.1?target=denonext", 181 | "https://esm.sh/safer-buffer@^2.1.2?target=denonext": "https://esm.sh/safer-buffer@2.1.2?target=denonext", 182 | "https://esm.sh/undici@^6.19.5?target=denonext": "https://esm.sh/undici@6.21.1?target=denonext", 183 | "https://esm.sh/whatwg-encoding@^3.1.1?target=denonext": "https://esm.sh/whatwg-encoding@3.1.1?target=denonext", 184 | "https://esm.sh/whatwg-mimetype@^4.0.0?target=denonext": "https://esm.sh/whatwg-mimetype@4.0.0?target=denonext" 185 | }, 186 | "remote": { 187 | "https://deno.land/x/cheerio@1.0.7/mod.ts": "3165160f0fe6507408115377a3e55d3cb3095ee1878d5f9b740e84c2d1dc1e0a", 188 | "https://esm.sh/boolbase@1.0.0/denonext/boolbase.mjs": "70e9521b9532b5e4dc0c807422529b15b4452663dbdb70dff9c7b65d0ff2e3cb", 189 | "https://esm.sh/boolbase@1.0.0?target=denonext": "5d10bc2e0fb13eedfc6859bffbeb5a6f08679797fa8740c7d821841c2e22945f", 190 | "https://esm.sh/cheerio-select@2.1.0/denonext/cheerio-select.mjs": "755b7da4011b67a75d1140d76c503cd6929c7213454debf5b6ebc086b73fa9d9", 191 | "https://esm.sh/cheerio-select@2.1.0?target=denonext": "ae26d1996b4bb1d701cb7095e1c2ed7310e5fe88c3786efc26ceb6168ce1513d", 192 | "https://esm.sh/cheerio@1.0.0": "cc561c217d49ac3194a2105520c4e195ba0cbffca153b4aeb5b5050c5a63f9ee", 193 | "https://esm.sh/cheerio@1.0.0/denonext/cheerio.mjs": "b89bf3f826c9b00c19ff88aa3243d82b18bb9d7607c000b70985d3f70d68a0e7", 194 | "https://esm.sh/cheerio@1.0.0/denonext/utils.mjs": "ef275ba049974692f75e97c696cb3f5e6fcbbbc3a782d2bf6febb4598bc668aa", 195 | "https://esm.sh/css-select@5.1.0/denonext/css-select.mjs": "73fe74e279149f98c8dbc173c54f7425199677b29e20bcf630020544a5324ee6", 196 | "https://esm.sh/css-select@5.1.0?target=denonext": "650d758890a760f4b8eb3e8e18e4060cec308d936d30613c09829f6b6cecb9da", 197 | "https://esm.sh/css-what@6.1.0/denonext/css-what.mjs": "b16cd5c84fc437a3e0f5a2ada73c2202d99400ec22c7eafb41ace95871c7f49f", 198 | "https://esm.sh/css-what@6.1.0?target=denonext": "308ca80cb48b37e11669a2d108c5d8939bcfa8b6c9ad8a7ec4aca0b474f774c7", 199 | "https://esm.sh/dom-serializer@2.0.0/denonext/dom-serializer.mjs": "545028b1d2c25bae5cbfe6930a28a2e4f7f05e1a0d09bbd0f3f5f9a33df8e3bd", 200 | "https://esm.sh/dom-serializer@2.0.0?target=denonext": "1626b2b8326556ea2816b5f9bf7522bc9581d545fd9ad117c066ab7a5ff1fb89", 201 | "https://esm.sh/domelementtype@2.3.0/denonext/domelementtype.mjs": "4f3b57348729cd517560139eb1969ca2fe9cc58c5188abe56e7336d5cb557cc0", 202 | "https://esm.sh/domelementtype@2.3.0?target=denonext": "2beb2a1e3d18892a9b00ef9528811b93f613a77d2b6fb25376ec0f109ac48a4f", 203 | "https://esm.sh/domhandler@5.0.3/denonext/domhandler.mjs": "3fb258a3d79bc9066a568bb6b09ce946d1fcfa2636a24ae80a4db220956e0873", 204 | "https://esm.sh/domhandler@5.0.3?target=denonext": "298fde249b7bff9e80667cfe643e7d4b390871b77b0928d086ce4c0b8fc570e2", 205 | "https://esm.sh/domutils@3.2.2/denonext/domutils.mjs": "f0b4e80e73810ed6f3d8c4e1822feef89208f32c88b6024a84328d02f5f77c40", 206 | "https://esm.sh/domutils@3.2.2?target=denonext": "7e487176c61dfd1dfdbcfd1195e7329a64f53421511561b69c570a6cff0a6167", 207 | "https://esm.sh/encoding-sniffer@0.2.0/denonext/encoding-sniffer.mjs": "f7197cde30a736915639025e2a4459996e4e2e3948a0b4eeedf67cfbc9cc3b7f", 208 | "https://esm.sh/encoding-sniffer@0.2.0/denonext/sniffer.mjs": "c58580cf2d2ddce058aff8a57a19f83ab2b3ed56cd3ea8213fe6d22b532b4abc", 209 | "https://esm.sh/encoding-sniffer@0.2.0?target=denonext": "303a1a7732560440d8d6512f599c0066f6095b3f7b26feb049e38d20da1c68dd", 210 | "https://esm.sh/entities@4.5.0/denonext/entities.mjs": "4a9306e4021ae1079e83b5db26e1678c536fa69c8f2839802bc3cc43282cef08", 211 | "https://esm.sh/entities@4.5.0/denonext/lib/decode.mjs": "ef22e25f6bca668e40c4f7d4ecaebe2172a833a18372d55b54f997d0d8702dcd", 212 | "https://esm.sh/entities@4.5.0/denonext/lib/escape.mjs": "116aef78e5ff05efa6f79851b8b59da025ab88f5c25d2262f73df98f4d57c3fa", 213 | "https://esm.sh/entities@4.5.0/lib/decode?target=denonext": "488bc8401a0c85a76527d61a41352c5371904aeda57a136eb10ccfadcd2f7c8c", 214 | "https://esm.sh/entities@4.5.0/lib/escape?target=denonext": "5a9169bd35526d3a3740b3d4aaed9a4ac0b43eecaa456252a379dabb5074a0ef", 215 | "https://esm.sh/entities@4.5.0?target=denonext": "f6bc559c07f40e94b3ef50f0b24e2666a2258db3b6697bf4da8fd2fc014ef7a1", 216 | "https://esm.sh/htmlparser2@9.1.0/denonext/htmlparser2.mjs": "c66451d0cf754ff574ace956b4f375046f6558ecc80478751a02ac424ea55381", 217 | "https://esm.sh/htmlparser2@9.1.0/denonext/lib/esm/Parser.mjs": "a90fca18b664f12a6197c42e038a218659500a5403fff22bb4f03c00d186dd5d", 218 | "https://esm.sh/htmlparser2@9.1.0/denonext/lib/esm/Tokenizer.mjs": "5bd2cb001d1e2b6bfe3d34e73f60db922f14652caa46039b897e06635633aed7", 219 | "https://esm.sh/htmlparser2@9.1.0?target=denonext": "c45715271b3924d41b412d0dd1736ffa1a9a0bf721e3c7c382fa9b6d483b6fb8", 220 | "https://esm.sh/iconv-lite@0.6.3/denonext/iconv-lite.mjs": "58314c9a1d16db741c1edb519849067c19f931ea0331a2e3ad5c02b1dcf2f82a", 221 | "https://esm.sh/iconv-lite@0.6.3?target=denonext": "4fae49808d7dec9e1855f930198aa4d71c2dba33a8f98db26b756b619da0f872", 222 | "https://esm.sh/nth-check@2.1.1/denonext/nth-check.mjs": "2b0541d4564b27c31b37b006329c64036bee04a4c8f14e8357037fd7d35ecfe4", 223 | "https://esm.sh/nth-check@2.1.1?target=denonext": "689135c5e0e825a2a89058636f1b3a497040597c17de9107c703e9d764d22e25", 224 | "https://esm.sh/parse5-htmlparser2-tree-adapter@7.1.0/denonext/parse5-htmlparser2-tree-adapter.mjs": "7bfd000e678a20d0648da01bf5a9bc85188b3d10e4e079525324d336d9a4a4a2", 225 | "https://esm.sh/parse5-htmlparser2-tree-adapter@7.1.0?target=denonext": "c3f6c7adc65cd1bc13b5fb95d1cd40cdb1250d49488c5252156d3fde0947b0e4", 226 | "https://esm.sh/parse5-parser-stream@7.1.2/denonext/parse5-parser-stream.mjs": "8aa99bf063a8d88b5ee8c55882454828ba1d46961c3a17380dc88321c6a3eb68", 227 | "https://esm.sh/parse5-parser-stream@7.1.2?target=denonext": "c20ec8395eae11e4a4046be4ecf1764067f28e154f8e10044b4a24dae0ac1844", 228 | "https://esm.sh/parse5@7.2.1/denonext/parse5.mjs": "de52f4e91aa9b18afc13befa7cff696c46a0e339510fc48f1f120720330c7a6e", 229 | "https://esm.sh/parse5@7.2.1?target=denonext": "830ccab36e4cdce029bbc48d458800f77854076a78c44696a005cb1fd3bc81a9", 230 | "https://esm.sh/safer-buffer@2.1.2/denonext/safer-buffer.mjs": "63b601ca3ed03a32349ca04538ac898f2c520dbc6b554246d11c482c31e8a6b8", 231 | "https://esm.sh/safer-buffer@2.1.2?target=denonext": "381ed15e73b07affd71d58c070213d027e4b8951c381f44e5f80589d3ea9957b", 232 | "https://esm.sh/undici@6.21.0/types/handlers": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", 233 | "https://esm.sh/undici@6.21.0/types/interceptors": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", 234 | "https://esm.sh/undici@6.21.0/types/retry-handler": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", 235 | "https://esm.sh/undici@6.21.1/denonext/undici.mjs": "bbbe503d42e243174555a5e6069346264853f6fa0e225afc511f76c274255a20", 236 | "https://esm.sh/undici@6.21.1/types/handlers": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", 237 | "https://esm.sh/undici@6.21.1/types/interceptors": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", 238 | "https://esm.sh/undici@6.21.1/types/retry-handler": "fabf6997a3adf11e45d11e3c4d58d0634ab98f9d72f3116f3694123818ccd457", 239 | "https://esm.sh/undici@6.21.1?target=denonext": "ad485b87c8d7f2725fbaf6470fec983d98dbcaa079186b856ee589a4b5a82a8e", 240 | "https://esm.sh/whatwg-encoding@3.1.1/denonext/whatwg-encoding.mjs": "771c409a89b301144c200fe8520bce25a72b9108068a5a57e21b76670549bccb", 241 | "https://esm.sh/whatwg-encoding@3.1.1?target=denonext": "0e24061fe35afd2b2c93625e4288c643837ae8d491abf572a067b55ecce45c1f", 242 | "https://esm.sh/whatwg-mimetype@4.0.0/denonext/whatwg-mimetype.mjs": "077315581483d77f815ed7e227ea4bf7ffdda61b211b471053c4bca423a7fd54", 243 | "https://esm.sh/whatwg-mimetype@4.0.0?target=denonext": "a0a0b4ee5d006be602d7e01eee5347c950d89662d502d72db5ba6daa60e92a3d" 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /deps.ts: -------------------------------------------------------------------------------- 1 | // JSR 2 | export { build } from 'jsr:@deno/dnt@0.41.3'; 3 | export { parse } from 'jsr:@std/jsonc@1.0.1'; 4 | 5 | -------------------------------------------------------------------------------- /dev/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | deno run -A ./util/build-mod.ts 5 | -------------------------------------------------------------------------------- /dev/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # DevOps: githooked - https://xcykrix.github.io/githooked.html#githooked-installation-and-help 5 | curl -s https://api.github.com/repos/xCykrix/githooked/releases/latest | 6 | grep "browser_download_url.*/githooked/.*/githooked" | 7 | cut -d : -f 2,3 | 8 | tr -d \" | 9 | wget -qi - -O githooked.prod 10 | chmod +x githooked.prod 11 | ./githooked.prod install 12 | rm ./githooked.prod 13 | -------------------------------------------------------------------------------- /dev/validate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | deno test -A 5 | -------------------------------------------------------------------------------- /mod.test.ts: -------------------------------------------------------------------------------- 1 | // deno-lint-ignore no-external-import 2 | import { assertEquals } from 'jsr:@std/assert@1.0.11'; 3 | import * as dismoji from './mod.ts'; 4 | 5 | /** 6 | * ID: Function. 7 | * Description: Test to validate the function the main application code. 8 | * Scope: mod.ts 9 | */ 10 | Deno.test('Function', async (t) => { 11 | await t.step('validate', () => { 12 | assertEquals(dismoji.people.grinning, '😀'); 13 | assertEquals(dismoji.nature.dog, '🐶'); 14 | assertEquals(dismoji.food.hamburger, '🍔'); 15 | assertEquals(dismoji.activity.basketball, '🏀'); 16 | assertEquals(dismoji.travel.airplane, '✈️'); 17 | assertEquals(dismoji.objects.watch, '⌚'); 18 | assertEquals(dismoji.symbols.eight_pointed_black_star, '✴️'); 19 | assertEquals(dismoji.flags.flag_us, '🇺🇸'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /util/build-dnt.ts: -------------------------------------------------------------------------------- 1 | // deno-lint-ignore no-external-import 2 | import { build } from 'jsr:@deno/dnt'; 3 | import { parse } from '../deps.ts'; 4 | 5 | const configuration = await parse(await Deno.readTextFile(new URL('../deno.jsonc', import.meta.url))) as { 6 | version: string; 7 | }; 8 | 9 | export const DNTConfig = { 10 | name: 'discord-emoji', 11 | description: 'A near exact emoji tables of Discord for string-based insertion of emotes without having to escape Unicode.', 12 | }; 13 | 14 | await build({ 15 | entryPoints: ['./mod.ts'], 16 | outDir: './dist/', 17 | shims: { 18 | deno: true, 19 | }, 20 | package: { 21 | name: DNTConfig.name, 22 | description: DNTConfig.description, 23 | version: configuration.version, 24 | license: 'MIT', 25 | author: 'Samuel Voeller (https://github.com/xCykrix/discord_emoji)', 26 | homepage: 'https://github.com/xCykrix/discord_emoji', 27 | repository: { 28 | type: 'git', 29 | url: 'git@github.com/xCykrix/discord_emoji.git', 30 | }, 31 | }, 32 | filterDiagnostic(diagnostic): boolean { 33 | if (diagnostic.file?.fileName.includes('@std')) return false; 34 | if (diagnostic.file?.fileName.includes('.test.ts')) return false; 35 | return true; 36 | }, 37 | }); 38 | 39 | Deno.copyFileSync('LICENSE', 'dist/LICENSE'); 40 | Deno.copyFileSync('README.md', 'dist/README.md'); 41 | -------------------------------------------------------------------------------- /util/build-mod.ts: -------------------------------------------------------------------------------- 1 | // deno-lint-ignore-file no-console 2 | // deno-lint-ignore no-external-import 3 | import { cheerio } from 'https://deno.land/x/cheerio@1.0.7/mod.ts'; 4 | 5 | interface EmojiIndex { 6 | [key: string]: IndividualEmojiIndex; 7 | } 8 | interface IndividualEmojiIndex { 9 | [key: string]: { 10 | names: string[]; 11 | surrogates: string; 12 | diversityChildren?: IndividualEmojiIndex; 13 | }; 14 | } 15 | 16 | async function assets(): Promise { 17 | console.info('Downloading UI...'); 18 | 19 | // Build Request State 20 | const result = await fetch( 21 | 'https://discord.com/channels/@me/1', 22 | ); 23 | const html = await result.text(); 24 | const $ = cheerio.load(html); 25 | 26 | // Pull all script assets from discord.com 27 | const urls: string[] = []; 28 | 29 | // Parse Script Tags 30 | const scripts = $('script'); 31 | console.info('Building the list of indexed assets...'); 32 | // deno-lint-ignore no-explicit-any 33 | scripts.each((_index: number, element: any) => { 34 | urls.push($(element).attr('src')!); 35 | }); 36 | 37 | // Parse Link Tags 38 | const links = $('link'); 39 | // deno-lint-ignore no-explicit-any 40 | links.each((_index: number, element: any) => { 41 | urls.push($(element).attr('href')!); 42 | }); 43 | 44 | // Return Filtered & Log Count 45 | const filtered = urls.filter((v) => v !== undefined && v.endsWith('.js')); 46 | console.info( 47 | `Finished building the indexed asset list. Found: ${filtered.length}.`, 48 | ); 49 | return filtered; 50 | } 51 | 52 | // Process Indexed Assets 53 | console.info('Processing the list of indexed assets.'); 54 | let result: EmojiIndex = {}; 55 | for (const asset of await assets()) { 56 | // Download and convert the asset to text in memory individually. 57 | // deno-lint-ignore no-await-in-loop 58 | const source = await fetch(`https://discord.com${asset}`); 59 | // deno-lint-ignore no-await-in-loop 60 | let js = await source.text(); 61 | 62 | // Skip the assets which do not include the expected snippet. 63 | if (!js.includes(`e.exports=JSON.parse('{"people":[`)) { 64 | console.info(`Skipped: ${asset}`); 65 | continue; 66 | } 67 | 68 | // Asset found. Extract emoji index. 69 | console.info(`Found emoji-index within: ${asset}`); 70 | js = js.toString().match( 71 | /(e\.exports=JSON.parse\('{"people":.*"unicodeVersion":6}]}'\))/gm, 72 | )![0]; 73 | // Extract to file and build with eval. 74 | const src = ` 75 | class EIndex { 76 | webpackChunkdiscord_app = [] 77 | e = { exports: {} } 78 | 79 | constructor() { 80 | _REPLACE_ME_WITH_JS_SRC 81 | } 82 | 83 | extract() { 84 | this.webpackChunkdiscord_app[0][1]['838426'](this.e) 85 | } 86 | 87 | recall() { 88 | return this.e; 89 | } 90 | } 91 | new EIndex(); 92 | `.replace('_REPLACE_ME_WITH_JS_SRC', js).replace( 93 | 'e.exports', 94 | 'this.e.exports', 95 | ); 96 | 97 | // deno-lint-ignore no-eval 98 | const extract = eval(src); 99 | result = extract.e.exports as EmojiIndex; 100 | console.info('Extracted the emoji-index.'); 101 | break; 102 | } 103 | 104 | // Define the outer scope needed to process the emoji-index. 105 | const groups: string[] = []; 106 | const output: string[] = [ 107 | // NOTE: This is the output file. Not this build file directly. Changes to THIS file are potentially accepted. 108 | '// deno-lint-ignore-file prefer-ascii', 109 | '// This file is generated automatically with "deno task build" and should not be modified manually.', 110 | '// Please do not commit changes to this file. They will be rejected regardless of proposed changes.', 111 | '//', 112 | `// GENERATED: ${new Date()}`, 113 | '', 114 | ]; 115 | let group = ''; 116 | let scope: { name: string; value: string }[] = []; 117 | 118 | for (const k of Object.keys(result)) { 119 | // Build the deep scope of the individual category. 120 | group = k; 121 | groups.push(k); 122 | for (const i of Object.values(result[k]!)) { 123 | for (const n of i.names) { 124 | scope.push({ name: n, value: i.surrogates }); 125 | } 126 | if (i.diversityChildren !== undefined) { 127 | for (const d of Object.values(i.diversityChildren!)) { 128 | for (const n of d.names) { 129 | scope.push({ name: n, value: d.surrogates }); 130 | } 131 | } 132 | } 133 | } 134 | 135 | // Process the category to output. 136 | const state = [ 137 | `/** The '${group}' set of emojis from Discord. */`, 138 | `const ${group} = {`, 139 | ]; 140 | for (const v of scope) { 141 | state.push(` "${v.name}": "${v.value}",`); 142 | } 143 | state.push('}', ''); 144 | output.push(state.join('\n')); 145 | group = ''; 146 | scope = []; 147 | } 148 | 149 | // Process the compiled category to output. 150 | const state = [ 151 | 'export {', 152 | ]; 153 | for (const g of groups) { 154 | state.push(` ${g},`); 155 | } 156 | state.push('}', ''); 157 | output.push(state.join('\n')); 158 | 159 | // Read Comparison 160 | const current = await Deno.readTextFile('./mod.ts'); 161 | const next = output.join('\n'); 162 | 163 | if (current.replace(/\/\/ GENERATED:.*$/gm, 'COMP_DIFF') !== next.replace(/\/\/ GENERATED:.*$/gm, 'COMP_DIFF')) { 164 | // Write to the output. 165 | console.info('File Different.'); 166 | await Deno.writeTextFile( 167 | './mod.ts', 168 | next, 169 | ); 170 | } else { 171 | console.info('File Identical.'); 172 | } 173 | --------------------------------------------------------------------------------