diff --git a/.circleci/config.yml b/.circleci/config.yml index ed2d5f0f4..a5690f6e5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,7 +21,7 @@ jobs: docker: - image: docker:latest steps: - - run: + - run: name: Git command: apk add --update git - checkout @@ -80,8 +80,8 @@ jobs: . venv/bin/activate mkdocs build docs-deploy: - docker: - - image: python:3.5 + machine: + image: circleci/classic:latest steps: - checkout - restore_cache: @@ -96,7 +96,10 @@ jobs: paths: - "venv" - run: - name: Compile + name: Build JS + command: npm run build + - run: + name: Build docs command: | . venv/bin/activate mkdocs build @@ -136,4 +139,4 @@ workflows: branches: ignore: /.*/ tags: - only: /v.+/ \ No newline at end of file + only: /v.+/ diff --git a/.eslintignore b/.eslintignore index 394522f42..1a3bf52da 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ -node_modules/** \ No newline at end of file +node_modules/** +docs/js/dist/* diff --git a/.gitignore b/.gitignore index 79ec904d5..7001c41ad 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,7 @@ typings/ # Docs build site + +# Command info dump +commandInfo.json +docs/js/dist/commands.js* diff --git a/docs/commands.md b/docs/commands.md index 18c2750b7..49ac64ef2 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -8,84 +8,40 @@ This is the command reference for WildBeast. You can find more elaborative infor !!! tip Send the message **++help ** (Prefix may vary) to the bot to get further information on any given command. -Some commands on this page will have an empty **Usage** field. This means that the command takes no arguments and is accepted as such. +## Gotchas -Parameters marked with **** are supposed to be replaced by other values. Do not incude the actual braces in the command. Similarly, **@user** placeholders refer to mentions. Parameters surrounded by **[brackets]** signify parameters that may be omitted. +1. Some commands on this page will have an empty **Usage** field. This means that the command takes no arguments and is accepted as such. + +2. Parameters marked with **** are supposed to be replaced by other values. Do not incude the actual braces in the command. Similarly, **@user** placeholders refer to mentions. Parameters surrounded by **[brackets]** signify parameters that may be omitted. + +3. Commands in the **NSFW** category have been labeled as not safe for work and can only be used in a channel that has been marked as NSFW in the channel settings. + +Additional command information: + +[Addendums](#addendums)
+[Tag subcommands](#tag-subcommands)
+[Settings subcommands](#settings-subcommands)
+[Available meme types](#available-meme-types) ## Commands -### Admin - -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| addrole | Give a role to user or users. | addrole @user @user2 **** | Manage Roles | -| takerole | Take a role from a user or users. | takerole @user @user2 **** | Manage Roles | -| colorrole | Change the color of a role. | colorrole **** ****[^1] | Manage Roles | -| kick | Kick a user. | kick @user **[reason]** | Kick Members | -| ban | Ban a user. | ban @user **[reason]** | Ban Members | -| softban | Softban[^2] a user. | softban @user **[reason]** | Ban Members | -| hackban | Ban a user by ID. | hackban **** **[reason]** | Ban Members | -| purge | Delete multiple messages at once. | purge **[author]** @user **** | Manage Messages | -| leaveserver | Make the bot leave the current server. | | 10 | - -### Fun - -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| advice | Get some clever advice. | | 0 | -| catfact | Get a cat fact. | | 0 | -| dice | Roll the dice. | | 0 | -| dogfact | Get a dog fact. | | 0 | -| fact | Get a random fact. | | 0 | -| fancyinsult | Insult someone in a fancy manner. | | 0 | -| gif | Search Giphy for a gif. | gif **** | 0 | -| leetspeak | Encode a message into l337sp3@K. | leetspeak **** | 0 | -| magic8ball | Ask the magic 8-ball for advice. | magic8ball **** | 0 | -| meme | Create a meme. | meme **** "upper text" "lower text"[^3] | 0 | -| randomcat | Get a random cat picture. | | 0 | -| randomdog | Get a random dog picture. | | 0 | -| randomcat | Get a random meme from Imgur. | | 0 | -| stroke | Stroke someone's ego. | stroke **** | 0 | -| twitch | Check if a streamer is live on Twitch. | twitch **** | 0 | -| urbandictionary | Get the definition of a word from the Urban Dictionary. | urbandictionary **** | 0 | -| xkcd | Get a random XKCD comic, or supply a number to get that particular comic. | xkcd **[comic number]** | 0 | -| yesno | Get a GIF saying yes or no. | | 0 | -| yomomma | Get a random yo momma joke. | | 0 | - -### Music - -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| join-voice | Make the bot join a voice channel. Optionally supply a track to play on join. | join-voice **[track link]** | 1 | -| leave-voice | Make the boit leave the current voice channel. | | 1 | -| nowplaying | Show the currently playing track. | | 1 | -| pause | Pause the playback of the current track. | | 1 | -| queue | Show the playback queue. | | 1 | -| request | Add a track to the playback queue. | request ****[^4] | 1 | -| resume | Resume the playback of the current track. | | 1 | -| shuffle | Shuffle the playback queue. | | 1 | -| skip | Skip the current song. | | 1 | -| volume | Change the playback volume. | volume **<0-100\>** | 1 | - -### NSFW - -!!! warning "NSFW content" - These commands are labeled as not safe for work and can only be used within a channel that is marked as NSFW via the channel settings. - -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| booru | Query various booru sites for images. | booru **** **** | 0 | -| e621 | Query e621 for an image. | e621 **** | 0 | -| rule34 | Query rule34 for an image. | rule34 **** | 0 | - -### Tags +
+ +## Addendums + +1. For the **colorrole** command, a hexadecimal value can be submitted in either **#FFFFFF** or **FFFFFF** format. +2. The **softban** command bans a user and then immediately unbans them, deleting their messages without barring future access to the server. +3. The **request** command supports playing from the following resources: YouTube, SoundCloud, Bandcamp, Twitch, Vimeo, Mixer and raw HTML audio. + +## Tag subcommands + +The tag command has the following subcommands. All subcommands inherit the permission level of the main command. !!! tip You can use JagTag formatting with the **tag create** command. See [the JagTag-JS documentation](https://thesharks.github.io/JagTag-JS/users/intro) for more information on how. -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| tag | Base command for tags. Returns a tag if specified. | tag **** | 0 (Applies to all subcommands) | +| Name | Description | Usage | +| ---- | ----------- | ----- | | tag create | Create a tag. | tag create **** **** | | tag delete | Delete a tag. | tag delete **** | | tag edit | Edit an existing tag. | tag edit **** **** | @@ -93,16 +49,12 @@ Parameters marked with **** are supposed to be replaced by other | tag random | Retrieve a random tag from the database. | tag random | | tag raw | Return the raw data of a tag. | tag raw **** | -### Settings +## Settings subcommands -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| settings | Base command for settings. Returns current settings if no setting is specified. | settings **** **** | 5 | -| setlevel | Change someone's permission level. | setlevel @user/@role @user2/@role2 **<0-10\>** | 7 | - -The following settings can be customised. All settings are server-specific. +The following settings can be edited with this command. All settings are server-specific and all subcommands inherit the permission level of the main command. -**Note:** Languages are still WIP. Only the "en" language is supported at the moment. +!!! note + Languages are still WIP. Only the "en" language is supported at the moment. | Name | Description | Usage | | ---- | ----------- | ----- | @@ -112,16 +64,7 @@ The following settings can be customised. All settings are server-specific. | welcomeMessage | Change the welcome message that is sent when a new member joins. | settings welcomeMessage **** | | reset | Reset a setting to its default value. | settings reset **** | -### Utility - -| Name | Description | Usage | Level/Required permission | -| ---- | ----------- | ----- | ------------------------- | -| info | Return information about the bot. | | 0 | -| ping | Return the bot's pseudo-ping. | | 0 | -| say | Make the bot send a message of your choice. | say **** | 0 | -| userinfo | Return information about a user ID, mention or name. Omit parameters to return information about yourself. | userinfo **** | 0 | - -### Available meme types +## Available meme types The values in the **Name** column of the table below correspond to the relevant meme ID on https://api.imgflip.com/popular_meme_ids. @@ -165,8 +108,3 @@ The values in the **Name** column of the table below correspond to the relevant | philosoraptor | 61516 | | 3rdworldsuccess | 101287 | | ancientaliens | 101470 | - -[^1]: A hexadecimal value can be submitted in either **#FFFFFF** or **FFFFFF** format. -[^2]: Softbanning includes banning a user and immediately unbanning them, removing their messages without barring their access in future. -[^3]: Including the quotes in the text values is important. -[^4]: Supported resources: YouTube, SoundCloud, Bandcamp, Twitch, Vimeo, Mixer and raw HTML audio. diff --git a/docs/js/dist/.gitempty b/docs/js/dist/.gitempty new file mode 100644 index 000000000..ef2f629d6 --- /dev/null +++ b/docs/js/dist/.gitempty @@ -0,0 +1 @@ +Dist versions of JavaScript files in the 'src' directory will go here. It's generally a bad idea to modify the files in this directory. diff --git a/docs/js/src/commands.js b/docs/js/src/commands.js new file mode 100644 index 000000000..64f3e62c4 --- /dev/null +++ b/docs/js/src/commands.js @@ -0,0 +1,127 @@ +// Tool to dynamically generate command documentation + +function generateCommandDocs (commandInfo) { + if (commandInfo) { // Only run if commandInfo is defined to prevent unexpected results + if (window.location.pathname === '/commands/') { // Only run if in the commands doc + const commandCategories = extractCategories(commandInfo) + const globalContainer = document.getElementById('commands-table') + + commandCategories.forEach(cmdCat => { + // Create header + const h3 = document.createElement('h3') + h3.setAttribute('id', cmdCat.toLowerCase()) + h3.innerHTML = cmdCat + + // Create table + const commandsInCategory = extractCommandsFromCategory(commandInfo, cmdCat) + + // Only proceed if there are commands in the category (Avoids "ghost tables") + if (commandsInCategory && commandsInCategory.length > 0) { + const table = generateHTMLTable(commandsInCategory) + + globalContainer.appendChild(h3) + globalContainer.appendChild(table) + } + }) + } + } +} + +// Extract categories from all commands +function extractCategories (commandInfo) { + const categories = [] + + for (const command in commandInfo) { + const category = commandInfo[command].module || 'Uncategorised' + if (!categories.includes(category)) categories.push(category) + } + + return categories +} + +function extractCommandsFromCategory (commandInfo, categoryToExtract) { + const commandsInCategory = [] + + for (const cmd in commandInfo) { + if (!commandInfo[cmd].doNotDocument) { // Ignore commands marked as non-documented + commandInfo[cmd].name = cmd // Allows later tracking of command name + const categoryOfCommand = commandInfo[cmd].module || 'Uncategorised' + if (categoryOfCommand === categoryToExtract) commandsInCategory.push(commandInfo[cmd]) + } + } + + return commandsInCategory +} + +// Generate a table for a category +function generateHTMLTable (commandsInCategory) { + const table = document.createElement('table') + + const header = constructHeader() + const body = constructBody(commandsInCategory) + + table.insertAdjacentElement('afterbegin', header) + table.insertAdjacentElement('beforeend', body) + + return table +} + +// Construct the table header +function constructHeader () { + const thead = document.createElement('thead') + const headerRow = document.createElement('tr') + + const headers = [ + 'Name', + 'Description', + 'Usage', + 'Level', + 'Required permissions' + ] + + // Construct header row + headers.forEach(header => { + const th = document.createElement('th') + th.innerHTML = header + headerRow.insertAdjacentElement('beforeend', th) + }) + + thead.appendChild(headerRow) + + // Append + return thead +} + +// Construct the table body +function constructBody (commands) { + const tbody = document.createElement('tbody') + + // Construct a row per command + commands.forEach(cmdObj => { + const tr = document.createElement('tr') + + const usage = cmdObj.usage ? `${cmdObj.name} ${sanitiseUsage(cmdObj.usage)}` : ' ' + const rowContent = `${cmdObj.name}${cmdObj.help}${usage}${cmdObj.level || '0'}${cmdObj.permAddons || ' '}` + tr.innerHTML = rowContent + + // Append + tbody.insertAdjacentElement('beforeend', tr) + return tbody + }) + + return tbody +} + +function sanitiseUsage (usageString) { + if (!usageString) return ' ' + + // Escape tags + usageString = usageString.replace('<', '<').replace('>', '>') + + return usageString +} + +// Run +generateCommandDocs() + +// DO NOT TOUCH ANYTHING BELOW THIS - MANAGED BY CI diff --git a/mkdocs.yml b/mkdocs.yml index cda38af43..9d4c69bb4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,6 +39,9 @@ extra: - type: 'github' link: 'https://github.com/TheSharks' +extra_javascript: + - js/dist/commands.js + extra_css: - css/style.css diff --git a/package-lock.json b/package-lock.json index d18366db4..a3c66693a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1229,6 +1229,17 @@ "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1682,6 +1693,15 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -2567,6 +2587,12 @@ "hoek": "4.x.x" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", @@ -3197,6 +3223,24 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "dev": true + } + } + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -3208,6 +3252,12 @@ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", + "dev": true + }, "user-home": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", diff --git a/package.json b/package.json index 7328af39e..4f6ea2c38 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,14 @@ "main": "index.js", "scripts": { "start": "node index.js", - "start-docs": "mkdocs serve", + "start-docs": "npm run generate-command-data && mkdocs serve", + "build": "npm run generate-command-data && npm run minify", + "minify": "uglifyjs --compress --mangle --toplevel --output docs/js/dist/commands.js -- docs/js/dist/commands.js.temp", "test": "eslint . && mocha", "dbcreate": "node src/internal/db-init.js", - "infodump": "node src/internal/info-dump.js" + "info-dump": "node src/internal/info-dump.js", + "append-command-info": "node src/internal/command-info-appender.js", + "generate-command-data": "npm run info-dump && npm run append-command-info" }, "repository": { "type": "git", @@ -33,8 +37,10 @@ "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.7.0", "eslint-plugin-standard": "^3.1.0", + "fs-extra": "^6.0.1", "mocha": "^5.2.0", - "standard": "^10.0.3" + "standard": "^10.0.3", + "uglify-es": "^3.3.9" }, "dependencies": { "@thesharks/jagtag-js": "^1.0.3", diff --git a/src/commands/addrole.js b/src/commands/addrole.js index 9cad0e273..4239fb783 100644 --- a/src/commands/addrole.js +++ b/src/commands/addrole.js @@ -5,7 +5,8 @@ module.exports = { module: 'Admin', level: 0, noDM: true, - alias: ['applyrole'] + alias: ['applyrole'], + permAddons: ['Manage Roles'] }, fn: function (msg, suffix) { const guildPerms = msg.member.permission.json diff --git a/src/commands/ban.js b/src/commands/ban.js index ba5d561a5..abffd1d39 100644 --- a/src/commands/ban.js +++ b/src/commands/ban.js @@ -4,7 +4,8 @@ module.exports = { usage: '@user [reason]', module: 'Admin', level: 0, - noDM: true + noDM: true, + permAddons: ['Ban Members'] }, fn: function (msg, suffix) { const bot = global.bot diff --git a/src/commands/eval.js b/src/commands/eval.js index 836b2a633..e08798a77 100644 --- a/src/commands/eval.js +++ b/src/commands/eval.js @@ -1,7 +1,8 @@ module.exports = { meta: { help: 'Evaluate arbitrary Javascript code.', - level: Infinity + level: Infinity, + doNotDocument: true }, fn: (msg, suffix) => { const util = require('util') diff --git a/src/commands/hackban.js b/src/commands/hackban.js index b9f5fdeb0..4c6224d81 100644 --- a/src/commands/hackban.js +++ b/src/commands/hackban.js @@ -5,7 +5,8 @@ module.exports = { module: 'Admin', level: 0, noDM: true, - alias: ['banbyid', 'idban'] + alias: ['banbyid', 'idban'], + permAddons: ['Ban Members'] }, fn: function (msg, suffix) { let bot = global.bot diff --git a/src/commands/kick.js b/src/commands/kick.js index 585b91073..eeab6bc10 100644 --- a/src/commands/kick.js +++ b/src/commands/kick.js @@ -5,7 +5,8 @@ module.exports = { module: 'Admin', level: 0, noDM: true, - alias: ['boot'] + alias: ['boot'], + permAddons: ['Kick Members'] }, fn: function (msg, suffix) { let bot = global.bot diff --git a/src/commands/killswitch.js b/src/commands/killswitch.js index 1230341e9..6596c350d 100644 --- a/src/commands/killswitch.js +++ b/src/commands/killswitch.js @@ -2,7 +2,8 @@ module.exports = { meta: { help: 'Instantly terminates the bot process.', level: Infinity, - alias: ['kill'] + alias: ['kill'], + doNotDocument: true }, fn: async (msg) => { await msg.channel.createMessage('Bye.') diff --git a/src/commands/purge.js b/src/commands/purge.js index 8a4ed30d9..7e2bb44fc 100644 --- a/src/commands/purge.js +++ b/src/commands/purge.js @@ -6,7 +6,8 @@ module.exports = { level: 0, timeout: 5, noDM: true, - alias: ['clean', 'filter'] + alias: ['clean', 'filter'], + permAddons: ['Manage Messages'] }, fn: (msg, suffix) => { msg.mentions = msg.mentions.filter(u => u.id !== msg.channel.guild.shard.client.user.id) // why eris... why diff --git a/src/commands/setstatus.js b/src/commands/setstatus.js index 8d08ce43d..dceacfdc9 100644 --- a/src/commands/setstatus.js +++ b/src/commands/setstatus.js @@ -2,7 +2,8 @@ module.exports = { meta: { help: 'Change my playing status on Discord to something else or pass nothing to clear the status!', level: Infinity, - alias: ['status'] + alias: ['status'], + doNotDocument: true }, fn: function (msg, suffix) { const bot = global.bot diff --git a/src/commands/softban.js b/src/commands/softban.js index 9e2571c06..46be948f6 100644 --- a/src/commands/softban.js +++ b/src/commands/softban.js @@ -5,7 +5,8 @@ module.exports = { module: 'Admin', level: 0, alias: ['messageban'], - noDM: true + noDM: true, + permAddons: ['Ban Members'] }, fn: function (msg, suffix) { const bot = global.bot diff --git a/src/commands/tag.js b/src/commands/tag.js index 0fce7c146..60ec33beb 100644 --- a/src/commands/tag.js +++ b/src/commands/tag.js @@ -12,6 +12,7 @@ module.exports = { meta: { help: 'Base command for tags. Returns a tag if specified.', usage: '', + module: 'Tags', level: 0, alias: ['t'], addons: [ diff --git a/src/commands/takerole.js b/src/commands/takerole.js index ec37337fc..c529fce83 100644 --- a/src/commands/takerole.js +++ b/src/commands/takerole.js @@ -5,7 +5,8 @@ module.exports = { module: 'Admin', level: 0, noDM: true, - alias: ['removerole'] + alias: ['removerole'], + permAddons: ['Manage Roles'] }, fn: function (msg, suffix) { const guildPerms = msg.member.permission.json diff --git a/src/internal/command-info-appender.js b/src/internal/command-info-appender.js new file mode 100644 index 000000000..2d1957ccc --- /dev/null +++ b/src/internal/command-info-appender.js @@ -0,0 +1,31 @@ +/* eslint-disable no-extend-native */ + +// Global String.prototype.replace polyfill +String.prototype.replaceAll = function (searchString, replaceString) { + return this.split(searchString).join(replaceString) +} + +const fs = require('fs-extra') +const commandInfo = require('../../commandInfo.json') + +const files = { + source: './docs/js/src/commands.js', + dest: './docs/js/dist/commands.js.temp' +} + +try { + if (fs.existsSync(files.dest)) fs.unlink(files.dest) // Cleanup potential old version + fs.copySync(files.source, files.dest) + // Inject runner code to end of file + fs.appendFileSync(files.dest, `\nconst commandInfo = JSON.parse(\`${cleanupJSON(commandInfo)}\`)\ngenerateCommandDocs(commandInfo)\n`) +} catch (err) { + console.error(err) +} + +function cleanupJSON (parsedJSON) { + let str = JSON.stringify(parsedJSON) + str = str.replaceAll('\\"', '\\\\"') // Properly escape double quotes + str = str.replaceAll('\\n', '\\\\n') // Properly escape newlines + + return str +} diff --git a/src/internal/info-dump.js b/src/internal/info-dump.js index 04a8e3230..c153aca08 100644 --- a/src/internal/info-dump.js +++ b/src/internal/info-dump.js @@ -8,4 +8,4 @@ for (const cmd in dex.commands) { if (dex.commands[cmd].meta.level === Infinity) final[cmd].level = 'Infinity' // lol json } -require('fs').writeFileSync('./info.json', JSON.stringify(final)) +require('fs').writeFileSync('./commandInfo.json', JSON.stringify(final))