From 6f204e00048c0877ba5d261a3216f846ef403f5d Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 16:36:36 +0100 Subject: [PATCH 01/10] feat: autogenerated config --- configtypes.js | 80 +++++++++++++++++ package.json | 4 +- src/activity.ts | 28 +++--- src/config.ts | 117 +------------------------ src/configtype.ts | 166 ++++++++++++++++++++++++++++++++++++ src/constants.ts | 212 +++++++++++++++++++++++----------------------- src/editor.ts | 5 +- 7 files changed, 373 insertions(+), 239 deletions(-) create mode 100644 configtypes.js create mode 100644 src/configtype.ts diff --git a/configtypes.js b/configtypes.js new file mode 100644 index 0000000..e5619f8 --- /dev/null +++ b/configtypes.js @@ -0,0 +1,80 @@ +const fs = require("fs"); // should be changed to import +const path = require("path"); + +const ROOT = process.cwd(); +const PACKAGE_JSON = path.join(ROOT, "package.json"); +const OUT_FILE = path.join(ROOT, "src", "configtype.ts"); + +const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf8")); + +const configurations = pkg.contributes?.configuration ?? []; + +function schemaTypeToTs(schema) { + if (!schema) return "unknown"; + + if (Array.isArray(schema.type)) { + return schema.type.map((t) => schemaTypeToTs({ type: t })).join(" | "); + } + + if (schema.enum) { + return schema.enum.map((v) => JSON.stringify(v)).join(" | "); + } + + switch (schema.type) { + case "boolean": + return "boolean"; + case "string": + return "string"; + case "number": + return "number"; + case "array": { + const itemType = schema.items ? schemaTypeToTs(schema.items) : "unknown"; + const needsParens = itemType.includes("|"); + return needsParens ? `(${itemType})[]` : `${itemType}[]`; + } + case "object": { + if (schema.additionalProperties) { + const valueType = schemaTypeToTs(schema.additionalProperties); + return `{ [key: string]: ${valueType} }`; + } + return "Record"; + } + default: + return "unknown"; + } +} + +const entries = []; + +for (const block of configurations) { + const props = block.properties ?? {}; + for (let [key, schema] of Object.entries(props)) { + key = JSON.stringify(key); + const tsType = schemaTypeToTs(schema); + entries.push(` ${key}: ${tsType};`); + } +} + +const output = `/* AUTO-GENERATED FILE + * DO NOT EDIT MANUALLY + * Generated from package.json contributes.configuration + */ + +export type ExtensionConfigGenerated = { +${entries.join("\n")} +}; +`; + +fs.mkdirSync(path.dirname(OUT_FILE), { recursive: true }); +if (process.argv.includes("--check")) { + const existing = fs.existsSync(OUT_FILE) ? fs.readFileSync(OUT_FILE, "utf8") : null; + if (existing === null) { + console.warn("missing", OUT_FILE); + } else if (existing !== output) { + console.log("up to date", OUT_FILE); + } + console.log("checked", OUT_FILE); +} else { + fs.writeFileSync(OUT_FILE, output, "utf8"); + console.log("generated", OUT_FILE); +} diff --git a/package.json b/package.json index d0f5d07..c97c16d 100644 --- a/package.json +++ b/package.json @@ -43,10 +43,10 @@ "compile": "npm run check-types && npm run lint && node esbuild.js", "watch": "npm-run-all -p watch:*", "watch:esbuild": "node esbuild.js --watch", - "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", + "watch:tsc": "node configtypes.js && tsc --noEmit --watch --project tsconfig.json", "package": "npm run check-types && npm run lint && node esbuild.js --production", "pkg": "vsce package", - "check-types": "tsc --noEmit", + "check-types": "node configtypes.js && tsc --noEmit", "lint": "prettier . --check" }, "dependencies": { diff --git a/src/activity.ts b/src/activity.ts index 9f8262c..2a69cec 100644 --- a/src/activity.ts +++ b/src/activity.ts @@ -1,6 +1,7 @@ +import type { SetActivity } from "@xhayper/discord-rpc"; +import type { ExtensionConfigGenerated } from "./configtype"; +import type { GatewayActivityButton } from "discord-api-types/v10"; import { resolveLangName, toLower, toTitle, toUpper, getArticle } from "./helpers/resolveLangName"; -import { type GatewayActivityButton } from "discord-api-types/v10"; -import { type SetActivity } from "@xhayper/discord-rpc"; import { CONFIG_KEYS, FAKE_EMPTY } from "./constants"; import { getFileSize } from "./helpers/getFileSize"; import { isExcluded } from "./helpers/isExcluded"; @@ -28,15 +29,8 @@ export enum CURRENT_STATUS { VIEWING = "viewing" } -export enum PROBLEM_LEVEL { - ERROR = "error", - WARNING = "warning", - INFO = "info", - HINT = "hint" -} - // TODO: move this to data class -const COUNTED_SEVERITIES: { [key in PROBLEM_LEVEL]: number } = { +const COUNTED_SEVERITIES = { error: 0, warning: 0, info: 0, @@ -187,7 +181,7 @@ export const activity = async ( if (isObject(ignoreWorkspacesText)) { workspaceExcludedText = (dataClass.workspaceFolder - ? await replaceAllText(ignoreWorkspacesText[dataClass.workspaceFolder.name]) + ? await replaceAllText(String(ignoreWorkspacesText[dataClass.workspaceFolder.name])) : undefined) ?? workspaceExcludedText; } else { const text = await replaceAllText(ignoreWorkspacesText); @@ -409,24 +403,26 @@ export const replaceAppInfo = (text: string): string => { return text; }; -export const getTotalProblems = (countedSeverities: PROBLEM_LEVEL[]): number => { +export const getTotalProblems = ( + countedSeverities: ExtensionConfigGenerated["vscord.status.problems.countedSeverities"] +): number => { let totalProblems = 0; for (const severity of countedSeverities) { switch (severity) { - case PROBLEM_LEVEL.ERROR: { + case "error": { totalProblems += COUNTED_SEVERITIES.error; break; } - case PROBLEM_LEVEL.WARNING: { + case "warning": { totalProblems += COUNTED_SEVERITIES.warning; break; } - case PROBLEM_LEVEL.INFO: { + case "info": { totalProblems += COUNTED_SEVERITIES.info; break; } - case PROBLEM_LEVEL.HINT: { + case "hint": { totalProblems += COUNTED_SEVERITIES.hint; break; } diff --git a/src/config.ts b/src/config.ts index f572d3b..5d33f58 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,119 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { type ConfigurationTarget, type WorkspaceConfiguration, workspace } from "vscode"; -import { type PROBLEM_LEVEL } from "./activity"; +import type { ExtensionConfigGenerated } from "./configtype"; export type FileSizeStandard = "iec" | "jedec"; -export interface ExtensionConfigurationType { - enable: string; - "app.id": string; - "app.name": "Code" | "Visual Studio Code" | "VSCodium" | "Antigravity" | "Cursor" | "Custom"; - "app.privacyMode.enable": boolean; - "app.whitelistEnabled": boolean; - "app.whitelistIsBlacklist": boolean; - "app.whitelist": string[]; - "status.details.enabled": boolean; - "status.details.idle.enabled": boolean; - "status.details.text.idle": string; - "status.details.text.viewing": string; - "status.details.text.editing": string; - "status.details.text.debugging": string; - "status.details.text.notInFile": string; - "status.details.text.noWorkSpaceText": string; - "status.state.enabled": boolean; - "status.state.debugging.enabled": boolean; - "status.state.idle.enabled": boolean; - "status.state.text.idle": string; - "status.state.text.viewing": string; - "status.state.text.editing": string; - "status.state.text.debugging": string; - "status.state.text.notInFile": string; - "status.state.text.noWorkspaceFound": string; - "status.buttons.button1.enabled": boolean; - "status.buttons.button1.active.enabled": boolean; - "status.buttons.button1.active.label": string; - "status.buttons.button1.active.url": string; - "status.buttons.button1.inactive.enabled": boolean; - "status.buttons.button1.inactive.label": string; - "status.buttons.button1.inactive.url": string; - "status.buttons.button1.idle.enabled": boolean; - "status.buttons.button1.idle.label": string; - "status.buttons.button1.idle.url": string; - "status.buttons.button1.git.active.enabled": boolean; - "status.buttons.button1.git.active.label": string; - "status.buttons.button1.git.active.url": string; - "status.buttons.button1.git.inactive.enabled": boolean; - "status.buttons.button1.git.inactive.label": string; - "status.buttons.button1.git.inactive.url": string; - "status.buttons.button1.git.idle.enabled": boolean; - "status.buttons.button1.git.idle.label": string; - "status.buttons.button1.git.idle.url": string; - "status.buttons.button2.enabled": boolean; - "status.buttons.button2.active.enabled": boolean; - "status.buttons.button2.active.label": string; - "status.buttons.button2.active.url": string; - "status.buttons.button2.inactive.enabled": boolean; - "status.buttons.button2.inactive.label": string; - "status.buttons.button2.inactive.url": string; - "status.buttons.button2.idle.enabled": boolean; - "status.buttons.button2.idle.label": string; - "status.buttons.button2.idle.url": string; - "status.buttons.button2.git.active.enabled": boolean; - "status.buttons.button2.git.active.label": string; - "status.buttons.button2.git.active.url": string; - "status.buttons.button2.git.inactive.enabled": boolean; - "status.buttons.button2.git.inactive.label": string; - "status.buttons.button2.git.inactive.url": string; - "status.buttons.button2.git.idle.enabled": boolean; - "status.buttons.button2.git.idle.label": string; - "status.buttons.button2.git.idle.url": string; - "status.image.large.idle.key": string; - "status.image.large.idle.text": string; - "status.image.large.viewing.key": string; - "status.image.large.viewing.text": string; - "status.image.large.editing.key": string; - "status.image.large.editing.text": string; - "status.image.large.debugging.key": string; - "status.image.large.debugging.text": string; - "status.image.large.notInFile.key": string; - "status.image.large.notInFile.text": string; - "status.image.small.idle.key": string; - "status.image.small.idle.text": string; - "status.image.small.viewing.key": string; - "status.image.small.viewing.text": string; - "status.image.small.editing.key": string; - "status.image.small.editing.text": string; - "status.image.small.debugging.key": string; - "status.image.small.debugging.text": string; - "status.image.small.notInFile.key": string; - "status.image.small.notInFile.text": string; - "status.image.problems.enabled": boolean; - "status.image.problems.text": string; - "status.problems.enabled": boolean; - "status.problems.text": string; - "status.problems.countedSeverities": Array; - "status.idle.enabled": boolean; - "status.idle.check": boolean; - "status.idle.disconnectOnIdle": boolean; - "status.idle.resetElapsedTime": boolean; - "status.idle.timeout": number; - "status.showElapsedTime": boolean; - "status.resetElapsedTimePerFile": boolean; - "ignore.workspaces": Array; - "ignore.workspacesText": string | Record; - "ignore.repositories": Array; - "ignore.organizations": Array; - "ignore.gitHosts": Array; - "file.size.humanReadable": boolean; - "file.size.standard": FileSizeStandard; - "file.size.round": number; - "file.size.spacer": string; - "behaviour.additionalFileMapping": Record; - "behaviour.suppressNotifications": boolean; - "behaviour.suppressRpcCouldNotConnect": boolean; - "behaviour.statusBarAlignment": "Right" | "Left"; - "behaviour.debug": boolean; -} +// export interface ExtensionConfigurationType was here // Created by hayper1919, you may use it inside your extension /** @@ -294,6 +185,6 @@ export type WorkspaceConfigurationWithType; +export type ExtensionConfiguration = WorkspaceConfigurationWithType; -export const getConfig = () => workspace.getConfiguration("vscord") as ExtensionConfiguration; +export const getConfig = () => workspace.getConfiguration() as ExtensionConfiguration; diff --git a/src/configtype.ts b/src/configtype.ts new file mode 100644 index 0000000..1fd9030 --- /dev/null +++ b/src/configtype.ts @@ -0,0 +1,166 @@ +/* AUTO-GENERATED FILE + * DO NOT EDIT MANUALLY + * Generated from package.json contributes.configuration + */ + +export type ExtensionConfigGenerated = { + "vscord.enable": boolean; + "vscord.app.name": "Code" | "Visual Studio Code" | "VSCodium" | "Antigravity" | "Cursor" | "Custom"; + "vscord.app.id": string; + "vscord.app.privacyMode.enable": boolean; + "vscord.app.whitelistEnabled": boolean; + "vscord.app.whitelistIsBlacklist": boolean; + "vscord.app.whitelist": string[]; + "vscord.status.showElapsedTime": boolean; + "vscord.status.resetElapsedTimePerFile": boolean; + "vscord.status.problems.enabled": boolean; + "vscord.status.problems.text": string; + "vscord.status.problems.countedSeverities": ("error" | "warning" | "info" | "hint")[]; + "vscord.status.idle.check": boolean; + "vscord.status.idle.enabled": boolean; + "vscord.status.idle.disconnectOnIdle": boolean; + "vscord.status.idle.resetElapsedTime": boolean; + "vscord.status.idle.timeout": number; + "vscord.ignore.workspaces": string[]; + "vscord.ignore.workspacesText": string | Record; + "vscord.ignore.repositories": string[]; + "vscord.ignore.organizations": string[]; + "vscord.ignore.gitHosts": string[]; + "vscord.status.details.enabled": boolean; + "vscord.status.details.idle.enabled": boolean; + "vscord.status.details.text.idle": string; + "vscord.status.details.text.editing": string; + "vscord.status.details.text.debugging": string; + "vscord.status.details.text.viewing": string; + "vscord.status.details.text.notInFile": string; + "vscord.status.details.text.noWorkSpaceText": string; + "vscord.status.state.enabled": boolean; + "vscord.status.state.debugging.enabled": boolean; + "vscord.status.state.idle.enabled": boolean; + "vscord.status.state.text.idle": string; + "vscord.status.state.text.editing": string; + "vscord.status.state.text.debugging": string; + "vscord.status.state.text.viewing": string; + "vscord.status.state.text.notInFile": string; + "vscord.status.state.text.noWorkspaceFound": string; + "vscord.status.image.large.idle.key": string; + "vscord.status.image.large.idle.text": string; + "vscord.status.image.large.viewing.key": string; + "vscord.status.image.large.viewing.text": string; + "vscord.status.image.large.editing.key": string; + "vscord.status.image.large.editing.text": string; + "vscord.status.image.large.debugging.key": string; + "vscord.status.image.large.debugging.text": string; + "vscord.status.image.large.notInFile.key": string; + "vscord.status.image.large.notInFile.text": string; + "vscord.status.image.small.idle.key": string; + "vscord.status.image.small.idle.text": string; + "vscord.status.image.small.viewing.key": string; + "vscord.status.image.small.viewing.text": string; + "vscord.status.image.small.editing.key": string; + "vscord.status.image.small.editing.text": string; + "vscord.status.image.small.debugging.key": string; + "vscord.status.image.small.debugging.text": string; + "vscord.status.image.small.notInFile.key": string; + "vscord.status.image.small.notInFile.text": string; + "vscord.status.buttons.button1.enabled": boolean; + "vscord.status.buttons.button1.active.enabled": boolean; + "vscord.status.buttons.button1.active.label": string; + "vscord.status.buttons.button1.active.url": string; + "vscord.status.buttons.button1.inactive.enabled": boolean; + "vscord.status.buttons.button1.inactive.label": string; + "vscord.status.buttons.button1.inactive.url": string; + "vscord.status.buttons.button1.idle.enabled": boolean; + "vscord.status.buttons.button1.idle.label": string; + "vscord.status.buttons.button1.idle.url": string; + "vscord.status.buttons.button1.git.active.enabled": boolean; + "vscord.status.buttons.button1.git.active.label": string; + "vscord.status.buttons.button1.git.active.url": string; + "vscord.status.buttons.button1.git.inactive.enabled": boolean; + "vscord.status.buttons.button1.git.inactive.label": string; + "vscord.status.buttons.button1.git.inactive.url": string; + "vscord.status.buttons.button1.git.idle.enabled": boolean; + "vscord.status.buttons.button1.git.idle.label": string; + "vscord.status.buttons.button1.git.idle.url": string; + "vscord.status.buttons.button2.enabled": boolean; + "vscord.status.buttons.button2.active.enabled": boolean; + "vscord.status.buttons.button2.active.label": string; + "vscord.status.buttons.button2.active.url": string; + "vscord.status.buttons.button2.inactive.enabled": boolean; + "vscord.status.buttons.button2.inactive.label": string; + "vscord.status.buttons.button2.inactive.url": string; + "vscord.status.buttons.button2.idle.enabled": boolean; + "vscord.status.buttons.button2.idle.label": string; + "vscord.status.buttons.button2.idle.url": string; + "vscord.status.buttons.button2.git.active.enabled": boolean; + "vscord.status.buttons.button2.git.active.label": string; + "vscord.status.buttons.button2.git.active.url": string; + "vscord.status.buttons.button2.git.inactive.enabled": boolean; + "vscord.status.buttons.button2.git.inactive.label": string; + "vscord.status.buttons.button2.git.inactive.url": string; + "vscord.status.buttons.button2.git.idle.enabled": boolean; + "vscord.status.buttons.button2.git.idle.label": string; + "vscord.status.buttons.button2.git.idle.url": string; + "vscord.file.size.round": number; + "vscord.file.size.spacer": string; + "vscord.behaviour.additionalFileMapping": { [key: string]: string }; + "vscord.behaviour.suppressNotifications": boolean; + "vscord.behaviour.suppressRpcCouldNotConnect": boolean; + "vscord.behaviour.statusBarAlignment": "Right" | "Left"; + "vscord.file.size.humanReadable": boolean; + "vscord.file.size.standard": "iec" | "jedec"; + "vscord.behaviour.debug": boolean; + "vscord.enabled": boolean; + "rpc.id": string; + "rpc.appName": string; + "rpc.enabled": boolean; + "rpc.detailsEditing": string; + "rpc.detailsIdling": string; + "rpc.detailsDebugging": string; + "rpc.detailsViewing": string; + "rpc.lowerDetailsEditing": string; + "rpc.lowerDetailsIdling": string; + "rpc.lowerDetailsDebugging": string; + "rpc.lowerDetailsViewing": string; + "rpc.lowerDetailsNoWorkspaceFound": string; + "rpc.baseImageLink": string; + "rpc.largeImage": string; + "rpc.largeImageIdling": string; + "rpc.smallImage": string; + "rpc.removeElapsedTime": boolean; + "rpc.removeDetails": boolean; + "rpc.removeLowerDetails": boolean; + "rpc.removeLowerDetailsIdling": boolean; + "rpc.showProblems": boolean; + "rpc.problemsText": string; + "rpc.ignoreWorkspaces": unknown[]; + "rpc.ignoreWorkspacesText": string | Record; + "rpc.checkIdle": boolean; + "rpc.disconnectOnIdle": boolean; + "rpc.resetElapsedTimeAfterIdle": boolean; + "rpc.idleTimeout": number; + "rpc.idleText": string; + "rpc.buttonEnabled": boolean; + "rpc.buttonActiveLabel": string; + "vscord.status.button.active.enabled": boolean; + "vscord.status.button.active.label": string; + "vscord.status.button.active.url": string; + "vscord.status.button.idle.enabled": boolean; + "vscord.status.button.idle.label": string; + "vscord.status.button.idle.url": string; + "vscord.status.button.inactive.enabled": boolean; + "vscord.status.button.inactive.label": string; + "vscord.status.button.inactive.url": string; + "rpc.buttonActiveUrl": string; + "rpc.buttonInactiveLabel": string; + "rpc.buttonInactiveUrl": string; + "rpc.ignoreRepositories": string[]; + "rpc.ignoreOrganizations": string[]; + "rpc.ignoreGitHosts": string[]; + "rpc.suppressNotifications": boolean; + "rpc.prioritizeLanguagesOverExtensions": boolean; + "rpc.fileSizeHumanReadable": boolean; + "rpc.fileSizeSpec": "si" | "iec" | "jedec"; + "rpc.fileSizeFixed": number; + "rpc.fileSizeSpacer": string; +}; diff --git a/src/constants.ts b/src/constants.ts index c4b03cb..1714d41 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,115 +9,115 @@ export const EMPTY = ""; export const FAKE_EMPTY = "\u200b\u200b"; export const CONFIG_KEYS = { - Enable: "enable" as const, + Enable: "vscord.enable" as const, App: { - Id: "app.id" as const, - Name: "app.name" as const, - PrivacyMode: "app.privacyMode.enable" as const, - WhitelistEnabled: "app.whitelistEnabled" as const, - whitelistIsBlacklist: "app.whitelistIsBlacklist" as const, - Whitelist: "app.whitelist" as const + Id: "vscord.app.id" as const, + Name: "vscord.app.name" as const, + PrivacyMode: "vscord.app.privacyMode.enable" as const, + WhitelistEnabled: "vscord.app.whitelistEnabled" as const, + whitelistIsBlacklist: "vscord.app.whitelistIsBlacklist" as const, + Whitelist: "vscord.app.whitelist" as const } as const, Status: { Details: { - Enabled: "status.details.enabled" as const, + Enabled: "vscord.status.details.enabled" as const, Idle: { - Enabled: "status.details.idle.enabled" as const + Enabled: "vscord.status.details.idle.enabled" as const } as const, Text: { - Idle: "status.details.text.idle" as const, - Editing: "status.details.text.editing" as const, - Viewing: "status.details.text.viewing" as const, - NotInFile: "status.details.text.notInFile" as const, - NoWorkspaceText: "status.details.text.noWorkSpaceText" as const, - Debugging: "status.details.text.debugging" as const + Idle: "vscord.status.details.text.idle" as const, + Editing: "vscord.status.details.text.editing" as const, + Viewing: "vscord.status.details.text.viewing" as const, + NotInFile: "vscord.status.details.text.notInFile" as const, + NoWorkspaceText: "vscord.status.details.text.noWorkSpaceText" as const, + Debugging: "vscord.status.details.text.debugging" as const } as const } as const, State: { - Enabled: "status.state.enabled" as const, + Enabled: "vscord.status.state.enabled" as const, Debugging: { - Enabled: "status.state.debugging.enabled" as const + Enabled: "vscord.status.state.debugging.enabled" as const } as const, Idle: { - Enabled: "status.state.idle.enabled" as const + Enabled: "vscord.status.state.idle.enabled" as const } as const, Text: { - Idle: "status.state.text.idle" as const, - Editing: "status.state.text.editing" as const, - Debugging: "status.state.text.debugging" as const, - Viewing: "status.state.text.viewing" as const, - NotInFile: "status.state.text.notInFile" as const, - NoWorkspaceFound: "status.state.text.noWorkspaceFound" as const + Idle: "vscord.status.state.text.idle" as const, + Editing: "vscord.status.state.text.editing" as const, + Debugging: "vscord.status.state.text.debugging" as const, + Viewing: "vscord.status.state.text.viewing" as const, + NotInFile: "vscord.status.state.text.notInFile" as const, + NoWorkspaceFound: "vscord.status.state.text.noWorkspaceFound" as const } as const } as const, Buttons: { Button1: { - Enabled: "status.buttons.button1.enabled" as const, + Enabled: "vscord.status.buttons.button1.enabled" as const, Active: { - Enabled: "status.buttons.button1.active.enabled" as const, - Label: "status.buttons.button1.active.label" as const, - Url: "status.buttons.button1.active.url" as const + Enabled: "vscord.status.buttons.button1.active.enabled" as const, + Label: "vscord.status.buttons.button1.active.label" as const, + Url: "vscord.status.buttons.button1.active.url" as const } as const, Inactive: { - Enabled: "status.buttons.button1.inactive.enabled" as const, - Label: "status.buttons.button1.inactive.label" as const, - Url: "status.buttons.button1.inactive.url" as const + Enabled: "vscord.status.buttons.button1.inactive.enabled" as const, + Label: "vscord.status.buttons.button1.inactive.label" as const, + Url: "vscord.status.buttons.button1.inactive.url" as const } as const, Idle: { - Enabled: "status.buttons.button1.idle.enabled" as const, - Label: "status.buttons.button1.idle.label" as const, - Url: "status.buttons.button1.idle.url" as const + Enabled: "vscord.status.buttons.button1.idle.enabled" as const, + Label: "vscord.status.buttons.button1.idle.label" as const, + Url: "vscord.status.buttons.button1.idle.url" as const } as const, Git: { Active: { - Enabled: "status.buttons.button1.git.active.enabled" as const, - Label: "status.buttons.button1.git.active.label" as const, - Url: "status.buttons.button1.git.active.url" as const + Enabled: "vscord.status.buttons.button1.git.active.enabled" as const, + Label: "vscord.status.buttons.button1.git.active.label" as const, + Url: "vscord.status.buttons.button1.git.active.url" as const } as const, Inactive: { - Enabled: "status.buttons.button1.git.inactive.enabled" as const, - Label: "status.buttons.button1.git.inactive.label" as const, - Url: "status.buttons.button1.git.inactive.url" as const + Enabled: "vscord.status.buttons.button1.git.inactive.enabled" as const, + Label: "vscord.status.buttons.button1.git.inactive.label" as const, + Url: "vscord.status.buttons.button1.git.inactive.url" as const } as const, Idle: { - Enabled: "status.buttons.button1.git.idle.enabled" as const, - Label: "status.buttons.button1.git.idle.label" as const, - Url: "status.buttons.button1.git.idle.url" as const + Enabled: "vscord.status.buttons.button1.git.idle.enabled" as const, + Label: "vscord.status.buttons.button1.git.idle.label" as const, + Url: "vscord.status.buttons.button1.git.idle.url" as const } as const } as const }, Button2: { - Enabled: "status.buttons.button2.enabled" as const, + Enabled: "vscord.status.buttons.button2.enabled" as const, Active: { - Enabled: "status.buttons.button2.active.enabled" as const, - Label: "status.buttons.button2.active.label" as const, - Url: "status.buttons.button2.active.url" as const + Enabled: "vscord.status.buttons.button2.active.enabled" as const, + Label: "vscord.status.buttons.button2.active.label" as const, + Url: "vscord.status.buttons.button2.active.url" as const } as const, Inactive: { - Enabled: "status.buttons.button2.inactive.enabled" as const, - Label: "status.buttons.button2.inactive.label" as const, - Url: "status.buttons.button2.inactive.url" as const + Enabled: "vscord.status.buttons.button2.inactive.enabled" as const, + Label: "vscord.status.buttons.button2.inactive.label" as const, + Url: "vscord.status.buttons.button2.inactive.url" as const } as const, Idle: { - Enabled: "status.buttons.button2.idle.enabled" as const, - Label: "status.buttons.button2.idle.label" as const, - Url: "status.buttons.button2.idle.url" as const + Enabled: "vscord.status.buttons.button2.idle.enabled" as const, + Label: "vscord.status.buttons.button2.idle.label" as const, + Url: "vscord.status.buttons.button2.idle.url" as const } as const, Git: { Active: { - Enabled: "status.buttons.button2.git.active.enabled" as const, - Label: "status.buttons.button2.git.active.label" as const, - Url: "status.buttons.button2.git.active.url" as const + Enabled: "vscord.status.buttons.button2.git.active.enabled" as const, + Label: "vscord.status.buttons.button2.git.active.label" as const, + Url: "vscord.status.buttons.button2.git.active.url" as const } as const, Inactive: { - Enabled: "status.buttons.button2.git.inactive.enabled" as const, - Label: "status.buttons.button2.git.inactive.label" as const, - Url: "status.buttons.button2.git.inactive.url" as const + Enabled: "vscord.status.buttons.button2.git.inactive.enabled" as const, + Label: "vscord.status.buttons.button2.git.inactive.label" as const, + Url: "vscord.status.buttons.button2.git.inactive.url" as const } as const, Idle: { - Enabled: "status.buttons.button2.git.idle.enabled" as const, - Label: "status.buttons.button2.git.idle.label" as const, - Url: "status.buttons.button2.git.idle.url" as const + Enabled: "vscord.status.buttons.button2.git.idle.enabled" as const, + Label: "vscord.status.buttons.button2.git.idle.label" as const, + Url: "vscord.status.buttons.button2.git.idle.url" as const } as const } as const } @@ -125,84 +125,84 @@ export const CONFIG_KEYS = { Image: { Large: { Idle: { - Key: "status.image.large.idle.key" as const, - Text: "status.image.large.idle.text" as const + Key: "vscord.status.image.large.idle.key" as const, + Text: "vscord.status.image.large.idle.text" as const } as const, Editing: { - Key: "status.image.large.editing.key" as const, - Text: "status.image.large.editing.text" as const + Key: "vscord.status.image.large.editing.key" as const, + Text: "vscord.status.image.large.editing.text" as const } as const, Debugging: { - Key: "status.image.large.debugging.key" as const, - Text: "status.image.large.debugging.text" as const + Key: "vscord.status.image.large.debugging.key" as const, + Text: "vscord.status.image.large.debugging.text" as const } as const, Viewing: { - Key: "status.image.large.viewing.key" as const, - Text: "status.image.large.viewing.text" as const + Key: "vscord.status.image.large.viewing.key" as const, + Text: "vscord.status.image.large.viewing.text" as const } as const, NotInFile: { - Key: "status.image.large.notInFile.key" as const, - Text: "status.image.large.notInFile.text" as const + Key: "vscord.status.image.large.notInFile.key" as const, + Text: "vscord.status.image.large.notInFile.text" as const } as const } as const, Small: { Idle: { - Key: "status.image.small.idle.key" as const, - Text: "status.image.small.idle.text" as const + Key: "vscord.status.image.small.idle.key" as const, + Text: "vscord.status.image.small.idle.text" as const } as const, Editing: { - Key: "status.image.small.editing.key" as const, - Text: "status.image.small.editing.text" as const + Key: "vscord.status.image.small.editing.key" as const, + Text: "vscord.status.image.small.editing.text" as const } as const, Debugging: { - Key: "status.image.small.debugging.key" as const, - Text: "status.image.small.debugging.text" as const + Key: "vscord.status.image.small.debugging.key" as const, + Text: "vscord.status.image.small.debugging.text" as const } as const, Viewing: { - Key: "status.image.small.viewing.key" as const, - Text: "status.image.small.viewing.text" as const + Key: "vscord.status.image.small.viewing.key" as const, + Text: "vscord.status.image.small.viewing.text" as const } as const, NotInFile: { - Key: "status.image.small.notInFile.key" as const, - Text: "status.image.small.notInFile.text" as const + Key: "vscord.status.image.small.notInFile.key" as const, + Text: "vscord.status.image.small.notInFile.text" as const } as const } as const } as const, Problems: { - Enabled: "status.problems.enabled" as const, - Text: "status.problems.text" as const, - countedSeverities: "status.problems.countedSeverities" as const + Enabled: "vscord.status.problems.enabled" as const, + Text: "vscord.status.problems.text" as const, + countedSeverities: "vscord.status.problems.countedSeverities" as const } as const, Idle: { - Enabled: "status.idle.enabled" as const, - Check: "status.idle.check" as const, - DisconnectOnIdle: "status.idle.disconnectOnIdle" as const, - ResetElapsedTime: "status.idle.resetElapsedTime" as const, - Timeout: "status.idle.timeout" as const + Enabled: "vscord.status.idle.enabled" as const, + Check: "vscord.status.idle.check" as const, + DisconnectOnIdle: "vscord.status.idle.disconnectOnIdle" as const, + ResetElapsedTime: "vscord.status.idle.resetElapsedTime" as const, + Timeout: "vscord.status.idle.timeout" as const } as const, - ShowElapsedTime: "status.showElapsedTime" as const, - ResetElapsedTimePerFile: "status.resetElapsedTimePerFile" as const + ShowElapsedTime: "vscord.status.showElapsedTime" as const, + ResetElapsedTimePerFile: "vscord.status.resetElapsedTimePerFile" as const } as const, Ignore: { - Workspaces: "ignore.workspaces" as const, - WorkspacesText: "ignore.workspacesText" as const, - Repositories: "ignore.repositories" as const, - Organizations: "ignore.organizations" as const, - GitHosts: "ignore.gitHosts" as const + Workspaces: "vscord.ignore.workspaces" as const, + WorkspacesText: "vscord.ignore.workspacesText" as const, + Repositories: "vscord.ignore.repositories" as const, + Organizations: "vscord.ignore.organizations" as const, + GitHosts: "vscord.ignore.gitHosts" as const } as const, File: { Size: { - HumanReadable: "file.size.humanReadable" as const, - Standard: "file.size.standard" as const, - Round: "file.size.round" as const, - Spacer: "file.size.spacer" as const + HumanReadable: "vscord.file.size.humanReadable" as const, + Standard: "vscord.file.size.standard" as const, + Round: "vscord.file.size.round" as const, + Spacer: "vscord.file.size.spacer" as const } as const } as const, Behaviour: { - AdditionalFileMapping: "behaviour.additionalFileMapping" as const, - SuppressNotifications: "behaviour.suppressNotifications" as const, - SuppressRpcCouldNotConnect: "behaviour.suppressRpcCouldNotConnect" as const, - StatusBarAlignment: "behaviour.statusBarAlignment" as const, - Debug: "behaviour.debug" as const + AdditionalFileMapping: "vscord.behaviour.additionalFileMapping" as const, + SuppressNotifications: "vscord.behaviour.suppressNotifications" as const, + SuppressRpcCouldNotConnect: "vscord.behaviour.suppressRpcCouldNotConnect" as const, + StatusBarAlignment: "vscord.behaviour.statusBarAlignment" as const, + Debug: "vscord.behaviour.debug" as const } as const } as const; diff --git a/src/editor.ts b/src/editor.ts index 0d9dd52..84f3e8b 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,5 +1,6 @@ +import type { ExtensionConfigGenerated } from "./configtype"; import { Disposable, ConfigurationTarget, StatusBarAlignment, StatusBarItem, window, commands } from "vscode"; -import { type ExtensionConfiguration, type ExtensionConfigurationType, getConfig } from "./config"; +import { type ExtensionConfiguration, getConfig } from "./config"; import { CONFIG_KEYS } from "./constants"; import { logInfo, outputChannel } from "./logger"; @@ -63,7 +64,7 @@ class EditorController implements Disposable { const cfgKey = CONFIG_KEYS.Behaviour.StatusBarAlignment; const literalAlign = ( align === StatusBarAlignment.Right ? "Right" : "Left" - ) satisfies ExtensionConfigurationType[typeof cfgKey]; + ) satisfies ExtensionConfigGenerated[typeof cfgKey]; config.update(cfgKey, literalAlign); // updateStatusBarFromConfig() // called from config listener From 23d72bf52f5788a196c2da4567ba2447ee57837d Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 18:37:23 +0100 Subject: [PATCH 02/10] refactor: remove CONFIG_KEYS --- src/activity.ts | 192 ++++++++++++++++++++---------- src/constants.ts | 199 -------------------------------- src/controller.ts | 27 +++-- src/data.ts | 3 +- src/editor.ts | 11 +- src/extension.ts | 35 +++--- src/helpers/getApplicationId.ts | 7 +- src/helpers/getFileSize.ts | 13 +-- src/helpers/resolveLangName.ts | 4 +- 9 files changed, 180 insertions(+), 311 deletions(-) diff --git a/src/activity.ts b/src/activity.ts index 2a69cec..bdbf9a6 100644 --- a/src/activity.ts +++ b/src/activity.ts @@ -2,7 +2,7 @@ import type { SetActivity } from "@xhayper/discord-rpc"; import type { ExtensionConfigGenerated } from "./configtype"; import type { GatewayActivityButton } from "discord-api-types/v10"; import { resolveLangName, toLower, toTitle, toUpper, getArticle } from "./helpers/resolveLangName"; -import { CONFIG_KEYS, FAKE_EMPTY } from "./constants"; +import { FAKE_EMPTY } from "./constants"; import { getFileSize } from "./helpers/getFileSize"; import { isExcluded } from "./helpers/isExcluded"; import { isObject } from "./helpers/isObject"; @@ -83,50 +83,50 @@ export const activity = async ( if ( isIdling && - config.get(CONFIG_KEYS.Status.Idle.DisconnectOnIdle) && - config.get(CONFIG_KEYS.Status.Idle.ResetElapsedTime) + config.get("vscord.status.idle.disconnectOnIdle") && + config.get("vscord.status.idle.resetElapsedTime") ) { delete presence.startTimestamp; return {}; } - if (isIdling && !config.get(CONFIG_KEYS.Status.Idle.Enabled)) return {}; + if (isIdling && !config.get("vscord.status.idle.enabled")) return {}; - if (config.get(CONFIG_KEYS.Status.ShowElapsedTime)) { - presence.startTimestamp = config.get(CONFIG_KEYS.Status.ResetElapsedTimePerFile) + if (config.get("vscord.status.showElapsedTime")) { + presence.startTimestamp = config.get("vscord.status.resetElapsedTimePerFile") ? Date.now() : (previous.startTimestamp ?? Date.now()); } else { delete presence.startTimestamp; } - const detailsEnabled = config.get(CONFIG_KEYS.Status.Details.Enabled); - const detailsIdleEnabled = config.get(CONFIG_KEYS.Status.Details.Idle.Enabled); - const stateEnabled = config.get(CONFIG_KEYS.Status.State.Enabled); - const stateIdleEnabled = config.get(CONFIG_KEYS.Status.State.Idle.Enabled); - const privacyModeEnabled = config.get(CONFIG_KEYS.App.PrivacyMode) as boolean; + const detailsEnabled = config.get("vscord.status.details.enabled"); + const detailsIdleEnabled = config.get("vscord.status.details.idle.enabled"); + const stateEnabled = config.get("vscord.status.state.enabled"); + const stateIdleEnabled = config.get("vscord.status.state.idle.enabled"); + const privacyModeEnabled = config.get("vscord.app.privacyMode.enable") ?? false; const gitRepo = dataClass.gitRemoteUrl?.toString("https").replace(/\.git$/, ""); const gitOrg = dataClass.gitRemoteUrl?.organization ?? dataClass.gitRemoteUrl?.owner; const gitHost = dataClass.gitRemoteUrl?.source; - const isRepositoryExcluded = !!gitRepo && isExcluded(config.get(CONFIG_KEYS.Ignore.Repositories)!, gitRepo); - const isOrganizationExcluded = !!gitOrg && isExcluded(config.get(CONFIG_KEYS.Ignore.Organizations)!, gitOrg); - const isGitHostExcluded = !!gitHost && isExcluded(config.get(CONFIG_KEYS.Ignore.GitHosts)!, gitHost); + const isRepositoryExcluded = !!gitRepo && isExcluded(config.get("vscord.ignore.repositories")!, gitRepo); + const isOrganizationExcluded = !!gitOrg && isExcluded(config.get("vscord.ignore.organizations")!, gitOrg); + const isGitHostExcluded = !!gitHost && isExcluded(config.get("vscord.ignore.gitHosts")!, gitHost); const isGitExcluded = isRepositoryExcluded || isOrganizationExcluded || isGitHostExcluded || privacyModeEnabled; let isWorkspaceExcluded = dataClass.workspaceFolder !== undefined && - isExcluded(config.get(CONFIG_KEYS.Ignore.Workspaces)!, dataClass.workspaceFolder.uri.fsPath); + isExcluded(config.get("vscord.ignore.workspaces")!, dataClass.workspaceFolder.uri.fsPath); if (!isWorkspaceExcluded) isWorkspaceExcluded = dataClass.workspaceName !== undefined && - isExcluded(config.get(CONFIG_KEYS.Ignore.Workspaces)!, dataClass.workspaceName); + isExcluded(config.get("vscord.ignore.workspaces")!, dataClass.workspaceName); const isNotInFile = !isWorkspaceExcluded && !dataClass.editor; - const isDebugging = config.get(CONFIG_KEYS.Status.State.Debugging.Enabled) && !!debug.activeDebugSession; + const isDebugging = config.get("vscord.status.state.debugging.enabled") && !!debug.activeDebugSession; isViewing = !isDebugging && isViewing; let status: CURRENT_STATUS; @@ -136,9 +136,9 @@ export const activity = async ( else if (isViewing) status = CURRENT_STATUS.VIEWING; else status = CURRENT_STATUS.EDITING; - const PROBLEMS = config.get(CONFIG_KEYS.Status.Problems.Enabled) + const PROBLEMS = config.get("vscord.status.problems.enabled") ? await replaceFileInfo( - replaceGitInfo(replaceAppInfo(config.get(CONFIG_KEYS.Status.Problems.Text)!), isGitExcluded), + replaceGitInfo(replaceAppInfo(config.get("vscord.status.problems.text") ?? ""), isGitExcluded), isWorkspaceExcluded, dataClass.editor?.document, dataClass.editor?.selection @@ -176,7 +176,7 @@ export const activity = async ( }; let workspaceExcludedText = "No workspace ignore text provided."; - const ignoreWorkspacesText = config.get(CONFIG_KEYS.Ignore.WorkspacesText)!; + const ignoreWorkspacesText = config.get("vscord.ignore.workspacesText") ?? ""; if (isObject(ignoreWorkspacesText)) { workspaceExcludedText = @@ -201,68 +201,68 @@ export const activity = async ( case CURRENT_STATUS.IDLE: { if (!isWorkspaceExcluded) { if (detailsIdleEnabled && detailsEnabled) - details = await replaceAllText(config.get(CONFIG_KEYS.Status.Details.Text.Idle)!); + details = await replaceAllText(config.get("vscord.status.details.text.idle")!); if (stateIdleEnabled && stateEnabled) - state = await replaceAllText(config.get(CONFIG_KEYS.Status.State.Text.Idle)!); + state = await replaceAllText(config.get("vscord.status.state.text.idle")!); } - largeImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Idle.Key)!); - largeImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Idle.Text)!); - smallImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Idle.Key)!); - smallImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Idle.Text)!); + largeImageKey = await replaceAllText(config.get("vscord.status.image.large.idle.key")!); + largeImageText = await replaceAllText(config.get("vscord.status.image.large.idle.text")!); + smallImageKey = await replaceAllText(config.get("vscord.status.image.small.idle.key")!); + smallImageText = await replaceAllText(config.get("vscord.status.image.small.idle.text")!); break; } case CURRENT_STATUS.EDITING: { if (!isWorkspaceExcluded) { if (detailsEnabled) - details = await replaceAllText(config.get(CONFIG_KEYS.Status.Details.Text.Editing)!); - if (stateEnabled) state = await replaceAllText(config.get(CONFIG_KEYS.Status.State.Text.Editing)!); + details = await replaceAllText(config.get("vscord.status.details.text.editing")!); + if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.editing")!); } - largeImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Editing.Key)!); - largeImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Editing.Text)!); + largeImageKey = await replaceAllText(config.get("vscord.status.image.large.editing.key")!); + largeImageText = await replaceAllText(config.get("vscord.status.image.large.editing.text")!); - smallImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Editing.Key)!); - smallImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Editing.Text)!); + smallImageKey = await replaceAllText(config.get("vscord.status.image.small.editing.key")!); + smallImageText = await replaceAllText(config.get("vscord.status.image.small.editing.text")!); break; } case CURRENT_STATUS.DEBUGGING: { if (!isWorkspaceExcluded) { if (detailsEnabled) - details = await replaceAllText(config.get(CONFIG_KEYS.Status.Details.Text.Debugging)!); - if (stateEnabled) state = await replaceAllText(config.get(CONFIG_KEYS.Status.State.Text.Debugging)!); + details = await replaceAllText(config.get("vscord.status.details.text.debugging")!); + if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.debugging")!); } - largeImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Debugging.Key)!); - largeImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Debugging.Text)!); + largeImageKey = await replaceAllText(config.get("vscord.status.image.large.debugging.key")!); + largeImageText = await replaceAllText(config.get("vscord.status.image.large.debugging.text")!); - smallImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Debugging.Key)!); - smallImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Debugging.Text)!); + smallImageKey = await replaceAllText(config.get("vscord.status.image.small.debugging.key")!); + smallImageText = await replaceAllText(config.get("vscord.status.image.small.debugging.text")!); break; } case CURRENT_STATUS.VIEWING: { if (!isWorkspaceExcluded) { if (detailsEnabled) - details = await replaceAllText(config.get(CONFIG_KEYS.Status.Details.Text.Viewing)!); - if (stateEnabled) state = await replaceAllText(config.get(CONFIG_KEYS.Status.State.Text.Viewing)!); + details = await replaceAllText(config.get("vscord.status.details.text.viewing")!); + if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.viewing")!); } - largeImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Viewing.Key)!); - largeImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.Viewing.Text)!); + largeImageKey = await replaceAllText(config.get("vscord.status.image.large.viewing.key")!); + largeImageText = await replaceAllText(config.get("vscord.status.image.large.viewing.text")!); - smallImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Viewing.Key)!); - smallImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.Viewing.Text)!); + smallImageKey = await replaceAllText(config.get("vscord.status.image.small.viewing.key")!); + smallImageText = await replaceAllText(config.get("vscord.status.image.small.viewing.text")!); break; } case CURRENT_STATUS.NOT_IN_FILE: { - if (detailsEnabled) details = await replaceAllText(config.get(CONFIG_KEYS.Status.Details.Text.NotInFile)!); - if (stateEnabled) state = await replaceAllText(config.get(CONFIG_KEYS.Status.State.Text.NotInFile)!); + if (detailsEnabled) details = await replaceAllText(config.get("vscord.status.details.text.notInFile")!); + if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.notInFile")!); - largeImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.NotInFile.Key)!); - largeImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Large.NotInFile.Text)!); + largeImageKey = await replaceAllText(config.get("vscord.status.image.large.notInFile.key")!); + largeImageText = await replaceAllText(config.get("vscord.status.image.large.notInFile.text")!); - smallImageKey = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.NotInFile.Key)!); - smallImageText = await replaceAllText(config.get(CONFIG_KEYS.Status.Image.Small.NotInFile.Text)!); + smallImageKey = await replaceAllText(config.get("vscord.status.image.small.notInFile.key")!); + smallImageText = await replaceAllText(config.get("vscord.status.image.small.notInFile.text")!); break; } } @@ -295,6 +295,80 @@ async function createButton( currentButton: "Button1" | "Button2" ): Promise { const config = getConfig(); + const CONFIG_KEYS = { + Status: { + Buttons: { + Button1: { + Git: { + Idle: { + Enabled: "vscord.status.buttons.button1.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button1.git.idle.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.git.idle.url" satisfies keyof ExtensionConfigGenerated, + }, + Active: { + Enabled: "vscord.status.buttons.button1.git.active.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button1.git.active.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.git.active.url" satisfies keyof ExtensionConfigGenerated, + }, + Inactive: { + Enabled: "vscord.status.buttons.button1.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button1.git.inactive.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.git.inactive.url" satisfies keyof ExtensionConfigGenerated, + }, + }, + Idle: { + Enabled: "vscord.status.buttons.button1.idle.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button1.idle.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.idle.url" satisfies keyof ExtensionConfigGenerated, + }, + Active: { + Enabled: "vscord.status.buttons.button1.active.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button1.active.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.active.url" satisfies keyof ExtensionConfigGenerated, + }, + Inactive: { + Enabled: "vscord.status.buttons.button1.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button1.inactive.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.inactive.url" satisfies keyof ExtensionConfigGenerated, + }, + }, + Button2: { + Git: { + Idle: { + Enabled: "vscord.status.buttons.button2.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button2.git.idle.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.git.idle.url" satisfies keyof ExtensionConfigGenerated, + }, + Active: { + Enabled: "vscord.status.buttons.button2.git.active.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button2.git.active.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.git.active.url" satisfies keyof ExtensionConfigGenerated, + }, + Inactive: { + Enabled: "vscord.status.buttons.button2.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button2.git.inactive.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.git.inactive.url" satisfies keyof ExtensionConfigGenerated, + }, + }, + Idle: { + Enabled: "vscord.status.buttons.button2.idle.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button2.idle.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.idle.url" satisfies keyof ExtensionConfigGenerated, + }, + Active: { + Enabled: "vscord.status.buttons.button2.active.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button2.active.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.active.url" satisfies keyof ExtensionConfigGenerated, + }, + Inactive: { + Enabled: "vscord.status.buttons.button2.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Label: "vscord.status.buttons.button2.inactive.label" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.inactive.url" satisfies keyof ExtensionConfigGenerated, + }, + }, + } + } + } const currentState = CONFIG_KEYS.Status.Buttons[currentButton]; const configKeyEnabled = isGit && state != "Inactive" ? currentState.Git[state].Enabled : currentState[state].Enabled; @@ -344,8 +418,8 @@ export const getPresenceButtons = async ( replaceAllText: (text: string) => Promise ): Promise => { const config = getConfig(); - let button1Enabled = config.get(CONFIG_KEYS.Status.Buttons.Button1.Enabled)!; - let button2Enabled = config.get(CONFIG_KEYS.Status.Buttons.Button2.Enabled)!; + let button1Enabled = config.get("vscord.status.buttons.button1.enabled")!; + let button2Enabled = config.get("vscord.status.buttons.button2.enabled")!; let state: "Idle" | "Active" | "Inactive" | undefined = isIdling ? "Idle" : isGitExcluded @@ -365,7 +439,7 @@ export const getPresenceButtons = async ( logInfo("[activity.ts] getPresenceButtons button2:", state, button2); if ( (button1.validationError || button2.validationError) && - !config.get(CONFIG_KEYS.Behaviour.SuppressNotifications) + !config.get("vscord.behaviour.suppressNotifications") ) window.showErrorMessage(`${button1.validationError} ${button2.validationError}`); return [button1.button, button2.button].filter(Boolean) as GatewayActivityButton[]; @@ -465,14 +539,14 @@ export const replaceFileInfo = async ( const config = getConfig(); text = text.slice(); let workspaceFolderName = - dataClass.workspaceFolder?.name ?? config.get(CONFIG_KEYS.Status.Details.Text.NoWorkspaceText)!; - let workspaceName = dataClass.workspaceName ?? config.get(CONFIG_KEYS.Status.Details.Text.NoWorkspaceText)!; + dataClass.workspaceFolder?.name ?? config.get("vscord.status.details.text.noWorkSpaceText")!; + let workspaceName = dataClass.workspaceName ?? config.get("vscord.status.details.text.noWorkSpaceText")!; let workspaceAndFolder = workspaceName + (workspaceFolderName != FAKE_EMPTY ? ` - ${workspaceFolderName}` : FAKE_EMPTY); workspaceAndFolder = workspaceAndFolder.trim() === "" - ? config.get(CONFIG_KEYS.Status.Details.Text.NoWorkspaceText)! + ? config.get("vscord.status.details.text.noWorkSpaceText")! : workspaceAndFolder; let fullDirectoryName: string = FAKE_EMPTY; @@ -497,8 +571,8 @@ export const replaceFileInfo = async ( relativeFilepath = FAKE_EMPTY; } - const totalProblems = config.get(CONFIG_KEYS.Status.Problems.Enabled) - ? getTotalProblems(config.get(CONFIG_KEYS.Status.Problems.countedSeverities)!) + const totalProblems = config.get("vscord.status.problems.enabled") + ? getTotalProblems(config.get("vscord.status.problems.countedSeverities")!) : 0; const replaceMap = new Map([ @@ -520,7 +594,7 @@ export const replaceFileInfo = async ( ["{a_LANG}", `${getArticle(toUpper(fileIcon))} ${toUpper(fileIcon)}`], [ "{problems_count}", - config.get(CONFIG_KEYS.Status.Problems.Enabled) ? totalProblems.toLocaleString() : FAKE_EMPTY + config.get("vscord.status.problems.enabled") ? totalProblems.toLocaleString() : FAKE_EMPTY ], ["{problems_pluralize}", totalProblems === 1 ? "problem" : "problems"], ["{problems_count_errors}", COUNTED_SEVERITIES.error.toLocaleString()], diff --git a/src/constants.ts b/src/constants.ts index 1714d41..6bf948f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -7,202 +7,3 @@ export const { KNOWN_EXTENSIONS, KNOWN_LANGUAGES } = lang as { export const EMPTY = ""; export const FAKE_EMPTY = "\u200b\u200b"; - -export const CONFIG_KEYS = { - Enable: "vscord.enable" as const, - App: { - Id: "vscord.app.id" as const, - Name: "vscord.app.name" as const, - PrivacyMode: "vscord.app.privacyMode.enable" as const, - WhitelistEnabled: "vscord.app.whitelistEnabled" as const, - whitelistIsBlacklist: "vscord.app.whitelistIsBlacklist" as const, - Whitelist: "vscord.app.whitelist" as const - } as const, - Status: { - Details: { - Enabled: "vscord.status.details.enabled" as const, - Idle: { - Enabled: "vscord.status.details.idle.enabled" as const - } as const, - Text: { - Idle: "vscord.status.details.text.idle" as const, - Editing: "vscord.status.details.text.editing" as const, - Viewing: "vscord.status.details.text.viewing" as const, - NotInFile: "vscord.status.details.text.notInFile" as const, - NoWorkspaceText: "vscord.status.details.text.noWorkSpaceText" as const, - Debugging: "vscord.status.details.text.debugging" as const - } as const - } as const, - State: { - Enabled: "vscord.status.state.enabled" as const, - Debugging: { - Enabled: "vscord.status.state.debugging.enabled" as const - } as const, - Idle: { - Enabled: "vscord.status.state.idle.enabled" as const - } as const, - Text: { - Idle: "vscord.status.state.text.idle" as const, - Editing: "vscord.status.state.text.editing" as const, - Debugging: "vscord.status.state.text.debugging" as const, - Viewing: "vscord.status.state.text.viewing" as const, - NotInFile: "vscord.status.state.text.notInFile" as const, - NoWorkspaceFound: "vscord.status.state.text.noWorkspaceFound" as const - } as const - } as const, - Buttons: { - Button1: { - Enabled: "vscord.status.buttons.button1.enabled" as const, - Active: { - Enabled: "vscord.status.buttons.button1.active.enabled" as const, - Label: "vscord.status.buttons.button1.active.label" as const, - Url: "vscord.status.buttons.button1.active.url" as const - } as const, - Inactive: { - Enabled: "vscord.status.buttons.button1.inactive.enabled" as const, - Label: "vscord.status.buttons.button1.inactive.label" as const, - Url: "vscord.status.buttons.button1.inactive.url" as const - } as const, - Idle: { - Enabled: "vscord.status.buttons.button1.idle.enabled" as const, - Label: "vscord.status.buttons.button1.idle.label" as const, - Url: "vscord.status.buttons.button1.idle.url" as const - } as const, - Git: { - Active: { - Enabled: "vscord.status.buttons.button1.git.active.enabled" as const, - Label: "vscord.status.buttons.button1.git.active.label" as const, - Url: "vscord.status.buttons.button1.git.active.url" as const - } as const, - Inactive: { - Enabled: "vscord.status.buttons.button1.git.inactive.enabled" as const, - Label: "vscord.status.buttons.button1.git.inactive.label" as const, - Url: "vscord.status.buttons.button1.git.inactive.url" as const - } as const, - Idle: { - Enabled: "vscord.status.buttons.button1.git.idle.enabled" as const, - Label: "vscord.status.buttons.button1.git.idle.label" as const, - Url: "vscord.status.buttons.button1.git.idle.url" as const - } as const - } as const - }, - Button2: { - Enabled: "vscord.status.buttons.button2.enabled" as const, - Active: { - Enabled: "vscord.status.buttons.button2.active.enabled" as const, - Label: "vscord.status.buttons.button2.active.label" as const, - Url: "vscord.status.buttons.button2.active.url" as const - } as const, - Inactive: { - Enabled: "vscord.status.buttons.button2.inactive.enabled" as const, - Label: "vscord.status.buttons.button2.inactive.label" as const, - Url: "vscord.status.buttons.button2.inactive.url" as const - } as const, - Idle: { - Enabled: "vscord.status.buttons.button2.idle.enabled" as const, - Label: "vscord.status.buttons.button2.idle.label" as const, - Url: "vscord.status.buttons.button2.idle.url" as const - } as const, - Git: { - Active: { - Enabled: "vscord.status.buttons.button2.git.active.enabled" as const, - Label: "vscord.status.buttons.button2.git.active.label" as const, - Url: "vscord.status.buttons.button2.git.active.url" as const - } as const, - Inactive: { - Enabled: "vscord.status.buttons.button2.git.inactive.enabled" as const, - Label: "vscord.status.buttons.button2.git.inactive.label" as const, - Url: "vscord.status.buttons.button2.git.inactive.url" as const - } as const, - Idle: { - Enabled: "vscord.status.buttons.button2.git.idle.enabled" as const, - Label: "vscord.status.buttons.button2.git.idle.label" as const, - Url: "vscord.status.buttons.button2.git.idle.url" as const - } as const - } as const - } - } as const, - Image: { - Large: { - Idle: { - Key: "vscord.status.image.large.idle.key" as const, - Text: "vscord.status.image.large.idle.text" as const - } as const, - Editing: { - Key: "vscord.status.image.large.editing.key" as const, - Text: "vscord.status.image.large.editing.text" as const - } as const, - Debugging: { - Key: "vscord.status.image.large.debugging.key" as const, - Text: "vscord.status.image.large.debugging.text" as const - } as const, - Viewing: { - Key: "vscord.status.image.large.viewing.key" as const, - Text: "vscord.status.image.large.viewing.text" as const - } as const, - NotInFile: { - Key: "vscord.status.image.large.notInFile.key" as const, - Text: "vscord.status.image.large.notInFile.text" as const - } as const - } as const, - Small: { - Idle: { - Key: "vscord.status.image.small.idle.key" as const, - Text: "vscord.status.image.small.idle.text" as const - } as const, - Editing: { - Key: "vscord.status.image.small.editing.key" as const, - Text: "vscord.status.image.small.editing.text" as const - } as const, - Debugging: { - Key: "vscord.status.image.small.debugging.key" as const, - Text: "vscord.status.image.small.debugging.text" as const - } as const, - Viewing: { - Key: "vscord.status.image.small.viewing.key" as const, - Text: "vscord.status.image.small.viewing.text" as const - } as const, - NotInFile: { - Key: "vscord.status.image.small.notInFile.key" as const, - Text: "vscord.status.image.small.notInFile.text" as const - } as const - } as const - } as const, - Problems: { - Enabled: "vscord.status.problems.enabled" as const, - Text: "vscord.status.problems.text" as const, - countedSeverities: "vscord.status.problems.countedSeverities" as const - } as const, - Idle: { - Enabled: "vscord.status.idle.enabled" as const, - Check: "vscord.status.idle.check" as const, - DisconnectOnIdle: "vscord.status.idle.disconnectOnIdle" as const, - ResetElapsedTime: "vscord.status.idle.resetElapsedTime" as const, - Timeout: "vscord.status.idle.timeout" as const - } as const, - ShowElapsedTime: "vscord.status.showElapsedTime" as const, - ResetElapsedTimePerFile: "vscord.status.resetElapsedTimePerFile" as const - } as const, - Ignore: { - Workspaces: "vscord.ignore.workspaces" as const, - WorkspacesText: "vscord.ignore.workspacesText" as const, - Repositories: "vscord.ignore.repositories" as const, - Organizations: "vscord.ignore.organizations" as const, - GitHosts: "vscord.ignore.gitHosts" as const - } as const, - File: { - Size: { - HumanReadable: "vscord.file.size.humanReadable" as const, - Standard: "vscord.file.size.standard" as const, - Round: "vscord.file.size.round" as const, - Spacer: "vscord.file.size.spacer" as const - } as const - } as const, - Behaviour: { - AdditionalFileMapping: "vscord.behaviour.additionalFileMapping" as const, - SuppressNotifications: "vscord.behaviour.suppressNotifications" as const, - SuppressRpcCouldNotConnect: "vscord.behaviour.suppressRpcCouldNotConnect" as const, - StatusBarAlignment: "vscord.behaviour.statusBarAlignment" as const, - Debug: "vscord.behaviour.debug" as const - } as const -} as const; diff --git a/src/controller.ts b/src/controller.ts index ef1d2e6..e86c50c 100644 --- a/src/controller.ts +++ b/src/controller.ts @@ -7,7 +7,6 @@ import { StatusBarMode, editor } from "./editor"; import { validURL } from "./helpers/validURL"; import { throttle } from "./helpers/throttle"; import { logError, logInfo } from "./logger"; -import { CONFIG_KEYS } from "./constants"; import { getConfig } from "./config"; import { dataClass } from "./data"; @@ -33,7 +32,7 @@ export class RPCController { const config = getConfig(); this.client = new Client({ clientId }); this.debug = debug; - this.manualIdleMode = config.get(CONFIG_KEYS.Status.Idle.Check) === false; + this.manualIdleMode = config.get("vscord.status.idle.check") === false; editor.setStatusBarItem(StatusBarMode.Pending); @@ -105,8 +104,8 @@ export class RPCController { // fire checkIdle at least once after loading this.checkIdle(window.state); - if (config.get(CONFIG_KEYS.Status.Problems.Enabled)) this.listeners.push(diagnosticsChange); - if (config.get(CONFIG_KEYS.Status.Idle.Check)) this.listeners.push(changeWindowState); + if (config.get("vscord.status.problems.enabled")) this.listeners.push(diagnosticsChange); + if (config.get("vscord.status.idle.check")) this.listeners.push(changeWindowState); this.listeners.push(fileSwitch, fileEdit, fileSelectionChanged, debugStart, debugEnd); } @@ -115,11 +114,11 @@ export class RPCController { const config = getConfig(); let userId = this.client.user?.id; if (!userId) return false; - if (isIdling && config.get(CONFIG_KEYS.Status.Idle.DisconnectOnIdle)) return (this.canSendActivity = false); - let whitelistEnabled = config.get(CONFIG_KEYS.App.WhitelistEnabled); + if (isIdling && config.get("vscord.status.idle.disconnectOnIdle")) return (this.canSendActivity = false); + let whitelistEnabled = config.get("vscord.app.whitelistEnabled"); if (whitelistEnabled) { - let whitelist = config.get(CONFIG_KEYS.App.Whitelist); - if (config.get(CONFIG_KEYS.App.whitelistIsBlacklist)) + let whitelist = config.get("vscord.app.whitelist"); + if (config.get("vscord.app.whitelistIsBlacklist")) if (whitelist!.includes(userId)) return (this.canSendActivity = false); else return (this.canSendActivity = true); else if (!whitelist!.includes(userId)) return (this.canSendActivity = false); @@ -132,18 +131,18 @@ export class RPCController { const config = getConfig(); - if (config.get(CONFIG_KEYS.Status.Idle.Timeout) !== 0) { + if (config.get("vscord.status.idle.timeout") !== 0) { if (windowState.focused && this.idleTimeout) { clearTimeout(this.idleTimeout); await this.sendActivity(); - } else if (config.get(CONFIG_KEYS.Status.Idle.Check)) { + } else if (config.get("vscord.status.idle.check")) { this.idleTimeout = setTimeout( async () => { - if (!config.get(CONFIG_KEYS.Status.Idle.Check)) return; + if (!config.get("vscord.status.idle.check")) return; if ( - config.get(CONFIG_KEYS.Status.Idle.DisconnectOnIdle) && - config.get(CONFIG_KEYS.Status.Idle.ResetElapsedTime) + config.get("vscord.status.idle.disconnectOnIdle") && + config.get("vscord.status.idle.resetElapsedTime") ) { delete this.state.startTimestamp; } @@ -153,7 +152,7 @@ export class RPCController { this.activityThrottle.reset(); await this.sendActivity(false, true); }, - config.get(CONFIG_KEYS.Status.Idle.Timeout)! * 1000 + config.get("vscord.status.idle.timeout")! * 1000 ); } } diff --git a/src/data.ts b/src/data.ts index 10ac0f8..28ed89f 100644 --- a/src/data.ts +++ b/src/data.ts @@ -1,7 +1,6 @@ import type { API as GitApi, GitExtension, Remote, Repository } from "./@types/git"; import { stripCredential } from "./helpers/stripCredential"; import { basename, parse, sep } from "node:path"; -import { CONFIG_KEYS } from "./constants"; import gitUrlParse from "git-url-parse"; import { getConfig } from "./config"; import { logInfo } from "./logger"; @@ -261,7 +260,7 @@ export class Data implements Disposable { // eslint-disable-next-line @typescript-eslint/no-explicit-any private debug(...message: any[]) { - if (!getConfig().get(CONFIG_KEYS.Behaviour.Debug)) return; + if (!getConfig().get("vscord.behaviour.debug")) return; // eslint-disable-next-line @typescript-eslint/no-unsafe-argument logInfo("[data.ts]", ...message); } diff --git a/src/editor.ts b/src/editor.ts index 84f3e8b..10c682b 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,7 +1,6 @@ import type { ExtensionConfigGenerated } from "./configtype"; import { Disposable, ConfigurationTarget, StatusBarAlignment, StatusBarItem, window, commands } from "vscode"; import { type ExtensionConfiguration, getConfig } from "./config"; -import { CONFIG_KEYS } from "./constants"; import { logInfo, outputChannel } from "./logger"; export enum StatusBarMode { @@ -16,14 +15,14 @@ class EditorController implements Disposable { statusBarItemMode: StatusBarMode = StatusBarMode.Disabled; #getAlignmentFromConfig(config: ExtensionConfiguration): StatusBarAlignment { - const value = config.get(CONFIG_KEYS.Behaviour.StatusBarAlignment); + const value = config.get("vscord.behaviour.statusBarAlignment"); return StatusBarAlignment[value ?? "Right"]; } setStatusBarItem(mode: StatusBarMode) { this.statusBarItemMode = mode; const config = getConfig(); - if (!config.get(CONFIG_KEYS.Enable)) { + if (!config.get("vscord.enable")) { mode = StatusBarMode.Disabled; } if (!this.statusBarItem) { @@ -61,7 +60,7 @@ class EditorController implements Disposable { toggleStatusBarAlignment(align: StatusBarAlignment = StatusBarAlignment.Right): StatusBarAlignment { const config = getConfig(); - const cfgKey = CONFIG_KEYS.Behaviour.StatusBarAlignment; + const cfgKey = "vscord.behaviour.statusBarAlignment" as const satisfies keyof ExtensionConfigGenerated; const literalAlign = ( align === StatusBarAlignment.Right ? "Right" : "Left" ) satisfies ExtensionConfigGenerated[typeof cfgKey]; @@ -111,7 +110,7 @@ class EditorController implements Disposable { } } errorMessageFailedToConnect(config: ExtensionConfiguration, error?: Error) { - if (config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) { + if (config.get("vscord.behaviour.suppressNotifications")) { return; } @@ -125,7 +124,7 @@ class EditorController implements Disposable { } const configKeyPairs = { - RPC_COULD_NOT_CONNECT: CONFIG_KEYS.Behaviour.SuppressRpcCouldNotConnect + RPC_COULD_NOT_CONNECT: "vscord.behaviour.suppressRpcCouldNotConnect" satisfies keyof ExtensionConfigGenerated, } as const; const errorName = error.name; diff --git a/src/extension.ts b/src/extension.ts index da1ce68..2bf4e34 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -2,23 +2,22 @@ import { commands, window, workspace, type ExtensionContext } from "vscode"; import { getApplicationId } from "./helpers/getApplicationId"; import { StatusBarMode, editor } from "./editor"; import { RPCController } from "./controller"; -import { CONFIG_KEYS } from "./constants"; import { getConfig } from "./config"; import { logInfo } from "./logger"; import { dataClass } from "./data"; const controller = new RPCController( getApplicationId(getConfig()).clientId, - getConfig().get(CONFIG_KEYS.Behaviour.Debug) + getConfig().get("vscord.behaviour.debug") ); export const registerListeners = (ctx: ExtensionContext) => { const onConfigurationChanged = workspace.onDidChangeConfiguration(async () => { const config = getConfig(); const clientId = getApplicationId(config).clientId; - const isEnabled = config.get(CONFIG_KEYS.Enable); + const isEnabled = config.get("vscord.enable"); - controller.debug = config.get(CONFIG_KEYS.Behaviour.Debug) ?? false; + controller.debug = config.get("vscord.behaviour.debug") ?? false; editor.updateStatusBarFromConfig(); if (controller.client.clientId !== clientId) { @@ -27,7 +26,7 @@ export const registerListeners = (ctx: ExtensionContext) => { if (isEnabled) await controller.enable(); } - controller.manualIdleMode = config.get(CONFIG_KEYS.Status.Idle.Check) === false; + controller.manualIdleMode = config.get("vscord.status.idle.check") === false; }); ctx.subscriptions.push(onConfigurationChanged); @@ -39,7 +38,7 @@ export const registerCommands = (ctx: ExtensionContext) => { const enable = async (update = true) => { if (update) try { - await config.update(CONFIG_KEYS.Enable, true); + await config.update("vscord.enable", true); } catch {} await controller.enable(); @@ -48,7 +47,7 @@ export const registerCommands = (ctx: ExtensionContext) => { const disable = async (update = true) => { if (update) try { - await config.update(CONFIG_KEYS.Enable, false); + await config.update("vscord.enable", false); } catch {} await controller.disable(); @@ -59,7 +58,7 @@ export const registerCommands = (ctx: ExtensionContext) => { const togglePrivacyMode = async (activate: boolean) => { try { - await config.update(CONFIG_KEYS.App.PrivacyMode, activate); + await config.update("vscord.app.privacyMode.enable", activate); } catch {} await controller.sendActivity(dataClass.editor != null); @@ -71,7 +70,7 @@ export const registerCommands = (ctx: ExtensionContext) => { logInfo("Enabled Discord Rich Presence."); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Enabled Discord Rich Presence"); }); @@ -80,7 +79,7 @@ export const registerCommands = (ctx: ExtensionContext) => { await disable(false); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Disabled Discord Rich Presence"); }); @@ -90,7 +89,7 @@ export const registerCommands = (ctx: ExtensionContext) => { await disable(); await enable(); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Enabled Discord Rich Presence for this workspace"); }); @@ -99,7 +98,7 @@ export const registerCommands = (ctx: ExtensionContext) => { await disable(); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Disabled Discord Rich Presence for this workspace"); }); @@ -112,7 +111,7 @@ export const registerCommands = (ctx: ExtensionContext) => { .login() .then(async () => await controller.enable()) .catch(() => { - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) window.showErrorMessage("Failed to reconnect to Discord Gateway"); editor.setStatusBarItem(StatusBarMode.Disconnected); }); @@ -131,7 +130,7 @@ export const registerCommands = (ctx: ExtensionContext) => { await togglePrivacyMode(true); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Enabled Privacy Mode."); }); @@ -140,7 +139,7 @@ export const registerCommands = (ctx: ExtensionContext) => { await togglePrivacyMode(false); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Disabled Privacy Mode."); }); @@ -150,7 +149,7 @@ export const registerCommands = (ctx: ExtensionContext) => { controller.manualIdling = true; await controller.sendActivity(false, true); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Started Idling."); }); @@ -160,7 +159,7 @@ export const registerCommands = (ctx: ExtensionContext) => { controller.manualIdling = false; await controller.sendActivity(); - if (!config.get(CONFIG_KEYS.Behaviour.SuppressNotifications)) + if (!config.get("vscord.behaviour.suppressNotifications")) await window.showInformationMessage("Stopped Idling."); }); @@ -186,7 +185,7 @@ export async function activate(ctx: ExtensionContext) { registerCommands(ctx); registerListeners(ctx); - if (!getConfig().get(CONFIG_KEYS.Enable)) await controller.disable(); + if (!getConfig().get("vscord.enable")) await controller.disable(); } export async function deactivate() { diff --git a/src/helpers/getApplicationId.ts b/src/helpers/getApplicationId.ts index cc874a6..8ab4b9c 100644 --- a/src/helpers/getApplicationId.ts +++ b/src/helpers/getApplicationId.ts @@ -1,5 +1,4 @@ import type { ExtensionConfiguration } from "../config"; -import { CONFIG_KEYS } from "../constants"; export const getApplicationId = (config: ExtensionConfiguration) => { const applicationIds = new Map([ @@ -8,12 +7,12 @@ export const getApplicationId = (config: ExtensionConfiguration) => { ["VSCodium", "1031067701474492496"], ["Antigravity", "1441771215290372156"], ["Cursor", "1376937466619232256"], - ["Custom", config.get(CONFIG_KEYS.App.Id)!] + ["Custom", config.get("vscord.app.id")!] ]); - const currentAppName = config.get(CONFIG_KEYS.App.Name)!; + const currentAppName = config.get("vscord.app.name")!; - let clientId = config.get(CONFIG_KEYS.App.Id)!; + let clientId = config.get("vscord.app.id")!; for (const [appName, id] of applicationIds.entries()) { if (currentAppName !== appName) continue; clientId = id; diff --git a/src/helpers/getFileSize.ts b/src/helpers/getFileSize.ts index ac46d1c..e5ba6b5 100644 --- a/src/helpers/getFileSize.ts +++ b/src/helpers/getFileSize.ts @@ -1,27 +1,26 @@ import type { ExtensionConfiguration, FileSizeStandard } from "../config"; import { FilesizeOptions, filesize } from "filesize"; -import { CONFIG_KEYS } from "../constants"; import type { Data } from "../data"; export const getFileSize = async (config: ExtensionConfiguration, dataClass: Data) => { if (!(await dataClass.fileSize)) return; let round = 2; - if (config.get(CONFIG_KEYS.File.Size.Round) === 0 || config.get(CONFIG_KEYS.File.Size.Round)) - round = config.get(CONFIG_KEYS.File.Size.Round)!; + if (config.get("vscord.file.size.round") === 0 || config.get("vscord.file.size.round")) + round = config.get("vscord.file.size.round")!; let spacer = " "; - if (config.get(CONFIG_KEYS.File.Size.Spacer) === "" || config.get(CONFIG_KEYS.File.Size.Spacer)) - spacer = config.get(CONFIG_KEYS.File.Size.Spacer)!; + if (config.get("vscord.file.size.spacer") === "" || config.get("vscord.file.size.spacer")) + spacer = config.get("vscord.file.size.spacer")!; - const fileSizeStandard: FileSizeStandard = config.get(CONFIG_KEYS.File.Size.Standard) ?? "iec"; + const fileSizeStandard: FileSizeStandard = config.get("vscord.file.size.standard") ?? "iec"; const fileSizeConfig: FilesizeOptions = { round, spacer, standard: fileSizeStandard } as const; - const fileSize = config.get(CONFIG_KEYS.File.Size.HumanReadable) + const fileSize = config.get("vscord.file.size.humanReadable") ? filesize((await dataClass.fileSize) ?? 0, fileSizeConfig).toLocaleString() : `${dataClass.fileSize.toLocaleString()}${fileSizeConfig.spacer ?? " "}B`; diff --git a/src/helpers/resolveLangName.ts b/src/helpers/resolveLangName.ts index 0618b8f..6d297b5 100644 --- a/src/helpers/resolveLangName.ts +++ b/src/helpers/resolveLangName.ts @@ -1,4 +1,4 @@ -import { CONFIG_KEYS, KNOWN_EXTENSIONS, KNOWN_LANGUAGES } from "../constants"; +import { KNOWN_EXTENSIONS, KNOWN_LANGUAGES } from "../constants"; import { type TextDocument } from "vscode"; import { getConfig } from "../config"; import { basename } from "node:path"; @@ -38,7 +38,7 @@ export const resolveLangName = (document: TextDocument): string => { const config = getConfig(); const ADDITIONAL_FILE_MAPPING = Object.fromEntries( - Object.entries(config.get(CONFIG_KEYS.Behaviour.AdditionalFileMapping)!).map(([key, value]) => [ + Object.entries(config.get("vscord.behaviour.additionalFileMapping")!).map(([key, value]) => [ key, { image: value } ]) From 2c094490002fdea89d42a8187bfe9774f45194d8 Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 18:43:51 +0100 Subject: [PATCH 03/10] ci: check --- .github/workflows/CI.yml | 4 ++++ configtypes.js | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7dce78b..f3f1c4f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,6 +19,10 @@ jobs: - run: npm install + - name: Check types + run: | + node configtypes.js --check + - name: Check types run: | npm run check-types diff --git a/configtypes.js b/configtypes.js index e5619f8..6701f17 100644 --- a/configtypes.js +++ b/configtypes.js @@ -4,6 +4,7 @@ const path = require("path"); const ROOT = process.cwd(); const PACKAGE_JSON = path.join(ROOT, "package.json"); const OUT_FILE = path.join(ROOT, "src", "configtype.ts"); +const OUT_FILE_REL = path.relative(ROOT, OUT_FILE); const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf8")); @@ -68,13 +69,12 @@ ${entries.join("\n")} fs.mkdirSync(path.dirname(OUT_FILE), { recursive: true }); if (process.argv.includes("--check")) { const existing = fs.existsSync(OUT_FILE) ? fs.readFileSync(OUT_FILE, "utf8") : null; - if (existing === null) { - console.warn("missing", OUT_FILE); - } else if (existing !== output) { - console.log("up to date", OUT_FILE); + if (existing !== output) { + console.log("configtypes.js: OUT OF DATE. Regenerate by running 'node configtypes.js'", OUT_FILE_REL); + process.exit(1) } - console.log("checked", OUT_FILE); + console.log("checked", OUT_FILE_REL); } else { fs.writeFileSync(OUT_FILE, output, "utf8"); - console.log("generated", OUT_FILE); + console.log("generated", OUT_FILE_REL); } From 36e0cdab0931fc1ba4bb3463ed14372a6f4a6575 Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 18:51:31 +0100 Subject: [PATCH 04/10] style: fix --- configtypes.js | 2 +- src/activity.ts | 80 +++++++++++++++++++++++++----------------------- src/editor.ts | 3 +- src/extension.ts | 5 +-- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/configtypes.js b/configtypes.js index 6701f17..36cca06 100644 --- a/configtypes.js +++ b/configtypes.js @@ -71,7 +71,7 @@ if (process.argv.includes("--check")) { const existing = fs.existsSync(OUT_FILE) ? fs.readFileSync(OUT_FILE, "utf8") : null; if (existing !== output) { console.log("configtypes.js: OUT OF DATE. Regenerate by running 'node configtypes.js'", OUT_FILE_REL); - process.exit(1) + process.exit(1); } console.log("checked", OUT_FILE_REL); } else { diff --git a/src/activity.ts b/src/activity.ts index bdbf9a6..2d7fdd7 100644 --- a/src/activity.ts +++ b/src/activity.ts @@ -214,8 +214,7 @@ export const activity = async ( } case CURRENT_STATUS.EDITING: { if (!isWorkspaceExcluded) { - if (detailsEnabled) - details = await replaceAllText(config.get("vscord.status.details.text.editing")!); + if (detailsEnabled) details = await replaceAllText(config.get("vscord.status.details.text.editing")!); if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.editing")!); } @@ -228,8 +227,7 @@ export const activity = async ( } case CURRENT_STATUS.DEBUGGING: { if (!isWorkspaceExcluded) { - if (detailsEnabled) - details = await replaceAllText(config.get("vscord.status.details.text.debugging")!); + if (detailsEnabled) details = await replaceAllText(config.get("vscord.status.details.text.debugging")!); if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.debugging")!); } @@ -242,8 +240,7 @@ export const activity = async ( } case CURRENT_STATUS.VIEWING: { if (!isWorkspaceExcluded) { - if (detailsEnabled) - details = await replaceAllText(config.get("vscord.status.details.text.viewing")!); + if (detailsEnabled) details = await replaceAllText(config.get("vscord.status.details.text.viewing")!); if (stateEnabled) state = await replaceAllText(config.get("vscord.status.state.text.viewing")!); } @@ -301,74 +298,84 @@ async function createButton( Button1: { Git: { Idle: { - Enabled: "vscord.status.buttons.button1.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button1.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button1.git.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.git.idle.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.git.idle.url" satisfies keyof ExtensionConfigGenerated }, Active: { - Enabled: "vscord.status.buttons.button1.git.active.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button1.git.active.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button1.git.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.git.active.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.git.active.url" satisfies keyof ExtensionConfigGenerated }, Inactive: { - Enabled: "vscord.status.buttons.button1.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button1.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button1.git.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.git.inactive.url" satisfies keyof ExtensionConfigGenerated, - }, + Url: "vscord.status.buttons.button1.git.inactive.url" satisfies keyof ExtensionConfigGenerated + } }, Idle: { Enabled: "vscord.status.buttons.button1.idle.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button1.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.idle.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.idle.url" satisfies keyof ExtensionConfigGenerated }, Active: { - Enabled: "vscord.status.buttons.button1.active.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button1.active.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button1.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.active.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button1.active.url" satisfies keyof ExtensionConfigGenerated }, Inactive: { - Enabled: "vscord.status.buttons.button1.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button1.inactive.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button1.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.inactive.url" satisfies keyof ExtensionConfigGenerated, - }, + Url: "vscord.status.buttons.button1.inactive.url" satisfies keyof ExtensionConfigGenerated + } }, Button2: { Git: { Idle: { - Enabled: "vscord.status.buttons.button2.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button2.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button2.git.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.git.idle.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.git.idle.url" satisfies keyof ExtensionConfigGenerated }, Active: { - Enabled: "vscord.status.buttons.button2.git.active.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button2.git.active.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button2.git.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.git.active.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.git.active.url" satisfies keyof ExtensionConfigGenerated }, Inactive: { - Enabled: "vscord.status.buttons.button2.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button2.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button2.git.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.git.inactive.url" satisfies keyof ExtensionConfigGenerated, - }, + Url: "vscord.status.buttons.button2.git.inactive.url" satisfies keyof ExtensionConfigGenerated + } }, Idle: { Enabled: "vscord.status.buttons.button2.idle.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button2.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.idle.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.idle.url" satisfies keyof ExtensionConfigGenerated }, Active: { - Enabled: "vscord.status.buttons.button2.active.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button2.active.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button2.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.active.url" satisfies keyof ExtensionConfigGenerated, + Url: "vscord.status.buttons.button2.active.url" satisfies keyof ExtensionConfigGenerated }, Inactive: { - Enabled: "vscord.status.buttons.button2.inactive.enabled" satisfies keyof ExtensionConfigGenerated, + Enabled: + "vscord.status.buttons.button2.inactive.enabled" satisfies keyof ExtensionConfigGenerated, Label: "vscord.status.buttons.button2.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.inactive.url" satisfies keyof ExtensionConfigGenerated, - }, - }, + Url: "vscord.status.buttons.button2.inactive.url" satisfies keyof ExtensionConfigGenerated + } + } } } - } + }; const currentState = CONFIG_KEYS.Status.Buttons[currentButton]; const configKeyEnabled = isGit && state != "Inactive" ? currentState.Git[state].Enabled : currentState[state].Enabled; @@ -437,10 +444,7 @@ export const getPresenceButtons = async ( let button2 = buttonValidation(await createButton(replaceAllText, state, isGit, "Button2"), "Button2"); logInfo("[activity.ts] getPresenceButtons button1:", state, button1); logInfo("[activity.ts] getPresenceButtons button2:", state, button2); - if ( - (button1.validationError || button2.validationError) && - !config.get("vscord.behaviour.suppressNotifications") - ) + if ((button1.validationError || button2.validationError) && !config.get("vscord.behaviour.suppressNotifications")) window.showErrorMessage(`${button1.validationError} ${button2.validationError}`); return [button1.button, button2.button].filter(Boolean) as GatewayActivityButton[]; }; diff --git a/src/editor.ts b/src/editor.ts index 10c682b..bf87772 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -124,7 +124,8 @@ class EditorController implements Disposable { } const configKeyPairs = { - RPC_COULD_NOT_CONNECT: "vscord.behaviour.suppressRpcCouldNotConnect" satisfies keyof ExtensionConfigGenerated, + RPC_COULD_NOT_CONNECT: + "vscord.behaviour.suppressRpcCouldNotConnect" satisfies keyof ExtensionConfigGenerated } as const; const errorName = error.name; diff --git a/src/extension.ts b/src/extension.ts index 2bf4e34..5e4ce94 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,10 +6,7 @@ import { getConfig } from "./config"; import { logInfo } from "./logger"; import { dataClass } from "./data"; -const controller = new RPCController( - getApplicationId(getConfig()).clientId, - getConfig().get("vscord.behaviour.debug") -); +const controller = new RPCController(getApplicationId(getConfig()).clientId, getConfig().get("vscord.behaviour.debug")); export const registerListeners = (ctx: ExtensionContext) => { const onConfigurationChanged = workspace.onDidChangeConfiguration(async () => { From 0d37666b18183e9b836884475f593ccda6049f4f Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 18:53:56 +0100 Subject: [PATCH 05/10] style: ci --- .github/workflows/CI.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f3f1c4f..9324874 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -22,9 +22,6 @@ jobs: - name: Check types run: | node configtypes.js --check - - - name: Check types - run: | npm run check-types - name: Lint From ecaed0c93abd5b2919f235cde0392a17c5049c8a Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:05:15 +0100 Subject: [PATCH 06/10] feat: add deprecated config types --- configtypes.js | 33 +++++++++++++++++++++++----- src/configtype.ts | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/configtypes.js b/configtypes.js index 36cca06..044f493 100644 --- a/configtypes.js +++ b/configtypes.js @@ -7,7 +7,6 @@ const OUT_FILE = path.join(ROOT, "src", "configtype.ts"); const OUT_FILE_REL = path.relative(ROOT, OUT_FILE); const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf8")); - const configurations = pkg.contributes?.configuration ?? []; function schemaTypeToTs(schema) { @@ -45,14 +44,31 @@ function schemaTypeToTs(schema) { } } -const entries = []; +function getDeprecation(schema) { + if (schema.deprecationMessage) { + return schema.deprecationMessage; + } + if (schema.markdownDeprecationMessage) { + return schema.markdownDeprecationMessage.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/[`#*]/g, ""); + } + return null; +} + +const activeEntries = []; +const deprecatedEntries = []; for (const block of configurations) { const props = block.properties ?? {}; - for (let [key, schema] of Object.entries(props)) { - key = JSON.stringify(key); + for (const [key, schema] of Object.entries(props)) { const tsType = schemaTypeToTs(schema); - entries.push(` ${key}: ${tsType};`); + const deprecation = getDeprecation(schema); + + if (deprecation) { + deprecatedEntries.push(` /** @deprecated ${deprecation} */`); + deprecatedEntries.push(` ${JSON.stringify(key)}: ${tsType};`); + } else { + activeEntries.push(` ${JSON.stringify(key)}: ${tsType};`); + } } } @@ -62,11 +78,16 @@ const output = `/* AUTO-GENERATED FILE */ export type ExtensionConfigGenerated = { -${entries.join("\n")} +${activeEntries.join("\n")} +}; + +export type DeprecatedConfigGenerated = { +${deprecatedEntries.join("\n")} }; `; fs.mkdirSync(path.dirname(OUT_FILE), { recursive: true }); + if (process.argv.includes("--check")) { const existing = fs.existsSync(OUT_FILE) ? fs.readFileSync(OUT_FILE, "utf8") : null; if (existing !== output) { diff --git a/src/configtype.ts b/src/configtype.ts index 1fd9030..877d030 100644 --- a/src/configtype.ts +++ b/src/configtype.ts @@ -110,57 +110,113 @@ export type ExtensionConfigGenerated = { "vscord.file.size.humanReadable": boolean; "vscord.file.size.standard": "iec" | "jedec"; "vscord.behaviour.debug": boolean; +}; + +export type DeprecatedConfigGenerated = { + /** @deprecated Use the built-in setting */ "vscord.enabled": boolean; + /** @deprecated Deprecated: Please use vscord.app.id instead. */ "rpc.id": string; + /** @deprecated Deprecated: Please use vscord.app.name instead. */ "rpc.appName": string; + /** @deprecated Deprecated: Please use vscord.enabled instead. */ "rpc.enabled": boolean; + /** @deprecated Deprecated: Please use vscord.status.details.text.editing instead. */ "rpc.detailsEditing": string; + /** @deprecated Deprecated: Please use vscord.status.details.text.idle instead. */ "rpc.detailsIdling": string; + /** @deprecated Deprecated: Please use vscord.status.details.text.debugging instead. */ "rpc.detailsDebugging": string; + /** @deprecated Deprecated: Please use vscord.status.details.text.viewing instead. */ "rpc.detailsViewing": string; + /** @deprecated Deprecated: Please use vscord.status.state.text.editing instead. */ "rpc.lowerDetailsEditing": string; + /** @deprecated Deprecated: Please use vscord.status.state.text.idle instead. */ "rpc.lowerDetailsIdling": string; + /** @deprecated Deprecated: Please use vscord.status.state.text.debugging instead. */ "rpc.lowerDetailsDebugging": string; + /** @deprecated Deprecated: Please use vscord.status.state.text.viewing instead. */ "rpc.lowerDetailsViewing": string; + /** @deprecated Deprecated: Please use vscord.status.state.text.noWorkspaceFound instead. */ "rpc.lowerDetailsNoWorkspaceFound": string; + /** @deprecated Deprecated: Please use vscord.status.image instead. */ "rpc.baseImageLink": string; + /** @deprecated Deprecated: Please use vscord.status.image instead. */ "rpc.largeImage": string; + /** @deprecated Deprecated: Please use vscord.status.image.small.idle.key instead. */ "rpc.largeImageIdling": string; + /** @deprecated Deprecated: Please use vscord.status.image.small instead. */ "rpc.smallImage": string; + /** @deprecated Deprecated: Please use vscord.status.showElapsedTime instead. */ "rpc.removeElapsedTime": boolean; + /** @deprecated Deprecated: Please use vscord.status.details.enabled instead. */ "rpc.removeDetails": boolean; + /** @deprecated Deprecated: Please use vscord.status.details instead. */ "rpc.removeLowerDetails": boolean; + /** @deprecated Deprecated: Please use vscord.status.details.text.idle instead. */ "rpc.removeLowerDetailsIdling": boolean; + /** @deprecated Deprecated: Please use vscord.status.problems.enabled instead. */ "rpc.showProblems": boolean; + /** @deprecated Deprecated: Please use vscord.status.problems.text instead. */ "rpc.problemsText": string; + /** @deprecated Deprecated: Please use vscord.ignore.workspaces instead. */ "rpc.ignoreWorkspaces": unknown[]; + /** @deprecated Deprecated: Please use vscord.ignore.workspacesText instead. */ "rpc.ignoreWorkspacesText": string | Record; + /** @deprecated Deprecated: Please use vscord.status.idle.enabled instead. */ "rpc.checkIdle": boolean; + /** @deprecated Deprecated: Please use vscord.status.idle.disconnectOnIdle instead. */ "rpc.disconnectOnIdle": boolean; + /** @deprecated Deprecated: Please use vscord.status.idle.resetElapsedTime instead. */ "rpc.resetElapsedTimeAfterIdle": boolean; + /** @deprecated Deprecated: Please use vscord.status.idle.timeout instead. */ "rpc.idleTimeout": number; + /** @deprecated Deprecated: Please use vscord.status.image.small.idle.text instead. */ "rpc.idleText": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.enabled instead. */ "rpc.buttonEnabled": boolean; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.active.label instead. */ "rpc.buttonActiveLabel": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.git.label instead. */ "vscord.status.button.active.enabled": boolean; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.git.label instead. */ "vscord.status.button.active.label": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.git.url instead. */ "vscord.status.button.active.url": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.idle.label instead. */ "vscord.status.button.idle.enabled": boolean; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.idle.label instead. */ "vscord.status.button.idle.label": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.idle.url instead. */ "vscord.status.button.idle.url": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.inactive.label instead. */ "vscord.status.button.inactive.enabled": boolean; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.inactive.label instead. */ "vscord.status.button.inactive.label": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.inactive.url instead. */ "vscord.status.button.inactive.url": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.active.url instead. */ "rpc.buttonActiveUrl": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.inactive.label instead. */ "rpc.buttonInactiveLabel": string; + /** @deprecated Deprecated: Please use vscord.status.buttons.button1.inactive.url instead. */ "rpc.buttonInactiveUrl": string; + /** @deprecated Deprecated: Please use vscord.ignore.repositories instead. */ "rpc.ignoreRepositories": string[]; + /** @deprecated Deprecated: Please use vscord.ignore.organizations instead. */ "rpc.ignoreOrganizations": string[]; + /** @deprecated Deprecated: Please use vscord.ignore.gitHosts instead. */ "rpc.ignoreGitHosts": string[]; + /** @deprecated Deprecated: Please use vscord.behaviour.suppressNotifications instead. */ "rpc.suppressNotifications": boolean; + /** @deprecated Deprecated */ "rpc.prioritizeLanguagesOverExtensions": boolean; + /** @deprecated Deprecated: Please use vscord.behaviour.size.humanReadable instead. */ "rpc.fileSizeHumanReadable": boolean; + /** @deprecated Deprecated: Please use vscord.file.size.standard instead. */ "rpc.fileSizeSpec": "si" | "iec" | "jedec"; + /** @deprecated Deprecated */ "rpc.fileSizeFixed": number; + /** @deprecated Deprecated: Please use vscord.file.size.spacer instead. */ "rpc.fileSizeSpacer": string; }; From 9e3fecea772d136e1e9b430d0a339f529fb02b67 Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:20:28 +0100 Subject: [PATCH 07/10] fixup: update path handling and improve output messages in config generation --- configtypes.js | 13 +++++++------ src/configtype.ts | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/configtypes.js b/configtypes.js index 044f493..797881e 100644 --- a/configtypes.js +++ b/configtypes.js @@ -1,7 +1,7 @@ const fs = require("fs"); // should be changed to import const path = require("path"); -const ROOT = process.cwd(); +const ROOT = __dirname; // import.meta.dirname const PACKAGE_JSON = path.join(ROOT, "package.json"); const OUT_FILE = path.join(ROOT, "src", "configtype.ts"); const OUT_FILE_REL = path.relative(ROOT, OUT_FILE); @@ -72,10 +72,10 @@ for (const block of configurations) { } } -const output = `/* AUTO-GENERATED FILE - * DO NOT EDIT MANUALLY - * Generated from package.json contributes.configuration - */ +const output = `// AUTO-GENERATED FILE +// DO NOT EDIT MANUALLY +// Edit package.json instead and re-run/edit configtypes.js to update +// Generated from package.json contributes.configuration export type ExtensionConfigGenerated = { ${activeEntries.join("\n")} @@ -91,7 +91,8 @@ fs.mkdirSync(path.dirname(OUT_FILE), { recursive: true }); if (process.argv.includes("--check")) { const existing = fs.existsSync(OUT_FILE) ? fs.readFileSync(OUT_FILE, "utf8") : null; if (existing !== output) { - console.log("configtypes.js: OUT OF DATE. Regenerate by running 'node configtypes.js'", OUT_FILE_REL); + console.log("%s: OUT OF DATE.", OUT_FILE_REL); + console.log("Regenerate by running 'node configtypes.js' or edit the generator script."); process.exit(1); } console.log("checked", OUT_FILE_REL); diff --git a/src/configtype.ts b/src/configtype.ts index 877d030..0336308 100644 --- a/src/configtype.ts +++ b/src/configtype.ts @@ -1,7 +1,7 @@ -/* AUTO-GENERATED FILE - * DO NOT EDIT MANUALLY - * Generated from package.json contributes.configuration - */ +// AUTO-GENERATED FILE +// DO NOT EDIT MANUALLY +// Edit package.json instead and re-run/edit configtypes.js to update +// Generated from package.json contributes.configuration export type ExtensionConfigGenerated = { "vscord.enable": boolean; From 24ede534071b86731f4b2fbffc53b15690f52ca2 Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:04:20 +0100 Subject: [PATCH 08/10] refactor: move the file move src/configtype.ts to src/@types/configtypes.d.ts --- configtypes.js | 2 +- src/{configtype.ts => @types/configtypes.d.ts} | 0 src/activity.ts | 2 +- src/config.ts | 2 +- src/editor.ts | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename src/{configtype.ts => @types/configtypes.d.ts} (100%) diff --git a/configtypes.js b/configtypes.js index 797881e..7184fd7 100644 --- a/configtypes.js +++ b/configtypes.js @@ -3,7 +3,7 @@ const path = require("path"); const ROOT = __dirname; // import.meta.dirname const PACKAGE_JSON = path.join(ROOT, "package.json"); -const OUT_FILE = path.join(ROOT, "src", "configtype.ts"); +const OUT_FILE = path.join(ROOT, "src", "@types", "configtypes.d.ts"); const OUT_FILE_REL = path.relative(ROOT, OUT_FILE); const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf8")); diff --git a/src/configtype.ts b/src/@types/configtypes.d.ts similarity index 100% rename from src/configtype.ts rename to src/@types/configtypes.d.ts diff --git a/src/activity.ts b/src/activity.ts index 2d7fdd7..0df3973 100644 --- a/src/activity.ts +++ b/src/activity.ts @@ -1,5 +1,5 @@ import type { SetActivity } from "@xhayper/discord-rpc"; -import type { ExtensionConfigGenerated } from "./configtype"; +import type { ExtensionConfigGenerated } from "./@types/configtypes.d.ts"; import type { GatewayActivityButton } from "discord-api-types/v10"; import { resolveLangName, toLower, toTitle, toUpper, getArticle } from "./helpers/resolveLangName"; import { FAKE_EMPTY } from "./constants"; diff --git a/src/config.ts b/src/config.ts index 5d33f58..a62d6ad 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { type ConfigurationTarget, type WorkspaceConfiguration, workspace } from "vscode"; -import type { ExtensionConfigGenerated } from "./configtype"; +import type { ExtensionConfigGenerated } from "./@types/configtypes.d.ts"; export type FileSizeStandard = "iec" | "jedec"; diff --git a/src/editor.ts b/src/editor.ts index bf87772..89d7c7e 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,4 +1,4 @@ -import type { ExtensionConfigGenerated } from "./configtype"; +import type { ExtensionConfigGenerated } from "./@types/configtypes.d.ts"; import { Disposable, ConfigurationTarget, StatusBarAlignment, StatusBarItem, window, commands } from "vscode"; import { type ExtensionConfiguration, getConfig } from "./config"; import { logInfo, outputChannel } from "./logger"; From ef612f2f6a4a08e4cc343c001baa09cbe8ab5a46 Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Sun, 15 Feb 2026 11:14:30 +0100 Subject: [PATCH 09/10] impr: object types --- configtypes.js | 25 +++++++++--- src/@types/configtypes.d.ts | 76 ++++++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/configtypes.js b/configtypes.js index 7184fd7..44fc1d6 100644 --- a/configtypes.js +++ b/configtypes.js @@ -1,7 +1,7 @@ -const fs = require("fs"); // should be changed to import -const path = require("path"); +import * as fs from "node:fs"; +import * as path from "node:path"; -const ROOT = __dirname; // import.meta.dirname +const ROOT = import.meta.dirname; const PACKAGE_JSON = path.join(ROOT, "package.json"); const OUT_FILE = path.join(ROOT, "src", "@types", "configtypes.d.ts"); const OUT_FILE_REL = path.relative(ROOT, OUT_FILE); @@ -9,7 +9,7 @@ const OUT_FILE_REL = path.relative(ROOT, OUT_FILE); const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf8")); const configurations = pkg.contributes?.configuration ?? []; -function schemaTypeToTs(schema) { +function schemaTypeToTs(schema, nesting = 1) { if (!schema) return "unknown"; if (Array.isArray(schema.type)) { @@ -33,11 +33,24 @@ function schemaTypeToTs(schema) { return needsParens ? `(${itemType})[]` : `${itemType}[]`; } case "object": { + if (!schema.additionalProperties && !schema.properties && !schema.propertyNames) { + return "Record"; + } + const spaceZero = " ".repeat(nesting); + const space = spaceZero + " "; + let obj = "{\n"; if (schema.additionalProperties) { const valueType = schemaTypeToTs(schema.additionalProperties); - return `{ [key: string]: ${valueType} }`; + obj += space + `[key: string]: ${valueType};\n`; + } + if (schema.properties) { + for (const prop in schema.properties) { + const valueType = schemaTypeToTs(schema.properties[prop], nesting + 1); + obj += space + `${prop}: ${valueType};\n`; + } } - return "Record"; + obj += spaceZero + "}"; + return obj; } default: return "unknown"; diff --git a/src/@types/configtypes.d.ts b/src/@types/configtypes.d.ts index 0336308..dd426e7 100644 --- a/src/@types/configtypes.d.ts +++ b/src/@types/configtypes.d.ts @@ -63,6 +63,78 @@ export type ExtensionConfigGenerated = { "vscord.status.image.small.debugging.text": string; "vscord.status.image.small.notInFile.key": string; "vscord.status.image.small.notInFile.text": string; + "vscord.status.buttons": { + button1: { + enabled: boolean; + active: { + enabled: boolean; + label: string; + url: string; + }; + inactive: { + enabled: boolean; + label: string; + url: string; + }; + idle: { + enabled: boolean; + label: string; + url: string; + }; + git: { + active: { + enabled: boolean; + label: string; + url: string; + }; + inactive: { + enabled: boolean; + label: string; + url: string; + }; + idle: { + enabled: boolean; + label: string; + url: string; + }; + }; + }; + button2: { + enabled: boolean; + active: { + enabled: boolean; + label: string; + url: string; + }; + inactive: { + enabled: boolean; + label: string; + url: string; + }; + idle: { + enabled: boolean; + label: string; + url: string; + }; + git: { + active: { + enabled: boolean; + label: string; + url: string; + }; + inactive: { + enabled: boolean; + label: string; + url: string; + }; + idle: { + enabled: boolean; + label: string; + url: string; + }; + }; + }; + }; "vscord.status.buttons.button1.enabled": boolean; "vscord.status.buttons.button1.active.enabled": boolean; "vscord.status.buttons.button1.active.label": string; @@ -103,7 +175,9 @@ export type ExtensionConfigGenerated = { "vscord.status.buttons.button2.git.idle.url": string; "vscord.file.size.round": number; "vscord.file.size.spacer": string; - "vscord.behaviour.additionalFileMapping": { [key: string]: string }; + "vscord.behaviour.additionalFileMapping": { + [key: string]: string; + }; "vscord.behaviour.suppressNotifications": boolean; "vscord.behaviour.suppressRpcCouldNotConnect": boolean; "vscord.behaviour.statusBarAlignment": "Right" | "Left"; From a4e5418ce5376fd594e48ec004821ab28b50c05e Mon Sep 17 00:00:00 2001 From: Mopsgamer <79159094+Mopsgamer@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:02:47 +0100 Subject: [PATCH 10/10] refactor: createButton --- src/activity.ts | 106 ++++++------------------------------------------ 1 file changed, 12 insertions(+), 94 deletions(-) diff --git a/src/activity.ts b/src/activity.ts index 0df3973..3d666ba 100644 --- a/src/activity.ts +++ b/src/activity.ts @@ -292,106 +292,24 @@ async function createButton( currentButton: "Button1" | "Button2" ): Promise { const config = getConfig(); - const CONFIG_KEYS = { - Status: { - Buttons: { - Button1: { - Git: { - Idle: { - Enabled: - "vscord.status.buttons.button1.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button1.git.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.git.idle.url" satisfies keyof ExtensionConfigGenerated - }, - Active: { - Enabled: - "vscord.status.buttons.button1.git.active.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button1.git.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.git.active.url" satisfies keyof ExtensionConfigGenerated - }, - Inactive: { - Enabled: - "vscord.status.buttons.button1.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button1.git.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.git.inactive.url" satisfies keyof ExtensionConfigGenerated - } - }, - Idle: { - Enabled: "vscord.status.buttons.button1.idle.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button1.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.idle.url" satisfies keyof ExtensionConfigGenerated - }, - Active: { - Enabled: - "vscord.status.buttons.button1.active.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button1.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.active.url" satisfies keyof ExtensionConfigGenerated - }, - Inactive: { - Enabled: - "vscord.status.buttons.button1.inactive.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button1.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button1.inactive.url" satisfies keyof ExtensionConfigGenerated - } - }, - Button2: { - Git: { - Idle: { - Enabled: - "vscord.status.buttons.button2.git.idle.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button2.git.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.git.idle.url" satisfies keyof ExtensionConfigGenerated - }, - Active: { - Enabled: - "vscord.status.buttons.button2.git.active.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button2.git.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.git.active.url" satisfies keyof ExtensionConfigGenerated - }, - Inactive: { - Enabled: - "vscord.status.buttons.button2.git.inactive.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button2.git.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.git.inactive.url" satisfies keyof ExtensionConfigGenerated - } - }, - Idle: { - Enabled: "vscord.status.buttons.button2.idle.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button2.idle.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.idle.url" satisfies keyof ExtensionConfigGenerated - }, - Active: { - Enabled: - "vscord.status.buttons.button2.active.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button2.active.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.active.url" satisfies keyof ExtensionConfigGenerated - }, - Inactive: { - Enabled: - "vscord.status.buttons.button2.inactive.enabled" satisfies keyof ExtensionConfigGenerated, - Label: "vscord.status.buttons.button2.inactive.label" satisfies keyof ExtensionConfigGenerated, - Url: "vscord.status.buttons.button2.inactive.url" satisfies keyof ExtensionConfigGenerated - } - } - } - } - }; - const currentState = CONFIG_KEYS.Status.Buttons[currentButton]; - const configKeyEnabled = - isGit && state != "Inactive" ? currentState.Git[state].Enabled : currentState[state].Enabled; - const enabled = config.get(configKeyEnabled); + + const b = ({ Button1: "button1", Button2: "button2" } as const)[currentButton]; + const g = isGit ? (".git" as const) : ("" as const); + const s = ({ Idle: "idle", Active: "active", Inactive: "inactive" } as const)[state]; + + const keyEnabled = `vscord.status.buttons.${b}${g}.${s}.enabled` as const satisfies keyof ExtensionConfigGenerated; + const keyLabel = `vscord.status.buttons.${b}${g}.${s}.label` as const satisfies keyof ExtensionConfigGenerated; + const keyUrl = `vscord.status.buttons.${b}${g}.${s}.url` as const satisfies keyof ExtensionConfigGenerated; + + const enabled = config.get(keyEnabled); logInfo("[activity.ts] createButton(): enabled", enabled); if (!enabled) { return undefined; } return { - label: await replaceAllText( - config.get(isGit && state != "Inactive" ? currentState.Git[state].Label : currentState[state].Label)! - ), - url: await replaceAllText( - config.get(isGit && state != "Inactive" ? currentState.Git[state].Url : currentState[state].Url)! - ) + label: await replaceAllText(config.get(keyLabel)!), + url: await replaceAllText(config.get(keyUrl)!) }; }