From 852e74ec209ff92884be2ac0b5abff1d0b93ebac Mon Sep 17 00:00:00 2001
From: Ethan Davidson <31261035+EthanThatOneKid@users.noreply.github.com>
Date: Sat, 13 Apr 2024 00:59:14 -0700
Subject: [PATCH] Introduce `add` and `remove` subcommands (#15)
* introduce `add` subcommand
* add `remove` subcommand
* run `deno task all`
---
app_schema.ts | 51 ++++++----
deno.jsonc | 2 +-
deno.lock | 84 +++++++++++++++-
deps.ts | 6 +-
docs/HANDBOOK.md | 4 +-
lib/shorter/shorter.ts | 6 ++
main.ts | 216 +++++++++++++++++++++++++++--------------
7 files changed, 267 insertions(+), 102 deletions(-)
diff --git a/app_schema.ts b/app_schema.ts
index 9d63917..1649819 100644
--- a/app_schema.ts
+++ b/app_schema.ts
@@ -4,25 +4,40 @@ import type { AppSchema } from "shorter/deps.ts";
export const appSchema = {
chatInput: {
name: "shorter",
- description: "Shorten a URL",
- options: {
- alias: {
- type: discord.ApplicationCommandOptionType.String,
- description: "The alias of the shortlink",
- required: true,
+ description: "Manage shortlinks.",
+ subcommands: {
+ add: {
+ description: "Add a shortlink.",
+ options: {
+ alias: {
+ type: discord.ApplicationCommandOptionType.String,
+ description: "The alias of the shortlink",
+ required: true,
+ },
+ destination: {
+ type: discord.ApplicationCommandOptionType.String,
+ description: "The destination of the shortlink",
+ required: true,
+ },
+ force: {
+ type: discord.ApplicationCommandOptionType.Boolean,
+ description: "Whether to overwrite an existing shortlink",
+ },
+ ttl: {
+ type: discord.ApplicationCommandOptionType.String,
+ description: "The time-to-live of the shortlink",
+ },
+ },
},
- destination: {
- type: discord.ApplicationCommandOptionType.String,
- description: "The destination of the shortlink",
- required: true,
- },
- force: {
- type: discord.ApplicationCommandOptionType.Boolean,
- description: "Whether to overwrite an existing shortlink",
- },
- ttl: {
- type: discord.ApplicationCommandOptionType.String,
- description: "The time-to-live of the shortlink",
+ remove: {
+ description: "Remove a shortlink.",
+ options: {
+ alias: {
+ type: discord.ApplicationCommandOptionType.String,
+ description: "The alias of the shortlink",
+ required: true,
+ },
+ },
},
},
},
diff --git a/deno.jsonc b/deno.jsonc
index ae19755..a1b44f5 100644
--- a/deno.jsonc
+++ b/deno.jsonc
@@ -4,7 +4,7 @@
"udd": "deno run -r --allow-read=. --allow-write=. --allow-net https://deno.land/x/udd/main.ts deps.ts && deno task lock",
"lock": "deno cache --lock=deno.lock --lock-write deps.ts",
"all": "deno task udd && deno lint && deno fmt",
- "start": "deno run -A main.ts",
+ "start": "deno run -A --unstable-kv main.ts",
"ngrok": "ngrok http 8080"
},
"imports": {
diff --git a/deno.lock b/deno.lock
index d6c32cf..ae773d9 100644
--- a/deno.lock
+++ b/deno.lock
@@ -118,7 +118,9 @@
"https://deno.land/std@0.191.0/dotenv/mod.ts": "f5a8123741d1561ae8184a7f043bc097b15132c5171c651142b804b6dbc21853",
"https://deno.land/std@0.191.0/http/http_errors.ts": "b9a18ef97d6c5966964de95e04d1f9f88a0f8bd8577c26fd402d9d632fb03a42",
"https://deno.land/std@0.191.0/http/http_status.ts": "8a7bcfe3ac025199ad804075385e57f63d055b2aed539d943ccc277616d6f932",
- "https://deno.land/std@0.208.0/dotenv/mod.ts": "039468f5c87d39b69d7ca6c3d68ebca82f206ec0ff5e011d48205eea292ea5a6",
+ "https://deno.land/std@0.222.1/dotenv/mod.ts": "0180eaeedaaf88647318811cdaa418cc64dc51fb08354f91f5f480d0a1309f7d",
+ "https://deno.land/std@0.222.1/dotenv/parse.ts": "09977ff88dfd1f24f9973a338f0f91bbdb9307eb5ff6085446e7c423e4c7ba0c",
+ "https://deno.land/std@0.222.1/dotenv/stringify.ts": "275da322c409170160440836342eaa7cf012a1d11a7e700d8ca4e7f2f8aa4615",
"https://deno.land/x/codemod@0.0.5/deps.ts": "5e27f88433fb872ab1873b104c4301825d2d16c5c37165a7b989a71e62ae908a",
"https://deno.land/x/codemod@0.0.5/github/api/github_api_client.ts": "0574f97e834c215f6151e420cf821bceb745750a7a4d4fcc60eb897b486d1f98",
"https://deno.land/x/codemod@0.0.5/github/api/github_api_client_interface.ts": "16e7466539ad7f50dc6fa2a3d1fcdee4407336ffb94643ab3e783e76f03e309b",
@@ -221,15 +223,89 @@
"https://deno.land/x/discord_api_types@0.37.65/utils/internals.ts": "cb70895ba89f7947c38f7fa447b0190cb14b5585be323414cda53d2ccb19b16c",
"https://deno.land/x/discord_api_types@0.37.65/utils/v10.ts": "056bd036f8c65365ff28eb63ec6897811d51921cca6d068392dd1ca5b397ae62",
"https://deno.land/x/discord_api_types@0.37.65/v10.ts": "f3f23492c59e77859aba5b34431edf3668c37f722d7f70c2e1ef7ba4bcda3010",
+ "https://deno.land/x/discord_api_types@0.37.79/gateway/common.ts": "c568382f2e1a8bdf5c5d37b622c32ad5428b70ea9eb6abef40914ce4e4de56a0",
+ "https://deno.land/x/discord_api_types@0.37.79/gateway/v10.ts": "572a1c3bfc7f564cffcd0312d282c6e0b494cd14fef7106edd77f96c7fc97fa2",
+ "https://deno.land/x/discord_api_types@0.37.79/globals.ts": "7d8879654c4741ac071668ad52f2659bcdb66694cfe7da306c8437ec752807a7",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/common.ts": "f4e3a52801ec5e93c55177531a0a09b6ee9d0b5d7172e1e51c042bd58cce8c2e",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/attachment.ts": "c66dccd54c1b84d073f2e1caa466e551b8045a84a2e8a88a1bfbc7e2c64a703d",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/base.ts": "f6a2556e14d489e1f0e5ddeb3a0303e2603e25330530dd9263e176013c5f51eb",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/boolean.ts": "65e29561b61785ca4ede4b1b4a88c5fc0696cfdf1fa74d5197588c196ee7ae98",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/channel.ts": "73c7fc49de242e1ce3be958375fd810750aed83553ef3860e3cddf858f9eb464",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/integer.ts": "a25d24a3e54d647c7039b99e3208fc0fc2228d174f6dcc421e93919b8154a011",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/mentionable.ts": "742e42857465866e0c08b587d7fb5ccd81d4705c61ce4cd6b97ad5692e88e969",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/number.ts": "be974ea68f5fdf55d7a7f5d3faf48a3193777d432b1aa9087afc204bcb916284",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/role.ts": "a57114d0f7eeee4ab7cf217a865dd9dbd9096d007c556aec6185d64257100f41",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/shared.ts": "de4aee14f9cd21e8dbff6c523cb90be9f4273893347fef00930919a976f598b6",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/string.ts": "33ab12dab64544a70729b9b66b5a9790964ea779f05d4ab1a1e190e7c1b59e98",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/subcommand.ts": "0013737da6d2b54e2f413fbf31cf9c84ea51bd9204b615cb4fd19b420f856cb2",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/subcommandGroup.ts": "db5cc701bcb3d68c094de409da39c9a2b8834dc0d5038e5f963c96e5eaf412ac",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/_chatInput/user.ts": "ed2871693744298225ba53ddfb18d3e7afff20a34f413822d5b1193918aea27f",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/chatInput.ts": "1f88245356202857d7a38d21af8ea1c96a65d7da5563734e5ea4af67ba51d1ae",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/contextMenu.ts": "e40500fa8c61f624575a789516e12d6219ce5299fa88da657963c97772ac00df",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/internals.ts": "5eb5ea13a1247c73c0611886dea09ab8d632a9c5555ff0f33d44cd379fd75a08",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/_applicationCommands/permissions.ts": "5af8dd6bac57e87d1339ab5e1c7465aab5c4e4f4aeac7a4808ff2cc3d1a315fc",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/applicationCommands.ts": "8c42e0a2416819a17b028878780f90f926f889b649f7195a8b95816a1ba9085f",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/autocomplete.ts": "821ae50ff9845cac4b03169dbd4c4b187d8399765eb1f0d658d477c68e4c6136",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/base.ts": "ae318712d1befd8ef225916ef83c236b821f59555f988c158e5399e98289eff6",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/messageComponents.ts": "9248c572492a5ea11a05c4f8f58c99f94b41425794b1133d5dd389127197eabf",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/modalSubmit.ts": "3a02d2d7df5bcdb1ffcd089f15e0d82ab65dcc0cefa904c6e0621f46edac041e",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/ping.ts": "096ce582e9af373649fd5355cccd7424adceaffb73367b5301f1594ef5a3c264",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/_interactions/responses.ts": "ae34794d507b38c2feb7e653fe1f436df194fcef6f945a25deb1ab0842db5b66",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/application.ts": "7ec267bf4b809534c8c5e919a7b1da7b33190f9d545445146e007ddb9d0554f5",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/auditLog.ts": "5a4f411a807665442dfdcc41a3e7d2ce23be902a2e57c365e8f3785d104e3db2",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/autoModeration.ts": "9ccb4408f1c6392d9619fac159997e08e660080b3f9567a1619163a40329e3a2",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/channel.ts": "469d3fe37ae22e6b39c0243dbb38a4927cc419cd346054f39aba681ae95539e2",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/emoji.ts": "b9a30b16e1ec4dc15d6149e59aa48b02ad57a51335b7be5a7f5368db0491b3dd",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/gateway.ts": "a00dd57a6756a98a024502d76381b57a66321b4d91d663de14e325e5ff21ae48",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/guild.ts": "99a524ceebdeec5721262dd436e02051848f154b2830ea94ba7efd4f2b0e2b23",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/guildScheduledEvent.ts": "16073e6dc7193eac59d6de79c1ab1070daf02b9466dccc866100cb7a3780be59",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/interactions.ts": "d2c31c147ec49663dc26c314eb2e764537dbf7f2f82eb1e659ae4dea9609ba41",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/invite.ts": "9785b4467016f73f8d2633cf31f7fd3470e94bfa4ce7ad22fe9ff2dcf1e67ad8",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/mod.ts": "83d68247652307f1587d71ac6983fd795ad7b9d5c92540a65207ea9293b09812",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/monetization.ts": "9a91c8dbb4f4c505e561630f0205f821e6877a5ea74faf4eaad9c154f5cc0d02",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/oauth2.ts": "dfb9f09fb44bf5faaa73ad4488ebe408905907d5fd46404895317f4e7c378489",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/permissions.ts": "5e7990e6dad3e35f8c130dc52de4bbf63afe5d6ad98e1c56b09da3ead94ad5a4",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/stageInstance.ts": "0f7ebce1aba67578f178a7c2aba783b4ec0e639c99d0a353888d678a92685c5c",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/sticker.ts": "6afaf40e19632cad9e3935477ab7d77a163a5d7419f6fdcc122d4762982513ec",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/teams.ts": "101044d8c48a3cbabb60048eff9f69588bdd1ea84d1825de0372b4e23ad7ccbe",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/template.ts": "c6bee171ed0ce61fc8b59de42541a023bdcde62718deb42325397e5c82efdc27",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/user.ts": "27284259de8fc67091cc652c7a6dd91c9e0286c2a6caf329eb17038762a02cc9",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/voice.ts": "62d03a540f2e78e5f3989f71a0ee1ec682ef7306a4fa096f89118cbd82351d47",
+ "https://deno.land/x/discord_api_types@0.37.79/payloads/v10/webhook.ts": "7fc370f40a84f12a6e57ddda7cf2814f15039d6320b46979db0b49d5b91e303b",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/common.ts": "a9a9021e7dda3413dbeffd7584304fb467173f1a44f71d53ca1bb204f57afe2d",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/application.ts": "2a1cbde372ed9a4c9c6486bb5a59448f15565374ed055f93bb44401e028b87ca",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/auditLog.ts": "39a0914b6c51445023d82c3e3e66c9866cbb3cb6774d3e7eac63414ea9bcbfec",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/autoModeration.ts": "3d388fd9a91c34f04b5e3e1b6ffe12029fb48b511f37ff88042325ec6cbc6605",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/channel.ts": "a3dc29bfbe589eb0fdf461bfe32d3efb2cfd16685f88787130438d51b097fcb8",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/emoji.ts": "9f694a1bd63886c62a87b4320f3bfa5d4f534b2d87c317d77d572d10522df3aa",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/gateway.ts": "747cb95c9a8bca4e52423c780d5fc492fb0dab2b6015cd7e51e890e8d51acf29",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/guild.ts": "e6e28477a878897454b02dfa40ba86f30647c54e2a07fa6ddea093f55d438769",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/guildScheduledEvent.ts": "29d361f395d8cd1ecb47550615d19e10793d513cc5ad8d32895da2cc9cd0fd89",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/interactions.ts": "5ffe19bba79304ecc0bf7caa7d8e747688b02440372be537e303750d9ade2e10",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/invite.ts": "28f8e740bdaa782c9d9d504049323762b5c1180348019dc5f9e0a900ec11213e",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/mod.ts": "d1f5103f2d5ac5fd351c824281834abb7810d5dc614d0e14e323910b46336e86",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/monetization.ts": "4ce23e105519637eb0a46aed552d7e71c33924ed927390dc9c5e4a1aa6eeb5da",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/oauth2.ts": "72c27a1d44d4e5dff8ae10619989ad8786a783b477d7f84b9bebfbdd75481006",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/stageInstance.ts": "a090ff8b54f77188323af5d06cdef9c42738edf9a9b0eba8aad3c89d5ac5569f",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/sticker.ts": "1f7f2729308a0ec1fe373b5df7ac71bafc200132f1a06df7e75bf5ce1d1069c1",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/template.ts": "0ad41c3c85571d3c5b0bec3914c678a21f376ec162ef0d3f1f7731a8d1d1009c",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/user.ts": "8ea167fc3537f4af0ec4618a3ee4f74819de9b8eeb588ec228583943844b6e0c",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/voice.ts": "cdbe9d6c39c8f44635d8632bf62a95b8c15877b92c56ddf69df2072bb1a74edc",
+ "https://deno.land/x/discord_api_types@0.37.79/rest/v10/webhook.ts": "7e2b75d68bc543f58c893bc41e268731a85d18b765618b6a3d477c46e76adee1",
+ "https://deno.land/x/discord_api_types@0.37.79/rpc/common.ts": "a693352ffd86ae9e995fb3fbfbfd2be30896257ecb83c5611050f060b08de4ef",
+ "https://deno.land/x/discord_api_types@0.37.79/rpc/v10.ts": "fbaad9f3d73fce88e76b0e52ad5345093f18077e4293937c9ec0ee24415b9a93",
+ "https://deno.land/x/discord_api_types@0.37.79/utils/internals.ts": "9a8b59a45efe216ad88d73036005babe17a475a470a80cbe5d4bba2f5bb7660e",
+ "https://deno.land/x/discord_api_types@0.37.79/utils/v10.ts": "2bf6a001a02e9958d1da37df412c11b04cd6ae2a6df6cfbae6c051088c37474b",
+ "https://deno.land/x/discord_api_types@0.37.79/v10.ts": "f3f23492c59e77859aba5b34431edf3668c37f722d7f70c2e1ef7ba4bcda3010",
"https://deno.land/x/discord_app@0.0.4/app.ts": "9ae505a728d3a43d2fa42cf443605da2115e371df7b42c1d67201ca0cb904515",
"https://deno.land/x/discord_app@0.0.4/app_handler.ts": "8bd6cb6e4bd897c27322e0478c869ced87276e44c0bb7ccf5cbbabaecba9f5fa",
"https://deno.land/x/discord_app@0.0.4/deps.ts": "33b3ad17eef3ae09dd8aaf9a6201e6dcba2f5c412af60c9193f9f956d25903bb",
"https://deno.land/x/discord_app@0.0.4/discord_api.ts": "398d7fec0898fba51735b3d44bd6d012a8203fc0893fa826f7101fbf914bce57",
"https://deno.land/x/discord_app@0.0.4/discord_api_types.ts": "7231c7ecff41407628097a4fe2d08e4afd74f189d2d4346c56c3224b01dd4ebd",
"https://deno.land/x/discord_app@0.0.4/mod.ts": "bbad0ae8c89db1e43ed9dce108854729ddd7a962d41fc4b6035d3d3f7aa8a752",
- "https://deno.land/x/durationjs@v4.1.0/mod.ts": "a7f9d3f38823caa9965f3e61f74a75fb09be548cca2517bd91be7ce15e4b35f1",
- "https://deno.land/x/durationjs@v4.1.0/src/duration.ts": "e0c9a09311c22a6dafb7429081802c85a7920176213215315cbf587c5ea7a5ac",
- "https://deno.land/x/durationjs@v4.1.0/src/in_words.ts": "1839490e2cb17fec2871bf87d6c7f7435c68416f9360d9f140777936d4680137",
+ "https://deno.land/x/durationjs@v4.1.1/mod.ts": "a7f9d3f38823caa9965f3e61f74a75fb09be548cca2517bd91be7ce15e4b35f1",
+ "https://deno.land/x/durationjs@v4.1.1/src/duration.ts": "dd82b556c311c83513b1e0e7184e27bacb7f1fa992518b56dfbdd69b7b79cb5b",
+ "https://deno.land/x/durationjs@v4.1.1/src/in_words.ts": "1839490e2cb17fec2871bf87d6c7f7435c68416f9360d9f140777936d4680137",
"https://deno.land/x/github_api_types@2023-05-17-05-41/mod.ts": "dc3a5cd3176c78085b49601e9c3fccac24809b037929230293255edabafbd0bb",
"https://esm.sh/fast-json-patch@3.1.1": "fd59bab1fabdb3e7e2ce8204aa92113dc451708797021fff6f96b8ff265faedf",
"https://esm.sh/tweetnacl@1.0.3": "4ed2ed58ad038fc065ff844177a0a3a216aedb87e6e25329899ecafb744a6f58",
diff --git a/deps.ts b/deps.ts
index 568eb66..967ae66 100644
--- a/deps.ts
+++ b/deps.ts
@@ -1,8 +1,8 @@
-export * as dotenv from "https://deno.land/std@0.208.0/dotenv/mod.ts";
-export * as discord from "https://deno.land/x/discord_api_types@0.37.65/v10.ts";
+export * as dotenv from "https://deno.land/std@0.222.1/dotenv/mod.ts";
+export * as discord from "https://deno.land/x/discord_api_types@0.37.79/v10.ts";
export * from "https://deno.land/x/codemod@0.0.5/github/mod.ts";
export type { GitHubAPIClientOptions } from "https://deno.land/x/codemod@0.0.5/github/api/mod.ts";
-export { Duration } from "https://deno.land/x/durationjs@v4.1.0/mod.ts";
+export { Duration } from "https://deno.land/x/durationjs@v4.1.1/mod.ts";
export {
type AppSchema,
createApp,
diff --git a/docs/HANDBOOK.md b/docs/HANDBOOK.md
index c7ae98c..916ff7a 100644
--- a/docs/HANDBOOK.md
+++ b/docs/HANDBOOK.md
@@ -116,13 +116,13 @@ on the [ACM CSUF Discord server](https://acmcsuf.com/discord).
- This slash command is only available to members with the `Board` role.
- This slash command is available in all text channels of the
[ACM CSUF Discord server](https://acmcsuf.com/discord).
-- Type `/shorter` in any text channel to use the tool.
+- Type `/shorter add` in any text channel to add a new shortlink.
- Populate both required fields `alias` and `destination` with your desired
alias string and destination string, respectively.
- Press Enter to submit the update.
- Wait for the response from the slash command to confirm the update. This may
take around 3 seconds.
-- Wait for redeployment to complete. This may take around 30 seconds.
+- Wait for redeployment to complete. This may take up to 60 seconds.
---
diff --git a/lib/shorter/shorter.ts b/lib/shorter/shorter.ts
index bd1ed07..956284a 100644
--- a/lib/shorter/shorter.ts
+++ b/lib/shorter/shorter.ts
@@ -21,6 +21,12 @@ export async function shorter(options: ShorterOptions): Promise {
}
if (isAliasToBeRemoved) {
+ if (data[options.data.alias] === undefined) {
+ throw new Error(
+ `the alias \`${options.data.alias}\` does not exist`,
+ );
+ }
+
delete data[options.data.alias];
} else {
data[options.data.alias] = options.data.destination;
diff --git a/main.ts b/main.ts
index 2468655..32e97a9 100644
--- a/main.ts
+++ b/main.ts
@@ -46,89 +46,156 @@ export async function main() {
register: { token: DISCORD_TOKEN },
schema: appSchema,
},
- (interaction) => {
- if (!interaction.member?.user) {
- throw new Error("Invalid request");
- }
-
- if (
- !interaction.member.roles.some((role) => DISCORD_ROLE_ID === role)
- ) {
- throw new Error("Invalid request");
- }
-
- // Make shorter options.
- const shorterOptions: ShorterOptions = {
- githubPAT: GITHUB_TOKEN,
- actor: {
- tag: interaction.member.user.username,
- nick: interaction.member.nick || undefined,
- },
- data: {
- alias: interaction.data.parsedOptions.alias,
- destination: interaction.data.parsedOptions.destination,
- force: interaction.data.parsedOptions.force,
- },
- };
-
- // Invoke the Shorter operation.
- shorter(shorterOptions)
- .then(async (result) => {
- // Parse the TTL duration.
- const ttlDuration = interaction.data.parsedOptions.ttl &&
- Duration.fromString(interaction.data.parsedOptions.ttl);
-
- // Compose the commit message.
- let content =
- `Created commit [${result.message}](https://acmcsuf.com/code/commit/${result.sha})!`;
- if (ttlDuration) {
- // Render to Discord timestamp format.
- // https://gist.github.com/LeviSnoot/d9147767abeef2f770e9ddcd91eb85aa
- const discordTimestamp = toDiscordTimestamp(
- (Date.now() + ttlDuration.raw) * 0.001,
+ {
+ add(interaction) {
+ if (!interaction.member?.user) {
+ throw new Error("Invalid request");
+ }
+
+ if (
+ !interaction.member.roles.some((role) => DISCORD_ROLE_ID === role)
+ ) {
+ return {
+ type: discord.InteractionResponseType.ChannelMessageWithSource,
+ data: {
+ flags: discord.MessageFlags.Ephemeral,
+ content: "You do not have permission to use this command.",
+ },
+ };
+ }
+
+ // Make shorter options.
+ const shorterOptions: ShorterOptions = {
+ githubPAT: GITHUB_TOKEN,
+ actor: {
+ tag: interaction.member.user.username,
+ nick: interaction.member.nick || undefined,
+ },
+ data: {
+ alias: interaction.data.parsedOptions.alias,
+ destination: interaction.data.parsedOptions.destination,
+ force: interaction.data.parsedOptions.force,
+ },
+ };
+
+ // Invoke the Shorter operation.
+ shorter(shorterOptions)
+ .then(async (result) => {
+ // Parse the TTL duration.
+ const ttlDuration = interaction.data.parsedOptions.ttl &&
+ Duration.fromString(interaction.data.parsedOptions.ttl);
+
+ // Compose the commit message.
+ let content =
+ `Created commit [${result.message}](https://acmcsuf.com/code/commit/${result.sha})!`;
+ if (ttlDuration) {
+ // Render to Discord timestamp format.
+ // https://gist.github.com/LeviSnoot/d9147767abeef2f770e9ddcd91eb85aa
+ const discordTimestamp = toDiscordTimestamp(
+ (Date.now() + ttlDuration.raw) * 0.001,
+ );
+ content += `\n\nThis shortlink will expire ${discordTimestamp}.`;
+ }
+
+ // Send the success message.
+ await discordAPI.editOriginalInteractionResponse({
+ botID: DISCORD_CLIENT_ID,
+ botToken: DISCORD_TOKEN,
+ interactionToken: interaction.token,
+ content,
+ });
+
+ // Enqueue the delete operation if TTL is set.
+ if (!ttlDuration) {
+ return;
+ }
+
+ await addTTLMessage(
+ kv,
+ {
+ alias: shorterOptions.data.alias,
+ actor: shorterOptions.actor,
+ },
+ ttlDuration.raw,
);
- content += `\n\nThis shortlink will expire ${discordTimestamp}.`;
- }
-
- // Send the success message.
- await discordAPI.editOriginalInteractionResponse({
- botID: DISCORD_CLIENT_ID,
- botToken: DISCORD_TOKEN,
- interactionToken: interaction.token,
- content,
+ })
+ .catch((error) => {
+ if (error instanceof Error) {
+ discordAPI.editOriginalInteractionResponse({
+ botID: DISCORD_CLIENT_ID,
+ botToken: DISCORD_TOKEN,
+ interactionToken: interaction.token,
+ content: `Error: ${error.message}`,
+ });
+ }
+
+ console.error(error);
});
- // Enqueue the delete operation if TTL is set.
- if (!ttlDuration) {
- return;
- }
-
- await addTTLMessage(
- kv,
- {
- alias: shorterOptions.data.alias,
- actor: shorterOptions.actor,
+ // Acknowledge the interaction.
+ return {
+ type:
+ discord.InteractionResponseType.DeferredChannelMessageWithSource,
+ } satisfies discord.APIInteractionResponseDeferredChannelMessageWithSource;
+ },
+ remove(interaction) {
+ if (!interaction.member?.user) {
+ throw new Error("Invalid request");
+ }
+
+ if (
+ !interaction.member.roles.some((role) => DISCORD_ROLE_ID === role)
+ ) {
+ return {
+ type: discord.InteractionResponseType.ChannelMessageWithSource,
+ data: {
+ flags: discord.MessageFlags.Ephemeral,
+ content: "You do not have permission to use this command.",
},
- ttlDuration.raw,
- );
- })
- .catch((error) => {
- if (error instanceof Error) {
- discordAPI.editOriginalInteractionResponse({
+ };
+ }
+
+ // Make shorter options.
+ const shorterOptions: ShorterOptions = {
+ githubPAT: GITHUB_TOKEN,
+ actor: {
+ tag: interaction.member.user.username,
+ nick: interaction.member.nick || undefined,
+ },
+ data: { alias: interaction.data.parsedOptions.alias },
+ };
+
+ // Invoke the Shorter operation.
+ shorter(shorterOptions)
+ .then(async (result) => {
+ // Send the success message.
+ await discordAPI.editOriginalInteractionResponse({
botID: DISCORD_CLIENT_ID,
botToken: DISCORD_TOKEN,
interactionToken: interaction.token,
- content: `Error: ${error.message}`,
+ content:
+ `Removed \`${interaction.data.parsedOptions.alias}\` in commit [${result.message}](https://acmcsuf.com/code/commit/${result.sha}).`,
});
- }
-
- console.error(error);
- });
+ })
+ .catch((error) => {
+ if (error instanceof Error) {
+ discordAPI.editOriginalInteractionResponse({
+ botID: DISCORD_CLIENT_ID,
+ botToken: DISCORD_TOKEN,
+ interactionToken: interaction.token,
+ content: `Error: ${error.message}`,
+ });
+ }
+
+ console.error(error);
+ });
- // Acknowledge the interaction.
- return {
- type: discord.InteractionResponseType.DeferredChannelMessageWithSource,
- } satisfies discord.APIInteractionResponseDeferredChannelMessageWithSource;
+ // Acknowledge the interaction.
+ return {
+ type:
+ discord.InteractionResponseType.DeferredChannelMessageWithSource,
+ } satisfies discord.APIInteractionResponseDeferredChannelMessageWithSource;
+ },
},
);
@@ -147,6 +214,7 @@ export async function main() {
handleInteraction,
);
}
+
function toDiscordTimestamp(timestamp: number) {
return ``;
}