diff --git a/src/commands/confess.ts b/src/commands/confess.ts
index 0562567..ab6aae7 100644
--- a/src/commands/confess.ts
+++ b/src/commands/confess.ts
@@ -16,21 +16,9 @@
* along with this program. If not, see .
*/
-import {
- ActionRowBuilder,
- ButtonBuilder,
- ButtonStyle,
- ChatInputCommandInteraction,
- EmbedBuilder,
- SlashCommandBuilder,
- TextChannel
-} from "discord.js";
-import { BotClient } from "../bot";
-import { dt } from "../main";
-import { StoreMan } from "../storeman";
-import getRandomColor from "../utils/getRandomColor";
+import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import Logger from "../utils/Logger";
-import { messageOpts } from "../constants";
+import { submitConfession } from "../commandutils";
const logger = new Logger("(/) confess");
@@ -53,145 +41,13 @@ export const data = new SlashCommandBuilder()
export async function execute(interaction: ChatInputCommandInteraction) {
// TODO: This all works as intended, but I'd like for it so be a reusable function
// instead because all of this is used in src/main.ts
- const { id: guildId } = interaction.guild!;
- const { id: userId, displayName: userName } = interaction.user;
+ const messageContent = `"${interaction.options.getString("message")}"`;
+ const attachment = interaction.options.getString("attachment")!;
try {
- // If the user is banned in this guild, don't let them post
- if (dt.isBannedByUser(guildId, userId)) {
- return interaction.reply({
- content: "You are banned from confessions in this server!",
- ...messageOpts
- });
- }
-
- // If no guild info is present for this guild, don't let the user post
- if (!dt.getGuildInfo(guildId)) {
- return interaction.reply({
- content:
- "The bot hasn't been set up yet! Ask the server admins to set it up.",
- ...messageOpts
- });
- }
-
- const confessChannel = dt.getGuildInfo(guildId)!.settings.confessChannel;
- const adminChannel = dt.getGuildInfo(guildId)?.settings.modChannel;
-
- const messageContent = `"${interaction.options.getString("message")}"`;
- const attachment = interaction.options.getString("attachment")!;
-
- const isAttachment = (text: string | null) =>
- text && (text.startsWith("http://") || text.startsWith("https://"));
-
- const color = getRandomColor();
- const messageId = StoreMan.genId();
-
- // Looks like:
- //
- // |
- // | Anonymous Confession a1b2
- // |
- // | "example confession content"
- // |
- //
- const userConfessionEmbed = new EmbedBuilder()
- .setColor(color)
- .setTitle(`Anonymous Confession \`${messageId}\``)
- .setDescription(messageContent);
-
- isAttachment(attachment) && userConfessionEmbed.setImage(attachment);
-
- // Looks like:
- //
- // |
- // | Anonymous Confession a1b2
- // |
- // | "example confession content"
- // |
- // | Author
- // | @user1
- // |
- // | Author ID
- // | 1234567890
- // |
- //
- const adminConfessionEmbed = new EmbedBuilder()
- .setColor(color)
- .setTitle(`Anonymous Confession \`${messageId}\``)
- .setTimestamp(Date.now())
- .setDescription(messageContent)
- .addFields(
- {
- name: "Author",
- value: `<@${userId}>`
- },
- {
- name: "Author ID",
- value: userId
- }
- );
-
- isAttachment(attachment) && adminConfessionEmbed.setImage(attachment);
-
- const submitConfessionButton = new ButtonBuilder()
- .setCustomId("requestSubmit")
- .setLabel("Submit a Confession")
- .setStyle(ButtonStyle.Primary);
-
- // const deleteConfessionButton = new ButtonBuilder()
- // .setCustomId("deleteConfession")
- // .setLabel("Delete")
- // .setStyle(ButtonStyle.Danger);
-
- const actionRow = new ActionRowBuilder().setComponents(
- submitConfessionButton
- // deleteConfessionButton
- );
-
- const message = await (
- BotClient.channels.cache.get(confessChannel!) as TextChannel
- ).send({
- embeds: [userConfessionEmbed],
- components: [actionRow]
- });
-
- adminChannel &&
- (await (BotClient.channels.cache.get(adminChannel!) as TextChannel).send({
- embeds: [adminConfessionEmbed]
- }));
-
- dt.addConfession(
- message,
- messageId,
- userName,
- userId,
- messageContent,
- attachment
- );
-
- const confessionsLength = dt.getGuildInfo(guildId)!.confessions.length;
-
- // If there are 2 or more confessions, remove the previous confession's button components
- if (confessionsLength >= 2) {
- (BotClient.channels.cache.get(confessChannel) as TextChannel).messages
- .fetch(
- dt.getGuildInfo(guildId)!.confessions[confessionsLength - 2].messageId
- )
- .then(message => {
- message.edit({ components: [] });
- })
- .catch(err => {
- logger.error(
- "An error occured removing embeds from the previous message:",
- err
- );
- });
- }
-
- return interaction.reply({
- content: "Confession sent!",
- ...messageOpts
- });
+ attachment
+ ? submitConfession(interaction, messageContent)
+ : submitConfession(interaction, messageContent);
} catch (err) {
logger.error("An error occured:", err);
}
diff --git a/src/commandutils/index.ts b/src/commandutils/index.ts
new file mode 100644
index 0000000..bca0fd6
--- /dev/null
+++ b/src/commandutils/index.ts
@@ -0,0 +1,19 @@
+/*
+ * Confoss: Anonymous confessions for Discord, free as in freedom and price!
+ * Copyright (C) 2024 powermaker450
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+export * from "./submitConfession";
diff --git a/src/commandutils/submitConfession.ts b/src/commandutils/submitConfession.ts
new file mode 100644
index 0000000..3c0d2e1
--- /dev/null
+++ b/src/commandutils/submitConfession.ts
@@ -0,0 +1,168 @@
+import {
+ ActionRowBuilder,
+ ButtonBuilder,
+ ButtonStyle,
+ ChatInputCommandInteraction,
+ EmbedBuilder,
+ inlineCode,
+ Message,
+ ModalSubmitInteraction,
+ TextChannel
+} from "discord.js";
+import { messageOpts } from "../constants";
+import { dt } from "../main";
+import getRandomColor from "../utils/getRandomColor";
+import { StoreMan } from "../storeman";
+import { BotClient } from "../bot";
+import Logger from "../utils/Logger";
+
+const logger = new Logger("submitConfession");
+
+export async function submitConfession(
+ interaction: ChatInputCommandInteraction | ModalSubmitInteraction,
+ messageContent: string,
+ attachmentContent?: string
+) {
+ const { id: guildId } = interaction.guild!;
+ const { id: userId, displayName: username } = interaction.user;
+
+ // If the user is banned in this guild, don't let them post
+ if (dt.isBannedByUser(guildId, userId)) {
+ return interaction.reply({
+ content: "You are banned from confessions in this server!",
+ ...messageOpts
+ });
+ }
+
+ // If no guild info is present for this guild, don't let the user post
+ if (!dt.getGuildInfo(guildId)) {
+ return interaction.reply({
+ content:
+ "The bot hasn't been set up yet! Ask the server admins to set it up.",
+ ...messageOpts
+ });
+ }
+
+ const confessChannel = dt.getGuildInfo(guildId)!.settings.confessChannel;
+ const adminChannel = dt.getGuildInfo(guildId)?.settings.modChannel;
+
+ const isAttachment = (text: string | null) =>
+ text && (text.startsWith("http://") || text.startsWith("https://"));
+
+ const color = getRandomColor();
+ const messageId = StoreMan.genId();
+
+ // Looks like:
+ //
+ // |
+ // | Anonymous Confession a1b2
+ // |
+ // | "example confession content"
+ // |
+ //
+ const userConfessionEmbed = new EmbedBuilder()
+ .setColor(color)
+ .setTitle(`Anonymous Confession ${inlineCode(messageId)}`)
+ .setDescription(messageContent);
+
+ attachmentContent &&
+ isAttachment(attachmentContent) &&
+ userConfessionEmbed.setImage(attachmentContent);
+
+ // Looks like:
+ //
+ // |
+ // | Anonymous Confession a1b2
+ // |
+ // | "example confession content"
+ // |
+ // | Author
+ // | @user1
+ // |
+ // | Author ID
+ // | 1234567890
+ // |
+ //
+ const adminConfessionEmbed = new EmbedBuilder()
+ .setColor(color)
+ .setTitle(`Anonymous Confession ${inlineCode(messageId)}`)
+ .setTimestamp(Date.now())
+ .setDescription(messageContent)
+ .addFields(
+ {
+ name: "Author",
+ value: `<@${userId}>`
+ },
+ {
+ name: "Author ID",
+ value: userId
+ }
+ );
+
+ attachmentContent &&
+ isAttachment(attachmentContent) &&
+ adminConfessionEmbed.setImage(attachmentContent);
+
+ const submitConfessionButton = new ButtonBuilder()
+ .setCustomId("requestSubmit")
+ .setLabel("Submit a Confession")
+ .setStyle(ButtonStyle.Primary);
+
+ // const deleteConfessionButton = new ButtonBuilder()
+ // .setCustomId("deleteConfession")
+ // .setLabel("Delete")
+ // .setStyle(ButtonStyle.Danger);
+
+ const actionRow = new ActionRowBuilder().setComponents(
+ submitConfessionButton
+ // deleteConfessionButton
+ );
+
+ const message = await (
+ BotClient.channels.cache.get(confessChannel!) as TextChannel
+ ).send({
+ embeds: [userConfessionEmbed],
+ components: [actionRow]
+ });
+
+ adminChannel &&
+ (await (BotClient.channels.cache.get(adminChannel!) as TextChannel).send({
+ embeds: [adminConfessionEmbed]
+ }));
+
+ const fields: readonly [Message, string, string, string, string] = [
+ message,
+ messageId,
+ username,
+ userId,
+ messageContent
+ ];
+
+ attachmentContent
+ ? dt.addConfession(...fields, attachmentContent)
+ : dt.addConfession(...fields);
+
+ const confessionsLength = dt.getGuildInfo(guildId)!.confessions.length;
+
+ // If there are 2 or more confessions, remove the previous confession's button components
+ if (confessionsLength >= 2) {
+ (BotClient.channels.cache.get(confessChannel) as TextChannel).messages
+ .fetch(
+ dt.getGuildInfo(guildId)!.confessions[confessionsLength - 2].messageId
+ )
+ .then(message => {
+ message.edit({ components: [] });
+ })
+ .catch(err => {
+ logger.error(
+ "An error occured removing embeds from the previous message:",
+ err
+ );
+ });
+ }
+
+ return interaction.reply({
+ content: "Confession sent!",
+ ...messageOpts
+ });
+}
diff --git a/src/main.ts b/src/main.ts
index fdf02c7..418f2e5 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -16,22 +16,14 @@
* along with this program. If not, see .
*/
-import {
- ActionRowBuilder,
- ButtonBuilder,
- ButtonStyle,
- ChatInputCommandInteraction,
- EmbedBuilder,
- Events,
- TextChannel
-} from "discord.js";
+import { ChatInputCommandInteraction, Events } from "discord.js";
import { BotClient, BOT_TOKEN, deployCommands } from "./bot";
import { commands } from "./commands";
import { StoreMan } from "./storeman";
import Logger from "./utils/Logger";
-import getRandomColor from "./utils/getRandomColor";
import { submit } from "./modals";
import { messageOpts } from "./constants";
+import { submitConfession } from "./commandutils";
export const dt = new StoreMan(StoreMan.checkFile());
const logger = new Logger("Main");
@@ -107,7 +99,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
}
});
-BotClient.on(Events.InteractionCreate, async interaction => {
+BotClient.on(Events.InteractionCreate, interaction => {
if (!interaction.isModalSubmit()) {
return;
}
@@ -119,108 +111,9 @@ BotClient.on(Events.InteractionCreate, async interaction => {
);
try {
- if (dt.isBannedByUser(interaction.guild?.id!, interaction.user.id)) {
- return interaction.reply({
- content: "You are banned from confessions in this server!",
- ...messageOpts
- });
- }
-
- if (!dt.getGuildInfo(interaction.guild?.id!)) {
- return interaction.reply({
- content:
- "The bot hasn't been set up yet! Ask the server admins to set it up.",
- ...messageOpts
- });
- }
-
- const confessChannel = dt.getGuildInfo(interaction.guild?.id!)?.settings
- .confessChannel;
- const adminChannel = dt.getGuildInfo(interaction.guild?.id!)?.settings
- .modChannel;
-
- const isAttachment = (text: string) =>
- text && (text.startsWith("http://") || text.startsWith("https://"));
-
- const color = getRandomColor();
- const messageId = StoreMan.genId();
- const userConfessionEmbed = new EmbedBuilder()
- .setColor(color)
- .setTitle(`Anonymous Confession \`${messageId}\``)
- .setDescription(messageContent);
-
- isAttachment(attachment) && userConfessionEmbed.setImage(attachment);
-
- const adminConfessionEmbed = new EmbedBuilder()
- .setColor(color)
- .setTitle(`Anonymous Confession \`${messageId}\``)
- .setDescription(messageContent)
- .addFields(
- {
- name: "Author",
- value: `<@${interaction.user.id}>`
- },
- {
- name: "Author ID",
- value: interaction.user.id
- }
- );
-
- isAttachment(attachment) && adminConfessionEmbed.setImage(attachment);
-
- const submitConfessionButton = new ButtonBuilder()
- .setCustomId("requestSubmit")
- .setLabel("Submit a Confession")
- .setStyle(ButtonStyle.Primary);
-
- const actionRow = new ActionRowBuilder().setComponents(
- submitConfessionButton
- );
-
- const message = await (
- BotClient.channels.cache.get(confessChannel!) as TextChannel
- ).send({
- embeds: [userConfessionEmbed],
- components: [actionRow]
- });
-
- adminChannel &&
- (await (
- BotClient.channels.cache.get(adminChannel!) as TextChannel
- ).send({
- embeds: [adminConfessionEmbed]
- }));
-
- dt.addConfession(
- message,
- messageId,
- interaction.user.displayName,
- interaction.user.id,
- messageContent,
- attachment
- );
-
- const confessionsLength = dt.getGuildInfo(interaction.guild?.id!)
- ?.confessions.length!;
-
- if (confessionsLength >= 2) {
- await (
- BotClient.channels.cache.get(confessChannel!) as TextChannel
- ).messages
- .fetch(
- dt.getGuildInfo(interaction.guild?.id!)?.confessions[
- confessionsLength - 2
- ].messageId!
- )
- .then(message => {
- message.edit({ components: [] });
- });
- }
-
- return interaction.reply({
- content: "Confession sent!",
- ...messageOpts
- });
+ attachment
+ ? submitConfession(interaction, messageContent)
+ : submitConfession(interaction, messageContent, attachment);
} catch (err) {
logger.error("An error occured:", err);
}
diff --git a/tsconfig.json b/tsconfig.json
index 84d67f2..abf0df7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,110 +1,17 @@
{
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig to read more about this file */
-
- /* Projects */
- // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
- // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
- // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
- // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
- // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
- // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
-
- /* Language and Environment */
- "target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
- // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
- // "jsx": "preserve", /* Specify what JSX code is generated. */
- // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
- // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
- // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
- // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
- // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
- // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
- // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
- // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
- // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
-
- /* Modules */
- "module": "commonjs", /* Specify what module code is generated. */
- "rootDir": "./src", /* Specify the root folder within your source files. */
- // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
- // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
- // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
- // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
- // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
- // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
- // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
- // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
- // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
- // "resolveJsonModule": true, /* Enable importing .json files. */
- // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
- // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
-
- /* JavaScript Support */
- // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
- // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
- // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
-
- /* Emit */
- // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
- // "declarationMap": true, /* Create sourcemaps for d.ts files. */
- // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
- "sourceMap": true, /* Create source map files for emitted JavaScript files. */
- // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
- // "noEmit": true, /* Disable emitting files from a compilation. */
- // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
- "removeComments": true, /* Disable emitting comments. */
- // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
- // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
- "sourceRoot": "./src", /* Specify the root path for debuggers to find the reference source code. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
- // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
- // "newLine": "crlf", /* Set the newline character for emitting files. */
- // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
- // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
- // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
- // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
- // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
-
- /* Interop Constraints */
- // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
- // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
- // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
- // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
- "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
- // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
- "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
-
- /* Type Checking */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
- // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
- // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
- // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
- // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
- // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
- // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
- "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
- // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
- // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
- // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
- // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
- // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
- // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
- // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
- // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
-
- /* Completeness */
- // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
- "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ "target": "es2020",
+ "module": "commonjs",
+ "rootDir": "./src",
+ "sourceMap": true,
+ "outDir": "./dist",
+ "removeComments": true,
+ "sourceRoot": "./src",
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "alwaysStrict": true,
+ "noUnusedLocals": true,
+ "skipLibCheck": true
}
}