diff --git a/.gitignore b/.gitignore index 782f930..abb4ada 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ packages/ioc/node_modules/* packages/ioc/dist packages/poster/dts/discord.d.ts packages/**/node_modules +packages/**/dist diff --git a/packages/ioc/package.json b/packages/ioc/package.json index 3e448e4..f067fbd 100644 --- a/packages/ioc/package.json +++ b/packages/ioc/package.json @@ -3,15 +3,15 @@ "version": "1.0.4", "description": "Dependency Injection system", "main": "dist/index.js", - "module": "./dist/index.js", + "module": "./dist/index.js", "exports": { - "." : { - "import": "./dist/index.js", - "require": "./dist/index.js" + ".": { + "import": "./dist/index.js", + "require": "./dist/index.js" }, "./global": { - "import": "./dist/global.js", - "require": "./dist/global.js" + "import": "./dist/global.js", + "require": "./dist/global.js" } }, "scripts": { diff --git a/packages/ioc/tsconfig.json b/packages/ioc/tsconfig.json index 3c3f07a..d4ca08f 100644 --- a/packages/ioc/tsconfig.json +++ b/packages/ioc/tsconfig.json @@ -25,8 +25,9 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ "rootDir": "./src", /* Specify the root folder within your source files. */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* 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. */ diff --git a/packages/localizer/index.mdx b/packages/localizer/index.mdx index dff7641..0d33a73 100644 --- a/packages/localizer/index.mdx +++ b/packages/localizer/index.mdx @@ -2,7 +2,7 @@ title: Localizer description: Translate your bot for the world sidebar: - order: 1 + order: 2 --- @@ -54,7 +54,7 @@ Create the directory `assets/locals`. Each json file in here must be named after - ```json title=~/assets/locals/es.json + ```json title=~/assets/locals/es-ES.json { "salute": { "hello": "hola" @@ -82,7 +82,7 @@ execute : (ctx, { deps }) => { //the localizer object from makeDependencies deps.localizer // Returns the Spanish translation for 'salute.hello' - deps.localizer.translate("salute.hello", "es"); + deps.localizer.translate("salute.hello", "es-ES"); } ``` @@ -91,5 +91,5 @@ execute : (ctx, { deps }) => { import { local } from '@sern/localizer'; // Returns the Spanish translation for 'salute.hello' -const greeting = local('salute.hello', 'es'); +const greeting = local('salute.hello', 'es-ES'); ``` diff --git a/packages/localizer/index.ts b/packages/localizer/index.ts index a926c7d..a08347e 100644 --- a/packages/localizer/index.ts +++ b/packages/localizer/index.ts @@ -54,10 +54,10 @@ class ShrimpleLocalizer implements Init { * Note: this method only works AFTER your container has been initiated * @example * ```ts - * assert.deepEqual(locals("salute.hello", "es"), "hola") + * assert.deepEqual(locals("salute.hello", "es-ES"), "hola") * ``` */ -export const local = (i: string, local: string) => { +export const local = (i: string, local: string) => { return Service('localizer').translate(i, local) } @@ -67,8 +67,9 @@ export const local = (i: string, local: string) => { /** * An init plugin to add localization fields to a command module. * Your localization configuration should look like, + * sets nloc and dloc on locals field of module. * @param root {string} If you have conflicting command names, you may configure the root of the name. (= command/{root}) - * Below is es.json (spanish) + * Below is es-ES.json (spanish) * ```json { "command/comer" : { @@ -87,16 +88,16 @@ export const localize = (root?: string) => //@ts-ignore CommandInitPlugin(({ module, deps }) => { if(module.type === CommandType.Slash || module.type === CommandType.Both) { - deps['@sern/logger'].info({ message: "Localizing "+ module.name }); - const resolvedLocalization= 'command/'+(root??module.name); - Reflect.set(module, 'name_localizations', deps.localizer.translationsFor(resolvedLocalization+".name")); - Reflect.set(module, 'description_localizations', deps.localizer.translationsFor(resolvedLocalization+'.description')); - const newOpts = module.options ?? []; - //@ts-ignore - dfsApplyLocalization(newOpts, deps, [resolvedLocalization]); + const { localizer, '@sern/logger':log } = deps + const resolvedRoot = 'command/'+(root??module.name); + log?.info({ message: "Localizing "+ resolvedRoot }); + //@ts-ignore + dfsApplyLocalization(module.options ?? [], deps, [resolvedRoot]); + Reflect.set(module.locals, 'nloc', localizer.translationsFor(resolvedRoot+".name")) + Reflect.set(module.locals, 'dloc', localizer.translationsFor(resolvedRoot+'.description')) return controller.next(); } else { - //@ts-ignore + //@ts-ignore return controller.stop("Cannot localize this type of module " + module.name); } }) diff --git a/packages/publisher/index.mdx b/packages/publisher/index.mdx new file mode 100644 index 0000000..d1cd15b --- /dev/null +++ b/packages/publisher/index.mdx @@ -0,0 +1,106 @@ +--- +title: Publisher +description: Publish application commands as a Service +sidebar: + order: 1 +--- + +## Implicits +- Requires process.env to be populated +- A common provider of this is `dotenv` +```txt title=".env" +DISCORD_TOKEN= +NODE_ENV= +``` +- Calls the discord API with the [PUT route](https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands). Wherever your commands directory is located, publish will override the existing application commands at Discord. + +## Usage + +**Initializing the Publisher** +```ts +import { makeDependencies } from '@sern/handler'; +import { Publisher } from '@sern/publisher'; + +await makeDependencies(({ add }) => { + add('publisher', new Publisher()); +}); +``` + +## Features +- Automatically syncs api with your command base +- generates JSON file of output (**.sern/command-data-remote.json**) +- supports a configuration that is the same as the original publish plugin. + + +Each command file can have an extra plugin `publishConfig` that follows `ValidPublishOptions`: +## Config +```ts + +type ValidMemberPermissions = + | typeof PermissionFlagBits //discord.js enum + | typeof PermissionFlagBits[] //array of discord.js enum + | string //must be a stringified number + | bigint + +interface PublishConfig { + guildIds?: string[]; + defaultMemberPermissions?: ValidMemberPermissions; + integrationTypes?: Array<'Guild'|'User'> + contexts: number[] +} +type ValidPublishOptions = + | PublishConfig + | (absPath: string, module: CommandModule) => PublishConfig +``` +:::tip +These types are exported under @sern/publisher +::: + +### Example: command published with integrationTypes + +:::tip +Make sure you modify the install method in the Discord dev portal +::: + +```ts title=src/commands/ping.ts +import { commandModule, CommandType } from '@sern/handler' +import { publishConfig } from '@sern/publisher' + +export default commandModule( { + type: CommandType.Slash, + plugins: [ + publishConfig({ + integrationTypes: ['User'], + contexts: [1,2] + }) + ], + description: `hello worl`, + execute: (ctx) => { + ctx.reply('pong') + } +}) + +``` + + +### Example: command published in guild + +```ts title=src/commands/ping.ts +import { commandModule, CommandType } from '@sern/handler' +import { publishConfig } from '@sern/publisher' + +export default commandModule( { + type: CommandType.Slash, + plugins: [ + publishConfig({ + guildIds: ["889026545715400705"] + }) + ], + description: `hello worl`, + execute: (ctx) => { + ctx.reply('pong') + } +}) + +``` + diff --git a/packages/publisher/index.ts b/packages/publisher/index.ts new file mode 100644 index 0000000..1d3e135 --- /dev/null +++ b/packages/publisher/index.ts @@ -0,0 +1,226 @@ +import type { Init, CommandModule, Emitter, Logging } from '@sern/handler' +import { controller, CommandInitPlugin, CommandType } from '@sern/handler' +import { writeFile } from 'node:fs/promises'; +import { inspect } from 'node:util'; +import type { PermissionFlagsBits } from 'discord.js' + +const optionsTransformer = (ops?: Array<{ type: number }>) => { + return ops?.map((el) => { + if ('command' in el) { + const { command, ...rest } = el; + return rest; + } + return el; + }) ?? []; +}; + +const intoApplicationType = (type: number) => + type === 3 ? 1 : Math.log2(type); + +const makeDescription = (type: number, desc: string) => { + if (type !== CommandType.Text && desc !== '') { + console.warn('Found context menu that has non empty description field. Implictly publishing with empty description'); + return ''; + } + return desc; +}; + +const serializePerms = (perms: unknown) => { + if(typeof perms === 'bigint' || typeof perms === 'number') { + return perms.toString(); + } + + if(Array.isArray(perms)) { + return perms.reduce((acc, cur) => acc|cur, BigInt(0)) + .toString() + } + return null; +} + +const BASE_URL = new URL('https://discord.com/api/v10/applications/'); +const PUBLISHABLE = 0b1110; + +export class Publisher implements Init { + constructor(private modules: Map, + private sernEmitter : Emitter, + private logger: Logging) {} + + async init() { + if(!process.env.DISCORD_TOKEN) { + throw Error("No token found to publish. add DISCORD_TOKEN to .env"); + } + const headers = [['Authorization', 'Bot ' + process.env.DISCORD_TOKEN], + ['Content-Type', 'application/json']] as Array<[string,string]> + let me; + let appid: string; + try { + me = await fetch(new URL('@me', BASE_URL), { headers }).then(res => res.json()); + appid = me.id; + } catch(e) { + console.log("Something went wrong while trying to fetch your application:"); + throw e; + } + const GLOBAL_URL = new URL(`${appid}/commands`, BASE_URL); + interface LocalPublish { + guildIds?: string[] + default_member_permissions: string, + integration_types: string[], + contexts: number[] + } + const listener = async () => { + this.logger.info({ message: 'publishing modules' }); + const modules = + Array.from(this.modules.values()) + .filter(module => (module.type & PUBLISHABLE) != 0) + .map(module => { + const publish = module.locals.publish as LocalPublish || {} + return { + guildIds: publish?.guildIds ?? [], + toJSON() { + const applicationType = intoApplicationType(module.type); + const { default_member_permissions, + integration_types, + contexts } = publish; + return { + name: module.name, type: applicationType, + //@ts-ignore we know description is at least empty str or filled + description: makeDescription(applicationType, module.description), + //@ts-ignore shutup + options: optionsTransformer(module?.options), + default_member_permissions, + integration_types, contexts, + //@ts-ignore + name_localizations: module.locals.nloc, + //@ts-ignore + description_localizations: module.locals.dloc + } + } + } + }) + const [globalCommands, guildedCommands] = modules.reduce( + //technically these aren't sern/handler modules. + ([globals, guilded], module) => { + const isPublishableGlobally = !module.guildIds || module.guildIds.length === 0; + if (isPublishableGlobally) { + return [[module, ...globals], guilded]; + } + return [globals, [module, ...guilded]]; + }, [[], []] as [any[], any[]]); + + const resultGlobal = await fetch(GLOBAL_URL, { + method: 'PUT', + headers, + body: JSON.stringify(globalCommands) + }) + const globalJsonBody = await resultGlobal.json(); + if(resultGlobal.ok) { + this.logger.info({ message: "Publisher: All global commands published." }) + } else { + this.logger.info({ message: inspect(globalJsonBody, false, Infinity ) }) + //todo: implement rate limiting + } + const guildIdMap: Map = new Map(); + const responsesMap = new Map(); + guildedCommands.forEach((entry) => { + const guildIds: string[] = entry.guildIds ?? []; + if (guildIds) { + guildIds.forEach((guildId) => { + if (guildIdMap.has(guildId)) { + guildIdMap.get(guildId)?.push(entry); + } else { + guildIdMap.set(guildId, [entry]); + } + }); + } + }); + for (const [guildId, array] of guildIdMap.entries()) { + const guildCommandURL = new URL(`${appid}/guilds/${guildId}/commands`, BASE_URL); + const response = await fetch(guildCommandURL, { + method: 'PUT', + body: JSON.stringify(array), + headers, + }); + const result = await response.json(); + if (response.ok) { + this.logger.info({ message: guildId + " published succesfully" }) + responsesMap.set(guildId, result); + } else { + switch(response.status) { + case 400 : { + console.error(inspect(result, { depth: Infinity })) + console.error("Modules with validation errors:" + + inspect(Object.keys(result.errors).map(idx => array[idx as any]))) + throw Error("400: Ensure your commands have proper fields and data and nothing left out"); + } + case 404 : { + console.error(inspect(result, { depth: Infinity })) + throw Error("Forbidden 404. Is you application id and/or token correct?") + } + case 429: { + console.error(inspect(result, { depth: Infinity })) + throw Error('Chill out homie, too many requests') + } + } + } + } + await writeFile( + '.sern/command-data-remote.json', + JSON.stringify({ global: globalJsonBody, + ...Object.fromEntries(responsesMap) }, null, 4), + 'utf8') + } + this.sernEmitter.addListener('modulesLoaded', () => { + listener(); + this.sernEmitter.removeListener('modulesLoaded', listener); + }) + } +} + +export type ValidMemberPermissions = + | typeof PermissionFlagsBits //discord.js enum + | Array + | string //must be a stringified number + | bigint + +export interface PublishConfig { + guildIds?: string[]; + defaultMemberPermissions?: ValidMemberPermissions; + integrationTypes?: Array<'Guild'|'User'> + contexts?: number[] +} + +export type ValidPublishOptions = + | PublishConfig + | ((absPath: string, module: CommandModule) => PublishConfig) + +const IntegrationType = { + Guild: '0', User: '1' +} +/** + * the publishConfig plugin. + * If your commandModule requires extra properties such as publishing for certain guilds, you would + * put those options in there. + * sets 'publish' on locals field for modules. + * @param {ValidPublishOptions} config options to configure how this module is published + */ +export const publishConfig = (config: ValidPublishOptions) => { + return CommandInitPlugin(({ module, absPath }) => { + if((module.type & PUBLISHABLE) === 0) { + //@ts-ignore + return controller.stop("Cannot publish this module; Not of type Both,Slash,CtxUsr,CtxMsg."); + } + let _config=config + if(typeof _config === 'function') { + _config = _config(absPath, module as CommandModule); + } + const { contexts, defaultMemberPermissions, integrationTypes:integration_types, guildIds } = _config + Reflect.set(module.locals, 'publish', { + guildIds, + contexts, + integration_types: integration_types?.map(i => Reflect.get(IntegrationType, i)), + default_member_permissions: serializePerms(defaultMemberPermissions), + }) + return controller.next(); + }) +} + diff --git a/packages/publisher/metadata.json b/packages/publisher/metadata.json new file mode 100644 index 0000000..f744f73 --- /dev/null +++ b/packages/publisher/metadata.json @@ -0,0 +1 @@ +{ "type" : "service" } diff --git a/packages/publisher/package.json b/packages/publisher/package.json new file mode 100644 index 0000000..340de9d --- /dev/null +++ b/packages/publisher/package.json @@ -0,0 +1,26 @@ +{ + "name": "@sern/publisher", + "version": "1.1.0", + "description": "Localizer", + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "watch": "tsc --watch", + "test": "exit 0" + }, + "devDependencies": { + "@sern/handler": "^3.3.0", + "discord.js": "^14.15.3", + "vitest": "^1.2.2" + }, + "keywords": [], + "author": "", + "license": "ISC", + "publishConfig": { + "access": "public", + "tag": "alpha" + }, + "dependencies": { + "@parcel/watcher": "^2.4.1" + } +} diff --git a/packages/publisher/tsconfig.json b/packages/publisher/tsconfig.json new file mode 100644 index 0000000..36da4e8 --- /dev/null +++ b/packages/publisher/tsconfig.json @@ -0,0 +1,112 @@ +{ + "files": [ + "./index.ts" + ], + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "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 legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "CommonJS", /* Specify what module code is generated. */ + // "rootDir": "./", /* 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. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "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. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "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. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "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, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/yarn.lock b/yarn.lock index cd6a09a..7f51199 100644 --- a/yarn.lock +++ b/yarn.lock @@ -331,6 +331,140 @@ __metadata: languageName: node linkType: hard +"@parcel/watcher-android-arm64@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-android-arm64@npm:2.4.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-arm64@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-darwin-arm64@npm:2.4.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-x64@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-darwin-x64@npm:2.4.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-freebsd-x64@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-freebsd-x64@npm:2.4.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm-glibc@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-linux-arm-glibc@npm:2.4.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-glibc@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-linux-arm64-glibc@npm:2.4.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-musl@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-linux-arm64-musl@npm:2.4.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-glibc@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-linux-x64-glibc@npm:2.4.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-musl@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-linux-x64-musl@npm:2.4.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-win32-arm64@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-win32-arm64@npm:2.4.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-win32-ia32@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-win32-ia32@npm:2.4.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@parcel/watcher-win32-x64@npm:2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher-win32-x64@npm:2.4.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher@npm:^2.4.1": + version: 2.4.1 + resolution: "@parcel/watcher@npm:2.4.1" + dependencies: + "@parcel/watcher-android-arm64": 2.4.1 + "@parcel/watcher-darwin-arm64": 2.4.1 + "@parcel/watcher-darwin-x64": 2.4.1 + "@parcel/watcher-freebsd-x64": 2.4.1 + "@parcel/watcher-linux-arm-glibc": 2.4.1 + "@parcel/watcher-linux-arm64-glibc": 2.4.1 + "@parcel/watcher-linux-arm64-musl": 2.4.1 + "@parcel/watcher-linux-x64-glibc": 2.4.1 + "@parcel/watcher-linux-x64-musl": 2.4.1 + "@parcel/watcher-win32-arm64": 2.4.1 + "@parcel/watcher-win32-ia32": 2.4.1 + "@parcel/watcher-win32-x64": 2.4.1 + detect-libc: ^1.0.3 + is-glob: ^4.0.3 + micromatch: ^4.0.5 + node-addon-api: ^7.0.0 + node-gyp: latest + dependenciesMeta: + "@parcel/watcher-android-arm64": + optional: true + "@parcel/watcher-darwin-arm64": + optional: true + "@parcel/watcher-darwin-x64": + optional: true + "@parcel/watcher-freebsd-x64": + optional: true + "@parcel/watcher-linux-arm-glibc": + optional: true + "@parcel/watcher-linux-arm64-glibc": + optional: true + "@parcel/watcher-linux-arm64-musl": + optional: true + "@parcel/watcher-linux-x64-glibc": + optional: true + "@parcel/watcher-linux-x64-musl": + optional: true + "@parcel/watcher-win32-arm64": + optional: true + "@parcel/watcher-win32-ia32": + optional: true + "@parcel/watcher-win32-x64": + optional: true + checksum: 4da70551da27e565c726b0bbd5ba5afcb2bca36dfd8619a649f0eaa41f693ddd1d630c36e53bc083895d71a3e28bc4199013e557cd13c7af6ccccab28ceecbff + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -522,6 +656,17 @@ __metadata: languageName: unknown linkType: soft +"@sern/publisher@workspace:packages/publisher": + version: 0.0.0-use.local + resolution: "@sern/publisher@workspace:packages/publisher" + dependencies: + "@parcel/watcher": ^2.4.1 + "@sern/handler": ^3.3.0 + discord.js: ^14.15.3 + vitest: ^1.2.2 + languageName: unknown + linkType: soft + "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -921,6 +1066,15 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e + languageName: node + linkType: hard + "diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -1339,7 +1493,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1": +"is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -1520,7 +1674,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.4": +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.7 resolution: "micromatch@npm:4.0.7" dependencies: @@ -1674,6 +1828,15 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^7.0.0": + version: 7.1.0 + resolution: "node-addon-api@npm:7.1.0" + dependencies: + node-gyp: latest + checksum: 26640c8d2ed7e2059e2ed65ee79e2a195306b3f1fc27ad11448943ba91d37767bd717a9a0453cc97e83a1109194dced8336a55f8650000458ef625c0b8b5e3df + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 10.1.0 resolution: "node-gyp@npm:10.1.0" @@ -2252,13 +2415,20 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.6.2, tslib@npm:^2.1.0, tslib@npm:^2.6.2": +"tslib@npm:2.6.2, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad languageName: node linkType: hard +"tslib@npm:^2.1.0": + version: 2.6.3 + resolution: "tslib@npm:2.6.3" + checksum: 74fce0e100f1ebd95b8995fbbd0e6c91bdd8f4c35c00d4da62e285a3363aaa534de40a80db30ecfd388ed7c313c42d930ee0eaf108e8114214b180eec3dbe6f5 + languageName: node + linkType: hard + "type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" @@ -2278,7 +2448,7 @@ __metadata: "typescript@patch:typescript@^5.0.0#~builtin": version: 5.4.5 - resolution: "typescript@patch:typescript@npm%3A5.4.5#~builtin::version=5.4.5&hash=f3b441" + resolution: "typescript@patch:typescript@npm%3A5.4.5#~builtin::version=5.4.5&hash=14eedb" bin: tsc: bin/tsc tsserver: bin/tsserver