diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fa0086a --- /dev/null +++ b/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. \ No newline at end of file diff --git a/apollo.config.js b/apollo.config.js new file mode 100644 index 0000000..4e69f06 --- /dev/null +++ b/apollo.config.js @@ -0,0 +1,8 @@ +module.exports = { + client: { + service: { + name: "pmd-api", + url: "https://api.premid.app/v3" + } + } +}; diff --git a/bin/actions/create.js b/bin/actions/create.js new file mode 100644 index 0000000..ae74557 --- /dev/null +++ b/bin/actions/create.js @@ -0,0 +1,177 @@ +import chalk from "chalk"; +import { access, cp, mkdir, readFile, writeFile } from "fs/promises"; +import inquirer from "inquirer"; +import { Validator } from "jsonschema"; +import ora from "ora"; +import { resolve } from "path"; +import { fileURLToPath } from "url"; +import fetchSchema from "../functions/fetchSchema.js"; +import getDiscordAppUser from "../functions/getDiscordAppUser.js"; +import getDiscordUser from "../functions/getDiscordUser.js"; +import getFolderLetter from "../functions/getFolderLetter.js"; +import isFirstTimeAuthor from "../functions/isFirstTimeAuthor.js"; +import { prefix } from "../util/prefix.js"; +const v = new Validator(); +const discordUser = await getDiscordAppUser(); +const spinner = ora("Fetching Schema...").start(); +const schema = await fetchSchema(); +v.addSchema({ definitions: schema.definitions }); +spinner.stop().clear(); +let serviceAuthor; +const metadata = JSON.parse(await readFile(resolve(fileURLToPath(import.meta.url), "../../../template/metadata.json"), "utf8")); +const res = await inquirer.prompt([ + { + name: "service", + message: "Presence name", + validate: async (input) => { + if (!input) + return "Presence name cannot be empty!"; + const schemaRes = v.validate(input, schema.properties.service); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + if (await serviceExists(input)) + return "Presence already exists!"; + return true; + }, + }, + { + name: "description", + message: "English description of the Presence", + validate: (input) => { + if (!input) + return "Description cannot be empty!"; + const schemaRes = v.validate({ en: input }, schema.properties.description); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + return true; + }, + }, + { + name: "author", + message: "Discord ID of the author", + default: discordUser?.id, + validate: async (input) => { + if (!input) + return "Author cannot be empty!"; + const schemaRes = v.validate({ id: input, name: "" }, schema.properties.author); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + serviceAuthor = discordUser ?? (await getDiscordUser(input)); + if (!serviceAuthor) + return "User not found."; + metadata.author = { + id: input, + name: serviceAuthor.username, + }; + return true; + }, + transformer: (input) => { + return serviceAuthor ? serviceAuthor.username : input; + }, + }, + { + name: "url", + message: "URL of the website (separate multiple URLs with a comma)", + validate: (input) => { + if (!input) + return "URL cannot be empty!"; + let urls; + if (input.split(",").length > 1) + urls = input.split(","); + else + urls = input; + const schemaRes = v.validate(urls, schema.properties.url); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + return true; + }, + }, + { + name: "logo", + message: "Image URL of the logo", + validate: (input) => { + if (!input) + return "Logo cannot be empty!"; + const schemaRes = v.validate(input, schema.properties.logo); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + return true; + }, + }, + { + name: "thumbnail", + message: "Image URL of the thumbnail", + validate: (input) => { + if (!input) + return "Thumbnail cannot be empty!"; + const schemaRes = v.validate(input, schema.properties.thumbnail); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + return true; + }, + }, + { + name: "color", + message: "Theme color of the Presence", + validate: (input) => { + if (!input) + return "Color cannot be empty!"; + const schemaRes = v.validate(input, schema.properties.color); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + return true; + }, + }, + { + name: "tags", + message: "Tags of the Presence (separate multiple tags with a comma)", + validate: (input) => { + if (!input) + return "Tags cannot be empty!"; + const schemaRes = v.validate(input.split(","), schema.properties.tags); + if (!schemaRes.valid) + return schemaRes.errors[0].message; + return true; + }, + }, + { + name: "category", + message: "Category of the service", + type: "list", + choices: schema.properties.category.enum, + }, +]); +const presencePath = resolve(`./websites/${getFolderLetter(res.service)}/${res.service.replace("!", " ").trim()}`); +await mkdir(resolve(presencePath, "dist"), { + recursive: true, +}); +metadata.service = res.service; +metadata.description = { en: res.description }; +metadata.author = { + id: res.author, + name: serviceAuthor.username, +}; +metadata.url = res.url.split(",").length > 1 ? res.url.split(",") : res.url; +metadata.logo = res.logo; +metadata.thumbnail = res.thumbnail; +metadata.color = res.color; +metadata.tags = res.tags.split(","); +metadata.category = res.category; +metadata.version = "1.0.0"; +await writeFile(resolve(presencePath, "metadata.json"), JSON.stringify(metadata, null, "\t")); +await cp(resolve(fileURLToPath(import.meta.url), "../../../template/tsconfig.json"), resolve(presencePath, "tsconfig.json")); +const presenceFileToCopy = (await isFirstTimeAuthor(res.author)) + ? "presence.ts" + : "presence.min.ts"; +await cp(resolve(fileURLToPath(import.meta.url), `../../../template/${presenceFileToCopy}`), resolve(presencePath, "presence.ts")); +console.log(prefix, chalk.green("Presence created! You can now start coding!")); +async function serviceExists(service) { + try { + await access(`./websites/${getFolderLetter(service)}/${service}`); + return true; + } + catch { + return false; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FjdGlvbnMvY3JlYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyRSxPQUFPLFFBQVEsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEdBQUcsTUFBTSxLQUFLLENBQUM7QUFDdEIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBRXBDLE9BQU8sV0FBVyxNQUFNLDZCQUE2QixDQUFDO0FBQ3RELE9BQU8saUJBQWlCLE1BQU0sbUNBQW1DLENBQUM7QUFDbEUsT0FBTyxjQUFjLE1BQU0sZ0NBQWdDLENBQUM7QUFDNUQsT0FBTyxlQUFlLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxpQkFBaUIsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0MsTUFBTSxDQUFDLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztBQUUxQixNQUFNLFdBQVcsR0FBRyxNQUFNLGlCQUFpQixFQUFFLENBQUM7QUFFOUMsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7QUFFbEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxXQUFXLEVBQUUsQ0FBQztBQUVuQyxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0FBRWpELE9BQU8sQ0FBQyxJQUFJ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 \ No newline at end of file diff --git a/bin/actions/modify.js b/bin/actions/modify.js new file mode 100644 index 0000000..3a807e0 --- /dev/null +++ b/bin/actions/modify.js @@ -0,0 +1,203 @@ +import chalk from "chalk"; +import { existsSync } from "fs"; +import { cp, rm } from "fs/promises"; +import { basename, dirname, resolve } from "path"; +import { Command } from "commander"; +import prompts from "prompts"; +import ts from "typescript"; +import { fileURLToPath } from "url"; +import webpack from "webpack"; +import CopyPlugin from "copy-webpack-plugin"; +import { createRequire } from "module"; +import getFolderLetter from "../functions/getFolderLetter.js"; +import getPresences from "../functions/getPresences.js"; +import { prefix } from "../util/prefix.js"; +import ModuleManager from "../util/ModuleManager.js"; +import { watch } from "chokidar"; +const program = new Command(); +program + .allowUnknownOption() + .option("-m, --modify [presence]") + .parse(process.argv); +let service = program.getOptionValue("modify")?.trim(); +if (typeof service !== "string") { + service = (await prompts({ + name: "service", + message: "Select or search for a presence to modify", + type: "autocomplete", + choices: (await getPresences()).map((s) => ({ + title: s.service, + description: "v" + s.version, + value: s.service, + })), + })).service?.trim(); + if (!service) + process.exit(0); +} +else { + if (!(await getPresences()) + .map((s) => ({ + title: s.service, + })) + .find((p) => p.title.toLowerCase() === service.replace("!", " ").trim().toLowerCase())) { + console.log(prefix, chalk.redBright("Could not find presence:", service)); + process.exit(0); + } +} +const require = createRequire(import.meta.url); +const presencePath = resolve(`./websites/${getFolderLetter(service)}/${service.replace("!", " ").trim()}`); +const moduleManager = new ModuleManager(presencePath); +await moduleManager.installDependencies(); +if (!existsSync(resolve(presencePath, "tsconfig.json"))) + await cp(resolve(fileURLToPath(import.meta.url), "../../../template/tsconfig.json"), resolve(presencePath, "tsconfig.json")); +console.log(prefix, chalk.greenBright("Starting TypeScript compiler...")); +class Compiler { + cwd; + compiler = null; + watching = null; + firstRun = true; + constructor(cwd) { + this.cwd = cwd; + } + async watch() { + this.compiler = webpack({ + mode: "none", + resolveLoader: { + modules: [ + fileURLToPath(new URL("../../node_modules", import.meta.url)), + ], + }, + devtool: "inline-source-map", + plugins: [ + new webpack.DynamicEntryPlugin(this.cwd, async () => { + return new Promise((r) => { + if (existsSync(resolve(this.cwd, "iframe.ts"))) + r({ + "iframe.js": { + filename: "iframe.js", + baseUri: this.cwd, + import: ["./iframe.ts"], + }, + }); + else + r({}); + }); + }), + new CopyPlugin({ + patterns: [ + { + from: resolve(this.cwd, "metadata.json"), + to: "metadata.json", + }, + ], + }), + new webpack.WatchIgnorePlugin({ + paths: [/\.js$/, /\.d\.[cm]ts$/], + }), + { + apply(compiler) { + compiler.hooks.emit.tap("PresenceCompiler", (compilation) => { + for (const file in compilation.assets) { + if (!file.endsWith(".js")) + continue; + compilation.assets[file].add("\n"); + } + }); + }, + }, + ], + module: { + rules: [ + { + test: /\.ts$/, + loader: require.resolve("ts-loader"), + exclude: /node_modules/, + options: { + onlyCompileBundledFiles: true, + errorFormatter: (error, colors) => { + return (`${prefix} ${colors.cyan(basename(dirname(error.file)) + "/" + basename(error.file))}` + + ":" + + colors.yellowBright(error.line) + + ":" + + colors.yellowBright(error.character) + + " - " + + colors.redBright("Error ") + + colors.gray("TS" + error.code + ":") + + " " + + ts.flattenDiagnosticMessageText(error.content, "\n")); + }, + }, + }, + ], + }, + resolve: { + extensions: [".ts"], + }, + entry: async () => { + const output = { + presence: resolve(this.cwd, "presence.ts"), + }; + return output; + }, + output: { + path: resolve(this.cwd, "dist"), + filename: "[name].js", + iife: false, + clean: true, + }, + }); + this.compiler.hooks.compile.tap("pmd", () => { + if (!this.firstRun) + console.log(prefix, chalk.yellowBright("Recompiling...")); + this.firstRun = false; + }); + this.compiler.hooks.afterCompile.tap("pmd", (compilation) => { + compilation.errors = compilation.errors.filter((e) => e.name !== "ModuleBuildError"); + for (const error of compilation.errors) { + if (error.name === "ModuleNotFoundError" && + error.message.includes(resolve(this.cwd, "package.json"))) { + console.error(prefix, chalk.redBright("package.json not valid!")); + continue; + } + console.error(error.message); + } + if (compilation.errors.length === 0) + return console.log(prefix, chalk.greenBright("Successfully compiled!")); + else + return console.log(prefix, chalk.redBright(`Failed to compile with ${compilation.errors.length} error${compilation.errors.length === 1 ? "" : "s"}!`)); + }); + await new Promise((r) => (this.watching = this.compiler.watch({}, r))); + } + async stop() { + this.watching?.suspend(); + if (this.watching) + await new Promise((r) => this.watching?.close(r)); + } + async restart() { + this.firstRun = true; + await this.stop(); + await this.watch(); + } +} +const compiler = new Compiler(presencePath); +watch(presencePath, { depth: 0, persistent: true, ignoreInitial: true }).on("all", async (event, file) => { + if (["add", "unlink"].includes(event) && basename(file) === "iframe.ts") + return await compiler.restart(); + if (basename(file) === "package.json") { + if (["add", "change"].includes(event) && + !(await moduleManager.isValidPackageJson())) + return console.error(prefix, chalk.redBright("Invalid package.json!")); + await compiler.stop(); + if ("change" === event) + await moduleManager.installDependencies(); + else if (event === "unlink") { + if (existsSync(resolve(presencePath, "node_modules"))) + rm(resolve(presencePath, "node_modules"), { recursive: true }); + if (existsSync(resolve(presencePath, "package-lock.json"))) + rm(resolve(presencePath, "package-lock.json")); + } + compiler.restart(); + } +}); +compiler.watch(); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kaWZ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FjdGlvbnMvbW9kaWZ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBd0IsTUFBTSxPQUFPLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLElBQUksQ0FBQztBQUNoQyxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDcEMsT0FBTyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFdkMsT0FBTyxlQUFlLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxZQUFZLE1BQU0sOEJBQThCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTNDLE9BQU8sYUFBYSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFakMsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUM5QixPQUFPO0tBQ0osa0JBQWtCLEVBQUU7S0FDcEIsTUFBTSxDQUFDLHlCQUF5QixDQUFDO0tBQ2pDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFdkIsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLGNB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 \ No newline at end of file diff --git a/bin/actions/translate.js b/bin/actions/translate.js new file mode 100644 index 0000000..a241988 --- /dev/null +++ b/bin/actions/translate.js @@ -0,0 +1,137 @@ +import { gql } from "@apollo/client/core/index.js"; +import chalk from "chalk"; +import { writeFile } from "fs/promises"; +import inquirer from "inquirer"; +import { getLanguage } from "language-flag-colors"; +import { resolve } from "node:path"; +import ora from "ora"; +import prompts from "prompts"; +import semver from "semver"; +import fetchSchema from "../functions/fetchSchema.js"; +import getFolderLetter from "../functions/getFolderLetter.js"; +import getPresences from "../functions/getPresences.js"; +import { apollo } from "../util/apollo.js"; +import { prefix } from "../util/prefix.js"; +const spinner = ora("Loading languages...").start(); +const { coerce, inc, valid } = semver; +const { data: { langFiles }, } = await apollo.query({ + query: gql ` + query { + langFiles(project: "website") { + lang + } + } + `, +}); +const schema = await fetchSchema(); +spinner.stop(); +const { lang } = await prompts({ + name: "lang", + message: "Select the language you want add translations for", + type: "autocomplete", + choices: langFiles + .filter((l) => l.lang !== "en") + .map((l) => ({ + title: getLanguage(l.lang.replace("_", "-"))?.nativeName ?? l.lang, + description: l.lang, + value: l.lang, + })), + suggest: async (input, choices) => { + const regex = new RegExp(input, "i"); + return choices.filter((c) => regex.test(c.title) || + (c.description ? regex.test(c.description) : false)); + }, +}); +if (!lang) { + console.log(prefix, chalk.redBright("No language selected, exiting...")); + process.exit(0); +} +let presences = await getPresences(); +const { mode } = await prompts([ + { + type: "select", + name: "mode", + message: "What do you want to do?", + choices: [ + { + title: "Translate every Presence in order", + value: 0, + }, + { + title: "Translate every Presence of category", + value: 1, + }, + { + title: "Translate selected Presences", + value: 2, + }, + ], + }, +]); +const { selPresences, category } = await prompts([ + { + type: mode === 1 ? "select" : false, + name: "category", + message: "Category of the service", + choices: schema.properties.category.enum.map((c) => ({ + title: c, + value: c, + })), + }, + { + type: mode === 2 ? "autocompleteMultiselect" : false, + name: "selPresences", + message: "Select the Presences you want to translate", + instructions: "Use arrow keys to select and space to toggle", + choices: presences.map((p) => ({ + title: p.service, + value: p, + })), + min: 1, + }, +]); +if (mode === 2) { + await translatePresences(selPresences, lang); + process.exit(0); +} +const { filterPresences } = await prompts([ + { + type: "confirm", + name: "filterPresences", + message: "Filter out already translated Presences?", + }, +]); +if (filterPresences) + presences = presences.filter((p) => !p.description?.[lang]); +if (category) + presences = presences.filter((p) => p.category === category); +await translatePresences(presences, lang); +process.exit(0); +async function translatePresences(presences, lang) { + if (!Array.isArray(presences)) + process.exit(0); + for (const presence of presences) { + const desc = presence.description?.[lang], enDesc = presence.description?.en; + console.log(`${enDesc ? chalk.green(enDesc) + "\n\n" : ""}Type "skip" to skip or "stop" to stop translating.`); + const { translation } = await inquirer.prompt({ + type: "input", + name: "translation", + message: presence.service, + default: desc, + validate: (input) => !!input || + "You need to enter a translation, or type 'skip' to skip, or 'stop' to stop translating.", + }); + if (translation === "skip" || translation === desc) + continue; + if (translation === "stop") + break; + const presencePath = resolve(`./websites/${getFolderLetter(presence.service)}/${presence.service.replace("!", " ").trim()}`); + presence.description[lang] = translation; + if (valid(coerce(presence.version))) + presence.version = inc(valid(coerce(presence.version)), "patch"); + else + console.warn(`Invalid version for ${presence.service}, skipping version bump.`); + await writeFile(resolve(presencePath, "metadata.json"), JSON.stringify(presence, null, "\t")); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FjdGlvbnMvdHJhbnNsYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNuRCxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLFFBQVEsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQ3RCLE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFFNUIsT0FBTyxXQUFXLE1BQU0sNkJBQTZCLENBQUM7QUFDdEQsT0FBTyxlQUFlLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxZQUFZLE1BQU0sOEJBQThCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNwRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUM7QUFFdEMsTUFBTSxFQUNKLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUNwQixHQUFHLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBb0M7SUFDeEQsS0FBSyxFQUFFLEdBQUcsQ0FBQTs7Ozs7O0dBTVQ7Q0FDRixDQUFDLENBQUM7QUFFSCxNQUFNLE1BQU0sR0FBRyxN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 \ No newline at end of file diff --git a/bin/functions/fetchSchema.js b/bin/functions/fetchSchema.js new file mode 100644 index 0000000..ca22112 --- /dev/null +++ b/bin/functions/fetchSchema.js @@ -0,0 +1,5 @@ +import fetch from "cross-fetch"; +export default async function fetchSchema() { + return (await fetch("https://schemas.premid.app/metadata/1.9")).json(); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2hTY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZnVuY3Rpb25zL2ZldGNoU2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUVoQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssVUFBVSxXQUFXO0lBQ3hDLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDeEUsQ0FBQyJ9 \ No newline at end of file diff --git a/bin/functions/getDiscordAppUser.js b/bin/functions/getDiscordAppUser.js new file mode 100644 index 0000000..5d6416a --- /dev/null +++ b/bin/functions/getDiscordAppUser.js @@ -0,0 +1,24 @@ +import { Client } from "discord-rpc"; +export let user; +export default function getDiscordAppUser() { + return new Promise(async (res, rej) => { + if (user) + return res(user); + const client = new Client({ transport: "ipc" }); + const t = setTimeout(() => { + if (user) + return res(user); + client.destroy().catch(() => { }); + res(undefined); + }, 500); + try { + await client.login({ clientId: "503557087041683458" }); + clearTimeout(t); + await client.destroy(); + } + catch { } + user = client.user; + res(client.user); + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0RGlzY29yZEFwcFVzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZnVuY3Rpb25zL2dldERpc2NvcmRBcHBVc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQVEsTUFBTSxhQUFhLENBQUM7QUFFM0MsTUFBTSxDQUFDLElBQUksSUFBc0IsQ0FBQztBQUVsQyxNQUFNLENBQUMsT0FBTyxVQUFVLGlCQUFpQjtJQUN4QyxPQUFPLElBQUksT0FBTyxDQUFtQixLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQ3ZELElBQUksSUFBSTtZQUFFLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTNCLE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFaEQsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUN6QixJQUFJLElBQUk7Z0JBQUUsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFM0IsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQztZQUNqQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRVIsSUFBSTtZQUNILE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUM7WUFDdkQsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hCLE1BQU0sTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ3ZCO1FBQUMsTUFBTSxHQUFFO1FBRVYsSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFFbkIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztBQUNKLENBQUMifQ== \ No newline at end of file diff --git a/bin/functions/getDiscordUser.js b/bin/functions/getDiscordUser.js new file mode 100644 index 0000000..a2435d7 --- /dev/null +++ b/bin/functions/getDiscordUser.js @@ -0,0 +1,16 @@ +import { gql } from "@apollo/client/core/index.js"; +import { apollo } from "../util/apollo.js"; +export default async function getDiscordUser(id) { + const user = await apollo.query({ + query: gql ` + query getUser($id: String) { + discordUsers(userId: $id) { + username + } + } + `, + variables: { id } + }); + return user.data.discordUsers[0]; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0RGlzY29yZFVzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZnVuY3Rpb25zL2dldERpc2NvcmRVc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0MsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUFDLEVBQVU7SUFDdEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUU1QjtRQUNGLEtBQUssRUFBRSxHQUFHLENBQUE7Ozs7OztHQU1UO1FBQ0QsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFO0tBQ2pCLENBQUMsQ0FBQztJQUVILE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEMsQ0FBQyJ9 \ No newline at end of file diff --git a/bin/functions/getFolderLetter.js b/bin/functions/getFolderLetter.js new file mode 100644 index 0000000..6e2c861 --- /dev/null +++ b/bin/functions/getFolderLetter.js @@ -0,0 +1,9 @@ +export default function getFolderLetter(service) { + const firstLetter = service.trim().at(0).toUpperCase(); + if (firstLetter.match(/[A-Z]/)) + return firstLetter; + if (firstLetter.match(/[0-9]/)) + return "0-9"; + return "#"; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0Rm9sZGVyTGV0dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Z1bmN0aW9ucy9nZXRGb2xkZXJMZXR0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFDLE9BQU8sVUFBVSxlQUFlLENBQUMsT0FBZTtJQUNyRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRXhELElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFBRSxPQUFPLFdBQVcsQ0FBQztJQUNuRCxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIn0= \ No newline at end of file diff --git a/bin/functions/getPresences.js b/bin/functions/getPresences.js new file mode 100644 index 0000000..6f85be1 --- /dev/null +++ b/bin/functions/getPresences.js @@ -0,0 +1,6 @@ +import { readFile } from "fs/promises"; +import { globby } from "globby"; +export default async function getPresences() { + return await Promise.all((await globby("websites/*/*/metadata.json")).map(async (s) => JSON.parse(await readFile(s, "utf-8")))); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0UHJlc2VuY2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Z1bmN0aW9ucy9nZXRQcmVzZW5jZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRWhDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxVQUFVLFlBQVk7SUFDekMsT0FBTyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ3ZCLENBQ0MsTUFBTSxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FDMUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUN4RCxDQUFDO0FBQ0gsQ0FBQyJ9 \ No newline at end of file diff --git a/bin/functions/isFirstTimeAuthor.js b/bin/functions/isFirstTimeAuthor.js new file mode 100644 index 0000000..1e1fd65 --- /dev/null +++ b/bin/functions/isFirstTimeAuthor.js @@ -0,0 +1,12 @@ +import { readFile } from "fs/promises"; +import { globby } from "globby"; +export default async function isFirstTimeAuthor(author) { + for (const m of await globby("websites/*/*/metadata.json")) { + const { author: { id } } = JSON.parse(await readFile(m, "utf-8")); + if (author !== id) + continue; + return false; + } + return true; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXNGaXJzdFRpbWVBdXRob3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZnVuY3Rpb25zL2lzRmlyc3RUaW1lQXV0aG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVoQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxNQUFjO0lBQzdELEtBQUssTUFBTSxDQUFDLElBQUksTUFBTSxNQUFNLENBQUMsNEJBQTRCLENBQUMsRUFBRTtRQUMzRCxNQUFNLEVBQ0wsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQ2QsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRTNDLElBQUksTUFBTSxLQUFLLEVBQUU7WUFBRSxTQUFTO1FBRTVCLE9BQU8sS0FBSyxDQUFDO0tBQ2I7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNiLENBQUMifQ== \ No newline at end of file diff --git a/bin/index.js b/bin/index.js new file mode 100644 index 0000000..ceac2d0 --- /dev/null +++ b/bin/index.js @@ -0,0 +1,65 @@ +#!/usr/bin/env node +import "source-map-support/register.js"; +import chalk from "chalk"; +import { readFile } from "fs/promises"; +import inquirer from "inquirer"; +import ora from "ora"; +import { Command } from "commander"; +import getDiscordAppUser from "./functions/getDiscordAppUser.js"; +import { prefix } from "./util/prefix.js"; +if (!(await inPresenceRepo())) { + console.error(prefix, chalk.redBright("This command can only be run in the presence repository")); + process.exit(1); +} +const program = new Command(); +program + .allowUnknownOption() + .option("-c, --create", "create a new Presence") + .option("-m, --modify", "modify an existing presence") + .option("-t, --translate", "translate a presence") + .parse(process.argv); +const method = Object.keys(program.opts()).find((key) => program.opts()[key] === true); +if (method) { + if (method === "create") + console.log(chalk.green("?"), chalk.bold("What do you want to do?"), chalk.cyan("Create a new Presence")); + await import(`./actions/${method}.js`); +} +else { + const spinner = ora("Fetching Discord User...").start(), user = await getDiscordAppUser(); + spinner.stop(); + if (user) + console.log(prefix, `Hello ${chalk.green(user.username)}!`); + const { action } = await inquirer.prompt([ + { + type: "list", + name: "action", + message: "What do you want to do?", + choices: [ + { + name: "Create a new Presence", + value: "create", + }, + { + name: "Modify an existing Presence", + value: "modify", + }, + { + name: "Translate a Presence", + value: "translate", + }, + ], + }, + ]); + if (action) + await import(`./actions/${action}.js`); +} +async function inPresenceRepo() { + try { + const { name } = JSON.parse(await readFile("./package.json", "utf8")); + return name === "presences"; + } + catch { + return false; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBLE9BQU8sZ0NBQWdDLENBQUM7QUFFeEMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkMsT0FBTyxRQUFRLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQztBQUN0QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BDLE9BQU8saUJBQWlCLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTFDLElBQUksQ0FBQyxDQUFDLE1BQU0sY0FBYyxFQUFFLENBQUMsRUFBRTtJQUM3QixPQUFPLENBQUMsS0FBSyxDQUNYLE1BQU0sRUFDTixLQUFLLENBQUMsU0FBUyxDQUFDLHlEQUF5RCxDQUFDLENBQzNFLENBQUM7SUFDRixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0NBQ2pCO0FBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUM5QixPQUFPO0tBQ0osa0JBQWtCLEVBQUU7S0FDcEIsTUFBTSxDQUFDLGNBQWMsRUFBRSx1QkFBdUIsQ0FBQztLQUMvQyxNQUFNLENBQUMsY0FBYyxFQUFFLDZCQUE2QixDQUFDO0tBQ3JELE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxzQkFBc0IsQ0FBQztLQUNqRCxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRXZCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUM3QyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FDdEMsQ0FBQztBQUVGLElBQUksTUFBTSxFQUFFO0lBQ1YsSUFBSSxNQUFNLEtBQUssUUFBUTtRQUNyQixPQUFPLENBQUMsR0FBRyxDQUNULEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQ2hCLEtBQUssQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsRUFDckMsS0FBSyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUNwQyxDQUFDO0lBQ0osTUFBTSxNQUFNLENBQUMsYUFBYSxNQUFNLEtBQUssQ0FBQyxDQUFDO0NBQ3hDO0tBQU07SUFDTCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFDckQsSUFBSSxHQUFHLE1BQU0saUJBQWlCLEVBQUUsQ0FBQztJQUNuQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFZixJQUFJLElBQUk7UUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxTQUFTLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN0RSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxRQUFRLENBQUMsTUFBTSxDQUFxQjtRQUMzRDtZQUNFLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLFFBQVE7WUFDZCxPQUFPLEVBQUUseUJBQXlCO1lBQ2xDLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsdUJBQXVCO29CQUM3QixLQUFLLEVBQUUsUUFBUTtpQkFDaEI7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLDZCQUE2QjtvQkFDbkMsS0FBSyxFQUFFLFFBQVE7aUJBQ2hCO2dCQUNEO29CQUNFLElBQUksRUFBRSxzQkFBc0I7b0JBQzVCLEtBQUssRUFBRSxXQUFXO2lCQUNuQjthQUNGO1NBQ0Y7S0FDRixDQUFDLENBQUM7SUFDSCxJQUFJLE1BQU07UUFBRSxNQUFNLE1BQU0sQ0FBQyxhQUFhLE1BQU0sS0FBSyxDQUFDLENBQUM7Q0FDcEQ7QUFFRCxLQUFLLFVBQVUsY0FBYztJQUMzQixJQUFJO1FBQ0YsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN0RSxPQUFPLElBQUksS0FBSyxXQUFXLENBQUM7S0FDN0I7SUFBQyxNQUFNO1FBQ04sT0FBTyxLQUFLLENBQUM7S0FDZDtBQUNILENBQUMifQ== \ No newline at end of file diff --git a/bin/util/ModuleManager.js b/bin/util/ModuleManager.js new file mode 100644 index 0000000..21d47c7 --- /dev/null +++ b/bin/util/ModuleManager.js @@ -0,0 +1,50 @@ +import { exec } from "child_process"; +import { resolve } from "path"; +import { existsSync } from "fs"; +import ora from "ora"; +import { prefix } from "./prefix.js"; +import chalk from "chalk"; +import { readFile } from "fs/promises"; +export default class ModuleManager { + cwd; + dependencies = []; + devDependencies = []; + constructor(cwd) { + this.cwd = cwd; + } + async isValidPackageJson() { + if (!existsSync(resolve(this.cwd, "package.json"))) + return false; + try { + JSON.parse(await readFile(resolve(this.cwd, "package.json"), "utf8")); + return true; + } + catch { + return false; + } + } + async installDependencies() { + const prevNodeEnv = process.env.NODE_ENV; + delete process.env.NODE_ENV; + if (!(await this.isValidPackageJson())) + return; + const spinner = ora(prefix + chalk.yellow(" Installing dependencies...")).start(); + const job = exec("npm install --loglevel error --save-exact", { + cwd: this.cwd + }); + let errorChunks = []; + job.stderr?.on("data", data => { + errorChunks = errorChunks.concat(data); + }); + await new Promise(r => job.once("exit", code => { + if (code === 0) { + spinner.succeed(prefix + chalk.green(" Installed dependencies!")); + return r(); + } + spinner.fail(prefix + " " + chalk.red(errorChunks.join(""))); + r(); + })); + process.env.NODE_ENV = prevNodeEnv; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTW9kdWxlTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsL01vZHVsZU1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDaEMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDckMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFdkMsTUFBTSxDQUFDLE9BQU8sT0FBTyxhQUFhO0lBSWQ7SUFIbkIsWUFBWSxHQUFhLEVBQUUsQ0FBQztJQUM1QixlQUFlLEdBQWEsRUFBRSxDQUFDO0lBRS9CLFlBQW1CLEdBQVc7UUFBWCxRQUFHLEdBQUgsR0FBRyxDQUFRO0lBQUcsQ0FBQztJQUVsQyxLQUFLLENBQUMsa0JBQWtCO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUVqRSxJQUFJO1lBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3RFLE9BQU8sSUFBSSxDQUFDO1NBQ1o7UUFBQyxNQUFNO1lBQ1AsT0FBTyxLQUFLLENBQUM7U0FDYjtJQUNGLENBQUM7SUFFRCxLQUFLLENBQUMsbUJBQW1CO1FBQ3hCLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO1FBQ3pDLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7UUFFNUIsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUFFLE9BQU87UUFFL0MsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUNsQixNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQyxDQUNwRCxDQUFDLEtBQUssRUFBRSxDQUFDO1FBR1YsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLDJDQUEyQyxFQUFFO1lBQzdELEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztTQUNiLENBQUMsQ0FBQztRQUVILElBQUksV0FBVyxHQUFVLEVBQUUsQ0FBQztRQUM1QixHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDN0IsV0FBVyxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsQ0FBQyxFQUFFLENBQzNCLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFO1lBQ3ZCLElBQUksSUFBSSxLQUFLLENBQUMsRUFBRTtnQkFDZixPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUMsQ0FBQztnQkFFbEUsT0FBTyxDQUFDLEVBQUUsQ0FBQzthQUNYO1lBRUQsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFN0QsQ0FBQyxFQUFFLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FDRixDQUFDO1FBRUYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDO0lBQ3BDLENBQUM7Q0FDRCJ9 \ No newline at end of file diff --git a/bin/util/apollo.js b/bin/util/apollo.js new file mode 100644 index 0000000..299ce68 --- /dev/null +++ b/bin/util/apollo.js @@ -0,0 +1,10 @@ +import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client/core/index.js"; +import fetch from "cross-fetch"; +export const apollo = new ApolloClient({ + cache: new InMemoryCache(), + link: new HttpLink({ + fetch: fetch, + uri: "https://api.premid.app/v3" + }) +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBvbGxvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWwvYXBvbGxvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3JGLE9BQU8sS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUVoQyxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxZQUFZLENBQUM7SUFDdEMsS0FBSyxFQUFFLElBQUksYUFBYSxFQUFFO0lBQzFCLElBQUksRUFBRSxJQUFJLFFBQVEsQ0FBQztRQUNsQixLQUFLLEVBQUUsS0FBSztRQUNaLEdBQUcsRUFBRSwyQkFBMkI7S0FDaEMsQ0FBQztDQUNGLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/bin/util/prefix.js b/bin/util/prefix.js new file mode 100644 index 0000000..53167fc --- /dev/null +++ b/bin/util/prefix.js @@ -0,0 +1,3 @@ +import chalk from "chalk"; +export const prefix = chalk.bold.hex("#7289DA")("pmd"); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlZml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWwvcHJlZml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUUxQixNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..432d2cf --- /dev/null +++ b/package.json @@ -0,0 +1,62 @@ +{ + "name": "@pmd/cli", + "description": "CLI for creating, modifying & translating Presences.", + "version": "1.2.2", + "author": "Timeraa ", + "main": "src/index.ts", + "license": "MPL-2.0", + "type": "module", + "contributors": [ + "Bas950 ", + "EncryptedDev", + "veryCrunchy " + ], + "scripts": { + "dev": "tsc -w", + "build": "rimraf bin && tsc" + }, + "files": [ + "template/*", + "bin/*" + ], + "bin": { + "pmd": "bin/index.js" + }, + "devDependencies": { + "@types/discord-rpc": "^4.0.3", + "@types/glob": "^8.0.0", + "@types/got": "^9.6.12", + "@types/inquirer": "^9.0.1", + "@types/node": "^18.7.16", + "@types/prompts": "^2.0.14", + "@types/semver": "^7.3.12", + "dotenv": "^16.3.1", + "octokit": "^3.1.2", + "rimraf": "^3.0.2", + "typescript": "^4.8.3" + }, + "dependencies": { + "@apollo/client": "^3.6.9", + "chalk": "^5.0.1", + "chokidar": "^3.5.3", + "commander": "^11.1.0", + "copy-webpack-plugin": "^11.0.0", + "cross-fetch": "^3.1.5", + "discord-rpc": "^4.0.1", + "displayastree": "^2.0.0", + "globby": "^13.1.2", + "graphql": "^16.6.0", + "inquirer": "^9.1.1", + "jsonschema": "^1.4.1", + "language-flag-colors": "^2.1.1", + "ora": "^6.1.2", + "prompts": "^2.4.2", + "semver": "^7.3.7", + "source-map-support": "^0.5.21", + "ts-loader": "^9.4.1", + "webpack": "^5.74.0" + }, + "peerDependencies": { + "typescript": "^4.8.3" + } +} diff --git a/template/metadata.json b/template/metadata.json new file mode 100644 index 0000000..6b2567a --- /dev/null +++ b/template/metadata.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://schemas.premid.app/metadata/1.9", + "author": { + "name": "", + "id": "" + }, + "service": "", + "description": { + "en": "" + }, + "url": "", + "version": "", + "logo": "", + "thumbnail": "", + "color": "", + "category": "", + "tags": [""] +} diff --git a/template/presence.min.ts b/template/presence.min.ts new file mode 100644 index 0000000..b46513b --- /dev/null +++ b/template/presence.min.ts @@ -0,0 +1,21 @@ +const presence = new Presence({ + clientId: "", + }), + strings = presence.getStrings({ + play: "presence.playback.playing", + pause: "presence.playback.paused", + }), + browsingTimestamp = Math.floor(Date.now() / 1000); + +const enum Assets { // Other default assets can be found at index.d.ts + Logo = "", +} + +presence.on("UpdateData", async () => { + const presenceData: PresenceData = { + largeImageKey: Assets.Logo, + startTimestamp: browsingTimestamp, + }; + + presence.setActivity(presenceData); +}); diff --git a/template/presence.ts b/template/presence.ts new file mode 100644 index 0000000..e7cb0d4 --- /dev/null +++ b/template/presence.ts @@ -0,0 +1,55 @@ +const presence = new Presence({ + //The client ID of the Application created at https://discordapp.com/developers/applications + clientId: "000000000000000000", + }), + //You can use this to get translated strings in their browser language + strings = presence.getStrings({ + play: "presence.playback.playing", + pause: "presence.playback.paused", + }), + browsingTimestamp = Math.floor(Date.now() / 1000); // Here you generate the time someone is spending on the page. You divivde the miliseconds to seconds (/ 1000) + +const enum Assets { // An Enum for collecting all images (that aren't loaded on the site or are better quality for usage for the presence. + Logo = "", // You should the logo link in here +} + +/* +function myOutsideHeavyLiftingFunction(){ + //Grab and process all your data here + + // element grabs // + // api calls // + // variable sets // +} + +setInterval(myOutsideHeavyLiftingFunction, 10000); +//Run the function separate from the UpdateData event every 10 seconds to get and set the variables which UpdateData picks up +*/ + +presence.on("UpdateData", async () => { + /*UpdateData is always firing, and therefore should be used as your refresh cycle, or `tick`. This is called several times a second where possible. + + It is recommended to set up another function outside of this event function which will change variable values and do the heavy lifting if you call data from an API.*/ + + const presenceData: PresenceData = { + //The large image on the presence. This can be a key of an image that has been added to the enum Assets. + largeImageKey: Assets.Logo, // Assets enum key or image url + //The small image on the presence. This can be a key of an image that has been added to the enum Assets. + smallImageKey: "", // Assets enum key or image url. + //The text which is displayed when hovering over the small image + smallImageText: "Some hover text", + //The upper section of the presence text + details: "Browsing Page Name", + //The lower section of the presence text + state: "Reading section A", + //The unix epoch timestamp for when to start counting from + startTimestamp: browsingTimestamp, + //If you want to show Time Left instead of Elapsed, this is the unix epoch timestamp at which the timer ends + endTimestamp: 3133700400000, + //Optionally you can set a largeImageKey here and change the rest as variable subproperties, for example presenceData.type = "blahblah"; type examples: details, state, etc. + }; + //Update the presence with all the values from the presenceData object + if (presenceData.details) presence.setActivity(presenceData); + //Update the presence with no data, therefore clearing it and making the large image the Discord Application icon, and the text the Discord Application name + else presence.setActivity(); +}); diff --git a/template/tsconfig.json b/template/tsconfig.json new file mode 100644 index 0000000..3bf4ca1 --- /dev/null +++ b/template/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist/" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..72b3b19 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,102 @@ +{ + "exclude": ["template"], + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "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": "ESNEXT" /* 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 TC39 stage 2 draft 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. */ + + /* Modules */ + "module": "ESNext" /* Specify what module code is generated. */, + "rootDir": "./src" /* Specify the root folder within your source files. */, + "moduleResolution": "node" /* 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. */ + // "resolveJsonModule": true, /* Enable importing .json files */ + // "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. */, + // "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": "./bin" /* Specify an output folder for all emitted files. */, + "removeComments": true /* Disable emitting comments. */, + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* 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. */ + "inlineSourceMap": true /* Include sourcemap files inside the emitted JavaScript. */, + // "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": "lf" /* 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. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + "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. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a 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, /* Include 'undefined' in index signature results */ + // "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. */ + } +}