Fix third party extension findings + enum provider - Allow extension names without the "third-party/" prefix - Expand enum provider to show what third-party extensions are
| @@ -244,7 +244,7 @@ import { commonEnumProviders, enumIcons } from './scripts/slash-commands/SlashCo | ||
| 244 | 244 | import { initInputMarkdown } from './scripts/input-md-formatting.js'; |
| 245 | 245 | import { AbortReason } from './scripts/util/AbortReason.js'; |
| 246 | 246 | import { initSystemPrompts } from './scripts/sysprompt.js'; |
| 247 | 247 | import { registerExtensionSlashCommands as initExtensionSlashCommands } from './scripts/extensions-slashcommands.js'; |
| 248 | 248 | |
| 249 | 249 | //exporting functions and vars for mods |
| 250 | 250 | export { |
| @@ -958,7 +958,7 @@ async function firstLoadInit() { | ||
| 958 | 958 | initLogprobs(); |
| 959 | 959 | initInputMarkdown(); |
| 960 | 960 | initExtensions(); |
| 961 | 961 | registerExtensionSlashCommandsinitExtensionSlashCommands(); |
| 962 | 962 | doDailyExtensionUpdatesCheck(); |
| 963 | 963 | await hideLoader(); |
| 964 | 964 | await fixViewport(); |
| @@ -3,7 +3,7 @@ import { SlashCommand } from './slash-commands/SlashCommand.js'; | ||
| 3 | 3 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; |
| 4 | 4 | import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js'; |
| 5 | 5 | import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 6 | 6 | import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; |
| 7 | 7 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; |
| 8 | 8 | import { equalsIgnoreCaseAndAccents, isFalseBoolean, isTrueBoolean } from './utils.js'; |
| 9 | 9 | |
| @@ -21,7 +21,7 @@ function getExtensionActionCallback(action) { | ||
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | const reload = isTrueBoolean(args?.reload); |
| 24 | 24 | const internalExtensionName = extensionNames.find(x => equalsIgnoreCaseAndAccentsfindExtension(x, extensionName)); |
| 25 | 25 | if (!internalExtensionName) { |
| 26 | 26 | toastr.warning(`Extension ${extensionName} does not exist.`); |
| 27 | 27 | return ''; |
| @@ -57,6 +57,33 @@ function getExtensionActionCallback(action) { | ||
| 57 | 57 | }; |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | +/** | |
| 61 | + * Finds an extension by name, allowing omission of the "third-party/" prefix. | |
| 62 | + * | |
| 63 | + * @param {string} name - The name of the extension to find | |
| 64 | + * @returns {string?} - The matched extension name or undefined if not found | |
| 65 | + */ | |
| 66 | +function findExtension(name) { | |
| 67 | + return extensionNames.find(extName => { | |
| 68 | + return equalsIgnoreCaseAndAccents(extName, name) || equalsIgnoreCaseAndAccents(extName, `third-party/${name}`); | |
| 69 | + }); | |
| 70 | +} | |
| 71 | + | |
| 72 | +/** | |
| 73 | + * Provides an array of SlashCommandEnumValue objects based on the extension names. | |
| 74 | + * Each object contains the name of the extension and a description indicating if it is a third-party extension. | |
| 75 | + * | |
| 76 | + * @returns {SlashCommandEnumValue[]} An array of SlashCommandEnumValue objects | |
| 77 | + */ | |
| 78 | +const extensionNamesEnumProvider = () => extensionNames.map(name => { | |
| 79 | + const isThirdParty = name.startsWith('third-party/'); | |
| 80 | + if (isThirdParty) name = name.slice('third-party/'.length); | |
| 81 | + | |
| 82 | + const description = isThirdParty ? 'third party extension' : null; | |
| 83 | + | |
| 84 | + return new SlashCommandEnumValue(name, description, !isThirdParty ? enumTypes.name : enumTypes.enum); | |
| 85 | +}); | |
| 86 | + | |
| 60 | 87 | export function registerExtensionSlashCommands() { |
| 61 | 88 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 62 | 89 | name: 'extension-enable', |
| @@ -75,7 +102,7 @@ export function registerExtensionSlashCommands() { | ||
| 75 | 102 | description: 'Extension name', |
| 76 | 103 | typeList: [ARGUMENT_TYPE.STRING], |
| 77 | 104 | isRequired: true, |
| 78 | - enumProvider: () => extensionNames.map(name => new SlashCommandEnumValue(name)), | |
| 105 | + enumProvider: extensionNamesEnumProvider, | |
| 79 | 106 | forceEnum: true, |
| 80 | 107 | }), |
| 81 | 108 | ], |
| @@ -115,7 +142,7 @@ export function registerExtensionSlashCommands() { | ||
| 115 | 142 | description: 'Extension name', |
| 116 | 143 | typeList: [ARGUMENT_TYPE.STRING], |
| 117 | 144 | isRequired: true, |
| 118 | - enumProvider: () => extensionNames.map(name => new SlashCommandEnumValue(name)), | |
| 145 | + enumProvider: extensionNamesEnumProvider, | |
| 119 | 146 | forceEnum: true, |
| 120 | 147 | }), |
| 121 | 148 | ], |
| @@ -170,7 +197,7 @@ export function registerExtensionSlashCommands() { | ||
| 170 | 197 | description: 'Extension name', |
| 171 | 198 | typeList: [ARGUMENT_TYPE.STRING], |
| 172 | 199 | isRequired: true, |
| 173 | - enumProvider: () => extensionNames.map(name => new SlashCommandEnumValue(name)), | |
| 200 | + enumProvider: extensionNamesEnumProvider, | |
| 174 | 201 | forceEnum: true, |
| 175 | 202 | }), |
| 176 | 203 | ], |
| @@ -200,7 +227,7 @@ export function registerExtensionSlashCommands() { | ||
| 200 | 227 | name: 'extension-state', |
| 201 | 228 | callback: async (_, extensionName) => { |
| 202 | 229 | if (typeof extensionName !== 'string') throw new Error('Extension name must be a string. Closures or arrays are not allowed.'); |
| 203 | 230 | const internalExtensionName = extensionNames.find(x => equalsIgnoreCaseAndAccentsfindExtension(x, extensionName)); |
| 204 | 231 | if (!internalExtensionName) { |
| 205 | 232 | toastr.warning(`Extension ${extensionName} does not exist.`); |
| 206 | 233 | return ''; |
| @@ -214,7 +241,7 @@ export function registerExtensionSlashCommands() { | ||
| 214 | 241 | description: 'Extension name', |
| 215 | 242 | typeList: [ARGUMENT_TYPE.STRING], |
| 216 | 243 | isRequired: true, |
| 217 | - enumProvider: () => extensionNames.map(name => new SlashCommandEnumValue(name)), | |
| 244 | + enumProvider: extensionNamesEnumProvider, | |
| 218 | 245 | forceEnum: true, |
| 219 | 246 | }), |
| 220 | 247 | ], |
| @@ -237,7 +264,7 @@ export function registerExtensionSlashCommands() { | ||
| 237 | 264 | aliases: ['extension-installed'], |
| 238 | 265 | callback: async (_, extensionName) => { |
| 239 | 266 | if (typeof extensionName !== 'string') throw new Error('Extension name must be a string. Closures or arrays are not allowed.'); |
| 240 | 267 | const exists = extensionNames.find(x => equalsIgnoreCaseAndAccentsfindExtension(x, extensionName)) !== undefined; |
| 241 | 268 | return exists ? 'true' : 'false'; |
| 242 | 269 | }, |
| 243 | 270 | unnamedArgumentList: [ |
| @@ -245,8 +272,7 @@ export function registerExtensionSlashCommands() { | ||
| 245 | 272 | description: 'Extension name', |
| 246 | 273 | typeList: [ARGUMENT_TYPE.STRING], |
| 247 | 274 | isRequired: true, |
| 248 | - enumProvider: () => extensionNames.map(name => new SlashCommandEnumValue(name)), | |
| 275 | + enumProvider: extensionNamesEnumProvider, | |
| 249 | - forceEnum: true, | |
| 250 | 276 | }), |
| 251 | 277 | ], |
| 252 | 278 | helpString: ` |
| @@ -257,7 +283,7 @@ export function registerExtensionSlashCommands() { | ||
| 257 | 283 | <strong>Example:</strong> |
| 258 | 284 | <ul> |
| 259 | 285 | <li> |
| 260 | 286 | <pre><code class="language-stscript">/extension-exists SillyTavern-LALib</code></pre> |
| 261 | 287 | </li> |
| 262 | 288 | </ul> |
| 263 | 289 | </div> |