generated from nhcarrigan/template
feat: last bit of polish
Some checks failed
Node.js CI / Lint and Test (pull_request) Failing after 37s
Some checks failed
Node.js CI / Lint and Test (pull_request) Failing after 37s
This commit is contained in:
@@ -5,7 +5,10 @@
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"lint": "eslint ./src --max-warnings 0",
|
||||
"build": "prisma generate && tsc",
|
||||
"start": "op run --env-file=./prod.env -- node ./prod/index.js",
|
||||
"test": "echo 'No tests yet' && exit 0"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getEntitlement } from "../modules/getEntitlement.js";
|
||||
import { getSkuLimit } from "../modules/getSkuLimit.js";
|
||||
import { sendUnentitledResponse } from "../modules/sendUnintitledResponse.js";
|
||||
import { errorHandler } from "../utils/errorHandler.js";
|
||||
import { logger } from "../utils/logger.js";
|
||||
import type { Command } from "../interfaces/command.js";
|
||||
|
||||
/**
|
||||
@@ -31,9 +32,21 @@ export const add: Command = async(lynira, interaction) => {
|
||||
return;
|
||||
}
|
||||
const url = interaction.options.getString("url", true);
|
||||
const slugExists = await lynira.db.links.findFirst({ where: {
|
||||
slug,
|
||||
} });
|
||||
const isValidUrl = /^https?:\/\/(?:[\da-z-]+\.)+[a-z]{2,}(?:\/\S*)?$/i.test(
|
||||
url,
|
||||
);
|
||||
if (!isValidUrl) {
|
||||
await logger.log("debug", `Provided URL did not match expected pattern: ${url}`);
|
||||
await interaction.editReply({
|
||||
content: "The provided URL is not valid. Please provide a valid URL.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
const slugExists = await lynira.db.links.findFirst({
|
||||
where: {
|
||||
slug,
|
||||
},
|
||||
});
|
||||
if (slugExists) {
|
||||
await interaction.editReply({
|
||||
content: "This slug is already in use. Please choose a different one.",
|
||||
@@ -63,6 +76,10 @@ export const add: Command = async(lynira, interaction) => {
|
||||
await interaction.editReply({
|
||||
content: `Short URL created. Visit <https://lynira.link/${slug}> to access it. Please note that for the safety of our users, you will not be able to edit this short link.`,
|
||||
});
|
||||
await logger.log(
|
||||
"info",
|
||||
`User ${interaction.user.id} created a short URL with slug "${slug}" pointing to "${url}".`,
|
||||
);
|
||||
} catch (error) {
|
||||
await errorHandler(error, "add command");
|
||||
await interaction.editReply({
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { getEntitlement } from "../modules/getEntitlement.js";
|
||||
import { sendUnentitledResponse } from "../modules/sendUnintitledResponse.js";
|
||||
import { errorHandler } from "../utils/errorHandler.js";
|
||||
import { logger } from "../utils/logger.js";
|
||||
import type { Command } from "../interfaces/command.js";
|
||||
|
||||
/**
|
||||
@@ -40,6 +41,7 @@ export const remove: Command = async(lynira, interaction) => {
|
||||
await interaction.editReply({
|
||||
content: `Short URL <https://lynira.link/${slug}> has been removed. Please note that for the safety of our users, this slug will not be available for reuse.`,
|
||||
});
|
||||
await logger.log("info", `User ${interaction.user.id} removed a short URL with slug "${slug}".`);
|
||||
} catch (error) {
|
||||
await errorHandler(error, "remove command");
|
||||
await interaction.editReply({
|
||||
|
||||
13
src/index.ts
13
src/index.ts
@@ -5,8 +5,8 @@
|
||||
*/
|
||||
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { Client, Events, MessageFlags } from "discord.js";
|
||||
import { handlers } from "./config/handlers.js";
|
||||
import { Client, Events } from "discord.js";
|
||||
import { processCommand } from "./modules/processCommand.js";
|
||||
import { instantiateServer } from "./server/serve.js";
|
||||
import { logger } from "./utils/logger.js";
|
||||
import type { Lynira } from "./interfaces/lynira.js";
|
||||
@@ -26,16 +26,11 @@ lynira.discord.on("error", (error) => {
|
||||
|
||||
lynira.discord.on(Events.InteractionCreate, (interaction) => {
|
||||
if (interaction.isChatInputCommand()) {
|
||||
void interaction.deferReply({
|
||||
flags: [ MessageFlags.Ephemeral ],
|
||||
});
|
||||
const { commandName } = interaction;
|
||||
// eslint-disable-next-line no-underscore-dangle -- Accessing private property for command handler.
|
||||
void (handlers[commandName] ?? handlers._default)(lynira, interaction);
|
||||
void processCommand(lynira, interaction);
|
||||
}
|
||||
});
|
||||
|
||||
await lynira.db.$connect();
|
||||
await lynira.discord.login(process.env.DISCORD_TOKEN);
|
||||
await lynira.discord.login(process.env.BOT_TOKEN);
|
||||
|
||||
instantiateServer(lynira);
|
||||
|
||||
@@ -9,5 +9,6 @@ export enum SKU {
|
||||
PERSONAL = "1404602103434973186",
|
||||
PROFESSIONAL = "1404602584404328573",
|
||||
BUSINESS = "1404602909370613931",
|
||||
ENTERPRISE = "1404603245963513898",
|
||||
ENTERPRISE = "1404653451224416317",
|
||||
ORGANISATION = "1404603245963513898",
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { type Entitlement, EntitlementType } from "discord.js";
|
||||
import { SKU } from "../interfaces/skus.js";
|
||||
import type { Lynira } from "../interfaces/lynira.js";
|
||||
import type { Entitlement } from "discord.js";
|
||||
|
||||
/**
|
||||
* Fetches an entitlement for a user. Only looks at the first ACTIVE entitlement.
|
||||
@@ -17,6 +18,27 @@ export const getEntitlement = async(
|
||||
lynira: Lynira,
|
||||
userId: string,
|
||||
): Promise<Entitlement | null> => {
|
||||
if (userId === "465650873650118659") {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Mock entitlement for Naomi.
|
||||
return {
|
||||
applicationId: lynira.discord.application?.id ?? "",
|
||||
consumed: false,
|
||||
deleted: false,
|
||||
endsAt: null,
|
||||
endsTimestamp: null,
|
||||
guild: null,
|
||||
guildId: null,
|
||||
id: "enterprise-entitlement-id",
|
||||
isActive: () => {
|
||||
return true;
|
||||
},
|
||||
skuId: SKU.ENTERPRISE,
|
||||
startsAt: null,
|
||||
startsTimestamp: null,
|
||||
type: EntitlementType.ApplicationSubscription,
|
||||
userId: "465650873650118659",
|
||||
} as Entitlement;
|
||||
}
|
||||
const entitlements = await lynira.discord.application?.entitlements.fetch({
|
||||
excludeDeleted: true,
|
||||
excludeEnded: true,
|
||||
|
||||
@@ -17,11 +17,14 @@ export const getSkuLimit = (sku: SKU | string): number => {
|
||||
return 10;
|
||||
}
|
||||
if (sku === SKU.PROFESSIONAL) {
|
||||
return 50;
|
||||
return 25;
|
||||
}
|
||||
if (sku === SKU.BUSINESS) {
|
||||
return 100;
|
||||
}
|
||||
if (sku === SKU.ORGANISATION) {
|
||||
return 250;
|
||||
}
|
||||
if (sku === SKU.ENTERPRISE) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
23
src/modules/processCommand.ts
Normal file
23
src/modules/processCommand.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @copyright nhcarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { MessageFlags } from "discord.js";
|
||||
import { handlers } from "../config/handlers.js";
|
||||
import type { Command } from "../interfaces/command.js";
|
||||
|
||||
/**
|
||||
* Process a command interaction.
|
||||
* @param lynira - The Lynira instance.
|
||||
* @param interaction - The interaction to process.
|
||||
*/
|
||||
export const processCommand: Command = async(lynira, interaction) => {
|
||||
await interaction.deferReply({
|
||||
flags: [ MessageFlags.Ephemeral ],
|
||||
});
|
||||
const { commandName } = interaction;
|
||||
// eslint-disable-next-line no-underscore-dangle -- Accessing private property for command handler.
|
||||
await (handlers[commandName] ?? handlers._default)(lynira, interaction);
|
||||
};
|
||||
Reference in New Issue
Block a user